diff --git a/pygeo/constraints/DVCon.py b/pygeo/constraints/DVCon.py index c9443f1e..0a438264 100644 --- a/pygeo/constraints/DVCon.py +++ b/pygeo/constraints/DVCon.py @@ -1825,14 +1825,18 @@ def addLeTeConstraints( indSetB : array of int Indices of control points on the *other* side of the FFD name : str - Normally this does not need to be set; a default name will - be generated automatically. Only use this if you have - multiple DVCon objects and the constriant names need to - be distinguished + Normally this does not need to be set; a default name will + be generated automatically. Only use this if you have + multiple DVCon objects and the constriant names need to + be distinguished config : str - The DVGeo configuration to apply this LETE con to. Must be either None - which will allpy to *ALL* the local DV groups or a single string specifying - a particular configuration. + The DVGeo configuration to apply this constraint to. Must be either None + which will apply to *ALL* the local DV groups or a single string specifying + a particular configuration. + childIdx : int + The zero-based index of the child FFD, if this constraint is being applied to a child FFD. + The index is defined by the order in which you add the child FFD to the parent. + For example, the first child FFD has an index of 0, the second an index of 1, and so on. Examples -------- @@ -1944,7 +1948,17 @@ def addLeTeConstraints( ) def addLinearConstraintsShape( - self, indSetA, indSetB, factorA, factorB, lower=0, upper=0, name=None, config=None, DVGeoName="default" + self, + indSetA, + indSetB, + factorA, + factorB, + lower=0, + upper=0, + name=None, + config=None, + childIdx=None, + DVGeoName="default", ): """ Add a complete generic set of linear constraints for the shape @@ -1987,10 +2001,18 @@ def addLinearConstraintsShape( upper : float or array The upper bound of the constraint(s) name : str - Normally this does not need to be set; a default name will - be generated automatically. Only use this if you have - multiple DVCon objects and the constriant names need to - be distinguished + Normally this does not need to be set; a default name will + be generated automatically. Only use this if you have + multiple DVCon objects and the constriant names need to + be distinguished + config : str + The DVGeo configuration to apply this constraint to. Must be either None + which will apply to *ALL* the local DV groups or a single string specifying + a particular configuration. + childIdx : int + The zero-based index of the child FFD, if this constraint is being applied to a child FFD. + The index is defined by the order in which you add the child FFD to the parent. + For example, the first child FFD has an index of 0, the second an index of 1, and so on. Examples -------- @@ -2007,6 +2029,11 @@ def addLinearConstraintsShape( self._checkDVGeo(DVGeoName) + if childIdx is not None: + DVGeo = self.DVGeometries[DVGeoName].children[childIdx] + else: + DVGeo = self.DVGeometries[DVGeoName] + if len(indSetA) != len(indSetB): raise Error("The length of the supplied indices are not " "the same length") @@ -2044,7 +2071,7 @@ def addLinearConstraintsShape( # Finally add the linear constraint object self.linearCon[conName] = LinearConstraint( - conName, indSetA, indSetB, factorA, factorB, lower, upper, self.DVGeometries[DVGeoName], config=config + conName, indSetA, indSetB, factorA, factorB, lower, upper, DVGeo, config=config ) def addGearPostConstraint( @@ -2751,7 +2778,9 @@ def addCurvatureConstraint( addToPyOpt, ) - def addMonotonicConstraints(self, key, slope=1.0, name=None, start=0, stop=-1, config=None, DVGeoName="default"): + def addMonotonicConstraints( + self, key, slope=1.0, name=None, start=0, stop=-1, config=None, childIdx=None, DVGeoName="default" + ): """ Parameters ---------- @@ -2773,9 +2802,13 @@ def addMonotonicConstraints(self, key, slope=1.0, name=None, start=0, stop=-1, c a design variable vector [4, 3, 6.5, 2, -5.4, -1], start=1 and stop=4 would constrain [3, 6.5, 2, -5.4] to be a monotonic sequence. config : str - The DVGeo configuration to apply this LETE con to. Must be either None - which will allpy to *ALL* the local DV groups or a single string specifying + The DVGeo configuration to apply this constraint to. Must be either None + which will apply to *ALL* the local DV groups or a single string specifying a particular configuration. + childIdx : int + The zero-based index of the child FFD, if this constraint is being applied to a child FFD. + The index is defined by the order in which you add the child FFD to the parent. + For example, the first child FFD has an index of 0, the second an index of 1, and so on. Examples -------- @@ -2783,6 +2816,11 @@ def addMonotonicConstraints(self, key, slope=1.0, name=None, start=0, stop=-1, c """ self._checkDVGeo(DVGeoName) + if childIdx is not None: + DVGeo = self.DVGeometries[DVGeoName].children[childIdx] + else: + DVGeo = self.DVGeometries[DVGeoName] + if name is None: conName = "%s_monotonic_constraint_%d" % (self.name, len(self.linearCon)) else: @@ -2797,7 +2835,7 @@ def addMonotonicConstraints(self, key, slope=1.0, name=None, start=0, stop=-1, c options=options, lower=0, upper=None, - DVGeo=self.DVGeometries[DVGeoName], + DVGeo=DVGeo, config=config, ) diff --git a/tests/reg_tests/ref/test_DVConstraints_LERadius.ref b/tests/reg_tests/ref/test_DVConstraints_LERadius.ref new file mode 100644 index 00000000..b7faf6e5 --- /dev/null +++ b/tests/reg_tests/ref/test_DVConstraints_LERadius.ref @@ -0,0 +1,1382 @@ +{ + "derivs_base": { + "DVCon1_leradius_constraints_0": { + "local": { + "__ndarray__": [ + [ + -3.504820301029838, + 3.6408039336541833, + -0.0001504166608519205, + 3.2512624305140736e-05, + -1.4512674948401669e-08, + 1.5075752678236853e-08, + -6.228416632734352e-13, + 1.346274866421345e-13, + -0.37988489973560036, + -0.013255396961674437, + 0.25190951655870464, + 0.005365051551098343, + -1.573018184712365e-09, + -5.488762643844855e-11, + 1.0431008200767692e-09, + 2.221547541813624e-11, + -0.01688421658884609, + -2.7112827984867877e-05, + -7.246213107270171e-07, + -1.1636034664995697e-09, + 0.01753930783706137, + 2.816477944697941e-05, + 1.5662720011023107e-07, + 2.5151337712318355e-10, + -0.0018300678423038008, + -2.9387395232656683e-06, + -6.385690964135719e-05, + -1.0254200410429748e-07, + 0.0012135557526642693, + 1.9487388235571185e-06, + 2.584574517913371e-05, + 4.150333179482592e-08 + ], + [ + -1.9249982325885036, + 1.8926358702381272, + -3.6031151072786504e-05, + 6.444097762390796e-05, + -0.026353383151117626, + 0.025910339765281953, + -4.932694033282897e-07, + 8.822022509973416e-07, + -0.15511219078407912, + -0.004121985825043223, + 0.18555684161717512, + 0.006011287515748073, + -0.0021234985705131937, + -5.6430322870878254e-05, + 0.0025402883289265196, + 8.229501744581966e-05, + -1.3815086342466394, + -0.3304879409216559, + -2.5858385460419357e-05, + -6.185907459805822e-06, + 1.3582832191502732, + 0.32493189919888366, + 4.624719414262203e-05, + 1.1063369121781859e-05, + -0.11131897537223545, + -0.026630002914415918, + -0.0029582151874924315, + -0.0007076716148434938, + 0.13316811127299544, + 0.03185680769562366, + 0.004314105574412912, + 0.0010320310947487272 + ], + [ + -0.7597556524414844, + 0.7628879208163608, + -2.2192752046472053e-05, + 1.9396131658942085e-05, + -0.23758647105326475, + 0.23856597622333936, + -6.939991331077993e-06, + 6.065448092585278e-06, + -0.07025576362339861, + -0.0021636494175118126, + 0.0673106805498048, + 0.001979260736650377, + -0.021969983239738054, + -0.0006766041529946696, + 0.021049013593553857, + 0.0006189431723263395, + -1.5470741048384546, + -1.0500912489300034, + -4.5190623980046e-05, + -3.0673565426969313e-05, + 1.5534522756050286, + 1.05442049294304, + 3.9495925995623984e-05, + 2.680823505912212e-05, + -0.14306030138523143, + -0.09710353892169005, + -0.004405792803284417, + -0.002990473728994922, + 0.13706329202423914, + 0.09303301183443652, + 0.00403032609570618, + 0.00273562213354806 + ], + [ + -0.1236265020238064, + 0.12568004272999814, + -6.324587542667213e-05, + 5.194277459597621e-05, + -0.6692813465262966, + 0.6803986754686122, + -0.0003423965248134773, + 0.00028120451161201996, + -0.029784608021259568, + -0.002381646260519516, + 0.02803568265932571, + 0.002088334017092593, + -0.16124602925663847, + -0.0128936060641987, + 0.15177780762092738, + 0.011305690770796479, + -0.6512262267288855, + -1.1434862035700508, + -0.0003331597362703479, + -0.0005849941946038648, + 0.6620436448684834, + 1.1624804760566025, + 0.00027361849241235324, + 0.0004804459007843637, + -0.15689611514324536, + -0.2754934240919772, + -0.012545776854079538, + -0.022029092436537882, + 0.14768331654716987, + 0.259316698311448, + 0.011000698554415933, + 0.019316094024334297 + ], + [ + -0.0022749137361386413, + 0.0023308094873611615, + -5.367728441783179e-06, + 4.526746070724667e-06, + -1.2902339082705823, + 1.3219355910244734, + -0.003044346313426537, + 0.002567377031400372, + -0.0009125250817124944, + -0.00012145587366620123, + 0.0008703355287917333, + 0.00010859065773552329, + -0.5175452518789878, + -0.06888458409361436, + 0.4936171394022739, + 0.06158798309846686, + -0.05649205333882014, + -0.4676151070022523, + -0.00013329472525679839, + -0.0011033521270674262, + 0.05788009091990025, + 0.4791046405496884, + 0.00011241093515604271, + 0.0009304857650676776, + -0.022660382576357895, + -0.18757217337458684, + -0.0030160667564960732, + -0.024965606589054175, + 0.021612705718954895, + 0.17889998858356884, + 0.002696589822920157, + 0.02232112419463935 + ] + ], + "dtype": "float64", + "shape": [ + 5, + 32 + ] + }, + "twist": { + "__ndarray__": [ + [ + -1.3877787807814457e-17, + -5.421010862427522e-20, + -2.6469779601696886e-23 + ], + [ + 1.1102230246251565e-16, + 3.469446951953614e-17, + 0.0 + ], + [ + 6.938893903907228e-17, + 2.42861286636753e-16, + 1.0581813203458523e-16 + ], + [ + -3.469446951953614e-18, + -6.765421556309548e-17, + -1.3877787807814457e-17 + ], + [ + -8.673617379884035e-19, + -3.469446951953614e-18, + -3.2959746043559335e-17 + ] + ], + "dtype": "float64", + "shape": [ + 5, + 3 + ] + } + }, + "unscaled_radius_con": { + "local": { + "__ndarray__": [ + [ + -0.009094043188999645, + 0.009446883255499028, + -3.902897988038249e-07, + 8.436130363996167e-08, + -3.765639360451634e-11, + 3.911742519931348e-11, + -1.6161025385674364e-15, + 3.493212412603052e-16, + -0.0009856966658259997, + -3.4394103578258475e-05, + 0.0006536358005663767, + 1.3920830834767469e-05, + -4.081548861336285e-12, + -1.4241827041068718e-13, + 2.706559279364917e-12, + 5.764303889056117e-14, + -4.380989085981963e-05, + -7.035031970051582e-08, + -1.8801926859088537e-09, + -3.019230451303785e-12, + 4.550967218733878e-05, + 7.307984395782827e-08, + 4.064044373276306e-10, + 6.52607927857907e-13, + -4.748521911899497e-06, + -7.625219512094776e-09, + -1.6569108950433626e-07, + -2.660682528394066e-10, + 3.14884287326957e-06, + 5.056440417302346e-09, + 6.706258886992484e-08, + 1.0768971285593063e-10 + ], + [ + -0.048407592246937026, + 0.047593781608421426, + -9.06069023748598e-07, + 1.6204859391572041e-06, + -0.0006627038946374498, + 0.0006515627604763031, + -1.2404158996082636e-08, + 2.2184584963584452e-08, + -0.003900579001523616, + -0.00010365485312577999, + 0.004666165285541771, + 0.00015116479070744187, + -5.3399245359374726e-05, + -1.4190434119117517e-06, + 6.388018416566264e-05, + 2.069458340808463e-06, + -0.03474055483277422, + -0.008310722168899387, + -6.502562747026095e-07, + -1.555559277521582e-07, + 0.03415650940108633, + 0.008171005364140976, + 1.1629700634117665e-06, + 2.7820859897851893e-07, + -0.0027993187099813466, + -0.0006696600032106946, + -7.438971742964825e-05, + -1.7795693729033178e-05, + 0.0033487550906109997, + 0.0008010975444612198, + 0.00010848605469917908, + 2.595230456579645e-05 + ], + [ + -0.01886613906560061, + 0.0189439190867973, + -5.510871094037459e-07, + 4.816418489765487e-07, + -0.005899711819967566, + 0.0059240347462856825, + -1.7233282983210788e-07, + 1.5061630254696884e-07, + -0.0017445806456584355, + -5.372741968922358e-05, + 0.0016714487819498615, + 4.91487074623708e-05, + -0.0005455553476145254, + -1.680133343100533e-05, + 0.0005226859666967593, + 1.5369504557535463e-05, + -0.03841671346949273, + -0.02607570930235304, + -1.1221668357834042e-06, + -7.616814025974961e-07, + 0.038575095254846356, + 0.026183212444101815, + 9.807569446355715e-07, + 6.656980953065851e-07, + -0.0035524520706456866, + -0.0024112605982877745, + -0.00010940398989316873, + -7.425899769477374e-05, + 0.0034035352284759544, + 0.0023101818766597853, + 0.00010008045660070723, + 6.7930560880464e-05 + ], + [ + -0.0031942783844992645, + 0.003247338048746776, + -1.6341555368544572e-06, + 1.3421044792717164e-06, + -0.01729298251879543, + 0.01758023357704317, + -8.846888007304001e-06, + 7.265800442149333e-06, + -0.00076957875565202, + -6.153730021444768e-05, + 0.000724389784126706, + 5.395865854983764e-05, + -0.004166296849049662, + -0.0003331467482691334, + 0.003921655649828668, + 0.00029211797680754343, + -0.01682647187622051, + -0.029545552152996805, + -8.608226607826499e-06, + -1.5115159616186862e-05, + 0.017105973798330662, + 0.030036328750569725, + 7.069791845633142e-06, + 1.2413826571759207e-05, + -0.004053903176177126, + -0.007118236585544033, + -0.0003241594897995285, + -0.000569190688470817, + 0.0038158616322165745, + 0.006700260143221278, + 0.0002842375464121472, + 0.0004990918662650902 + ], + [ + -6.0154594506228e-05, + 6.163262252812521e-05, + -1.4193660300415705e-07, + 1.196988571440529e-07, + -0.03411711676678387, + 0.03495539113338133, + -8.050037903043493e-05, + 6.788807936543256e-05, + -2.4129519900104154e-05, + -3.211606978641377e-06, + 2.3013919159719533e-05, + 2.87141744298954e-06, + -0.0136852331017385, + -0.0018214863087138173, + 0.013052512009738183, + 0.0016285453337817968, + -0.0014937957898961962, + -0.012364951118741054, + -3.5246567903940555e-06, + -2.9175479820163237e-05, + 0.0015304990883654394, + 0.012668764059263735, + 2.9724354444556977e-06, + 2.4604446754306394e-05, + -0.0005991990393229263, + -0.004959892698679682, + -7.975259450878735e-05, + -0.0006601551158223972, + 0.0005714957574228358, + 0.004730577735523217, + 7.130479928558374e-05, + 0.0005902281715221285 + ] + ], + "dtype": "float64", + "shape": [ + 5, + 32 + ] + }, + "twist": { + "__ndarray__": [ + [ + -4.0657581468206416e-20, + -1.0587911840678754e-22, + -7.754818242684634e-26 + ], + [ + 3.469446951953614e-18, + 1.5178830414797062e-18, + -4.0657581468206416e-20 + ], + [ + 2.2768245622195593e-18, + 6.396792817664476e-18, + 2.6834003769016235e-18 + ], + [ + -1.6263032587282567e-19, + -1.6263032587282567e-18, + -9.486769009248164e-20 + ], + [ + -2.795208725939191e-20, + -8.809142651444724e-20, + -6.2341624917916505e-19 + ] + ], + "dtype": "float64", + "shape": [ + 5, + 3 + ] + } + } + }, + "derivs_deformed": { + "DVCon1_leradius_constraints_0": { + "local": { + "__ndarray__": [ + [ + -3.7182073819373613, + 3.8650395966027986, + -0.00016072138063411186, + 3.341112667301638e-05, + -1.5396263000688627e-08, + 1.6004262276077194e-08, + -6.655111971691968e-13, + 1.383479834680476e-13, + -0.40433638501500724, + -0.014140327601040337, + 0.2661513066225254, + 0.005620501584205906, + -1.674266302272473e-09, + -5.855192577990782e-11, + 1.102072879163106e-09, + 2.3273236723320068e-11, + -0.01791219331285898, + -2.876356232270035e-05, + -7.742635479164104e-07, + -1.2433194207825018e-09, + 0.018619546815092924, + 2.9899436985859288e-05, + 1.6095566984102478e-07, + 2.58464073036796e-10, + -0.0019478610921474793, + -3.127892991179658e-06, + -6.811999855828917e-05, + -1.0938771091460739e-07, + 0.0012821645392487313, + 2.0589114347130074e-06, + 2.7076357112463742e-05, + 4.347945958783897e-08 + ], + [ + -1.8274079695420866, + 1.8037344917487417, + -3.739095586075762e-05, + 5.8173103674628575e-05, + -0.025017364473104403, + 0.024693272627073243, + -5.118852420243782e-07, + 7.963945443034235e-07, + -0.15087834169471503, + -0.0041281071294623425, + 0.17314898923339794, + 0.00551015523632329, + -0.0020655368304101952, + -5.6514124028723945e-05, + 0.0023704238155900677, + 7.54344755785598e-05, + -1.311471275908005, + -0.31373342938901727, + -2.6834273138480144e-05, + -6.419361743983408e-06, + 1.2944815907122198, + 0.3096691145247683, + 4.1748944828566494e-05, + 9.987286702387415e-06, + -0.10828047955752007, + -0.02590312636771097, + -0.0029626082486208655, + -0.0007087225338827802, + 0.12426339909692441, + 0.029726600240804202, + 0.00395445923333855, + 0.000945995600090753 + ], + [ + -0.6555808837056132, + 0.6685612868484094, + -2.3878271270869256e-05, + 1.2288823713007445e-05, + -0.2050095292467642, + 0.209068687168946, + -7.467077326595134e-06, + 3.842891132150732e-06, + -0.0659185533705765, + -0.002183468827861008, + 0.053713863028201025, + 0.0014193454750327395, + -0.020613675491486738, + -0.0006828019663943953, + 0.016797094068991103, + 0.0004438496528913743, + -1.3349452623995823, + -0.9061067814800925, + -4.86228105480465e-05, + -3.300319467257595e-05, + 1.3613769783177503, + 0.9240475598132143, + 2.5023467590170082e-05, + 1.69849163993756e-05, + -0.13422853337163554, + -0.09110889246315768, + -0.004446150642579014, + -0.0030178669958955996, + 0.10937638475571165, + 0.07424026044541854, + 0.0028901826833224384, + 0.001961738958769988 + ], + [ + -0.10553279543328117, + 0.10936969040408953, + -6.020588517643791e-05, + 3.908684399985973e-05, + -0.5713267808602202, + 0.5920987204565352, + -0.0003259388176487805, + 0.0002116058867268754, + -0.026554445024865824, + -0.0022005802375675843, + 0.02328670219157729, + 0.001652547141224196, + -0.14375877689298655, + -0.011913362268025491, + 0.1260680771824676, + 0.008946455313147406, + -0.5559141692202276, + -0.976128043960182, + -0.0003171460066286933, + -0.0005568757341344349, + 0.5761257467807837, + 1.0116174931627582, + 0.00020589742099042448, + 0.0003615346719615793, + -0.13988061421565534, + -0.24561595638729802, + -0.011591976973103475, + -0.02035431804923891, + 0.12266715431501816, + 0.2153908931078984, + 0.008705107898820947, + 0.015285273188228744 + ], + [ + -0.0020657266235215165, + 0.002150367288272654, + -5.165449675787438e-06, + 3.891984244631173e-06, + -1.1715919124954162, + 1.2195964824910324, + -0.0029296224367955873, + 0.0022073672346809153, + -0.0008479611428806703, + -0.00011503330571346199, + 0.000784075217266195, + 9.555203200797613e-05, + -0.4809273433363454, + -0.06524197786237268, + 0.4446939749322472, + 0.05419303147296694, + -0.05129739064193092, + -0.42461609016217533, + -0.00012827161486082448, + -0.0010617731408831279, + 0.053399239548021726, + 0.4420142239355989, + 9.664814012453253e-05, + 0.0008000086333354345, + -0.02105709124345551, + -0.17430086875950515, + -0.002856577609459587, + -0.023645429145514263, + 0.019470636750662833, + 0.16116893172489052, + 0.0023728066708979855, + 0.019640996914253653 + ] + ], + "dtype": "float64", + "shape": [ + 5, + 32 + ] + }, + "twist": { + "__ndarray__": [ + [ + -3.196704166583131e-06, + -1.6781905374771736e-08, + -1.5149627578124044e-11 + ], + [ + 0.0001351811727267893, + -0.00010466891672378242, + -1.9207940913580808e-05 + ], + [ + 0.0005321670714041882, + -7.635435356311004e-05, + -0.00011614504091379818 + ], + [ + 0.000525249159982831, + 0.00026064308625454655, + -0.00023586433701668942 + ], + [ + 9.579632370206146e-05, + 0.0004055671368795267, + 4.163593860482401e-05 + ] + ], + "dtype": "float64", + "shape": [ + 5, + 3 + ] + } + }, + "unscaled_radius_con": { + "local": { + "__ndarray__": [ + [ + -0.009647723881039294, + 0.010028713029416325, + -4.1702770794064387e-07, + 8.669266976919055e-08, + -3.994906119332963e-11, + 4.152665182404919e-11, + -1.7268182246151687e-15, + 3.589749056177778e-16, + -0.0010491415343406169, + -3.669025481069146e-05, + 0.000690589322517518, + 1.4583653300453102e-05, + -4.3442598350275234e-12, + -1.5192611777703499e-13, + 2.859575527335858e-12, + 6.038763809017293e-14, + -4.647720727621665e-05, + -7.463352057030277e-08, + -2.0090006161945273e-09, + -3.226071392874613e-12, + 4.831259475594329e-05, + 7.758080241554201e-08, + 4.1763562389161693e-10, + 6.70643069007128e-13, + -5.054162946087934e-06, + -8.116020654183091e-09, + -1.767526308671712e-07, + -2.8383097618756143e-10, + 3.3268637744153853e-06, + 5.3423079933951825e-09, + 7.02556878334591e-08, + 1.1281722010397335e-10 + ], + [ + -0.045953507053066556, + 0.045358194267482554, + -9.402637957734107e-07, + 1.462868814499423e-06, + -0.0006291072677394628, + 0.0006209573870447002, + -1.2872288220140763e-08, + 2.00267936435901e-08, + -0.0037941111425493154, + -0.00010380878449222112, + 0.0043541472022594965, + 0.00013856290534801884, + -5.1941691667465066e-05, + -1.4211507449004918e-06, + 5.960863110155497e-05, + 1.8969375001753982e-06, + -0.03297933769131711, + -0.007889399411902323, + -6.747967506358542e-07, + -1.614265616080489e-07, + 0.03255210106354389, + 0.007787194800292316, + 1.0498533784540545e-06, + 2.5114854349363813e-07, + -0.002722910189727812, + -0.0006513813664353, + -7.450018896578781e-05, + -1.7822121005420954e-05, + 0.0031248298584740652, + 0.000747529591967248, + 9.944209136607002e-05, + 2.3788785101902526e-05 + ], + [ + -0.01627928674303876, + 0.016601614178224797, + -5.929416714369919e-07, + 3.0515423791480995e-07, + -0.005090766058947704, + 0.005191562463164004, + -1.8542135067298811e-07, + 9.542609953626237e-08, + -0.0016368796874312117, + -5.421957233151686e-05, + 0.0013338146368298432, + 3.524497518122915e-05, + -0.0005118757158644556, + -1.6955236609120686e-05, + 0.00041710293511500966, + 1.1021608393117096e-05, + -0.03314916168700047, + -0.0225003084778021, + -1.2073943808275283e-06, + -8.195304086268244e-07, + 0.03380551011514585, + 0.022945811210016265, + 6.213790156645908e-07, + 4.2176691121478793e-07, + -0.0033331429243376905, + -0.0022624024313595732, + -0.00011040614974031538, + -7.493922321352936e-05, + 0.0027160180758942325, + 0.0018435230765690806, + 7.176858540417549e-05, + 4.8713609286917176e-05 + ], + [ + -0.0027267707311123173, + 0.002825908945558329, + -1.555607855035054e-06, + 1.009931194874412e-06, + -0.014762019119783212, + 0.015298727322073505, + -8.42165152973638e-06, + 5.4675017001960995e-06, + -0.0006861173645353877, + -5.6858891670855306e-05, + 0.000601684980478563, + 4.2698737941820934e-05, + -0.003714458842513327, + -0.000307819075655274, + 0.003257364135740043, + 0.00023115972996770777, + -0.014363785962617379, + -0.02522132924803718, + -8.194461681923306e-06, + -1.438863100773686e-05, + 0.014886015454364077, + 0.026138310466544395, + 5.3200055855920635e-06, + 9.34138205796294e-06, + -0.0036142543474497572, + -0.006346258508753877, + -0.0002995150786654728, + -0.0005259176399198522, + 0.003169490627835156, + 0.005565299210197351, + 0.00022492376262965786, + 0.00039494296891877644 + ], + [ + -5.4623146989993455e-05, + 5.6861264763850014e-05, + -1.365878300144842e-07, + 1.0291411508983401e-07, + -0.03097991598686393, + 0.032249280796904436, + -7.746678343984725e-05, + 5.836849055821604e-05, + -2.242228261085839e-05, + -3.0417776946785035e-06, + 2.0732973742155177e-05, + 2.5266425044503895e-06, + -0.012716961028359727, + -0.0017251663923559639, + 0.0117588571893795, + 0.0014330037141772767, + -0.0013564354921565553, + -0.011227946061761761, + -3.3918327785514286e-06, + -2.8076024041175355e-05, + 0.0014120138055891609, + 0.011687997652149468, + 2.5556264339238417e-06, + 2.1154294413580254e-05, + -0.0005568038757288127, + -0.0046089651294242695, + -7.553528955532194e-05, + -0.0006252462146492002, + 0.0005148539216709903, + 0.004261722798935125, + 6.274313652517428e-05, + 0.000519358684378263 + ] + ], + "dtype": "float64", + "shape": [ + 5, + 32 + ] + }, + "twist": { + "__ndarray__": [ + [ + -8.294566698578958e-09, + -4.354442144347678e-11, + -3.9309110213779874e-14 + ], + [ + 3.3993771932049055e-06, + -2.632090853859183e-06, + -4.830187144627072e-07 + ], + [ + 1.3214693359611153e-05, + -1.8960199216102973e-06, + -2.8840963362602393e-06 + ], + [ + 1.3571459280522884e-05, + 6.734531535412629e-06, + -6.094294840288956e-06 + ], + [ + 2.5331022077637463e-06, + 1.0724242540048823e-05, + 1.1009617480749504e-06 + ] + ], + "dtype": "float64", + "shape": [ + 5, + 3 + ] + } + } + }, + "derivs_twisted": { + "DVCon1_leradius_constraints_0": { + "local": { + "__ndarray__": [ + [ + -3.5048196793091506, + 3.640804348357051, + -0.00015041710751549642, + 3.251217234187011e-05, + -1.4512672373996645e-08, + 1.5075754395428017e-08, + -6.228435128071504e-13, + 1.3462561516356973e-13, + -0.379885378277379, + -0.013255426760789613, + 0.2519090197130467, + 0.00536502121252469, + -1.573020166246604e-09, + -5.488774982990283e-11, + 1.0430987627502338e-09, + 2.2215349792907184e-11, + -0.016884213593753028, + -2.7112823175319285e-05, + -7.246234624962719e-07, + -1.1636069218301353e-09, + 0.01753930983486196, + 2.816478265506555e-05, + 1.566250228100886e-07, + 2.515098807948734e-10, + -0.0018300701476439418, + -2.9387432252018326e-06, + -6.385705319642346e-05, + -1.0254223462633001e-07, + 0.0012135533591464132, + 1.9487349800244758e-06, + 2.5845599025266057e-05, + 4.1503097099619603e-08 + ], + [ + -1.9214445153153825, + 1.8966992795221351, + -3.938126735151057e-05, + 6.11042753707127e-05, + -0.0263047324711721, + 0.02596596817051816, + -5.39132769018391e-07, + 8.365225244131729e-07, + -0.15871780960879667, + -0.004345004662832705, + 0.18199670548658053, + 0.005789621570437761, + -0.0021728597869424132, + -5.948346898950081e-05, + 0.0024915497742975523, + 7.926039253582074e-05, + -1.3789582469198454, + -0.3298778309047594, + -2.8262654974248647e-05, + -6.761062809073262e-06, + 1.3611993958590656, + 0.32562951426401154, + 4.3852551438716073e-05, + 1.049051672199324e-05, + -0.11390661075486719, + -0.027249023504126835, + -0.0031182685552254355, + -0.0007459599806404187, + 0.13061311734092484, + 0.03124559567512264, + 0.004155023133618742, + 0.0009939749965155644 + ], + [ + -0.7529841208863646, + 0.7683549535175809, + -2.763848812942598e-05, + 1.3914765010778184e-05, + -0.23546891617804033, + 0.24027559562852896, + -8.642950978799759e-06, + 4.351346256947315e-06, + -0.07595042675921954, + -0.0025221013249953367, + 0.06149815971444722, + 0.0016172594617096022, + -0.02375078594114466, + -0.0007886971969458994, + 0.019231355101960723, + 0.0005057401903497362, + -1.5332853806804252, + -1.0407320213875266, + -5.627965931482589e-05, + -3.8200353528269464e-05, + 1.564584676785831, + 1.0619767160243896, + 2.83343369067522e-05, + 1.923220040782767e-05, + -0.1546562215273133, + -0.10497437990235692, + -0.005135700717908864, + -0.0034859056616184173, + 0.1252273807818305, + 0.08499927461403167, + 0.00329319068041882, + 0.002235284466174041 + ], + [ + -0.12113618666488851, + 0.12692782930003782, + -7.324646099094057e-05, + 4.136809574447981e-05, + -0.6557994345623833, + 0.6871538635723132, + -0.0003965370631522242, + 0.00022395598330334236, + -0.031232323809856875, + -0.002637468326640955, + 0.026299794027841834, + 0.0018102338387533798, + -0.16908358153319827, + -0.014278559404154281, + 0.1423801634129279, + 0.009800129594340715, + -0.6381080146303122, + -1.1204519737823893, + -0.0003858397320275987, + -0.0006774948431958688, + 0.6686165991013342, + 1.1740219069349551, + 0.00021791435054474887, + 0.000382635162990119, + -0.16452223474503197, + -0.2888841049237683, + -0.013893368479717947, + -0.0243953245824763, + 0.13853919142030086, + 0.24326055607219182, + 0.00953575271490976, + 0.016743799961690495 + ], + [ + -0.0022020493597208666, + 0.002337707772477752, + -5.896907562435586e-06, + 3.855852005991579e-06, + -1.248908346045631, + 1.3258480037128941, + -0.0033444741091175774, + 0.0021868745721531154, + -0.0009298594799149757, + -0.0001289877027898241, + 0.0008274658693278414, + 9.7763956176549e-05, + -0.5273765821773716, + -0.07315631588380223, + 0.469303299542036, + 0.055447540388834544, + -0.05468264044825513, + -0.45263762340189356, + -0.0001464356257818564, + -0.0012121264279106978, + 0.058051393367356596, + 0.48052260303401445, + 9.575088221094511e-05, + 0.0007925815470379255, + -0.02309084098552516, + -0.19113530912848703, + -0.003203101757354084, + -0.026513795878879195, + 0.02054814003869224, + 0.17008800592290535, + 0.0024277345286569055, + 0.02009566433321418 + ] + ], + "dtype": "float64", + "shape": [ + 5, + 32 + ] + }, + "twist": { + "__ndarray__": [ + [ + 5.6205585324820007e-11, + -1.171085491414762e-08, + -1.2489272790607617e-11 + ], + [ + 5.999862080766083e-05, + -0.0001229264430283386, + -2.0674434147672713e-05 + ], + [ + 0.0002778805487017033, + -0.0002561861842491353, + -0.00015815926740657058 + ], + [ + 0.00036723398871972394, + -2.7483368542816078e-05, + -0.00040946503213744843 + ], + [ + 7.920049625422334e-05, + 0.00026572132050833343, + -0.00034811119095214463 + ] + ], + "dtype": "float64", + "shape": [ + 5, + 3 + ] + } + }, + "unscaled_radius_con": { + "local": { + "__ndarray__": [ + [ + -0.009094041575806289, + 0.009446884331538508, + -3.902909577727723e-07, + 8.436013091976639e-08, + -3.765638692464495e-11, + 3.911742965494915e-11, + -1.616107337597957e-15, + 3.493163852889966e-16, + -0.0009856979075101024, + -3.4394180898754834e-05, + 0.0006536345113887371, + 1.392075211452664e-05, + -4.0815540028716665e-12, + -1.4241859057752356e-13, + 2.7065539411693613e-12, + 5.764271292769448e-14, + -4.380988308837815e-05, + -7.035030722106252e-08, + -1.88019826915731e-09, + -3.019239416934817e-12, + 4.55096773710811e-05, + 7.307985228192428e-08, + 4.0639878783354816e-10, + 6.525988558490184e-13, + -4.74852789362221e-06, + -7.625229117599487e-09, + -1.6569146199019528e-07, + -2.660688509805698e-10, + 3.14883666274995e-06, + 5.056430444393811e-09, + 6.706220964089751e-08, + 1.0768910388651658e-10 + ], + [ + -0.048318227543216796, + 0.047695963447564216, + -9.903138090449648e-07, + 1.5365784740033656e-06, + -0.0006614804845389566, + 0.0006529616382063893, + -1.3557476992854725e-08, + 2.1035884907135685e-08, + -0.003991248864440938, + -0.00010926306864532539, + 0.0045766391679402385, + 0.0001455905961373074, + -5.4640523193955396e-05, + -1.4958203407829386e-06, + 6.265456429794343e-05, + 1.993147161515537e-06, + -0.03467642069088406, + -0.008295379839528022, + -7.107160176295867e-07, + -1.7001925823976352e-07, + 0.03422984198427981, + 0.008188548167581633, + 1.1027524041820684e-06, + 2.6380318035672667e-07, + -0.002864389522185557, + -0.0006852264051906542, + -7.841455133952087e-05, + -1.8758524534756707e-05, + 0.0032845051072274943, + 0.0007857275031988697, + 0.00010448563651840122, + 2.499531455167926e-05 + ], + [ + -0.01869798940380421, + 0.01907967562758242, + -6.863148157398712e-07, + 3.455293697584092e-07, + -0.005847129013078746, + 0.005966487760414495, + -2.1462046985660808e-07, + 1.0805198137367182e-07, + -0.001885989671451, + -6.262844400300473e-05, + 0.0015271131313375, + 4.0159545785178126e-05, + -0.0005897759747400611, + -1.9584811182930622e-05, + 0.00047755014208529945, + 1.255846499007956e-05, + -0.03807431392739441, + -0.025843302359679354, + -1.397528107604187e-06, + -9.485854823238031e-07, + 0.038851533380888814, + 0.026370847448863366, + 7.035940288124912e-07, + 4.775711325945335e-07, + -0.0038404002304140254, + -0.002606708147808865, + -0.00012752895438423377, + -8.656148956617718e-05, + 0.0031096276454921114, + 0.002110689312004834, + 8.177601989095627e-05, + 5.550625053528542e-05 + ], + [ + -0.0031299332773308515, + 0.003279578527963594, + -1.8925520277146983e-06, + 1.0688744879236476e-06, + -0.016944635042622735, + 0.017754775046628122, + -1.0245778605270695e-05, + 5.7866051763511485e-06, + -0.0008069850332277143, + -6.814726557553418e-05, + 0.0006795376574170212, + 4.6773068293281845e-05, + -0.0043688045914395375, + -0.0003689313611550363, + 0.0036788380397902746, + 0.00025321708222777236, + -0.016487521726666978, + -0.02895039058885141, + -9.969379507796903e-06, + -1.7505203963576913e-05, + 0.017275806684359036, + 0.030334537812359806, + 5.6305006468859276e-06, + 9.88657941687395e-06, + -0.0042509478923408355, + -0.0074642268193086565, + -0.00035897874562608337, + -0.0006303297166949013, + 0.0035795944826996348, + 0.006285399354849012, + 0.00024638607643610963, + 0.0004326285821927417 + ], + [ + -5.822787221002342e-05, + 6.18150310025146e-05, + -1.5592946564256164e-07, + 1.019586853830107e-07, + -0.03302436217178839, + 0.03505884542928461, + -8.843653307576886e-05, + 5.782661163545509e-05, + -2.4587886157389012e-05, + -3.410767992803947e-06, + 2.1880334645852337e-05, + 2.585131492109705e-06, + -0.013945198865785402, + -0.0019344419296659675, + 0.012409591289515845, + 0.0014661761698795104, + -0.0014459502399761233, + -0.011968907770639203, + -3.8721361387201535e-06, + -3.2051753261208896e-05, + 0.0015350287674917129, + 0.01270625864946057, + 2.5319006173788248e-06, + 2.0957903070254962e-05, + -0.000610581471387891, + -0.005054111210371609, + -8.469828297879615e-05, + -0.0007010932390878475, + 0.0005433458914282936, + 0.0044975661556433295, + 6.419557094415669e-05, + 0.0005313812651857384 + ] + ], + "dtype": "float64", + "shape": [ + 5, + 32 + ] + }, + "twist": { + "__ndarray__": [ + [ + 1.4583802644251714e-13, + -3.0386442448485424e-11, + -3.240622240277657e-14 + ], + [ + 1.5087747730225393e-06, + -3.0912096591791116e-06, + -5.198963620921894e-07 + ], + [ + 6.900288347425586e-06, + -6.361577124432312e-06, + -3.927387343309044e-06 + ], + [ + 9.488641780020825e-06, + -7.101190168159457e-07, + -1.0579813227369649e-05 + ], + [ + 2.0942656687068558e-06, + 7.026357981366538e-06, + -9.204958940706913e-06 + ] + ], + "dtype": "float64", + "shape": [ + 5, + 3 + ] + } + } + }, + "funcs_base": { + "DVCon1_leradius_constraints_0": { + "__ndarray__": [ + 0.999999999999638, + 1.000000000000056, + 0.9999999999999756, + 1.0000000000000024, + 0.9999999999999967 + ], + "dtype": "float64", + "shape": [ + 5 + ] + }, + "unscaled_radius_con": { + "__ndarray__": [ + 0.002594724524485424, + 0.025146824255442193, + 0.024831850878599727, + 0.025838136097098008, + 0.026442582657367954 + ], + "dtype": "float64", + "shape": [ + 5 + ] + } + }, + "funcs_deformed": { + "DVCon1_leradius_constraints_0": { + "__ndarray__": [ + 1.1238302512995253, + 0.9048631294876949, + 0.7607240852802922, + 0.7936706232753896, + 0.8973692143764042 + ], + "dtype": "float64", + "shape": [ + 5 + ] + }, + "unscaled_radius_con": { + "__ndarray__": [ + 0.002916029914406551, + 0.022754434092455224, + 0.01889018704543986, + 0.02050696958045807, + 0.023728759625325488 + ], + "dtype": "float64", + "shape": [ + 5 + ] + } + }, + "funcs_twisted": { + "DVCon1_leradius_constraints_0": { + "__ndarray__": [ + 0.9999999706412626, + 0.9995889472886494, + 0.9985676262837536, + 0.9978826211320478, + 0.9989229783092907 + ], + "dtype": "float64", + "shape": [ + 5 + ] + }, + "unscaled_radius_con": { + "__ndarray__": [ + 0.002594724448308527, + 0.025136487585148734, + 0.024796282388076078, + 0.025783426973738678, + 0.026414103422287682 + ], + "dtype": "float64", + "shape": [ + 5 + ] + } + } +} \ No newline at end of file diff --git a/tests/reg_tests/ref/test_DVConstraints_04.ref b/tests/reg_tests/ref/test_DVConstraints_LeTe.ref similarity index 100% rename from tests/reg_tests/ref/test_DVConstraints_04.ref rename to tests/reg_tests/ref/test_DVConstraints_LeTe.ref diff --git a/tests/reg_tests/ref/test_DVConstraints_08.ref b/tests/reg_tests/ref/test_DVConstraints_circularity.ref similarity index 100% rename from tests/reg_tests/ref/test_DVConstraints_08.ref rename to tests/reg_tests/ref/test_DVConstraints_circularity.ref diff --git a/tests/reg_tests/ref/test_DVConstraints_09.ref b/tests/reg_tests/ref/test_DVConstraints_colinearity.ref similarity index 100% rename from tests/reg_tests/ref/test_DVConstraints_09.ref rename to tests/reg_tests/ref/test_DVConstraints_colinearity.ref diff --git a/tests/reg_tests/ref/test_DVConstraints_11.ref b/tests/reg_tests/ref/test_DVConstraints_compositeVolume_box.ref similarity index 100% rename from tests/reg_tests/ref/test_DVConstraints_11.ref rename to tests/reg_tests/ref/test_DVConstraints_compositeVolume_box.ref diff --git a/tests/reg_tests/ref/test_DVConstraints_curvature.ref b/tests/reg_tests/ref/test_DVConstraints_curvature.ref new file mode 100644 index 00000000..1f277759 --- /dev/null +++ b/tests/reg_tests/ref/test_DVConstraints_curvature.ref @@ -0,0 +1,782 @@ +{ + "derivs_base": { + "DVCon1_mean_curvature_constraint_0": { + "local": { + "__ndarray__": [ + [ + 0.0726787457845837, + -0.07149553312604197, + -0.0007501919691118324, + -0.00041756764157130453, + 0.1270838610875411, + -0.13060203254911196, + 0.00605367220445035, + -0.018537273395809295, + 0.020585244916420612, + 0.0009226378742963368, + 3.196962265557756e-05, + 0.0007114728089510525, + -0.022012681100461375, + -0.0013731314780467902, + -4.302112661682165e-05, + 0.0006481232637273241, + 0.16575301983072088, + 0.04722669567802391, + 0.021991760927862626, + 0.015322550002229252, + -0.15152029226175112, + -0.04067150303470954, + -0.01521809336856202, + -0.0028711897734687813, + 0.10504160288555127, + 0.11629654811314112, + 0.1420213288739646, + 0.16883997713238338, + 0.18259155326152987, + 0.20095988939233755, + -0.0007841998976015772, + -0.0009592465931242463, + -0.0012194974061215565, + -0.0015342154848025848, + -0.001751576734112522, + -0.000964745339455487, + -0.10317532075644376, + -0.11479591508701201, + -0.14108144985727164, + -0.16966248963367858, + -0.1870265142304948, + -0.21000827015930887, + -0.00028369780381527207, + -0.00041064025737114614, + -0.0005528352144711806, + -0.0007523366665326553, + -0.0010955431724640793, + -0.00557430727811057, + 0.03410044996225281, + 0.04467880563007315, + 0.06609408643037572, + 0.10035702394713295, + 0.13928069763274942, + 0.19817195510610353, + 0.0014679722234089072, + 0.002413969159370124, + 0.0043834818152530385, + 0.008578123996233021, + 0.015298050349462225, + 0.03126881752077359, + -0.00016886574291345501, + -0.0001699221395153686, + -0.00019032714833616915, + -0.00016167549306659972, + 0.00016952754732051846, + 0.005681897805116767, + 0.001062123144348192, + 0.0011748294107385316, + 0.0015117847164313621, + 0.0019357621002964026, + 0.0023673883511703686, + 0.005542240156458097, + -0.03572100729324529, + -0.04584373081303224, + -0.06658173421722309, + -0.09899912745773488, + -0.13489503627165764, + -0.1932530997307725, + -0.0023401331508099464, + -0.0034059667625836627, + -0.005645062629930626, + -0.009978492736529246, + -0.01659463802281394, + -0.03767225087194111, + -8.119206099963513e-06, + -7.296632341618528e-05, + -0.00012199274198511478, + -0.00023922530436129027, + -0.0009682950742916854, + -0.012472078253477957, + 0.0010765590535555575, + 0.0011867865367915541, + 0.0015487514360575318, + 0.0020165263119910973, + 0.002001672548144145, + -0.005480876768783222 + ] + ], + "dtype": "float64", + "shape": [ + 1, + 96 + ] + }, + "twist": { + "__ndarray__": [ + [ + 4.836091541483631e-06, + -5.271059062262555e-06, + -3.4820835022651185e-06, + 4.4473634043649366e-07, + -1.1216772973797717e-05, + -0.00030401211470332154, + -2.0843288667206865e-06 + ] + ], + "dtype": "float64", + "shape": [ + 1, + 7 + ] + } + }, + "unscaled_curvature_con": { + "local": { + "__ndarray__": [ + [ + 17.82530908979518, + -17.535112401206355, + -0.1839933199415299, + -0.10241332863623775, + 31.168797421522626, + -32.03166995814066, + 1.4847336316518167, + -4.546482254134045, + 5.048771127833152, + 0.22628768713249126, + 0.00784092239303187, + 0.17449699484533004, + -5.398866481183099, + -0.3367764915709797, + -0.010551432486314712, + 0.15895978087554027, + 40.6528590876734, + 11.5828972922237, + 5.393735565139313, + 3.7580338912717233, + -37.16211684427164, + -9.975159930374362, + -3.732414684975491, + -0.7041927404639292, + 25.76267681162481, + 28.52308324551035, + 34.83238541327216, + 41.409971328055924, + 44.7827055755678, + 49.28775399739143, + -0.19233416058647068, + -0.23526640190582682, + -0.299095945639284, + -0.37628422080939344, + -0.4295945993977094, + -0.2366150335023517, + -25.30494937782024, + -28.15503551391656, + -34.60186913511259, + -41.61170210102846, + -45.870431419204024, + -51.506974791480204, + -0.06958019138236322, + -0.10071430695922054, + -0.135589276717417, + -0.18451933196918288, + -0.2686947258041173, + -1.3671637990057157, + 8.363532613508362, + 10.957997575790053, + 16.210344673820522, + 24.61372925300361, + 34.1602136738124, + 48.60398063507336, + 0.3600372892379762, + 0.5920540583700173, + 1.0750999814715496, + 2.103884842711154, + 3.7520250660166683, + 7.669041769546097, + -0.04141629068602704, + -0.041675384259357406, + -0.04667995038504275, + -0.03965279814677971, + 0.04157860592668945, + 1.3935516291520598, + 0.2604980745752661, + 0.28814059940251635, + 0.37078281355440484, + 0.47476820615982396, + 0.5806295725062378, + 1.3592989638477369, + -8.760993177953091, + -11.24370904794834, + -16.329945974498862, + -24.280689319881837, + -33.084579133332944, + -47.39757405104744, + -0.5739449171027304, + -0.8353530270400029, + -1.3845173733186318, + -2.447341590154943, + -4.070028297773234, + -9.239558397045112, + -0.001991329882391887, + -0.01789584085414077, + -0.02992014115160561, + -0.058672792799416305, + -0.23748564732437327, + -3.0589224877283603, + 0.2640386494825152, + 0.291073223864108, + 0.3798493321942804, + 0.4945765699573747, + 0.49093351133188573, + -1.3442488781550181 + ] + ], + "dtype": "float64", + "shape": [ + 1, + 96 + ] + }, + "twist": { + "__ndarray__": [ + [ + 0.0011861077896062671, + -0.0012927886412543122, + -0.000854021544199994, + 0.00010907676850787445, + -0.0027510442439588017, + -0.07456251278319097, + -0.0005112059363546891 + ] + ], + "dtype": "float64", + "shape": [ + 1, + 7 + ] + } + } + }, + "derivs_deformed": { + "DVCon1_mean_curvature_constraint_0": { + "local": { + "__ndarray__": [ + [ + 0.06753923379893019, + -0.07080160634040134, + -0.0009416143929713119, + -0.0006158714934344247, + 0.1817142743792997, + -0.16448463429110569, + 0.03369510174875596, + -0.022712058199219804, + 0.02342181389532268, + 0.0007436624508294373, + -5.5864053798274354e-05, + 0.0009904419424456032, + -0.018813737678732543, + -0.0012723510235125685, + -0.00010046524656935054, + 0.0009451758102458235, + 0.20100556598029848, + 0.06531113755415091, + 0.02841718032577503, + 0.024812959702791605, + -0.22234452166343965, + -0.06268700498107753, + -0.031239126978263847, + -0.027943889155494686, + 0.1028332915653089, + 0.12321988398453047, + 0.13374984650425753, + 0.12523168804241097, + 0.1799905514556455, + 0.26423095242725064, + -0.0009183738007906911, + -0.0008940426604340797, + -0.0010671282006413626, + -0.001744918559861611, + -0.0011500455858421414, + 0.006411209780139845, + -0.10077153544208853, + -0.10041036032664963, + -0.12370135924634251, + -0.16362474772113597, + -0.19482900633699335, + -0.23443445280083214, + -0.0004461592554682135, + -0.0004234112706759273, + -0.00047993267345194663, + -0.0008338358575289679, + -0.0005479345243429362, + -0.0036045440250989692, + 0.03246092450317831, + 0.03397595099887895, + 0.06003884169467486, + 0.10611932188765558, + 0.14592546222017827, + 0.22301526964437715, + 0.0012876558414114182, + 0.0019185673524184962, + 0.004728984657721483, + 0.011521495591582772, + 0.01835257086763019, + 0.03950019782430172, + -0.0004133040085387381, + -3.465248906933769e-05, + 0.0003485628884847213, + -2.6027477887064525e-05, + 0.0001387775525930855, + 0.00907867902160724, + 0.0013742153138643104, + 0.000973325853858088, + 0.0008729304152838769, + 0.001997120729055926, + 0.0019014741211524798, + 0.006861734624880232, + -0.037561435617710845, + -0.05505109931993362, + -0.06194339129926199, + -0.0714044541086203, + -0.13968445479834043, + -0.2507060346139286, + -0.002253233939234086, + -0.004015549391144769, + -0.005107630177280382, + -0.00648598208201504, + -0.01607897296022496, + -0.044853102700050794, + -1.3216088685972984e-05, + 0.000255464374420133, + 0.0004774114746399319, + 4.7373604997436137e-05, + -0.0012447643493587813, + -0.013525786718371416, + 0.0014576768529369123, + 0.0010177818743222766, + 0.0008169665632099241, + 0.0021084229396934983, + 0.0013528398501565216, + -0.009892346561698727 + ] + ], + "dtype": "float64", + "shape": [ + 1, + 96 + ] + }, + "twist": { + "__ndarray__": [ + [ + 4.0268112401852936e-05, + -9.794038625626783e-05, + -7.572269783065179e-05, + 0.00019394804555422597, + 9.049968828488312e-05, + -0.00017700073591346677, + -0.0001725229650022423 + ] + ], + "dtype": "float64", + "shape": [ + 1, + 7 + ] + } + }, + "unscaled_curvature_con": { + "local": { + "__ndarray__": [ + [ + 16.56478390150255, + -17.364918772984012, + -0.23094189940855223, + -0.15104965848752794, + 44.567542709659214, + -40.34177275776345, + 8.264116241960064, + -5.570396862192071, + 5.7444727151076185, + 0.18239187951591126, + -0.013701309993910112, + 0.24291742474365952, + -4.614288340249074, + -0.3120589110336498, + -0.024640272111864273, + 0.23181537848446793, + 49.2989567127063, + 16.018317340801044, + 6.969644526733516, + 6.0856674308307905, + -54.53258418658898, + -15.374718256877983, + -7.661759818109377, + -6.853564353518789, + 25.221062734154494, + 30.221112022806093, + 32.80370800175228, + 30.714530404929935, + 44.14477958176518, + 64.80571929607733, + -0.22524187342980312, + -0.21927437780685027, + -0.2617256229387675, + -0.427961604596743, + -0.28206207762254226, + 1.572423887297539, + -24.715393026079145, + -24.62681062143329, + -30.339199439811438, + -40.13087555905074, + -47.78408350507279, + -57.497780642194606, + -0.10942575502860367, + -0.10384654675072184, + -0.11770907923924687, + -0.20450795800278934, + -0.13438732537188972, + -0.884056414039048, + 7.961419894678388, + 8.33299779236447, + 14.725225360560193, + 26.026999952001848, + 35.78991959844198, + 54.69709294293147, + 0.31581259591999455, + 0.47055099392900485, + 1.1598385785939782, + 2.825781015888669, + 4.501181807367786, + 9.687883682158633, + -0.10136762296491188, + -0.00849892663561454, + 0.08548910905655513, + -0.006383542164303988, + 0.034036811491344736, + 2.2266517940037653, + 0.33704231493159514, + 0.23871950462013677, + 0.21409635373238325, + 0.48981712467325106, + 0.4663586798298803, + 1.6829203539528301, + -9.212379664979812, + -13.50192343741541, + -15.192338338530963, + -17.51277421113984, + -34.25923982232649, + -61.4885756410248, + -0.5526318731133611, + -0.9848602681538969, + -1.2527058033753176, + -1.5907626654079525, + -3.943555433826187, + -11.00074596271209, + -0.003241399713801732, + 0.06265561391176212, + 0.11709072585945268, + 0.011618928514259141, + -0.30529295782075155, + -3.3173567641388324, + 0.3575122296916616, + 0.24962286153861485, + 0.20037056704868922, + 0.5171152884702933, + 0.331799733439337, + -2.4262132372000424 + ] + ], + "dtype": "float64", + "shape": [ + 1, + 96 + ] + }, + "twist": { + "__ndarray__": [ + [ + 0.009876223678301868, + -0.02402102070615799, + -0.0185718737902537, + 0.047568017610138284, + 0.02219610284676856, + -0.043411492489568985, + -0.042313267008922184 + ] + ], + "dtype": "float64", + "shape": [ + 1, + 7 + ] + } + } + }, + "derivs_twisted": { + "DVCon1_mean_curvature_constraint_0": { + "local": { + "__ndarray__": [ + [ + 0.0726931018002589, + -0.07149429113483631, + -0.0007303947715396589, + -0.0004065532811918188, + 0.09269214325724258, + -0.1638796845470272, + 0.014821558824867926, + -0.01242700940933655, + 0.020778365383978432, + 0.0009317259160386271, + 2.835953613311666e-05, + 0.0006943219289307497, + -0.021823596048410006, + -0.0013643976719422044, + -4.726408243586769e-05, + 0.0006296582741376356, + 0.17071165753503187, + 0.05180856586345022, + 0.017314128208140104, + 0.019998849467948204, + -0.14661947115226376, + -0.03583046892194287, + -0.020476184250689405, + -0.0009794850273932862, + 0.1045180203664342, + 0.11407876886303979, + 0.13632103864698386, + 0.15711412359912777, + 0.16387931824435903, + 0.17205457287761466, + -0.0007848213828070322, + -0.0010122187044113151, + -0.0013279840021367443, + -0.0016837741809354757, + -0.0018724244782225637, + 0.0005675265767278491, + -0.10377819260683187, + -0.11712813082864275, + -0.1467229766987428, + -0.1806709129556714, + -0.20406201900435278, + -0.236351650308406, + -0.0002939839006765113, + -0.0004518465493424073, + -0.0006276392967889349, + -0.0008589267077789617, + -0.0011818842233692034, + -0.004390866308408813, + 0.035229287578230364, + 0.04756888717810548, + 0.07210806556968583, + 0.11116117311468134, + 0.154899902654076, + 0.22028309645936314, + 0.0015669415507198851, + 0.0027421725177379187, + 0.005245411217365179, + 0.010695337556169438, + 0.01954028380919623, + 0.0404295178406364, + -0.0001729425943693737, + -0.0001596243653959015, + -0.00016222593163069224, + -8.597003735558998e-05, + 0.00041666754673352565, + 0.0071015731936982605, + 0.001038739793311079, + 0.0011994367276844174, + 0.0015807052742025595, + 0.0020210368290040294, + 0.0025417147253525073, + 0.007775034249153297, + -0.034616838738572846, + -0.04298800349176777, + -0.060520214876583545, + -0.08776362986718911, + -0.11810087952786567, + -0.16892326006187336, + -0.0022417822170850187, + -0.0030772243049402063, + -0.0047755515913819975, + -0.007816821955147898, + -0.01218402983954608, + -0.027487991026786642, + -1.3276753780402137e-05, + -6.164711238826185e-05, + -9.224440665164273e-05, + -0.00016209113144613875, + -0.0006824515965592588, + -0.010354702048507764, + 0.0010506416573611338, + 0.0012137050796660928, + 0.0016241530461380146, + 0.002110845419004736, + 0.0021972206700689384, + -0.003254900514428212 + ] + ], + "dtype": "float64", + "shape": [ + 1, + 96 + ] + }, + "twist": { + "__ndarray__": [ + [ + -1.450390086919188e-05, + 1.2645338937764902e-05, + 5.306665488377784e-05, + 9.948119400675316e-05, + 0.00014675689852864128, + 0.00011318711888521992, + 0.0003154349202843937 + ] + ], + "dtype": "float64", + "shape": [ + 1, + 7 + ] + } + }, + "unscaled_curvature_con": { + "local": { + "__ndarray__": [ + [ + 17.828830069882727, + -17.53480778839434, + -0.1791378266055722, + -0.0997119284390652, + 22.73382797019038, + -40.19340178553942, + 3.6351599686233467, + -3.047868828663471, + 5.0961361722986664, + 0.2285166352428154, + 0.0069555066169462885, + 0.17029054171760868, + -5.3524911693819615, + -0.3346344238775445, + -0.0115920668301294, + 0.15443102706694647, + 41.869022751334946, + 12.706654332646632, + 4.246491647574609, + 4.9049508127600125, + -35.96013337403756, + -8.787839917587078, + -5.022022729037657, + -0.24023011368219388, + 25.634262099228284, + 27.97914704794361, + 33.43432282839156, + 38.53406914626189, + 40.19331194554261, + 42.19838838367407, + -0.19248658707294913, + -0.24825842930853867, + -0.3257035471492169, + -0.412965233351028, + -0.459233916481382, + 0.13919250446099968, + -25.45281072240874, + -28.72703859418273, + -35.98551931512099, + -44.311646165659084, + -50.048587423640576, + -57.96799566571721, + -0.07210297646729567, + -0.1108206301065024, + -0.15393584935164278, + -0.21066178132766258, + -0.28987087438685993, + -1.0769111144450212, + 8.640393189454816, + 11.666823744049564, + 17.685343118833835, + 27.263572701521802, + 37.9910056644618, + 54.02699564028775, + 0.3843106697247029, + 0.6725497554828241, + 1.2864982085649281, + 2.623156133204116, + 4.792482242795163, + 9.915810242470974, + -0.04241618599971768, + -0.03914973519050301, + -0.03978779961707066, + -0.021085153187244677, + 0.10219256989141812, + 1.7417435570046045, + 0.2547630353242611, + 0.29417583055157515, + 0.3876863832521654, + 0.49568282680102876, + 0.6233851466256335, + 1.9069177264791923, + -8.490182976679028, + -10.543308654020432, + -14.843287741280063, + -21.525052645540384, + -28.965616544904957, + -41.4303974367354, + -0.5498232048470895, + -0.7547251095494841, + -1.1712596615653712, + -1.9171666481889735, + -2.9882752585318135, + -6.741750026373238, + -0.00325627853494085, + -0.015119672484046293, + -0.02262401535166808, + -0.03975473830142679, + -0.16737920441760545, + -2.5396113066460893, + 0.25768210613575254, + 0.29767531009724046, + 0.39834245547317315, + 0.5177094297425471, + 0.5388939663124328, + -0.7983022698023157 + ] + ], + "dtype": "float64", + "shape": [ + 1, + 96 + ] + }, + "twist": { + "__ndarray__": [ + [ + -0.003557250654400613, + 0.003101416689001594, + 0.013015215321211792, + 0.02439892175690258, + 0.03599383903911353, + 0.0277604595034052, + 0.07736408892425645 + ] + ], + "dtype": "float64", + "shape": [ + 1, + 7 + ] + } + } + }, + "funcs_base": { + "DVCon1_mean_curvature_constraint_0": 0.9999999999914938, + "unscaled_curvature_con": 245.26164970536027 + }, + "funcs_deformed": { + "DVCon1_mean_curvature_constraint_0": 1.0310909789054612, + "unscaled_curvature_con": 252.8870744848193 + }, + "funcs_twisted": { + "DVCon1_mean_curvature_constraint_0": 1.001587940678982, + "unscaled_curvature_con": 245.6511106580112 + } +} \ No newline at end of file diff --git a/tests/reg_tests/ref/test_DVConstraints_10.ref b/tests/reg_tests/ref/test_DVConstraints_linearConstraintShape.ref similarity index 100% rename from tests/reg_tests/ref/test_DVConstraints_10.ref rename to tests/reg_tests/ref/test_DVConstraints_linearConstraintShape.ref diff --git a/tests/reg_tests/ref/test_DVConstraints_12.ref b/tests/reg_tests/ref/test_DVConstraints_location_box.ref similarity index 100% rename from tests/reg_tests/ref/test_DVConstraints_12.ref rename to tests/reg_tests/ref/test_DVConstraints_location_box.ref diff --git a/tests/reg_tests/ref/test_DVConstraints_14.ref b/tests/reg_tests/ref/test_DVConstraints_monotonic.ref similarity index 100% rename from tests/reg_tests/ref/test_DVConstraints_14.ref rename to tests/reg_tests/ref/test_DVConstraints_monotonic.ref diff --git a/tests/reg_tests/ref/test_DVConstraints_13.ref b/tests/reg_tests/ref/test_DVConstraints_planarity_box.ref similarity index 100% rename from tests/reg_tests/ref/test_DVConstraints_13.ref rename to tests/reg_tests/ref/test_DVConstraints_planarity_box.ref diff --git a/tests/reg_tests/ref/test_DVConstraints_13b.ref b/tests/reg_tests/ref/test_DVConstraints_planarity_tri.ref similarity index 100% rename from tests/reg_tests/ref/test_DVConstraints_13b.ref rename to tests/reg_tests/ref/test_DVConstraints_planarity_tri.ref diff --git a/tests/reg_tests/ref/test_DVConstraints_07.ref b/tests/reg_tests/ref/test_DVConstraints_projectedArea.ref similarity index 100% rename from tests/reg_tests/ref/test_DVConstraints_07.ref rename to tests/reg_tests/ref/test_DVConstraints_projectedArea.ref diff --git a/tests/reg_tests/ref/test_DVConstraints_07b.ref b/tests/reg_tests/ref/test_DVConstraints_projectedArea_box.ref similarity index 100% rename from tests/reg_tests/ref/test_DVConstraints_07b.ref rename to tests/reg_tests/ref/test_DVConstraints_projectedArea_box.ref diff --git a/tests/reg_tests/ref/test_DVConstraints_06.ref b/tests/reg_tests/ref/test_DVConstraints_surfaceArea.ref similarity index 100% rename from tests/reg_tests/ref/test_DVConstraints_06.ref rename to tests/reg_tests/ref/test_DVConstraints_surfaceArea.ref diff --git a/tests/reg_tests/ref/test_DVConstraints_06b.ref b/tests/reg_tests/ref/test_DVConstraints_surfaceArea_box.ref similarity index 100% rename from tests/reg_tests/ref/test_DVConstraints_06b.ref rename to tests/reg_tests/ref/test_DVConstraints_surfaceArea_box.ref diff --git a/tests/reg_tests/ref/test_DVConstraints_01.ref b/tests/reg_tests/ref/test_DVConstraints_thickness1D.ref similarity index 100% rename from tests/reg_tests/ref/test_DVConstraints_01.ref rename to tests/reg_tests/ref/test_DVConstraints_thickness1D.ref diff --git a/tests/reg_tests/ref/test_DVConstraints_01b.ref b/tests/reg_tests/ref/test_DVConstraints_thickness1D_box.ref similarity index 100% rename from tests/reg_tests/ref/test_DVConstraints_01b.ref rename to tests/reg_tests/ref/test_DVConstraints_thickness1D_box.ref diff --git a/tests/reg_tests/ref/test_DVConstraints_02.ref b/tests/reg_tests/ref/test_DVConstraints_thickness2D.ref similarity index 100% rename from tests/reg_tests/ref/test_DVConstraints_02.ref rename to tests/reg_tests/ref/test_DVConstraints_thickness2D.ref diff --git a/tests/reg_tests/ref/test_DVConstraints_02b.ref b/tests/reg_tests/ref/test_DVConstraints_thickness2D_box.ref similarity index 100% rename from tests/reg_tests/ref/test_DVConstraints_02b.ref rename to tests/reg_tests/ref/test_DVConstraints_thickness2D_box.ref diff --git a/tests/reg_tests/ref/test_DVConstraints_05.ref b/tests/reg_tests/ref/test_DVConstraints_thicknessToChord.ref similarity index 100% rename from tests/reg_tests/ref/test_DVConstraints_05.ref rename to tests/reg_tests/ref/test_DVConstraints_thicknessToChord.ref diff --git a/tests/reg_tests/ref/test_DVConstraints_15.ref b/tests/reg_tests/ref/test_DVConstraints_triangulatedSurface.ref similarity index 100% rename from tests/reg_tests/ref/test_DVConstraints_15.ref rename to tests/reg_tests/ref/test_DVConstraints_triangulatedSurface.ref diff --git a/tests/reg_tests/ref/test_DVConstraints_16.ref b/tests/reg_tests/ref/test_DVConstraints_triangulatedSurface_intersected.ref similarity index 100% rename from tests/reg_tests/ref/test_DVConstraints_16.ref rename to tests/reg_tests/ref/test_DVConstraints_triangulatedSurface_intersected.ref diff --git a/tests/reg_tests/ref/test_DVConstraints_17.ref b/tests/reg_tests/ref/test_DVConstraints_triangulatedSurface_intersected_2DVGeos.ref similarity index 100% rename from tests/reg_tests/ref/test_DVConstraints_17.ref rename to tests/reg_tests/ref/test_DVConstraints_triangulatedSurface_intersected_2DVGeos.ref diff --git a/tests/reg_tests/ref/test_DVConstraints_18.ref b/tests/reg_tests/ref/test_DVConstraints_triangulatedVolume_box.ref similarity index 100% rename from tests/reg_tests/ref/test_DVConstraints_18.ref rename to tests/reg_tests/ref/test_DVConstraints_triangulatedVolume_box.ref diff --git a/tests/reg_tests/ref/test_DVConstraints_19.ref b/tests/reg_tests/ref/test_DVConstraints_triangulatedVolume_bwb.ref similarity index 100% rename from tests/reg_tests/ref/test_DVConstraints_19.ref rename to tests/reg_tests/ref/test_DVConstraints_triangulatedVolume_bwb.ref diff --git a/tests/reg_tests/ref/test_DVConstraints_03.ref b/tests/reg_tests/ref/test_DVConstraints_volume.ref similarity index 100% rename from tests/reg_tests/ref/test_DVConstraints_03.ref rename to tests/reg_tests/ref/test_DVConstraints_volume.ref diff --git a/tests/reg_tests/ref/test_DVConstraints_03b.ref b/tests/reg_tests/ref/test_DVConstraints_volume_box.ref similarity index 100% rename from tests/reg_tests/ref/test_DVConstraints_03b.ref rename to tests/reg_tests/ref/test_DVConstraints_volume_box.ref diff --git a/tests/reg_tests/test_DVConstraints.py b/tests/reg_tests/test_DVConstraints.py index e56afa88..04d29098 100644 --- a/tests/reg_tests/test_DVConstraints.py +++ b/tests/reg_tests/test_DVConstraints.py @@ -4,6 +4,7 @@ from baseclasses import BaseRegTest from pygeo import DVGeometry, DVConstraints from stl import mesh +from parameterized import parameterized_class try: import geograd # noqa @@ -13,6 +14,94 @@ missing_geograd = True +def evalFunctionsSensFD(DVGeo, DVCon, fdstep=1e-2): + funcs = {} + DVCon.evalFunctions(funcs, includeLinear=True) + # make a deep copy of this + outdims = {} + for key in funcs.keys(): + val = funcs[key] + if isinstance(val, np.ndarray): + outdims[key] = val.shape[0] + funcs[key] = val.copy() + elif isinstance(val, (list, tuple)): + outdims[key] = len(val) + else: + outdims[key] = 1 + + xDV = DVGeo.getValues() + indims = {} + for key in xDV.keys(): + val = xDV[key] + indims[key] = val.shape[0] + + # setup the output data structure + funcsSens = {} + for outkey in funcs.keys(): + funcsSens[outkey] = {} + for inkey in xDV.keys(): + nRows = outdims[outkey] + nCols = indims[inkey] + funcsSens[outkey][inkey] = np.zeros((nRows, nCols)) + # now do finite differencing + for inkey in xDV.keys(): + baseVar = xDV[inkey].copy() + nDV = len(baseVar) + for array_ind in range(nDV): + xDV[inkey][array_ind] = baseVar[array_ind] + fdstep + DVGeo.setDesignVars(xDV) + funcs_fd = {} + DVCon.evalFunctions(funcs_fd, includeLinear=True) + for outkey in funcs.keys(): + temp_a = funcs_fd[outkey] + temp_b = funcs[outkey] + diff = temp_a - temp_b + deriv_temp = diff / fdstep + funcsSens[outkey][inkey][:, array_ind] = deriv_temp + xDV[inkey][array_ind] = baseVar[array_ind] + DVGeo.setDesignVars(xDV) + DVCon.evalFunctions({}) + return funcsSens + + +def generic_test_base(DVGeo, DVCon, handler, checkDerivs=True, fdstep=1e-4): + linear_constraint_keywords = ["lete", "monotonic", "linear_constraint"] + funcs = {} + DVCon.evalFunctions(funcs, includeLinear=True) + handler.root_add_dict("funcs_base", funcs, rtol=1e-6, atol=1e-6) + funcsSens = {} + DVCon.evalFunctionsSens(funcsSens, includeLinear=True) + # regress the derivatives + if checkDerivs: + handler.root_add_dict("derivs_base", funcsSens, rtol=1e-6, atol=1e-6) + funcsSensFD = evalFunctionsSensFD(DVGeo, DVCon, fdstep=fdstep) + for outkey in funcs.keys(): + for inkey in DVGeo.getValues().keys(): + try: + analytic = funcsSens[outkey][inkey] + fd = funcsSensFD[outkey][inkey] + handler.assert_allclose(analytic, fd, name="finite_diff_check", rtol=1e-3, atol=1e-3) + except KeyError: + if any(sbstr in outkey for sbstr in linear_constraint_keywords): + # linear constraints only have their affected DVs in the dict + pass + else: + raise + return funcs, funcsSens + + +@parameterized_class( + [ + { + "name": "standard", + "child": False, + }, + { + "name": "child", + "child": True, + }, + ] +) class RegTestPyGeo(unittest.TestCase): N_PROCS = 1 @@ -23,68 +112,53 @@ def setUp(self): # This is needed to support testflo running directories and files as inputs self.base_path = os.path.dirname(os.path.abspath(__file__)) - def evalFunctionsSensFD(self, DVGeo, DVCon, fdstep=1e-2): - funcs = {} - DVCon.evalFunctions(funcs, includeLinear=True) - # make a deep copy of this - outdims = {} - for key in funcs.keys(): - val = funcs[key] - if isinstance(val, np.ndarray): - outdims[key] = val.shape[0] - funcs[key] = val.copy() - elif isinstance(val, (list, tuple)): - outdims[key] = len(val) - else: - outdims[key] = 1 + def generate_dvgeo_dvcon(self, geometry, addToDVGeo=False, intersected=False): + """ + This function creates the DVGeometry and DVConstraints objects for each geometry used in this class. - xDV = DVGeo.getValues() - indims = {} - for key in xDV.keys(): - val = xDV[key] - indims[key] = val.shape[0] + The C172 wing represents a typical use case with twist and shape variables. - # setup the output data structure - funcsSens = {} - for outkey in funcs.keys(): - funcsSens[outkey] = {} - for inkey in xDV.keys(): - nRows = outdims[outkey] - nCols = indims[inkey] - funcsSens[outkey][inkey] = np.zeros((nRows, nCols)) - # now do finite differencing - for inkey in xDV.keys(): - baseVar = xDV[inkey].copy() - nDV = len(baseVar) - for array_ind in range(nDV): - xDV[inkey][array_ind] = baseVar[array_ind] + fdstep - DVGeo.setDesignVars(xDV) - funcs_fd = {} - DVCon.evalFunctions(funcs_fd, includeLinear=True) - for outkey in funcs.keys(): - temp_a = funcs_fd[outkey] - temp_b = funcs[outkey] - diff = temp_a - temp_b - deriv_temp = diff / fdstep - funcsSens[outkey][inkey][:, array_ind] = deriv_temp - xDV[inkey][array_ind] = baseVar[array_ind] - DVGeo.setDesignVars(xDV) - DVCon.evalFunctions({}) - return funcsSens - - def generate_dvgeo_dvcon_rect(self, addToDVGeo=False): - meshfile = os.path.join(self.base_path, "../../input_files/2x1x8_rectangle.stl") - ffdfile = os.path.join(self.base_path, "../../input_files/2x1x8_rectangle.xyz") - testmesh = mesh.Mesh.from_file(meshfile) - # test mesh dim 0 is triangle index - # dim 1 is each vertex of the triangle - # dim 2 is x, y, z dimension + The rectangular box is primarily used to test unscaled constraint function + values against known values for thickness, volume, and surface area. + + The BWB is used for the triangulated surface and volume constraint tests. + + The RAE 2822 wing is used for the curvature constraint test. + """ + + if geometry == "c172": + meshFile = os.path.join(self.base_path, "../../input_files/c172.stl") + ffdFile = os.path.join(self.base_path, "../../input_files/c172.xyz") + xFraction = 0.25 + meshScale = 1e-3 + elif geometry == "box": + meshFile = os.path.join(self.base_path, "../../input_files/2x1x8_rectangle.stl") + ffdFile = os.path.join(self.base_path, "../../input_files/2x1x8_rectangle.xyz") + xFraction = 0.5 + meshScale = 1 + elif geometry == "bwb": + meshFile = os.path.join(self.base_path, "../../input_files/bwb.stl") + ffdFile = os.path.join(self.base_path, "../../input_files/bwb.xyz") + xFraction = 0.25 + meshScale = 1 + elif geometry == "rae2822": + ffdFile = os.path.join(self.base_path, "../../input_files/deform_geometry_ffd.xyz") + xFraction = 0.25 - # create a DVGeo object with a few local thickness variables - DVGeo = DVGeometry(ffdfile) - nRefAxPts = DVGeo.addRefAxis("wing", xFraction=0.5, alignIndex="k") + DVGeo = DVGeometry(ffdFile, child=self.child) + DVCon = DVConstraints() + nRefAxPts = DVGeo.addRefAxis("wing", xFraction=xFraction, alignIndex="k") self.nTwist = nRefAxPts - 1 + if self.child: + parentFFD = os.path.join(self.base_path, "../../input_files/parent.xyz") + self.parentDVGeo = DVGeometry(parentFFD) + self.parentDVGeo.addChild(DVGeo) + DVCon.setDVGeo(self.parentDVGeo) + else: + DVCon.setDVGeo(DVGeo) + + # Add design variables def twist(val, geo): for i in range(1, nRefAxPts): geo.rot_z["wing"].coef[i] = val[i - 1] @@ -92,78 +166,45 @@ def twist(val, geo): DVGeo.addGlobalDV(dvName="twist", value=[0] * self.nTwist, func=twist, lower=-10, upper=10, scale=1) DVGeo.addLocalDV("local", lower=-0.5, upper=0.5, axis="y", scale=1) - # create a DVConstraints object for the wing - DVCon = DVConstraints() - DVCon.setDVGeo(DVGeo) - p0 = testmesh.vectors[:, 0, :] - v1 = testmesh.vectors[:, 1, :] - p0 - v2 = testmesh.vectors[:, 2, :] - p0 - DVCon.setSurface([p0, v1, v2], addToDVGeo=addToDVGeo) - - return DVGeo, DVCon + # RAE 2822 does not have a DVCon surface so we just return + if geometry == "rae2822": + return DVGeo, DVCon - def generate_dvgeo_dvcon_c172(self): - meshfile = os.path.join(self.base_path, "../../input_files/c172.stl") - ffdfile = os.path.join(self.base_path, "../../input_files/c172.xyz") - testmesh = mesh.Mesh.from_file(meshfile) - # test mesh dim 0 is triangle index + # Get the mesh from the STL + testMesh = mesh.Mesh.from_file(meshFile) + # dim 0 is triangle index # dim 1 is each vertex of the triangle # dim 2 is x, y, z dimension - # create a DVGeo object with a few local thickness variables - DVGeo = DVGeometry(ffdfile) - nRefAxPts = DVGeo.addRefAxis("wing", xFraction=0.25, alignIndex="k") - self.nTwist = nRefAxPts - 1 - - def twist(val, geo): - for i in range(1, nRefAxPts): - geo.rot_z["wing"].coef[i] = val[i - 1] - - DVGeo.addGlobalDV(dvName="twist", value=[0] * self.nTwist, func=twist, lower=-10, upper=10, scale=1) - DVGeo.addLocalDV("local", lower=-0.5, upper=0.5, axis="y", scale=1) + p0 = testMesh.vectors[:, 0, :] * meshScale + v1 = testMesh.vectors[:, 1, :] * meshScale - p0 + v2 = testMesh.vectors[:, 2, :] * meshScale - p0 + DVCon.setSurface([p0, v1, v2], addToDVGeo=addToDVGeo) - # create a DVConstraints object for the wing - DVCon = DVConstraints() - DVCon.setDVGeo(DVGeo) - p0 = testmesh.vectors[:, 0, :] / 1000 - v1 = testmesh.vectors[:, 1, :] / 1000 - p0 - v2 = testmesh.vectors[:, 2, :] / 1000 - p0 - DVCon.setSurface([p0, v1, v2]) + # Add the blob surface for the BWB + if geometry == "bwb": + objFile = os.path.join(self.base_path, "../../input_files/blob_bwb_wing.stl") + testObj = mesh.Mesh.from_file(objFile) + p0b = testObj.vectors[:, 0, :] + v1b = testObj.vectors[:, 1, :] - p0b + v2b = testObj.vectors[:, 2, :] - p0b + if intersected: + p0b = p0b + np.array([0.0, 0.3, 0.0]) + DVCon.setSurface([p0b, v1b, v2b], name="blob") return DVGeo, DVCon - def generic_test_base(self, DVGeo, DVCon, handler, checkDerivs=True, fdstep=1e-4): - linear_constraint_keywords = ["lete", "monotonic", "linear_constraint"] - funcs = {} - DVCon.evalFunctions(funcs, includeLinear=True) - handler.root_add_dict("funcs_base", funcs, rtol=1e-6, atol=1e-6) - funcsSens = {} - DVCon.evalFunctionsSens(funcsSens, includeLinear=True) - # regress the derivatives - if checkDerivs: - handler.root_add_dict("derivs_base", funcsSens, rtol=1e-6, atol=1e-6) - funcsSensFD = self.evalFunctionsSensFD(DVGeo, DVCon, fdstep=fdstep) - for outkey in funcs.keys(): - for inkey in DVGeo.getValues().keys(): - try: - analytic = funcsSens[outkey][inkey] - fd = funcsSensFD[outkey][inkey] - handler.assert_allclose(analytic, fd, name="finite_diff_check", rtol=1e-3, atol=1e-3) - except KeyError: - if any(sbstr in outkey for sbstr in linear_constraint_keywords): - # linear constraints only have their affected DVs in the dict - pass - else: - raise - return funcs, funcsSens - - def c172_test_twist(self, DVGeo, DVCon, handler): + def wing_test_twist(self, DVGeo, DVCon, handler): funcs = {} funcsSens = {} # change the DVs xDV = DVGeo.getValues() - xDV["twist"] = np.linspace(0, 10, self.nTwist) - DVGeo.setDesignVars(xDV) + xDV["twist"] = np.linspace(0, 10, len(xDV["twist"])) + if self.child: + # Twist needs to be set on the parent FFD to get accurate derivatives + self.parentDVGeo.setDesignVars(xDV) + else: + DVGeo.setDesignVars(xDV) # check the constraint values changed DVCon.evalFunctions(funcs, includeLinear=True) @@ -174,12 +215,12 @@ def c172_test_twist(self, DVGeo, DVCon, handler): handler.root_add_dict("derivs_twisted", funcsSens, rtol=1e-6, atol=1e-6) return funcs, funcsSens - def c172_test_deformed(self, DVGeo, DVCon, handler): + def wing_test_deformed(self, DVGeo, DVCon, handler): funcs = {} funcsSens = {} xDV = DVGeo.getValues() np.random.seed(37) - xDV["local"] = np.random.normal(0.0, 0.05, 32) + xDV["local"] = np.random.normal(0.0, 0.05, len(xDV["local"])) DVGeo.setDesignVars(xDV) DVCon.evalFunctions(funcs, includeLinear=True) DVCon.evalFunctionsSens(funcsSens, includeLinear=True) @@ -187,42 +228,32 @@ def c172_test_deformed(self, DVGeo, DVCon, handler): handler.root_add_dict("derivs_deformed", funcsSens, rtol=1e-6, atol=1e-6) return funcs, funcsSens - def test_1(self, train=False, refDeriv=False): - """ - Test 1: 1D Thickness Constraint - """ - refFile = os.path.join(self.base_path, "ref/test_DVConstraints_01.ref") + def test_thickness1D(self, train=False, refDeriv=False): + refFile = os.path.join(self.base_path, "ref/test_DVConstraints_thickness1D.ref") with BaseRegTest(refFile, train=train) as handler: - handler.root_print("Test 1: 1D thickness constraint, C172 wing") - - DVGeo, DVCon = self.generate_dvgeo_dvcon_c172() + DVGeo, DVCon = self.generate_dvgeo_dvcon("c172") ptList = [[0.8, 0.0, 0.1], [0.8, 0.0, 5.0]] DVCon.addThicknessConstraints1D(ptList, nCon=10, axis=[0, 1, 0]) - funcs, funcsSens = self.generic_test_base(DVGeo, DVCon, handler, checkDerivs=True) + funcs, funcsSens = generic_test_base(DVGeo, DVCon, handler, checkDerivs=True) # 1D thickness should be all ones at the start handler.assert_allclose( funcs["DVCon1_thickness_constraints_0"], np.ones(10), name="thickness_base", rtol=1e-7, atol=1e-7 ) - funcs, funcsSens = self.c172_test_twist(DVGeo, DVCon, handler) + funcs, funcsSens = self.wing_test_twist(DVGeo, DVCon, handler) # 1D thickness shouldn't change much under only twist handler.assert_allclose( funcs["DVCon1_thickness_constraints_0"], np.ones(10), name="thickness_twisted", rtol=1e-2, atol=1e-2 ) - funcs, funcsSens = self.c172_test_deformed(DVGeo, DVCon, handler) + funcs, funcsSens = self.wing_test_deformed(DVGeo, DVCon, handler) - def test_1b(self, train=False, refDeriv=False): - """ - Test 1b: 1D Thickness Constraint - """ - refFile = os.path.join(self.base_path, "ref/test_DVConstraints_01b.ref") + def test_thickness1D_box(self, train=False, refDeriv=False): + refFile = os.path.join(self.base_path, "ref/test_DVConstraints_thickness1D_box.ref") with BaseRegTest(refFile, train=train) as handler: - handler.root_print("Test 1b: 1D thickness constraint, rectangular box") - - DVGeo, DVCon = self.generate_dvgeo_dvcon_rect() + DVGeo, DVCon = self.generate_dvgeo_dvcon("box") ptList = [[0.0, 0.0, 0.1], [0.0, 0.0, 5.0]] ptList2 = [[-0.5, 0.0, 2.0], [0.5, 0.0, 2.0]] @@ -230,8 +261,8 @@ def test_1b(self, train=False, refDeriv=False): DVCon.addThicknessConstraints1D(ptList, nCon=3, axis=[1, 0, 0], scaled=False) DVCon.addThicknessConstraints1D(ptList2, nCon=3, axis=[0, 0, 1], scaled=False) - funcs, funcsSens = self.generic_test_base(DVGeo, DVCon, handler) - # check that unscaled thicknesses are being computed correctly at baseline + funcs, funcsSens = generic_test_base(DVGeo, DVCon, handler) + # Check that unscaled thicknesses are computed correctly at baseline handler.assert_allclose( funcs["DVCon1_thickness_constraints_0"], np.ones(3), name="thickness_base", rtol=1e-7, atol=1e-7 ) @@ -242,44 +273,34 @@ def test_1b(self, train=False, refDeriv=False): funcs["DVCon1_thickness_constraints_2"], 8.0 * np.ones(3), name="thickness_base", rtol=1e-7, atol=1e-7 ) - def test_2(self, train=False, refDeriv=False): - """ - Test 2: 2D Thickness Constraint - """ - refFile = os.path.join(self.base_path, "ref/test_DVConstraints_02.ref") + def test_thickness2D(self, train=False, refDeriv=False): + refFile = os.path.join(self.base_path, "ref/test_DVConstraints_thickness2D.ref") with BaseRegTest(refFile, train=train) as handler: - handler.root_print("Test 2: 2D thickness constraint, C172 wing") - - DVGeo, DVCon = self.generate_dvgeo_dvcon_c172() + DVGeo, DVCon = self.generate_dvgeo_dvcon("c172") leList = [[0.7, 0.0, 0.1], [0.7, 0.0, 5.0]] teList = [[0.9, 0.0, 0.1], [0.9, 0.0, 5.0]] DVCon.addThicknessConstraints2D(leList, teList, 5, 5) - funcs, funcsSens = self.generic_test_base(DVGeo, DVCon, handler) + funcs, funcsSens = generic_test_base(DVGeo, DVCon, handler) # 2D thickness should be all ones at the start handler.assert_allclose( funcs["DVCon1_thickness_constraints_0"], np.ones(25), name="thickness_base", rtol=1e-7, atol=1e-7 ) - funcs, funcsSens = self.c172_test_twist(DVGeo, DVCon, handler) + funcs, funcsSens = self.wing_test_twist(DVGeo, DVCon, handler) # 2D thickness shouldn't change much under only twist handler.assert_allclose( funcs["DVCon1_thickness_constraints_0"], np.ones(25), name="thickness_twisted", rtol=1e-2, atol=1e-2 ) - funcs, funcsSens = self.c172_test_deformed(DVGeo, DVCon, handler) + funcs, funcsSens = self.wing_test_deformed(DVGeo, DVCon, handler) - def test_2b(self, train=False, refDeriv=False): - """ - Test 2b: 2D Thickness Constraint - """ - refFile = os.path.join(self.base_path, "ref/test_DVConstraints_02b.ref") + def test_thickness2D_box(self, train=False, refDeriv=False): + refFile = os.path.join(self.base_path, "ref/test_DVConstraints_thickness2D_box.ref") with BaseRegTest(refFile, train=train) as handler: - handler.root_print("Test 2: 2D thickness constraint, rectangular box") - - DVGeo, DVCon = self.generate_dvgeo_dvcon_rect() + DVGeo, DVCon = self.generate_dvgeo_dvcon("box") leList = [[-0.25, 0.0, 0.1], [-0.25, 0.0, 7.9]] teList = [[0.75, 0.0, 0.1], [0.75, 0.0, 7.9]] @@ -294,8 +315,8 @@ def test_2b(self, train=False, refDeriv=False): DVCon.addThicknessConstraints2D(leList2, teList2, 2, 2, scaled=False) DVCon.addThicknessConstraints2D(leList3, teList3, 2, 2, scaled=False) - funcs, funcsSens = self.generic_test_base(DVGeo, DVCon, handler) - # 2D thickness should be all ones at the start + funcs, funcsSens = generic_test_base(DVGeo, DVCon, handler) + # Check that unscaled thicknesses are computed correctly at baseline handler.assert_allclose( funcs["DVCon1_thickness_constraints_0"], np.ones(4), name="thickness_base", rtol=1e-7, atol=1e-7 ) @@ -306,44 +327,34 @@ def test_2b(self, train=False, refDeriv=False): funcs["DVCon1_thickness_constraints_2"], 8.0 * np.ones(4), name="thickness_base", rtol=1e-7, atol=1e-7 ) - def test_3(self, train=False, refDeriv=False): - """ - Test 3: Volume Constraint - """ - refFile = os.path.join(self.base_path, "ref/test_DVConstraints_03.ref") + def test_volume(self, train=False, refDeriv=False): + refFile = os.path.join(self.base_path, "ref/test_DVConstraints_volume.ref") with BaseRegTest(refFile, train=train) as handler: - handler.root_print("Test 3: Volume constraint, C172 wing") - - DVGeo, DVCon = self.generate_dvgeo_dvcon_c172() + DVGeo, DVCon = self.generate_dvgeo_dvcon("c172") leList = [[0.7, 0.0, 0.1], [0.7, 0.0, 5.0]] teList = [[0.9, 0.0, 0.1], [0.9, 0.0, 5.0]] DVCon.addVolumeConstraint(leList, teList, 5, 5) - funcs, funcsSens = self.generic_test_base(DVGeo, DVCon, handler) + funcs, funcsSens = generic_test_base(DVGeo, DVCon, handler) # Volume should be normalized to 1 at the start handler.assert_allclose( funcs["DVCon1_volume_constraint_0"], np.ones(1), name="volume_base", rtol=1e-7, atol=1e-7 ) - funcs, funcsSens = self.c172_test_twist(DVGeo, DVCon, handler) + funcs, funcsSens = self.wing_test_twist(DVGeo, DVCon, handler) # Volume shouldn't change much with twist only handler.assert_allclose( funcs["DVCon1_volume_constraint_0"], np.ones(1), name="volume_twisted", rtol=1e-2, atol=1e-2 ) - funcs, funcsSens = self.c172_test_deformed(DVGeo, DVCon, handler) + funcs, funcsSens = self.wing_test_deformed(DVGeo, DVCon, handler) - def test_3b(self, train=False, refDeriv=False): - """ - Test 3b: Volume Constraint - """ - refFile = os.path.join(self.base_path, "ref/test_DVConstraints_03b.ref") + def test_volume_box(self, train=False, refDeriv=False): + refFile = os.path.join(self.base_path, "ref/test_DVConstraints_volume_box.ref") with BaseRegTest(refFile, train=train) as handler: - handler.root_print("Test 3b: Volume constraint, rectangular box") - - DVGeo, DVCon = self.generate_dvgeo_dvcon_rect() + DVGeo, DVCon = self.generate_dvgeo_dvcon("box") # this projects in the z direction which is of dimension 8 # 1x0.5x8 = 4 @@ -352,36 +363,35 @@ def test_3b(self, train=False, refDeriv=False): DVCon.addVolumeConstraint(leList, teList, 4, 4, scaled=False) - funcs, funcsSens = self.generic_test_base(DVGeo, DVCon, handler) - # Volume should be normalized to 1 at the start + funcs, funcsSens = generic_test_base(DVGeo, DVCon, handler) + # Check that unscaled volume is computed correctly at baseline handler.assert_allclose( funcs["DVCon1_volume_constraint_0"], 4.0 * np.ones(1), name="volume_base", rtol=1e-7, atol=1e-7 ) - def test_4(self, train=False, refDeriv=False): + def test_LeTe(self, train=False, refDeriv=False): """ - Test 4: LeTe Constraint using the ilow, ihigh method - - There's no need to test this with the rectangular box - because it doesn't depend on a projected pointset (only the FFD) + LeTe constraint test using the iLow, iHigh method """ - refFile = os.path.join(self.base_path, "ref/test_DVConstraints_04.ref") + refFile = os.path.join(self.base_path, "ref/test_DVConstraints_LeTe.ref") with BaseRegTest(refFile, train=train) as handler: - handler.root_print("Test 4: LETE constraint, C172 wing") + DVGeo, DVCon = self.generate_dvgeo_dvcon("c172") - DVGeo, DVCon = self.generate_dvgeo_dvcon_c172() - - DVCon.addLeTeConstraints(0, "iLow") - DVCon.addLeTeConstraints(0, "iHigh") + if self.child: + DVCon.addLeTeConstraints(0, "iLow", childIdx=0) + DVCon.addLeTeConstraints(0, "iHigh", childIdx=0) + else: + DVCon.addLeTeConstraints(0, "iLow") + DVCon.addLeTeConstraints(0, "iHigh") - funcs, funcsSens = self.generic_test_base(DVGeo, DVCon, handler) + funcs, funcsSens = generic_test_base(DVGeo, DVCon, handler) # LeTe constraints should be all zero at the start for i in range(2): handler.assert_allclose( funcs["DVCon1_lete_constraint_" + str(i)], np.zeros(4), name="lete_" + str(i), rtol=1e-7, atol=1e-7 ) - funcs, funcsSens = self.c172_test_twist(DVGeo, DVCon, handler) + funcs, funcsSens = self.wing_test_twist(DVGeo, DVCon, handler) # Global DVs should produce no change, especially twist for i in range(2): handler.assert_allclose( @@ -391,30 +401,22 @@ def test_4(self, train=False, refDeriv=False): rtol=1e-7, atol=1e-7, ) - funcs, funcsSens = self.c172_test_deformed(DVGeo, DVCon, handler) - - def test_5(self, train=False, refDeriv=False): - """ - Test 5: Thickness-to-chord constraint + funcs, funcsSens = self.wing_test_deformed(DVGeo, DVCon, handler) - There's no need to test this with the rectangular box - because it doesn't depend on a projected pointset (only the FFD) - """ - refFile = os.path.join(self.base_path, "ref/test_DVConstraints_05.ref") + def test_thicknessToChord(self, train=False, refDeriv=False): + refFile = os.path.join(self.base_path, "ref/test_DVConstraints_thicknessToChord.ref") with BaseRegTest(refFile, train=train) as handler: - handler.root_print("Test 5: t/c constraint, C172 wing") - - DVGeo, DVCon = self.generate_dvgeo_dvcon_c172() + DVGeo, DVCon = self.generate_dvgeo_dvcon("c172") ptList = [[0.8, 0.0, 0.1], [0.8, 0.0, 5.0]] DVCon.addThicknessToChordConstraints1D(ptList, nCon=10, axis=[0, 1, 0], chordDir=[1, 0, 0]) - funcs, funcsSens = self.generic_test_base(DVGeo, DVCon, handler) + funcs, funcsSens = generic_test_base(DVGeo, DVCon, handler) handler.assert_allclose( funcs["DVCon1_thickness_to_chord_constraints_0"], np.ones(10), name="toverc_base", rtol=1e-7, atol=1e-7 ) - funcs, funcsSens = self.c172_test_twist(DVGeo, DVCon, handler) + funcs, funcsSens = self.wing_test_twist(DVGeo, DVCon, handler) handler.assert_allclose( funcs["DVCon1_thickness_to_chord_constraints_0"], np.ones(10), @@ -423,45 +425,35 @@ def test_5(self, train=False, refDeriv=False): atol=1e-3, ) - funcs, funcsSens = self.c172_test_deformed(DVGeo, DVCon, handler) + funcs, funcsSens = self.wing_test_deformed(DVGeo, DVCon, handler) - def test_6(self, train=False, refDeriv=False): - """ - Test 6: Surface area constraint - """ - refFile = os.path.join(self.base_path, "ref/test_DVConstraints_06.ref") + def test_surfaceArea(self, train=False, refDeriv=False): + refFile = os.path.join(self.base_path, "ref/test_DVConstraints_surfaceArea.ref") with BaseRegTest(refFile, train=train) as handler: - handler.root_print("Test 6: surface area constraint, C172 wing") - - DVGeo, DVCon = self.generate_dvgeo_dvcon_c172() + DVGeo, DVCon = self.generate_dvgeo_dvcon("c172") DVCon.addSurfaceAreaConstraint() - funcs, funcsSens = self.generic_test_base(DVGeo, DVCon, handler) + funcs, funcsSens = generic_test_base(DVGeo, DVCon, handler) handler.assert_allclose( funcs["DVCon1_surfaceArea_constraints_0"], np.ones(1), name="surface_area_base", rtol=1e-7, atol=1e-7 ) - funcs, funcsSens = self.c172_test_twist(DVGeo, DVCon, handler) + funcs, funcsSens = self.wing_test_twist(DVGeo, DVCon, handler) handler.assert_allclose( funcs["DVCon1_surfaceArea_constraints_0"], np.ones(1), name="surface_area_twisted", rtol=1e-3, atol=1e-3 ) - funcs, funcsSens = self.c172_test_deformed(DVGeo, DVCon, handler) + funcs, funcsSens = self.wing_test_deformed(DVGeo, DVCon, handler) - def test_6b(self, train=False, refDeriv=False): - """ - Test 6b: Surface area constraint - """ - refFile = os.path.join(self.base_path, "ref/test_DVConstraints_06b.ref") + def test_surfaceArea_box(self, train=False, refDeriv=False): + refFile = os.path.join(self.base_path, "ref/test_DVConstraints_surfaceArea_box.ref") with BaseRegTest(refFile, train=train) as handler: - handler.root_print("Test 6: surface area constraint, rectangular box") - - DVGeo, DVCon = self.generate_dvgeo_dvcon_rect() + DVGeo, DVCon = self.generate_dvgeo_dvcon("box") DVCon.addSurfaceAreaConstraint(scaled=False) # 2x1x8 box has surface area 2*(8*2+1*2+8*1) = 52 - funcs, funcsSens = self.generic_test_base(DVGeo, DVCon, handler) + funcs, funcsSens = generic_test_base(DVGeo, DVCon, handler) handler.assert_allclose( funcs["DVCon1_surfaceArea_constraints_0"], 52.0 * np.ones(1), @@ -470,19 +462,14 @@ def test_6b(self, train=False, refDeriv=False): atol=1e-7, ) - def test_7(self, train=False, refDeriv=False): - """ - Test 7: Projected area constraint - """ - refFile = os.path.join(self.base_path, "ref/test_DVConstraints_07.ref") + def test_projectedArea(self, train=False, refDeriv=False): + refFile = os.path.join(self.base_path, "ref/test_DVConstraints_projectedArea.ref") with BaseRegTest(refFile, train=train) as handler: - handler.root_print("Test 7: projected area constraint, C172 wing") - - DVGeo, DVCon = self.generate_dvgeo_dvcon_c172() + DVGeo, DVCon = self.generate_dvgeo_dvcon("c172") DVCon.addProjectedAreaConstraint() - funcs, funcsSens = self.generic_test_base(DVGeo, DVCon, handler) + funcs, funcsSens = generic_test_base(DVGeo, DVCon, handler) handler.assert_allclose( funcs["DVCon1_projectedArea_constraints_0"], np.ones(1), @@ -491,25 +478,20 @@ def test_7(self, train=False, refDeriv=False): atol=1e-7, ) - funcs, funcsSens = self.c172_test_twist(DVGeo, DVCon, handler) + funcs, funcsSens = self.wing_test_twist(DVGeo, DVCon, handler) - funcs, funcsSens = self.c172_test_deformed(DVGeo, DVCon, handler) + funcs, funcsSens = self.wing_test_deformed(DVGeo, DVCon, handler) - def test_7b(self, train=False, refDeriv=False): - """ - Test 7b: Projected area constraint - """ - refFile = os.path.join(self.base_path, "ref/test_DVConstraints_07b.ref") + def test_projectedArea_box(self, train=False, refDeriv=False): + refFile = os.path.join(self.base_path, "ref/test_DVConstraints_projectedArea_box.ref") with BaseRegTest(refFile, train=train) as handler: - handler.root_print("Test 7b: projected area constraint, rectangular box") - - DVGeo, DVCon = self.generate_dvgeo_dvcon_rect() + DVGeo, DVCon = self.generate_dvgeo_dvcon("box") DVCon.addProjectedAreaConstraint(scaled=False) DVCon.addProjectedAreaConstraint(axis="z", scaled=False) DVCon.addProjectedAreaConstraint(axis="x", scaled=False) - funcs, funcsSens = self.generic_test_base(DVGeo, DVCon, handler, checkDerivs=False) + funcs, funcsSens = generic_test_base(DVGeo, DVCon, handler, checkDerivs=False) handler.assert_allclose( funcs["DVCon1_projectedArea_constraints_0"], 8 * 2 * np.ones(1), @@ -532,18 +514,10 @@ def test_7b(self, train=False, refDeriv=False): atol=1e-7, ) - def test_8(self, train=False, refDeriv=False): - """ - Test 8: Circularity constraint - - No need to test this with the rectangular box - because it only depends on the FFD, no projected points - """ - refFile = os.path.join(self.base_path, "ref/test_DVConstraints_08.ref") + def test_circularity(self, train=False, refDeriv=False): + refFile = os.path.join(self.base_path, "ref/test_DVConstraints_circularity.ref") with BaseRegTest(refFile, train=train) as handler: - handler.root_print("Test 8: Circularity constraint, C172 wing") - - DVGeo, DVCon = self.generate_dvgeo_dvcon_c172() + DVGeo, DVCon = self.generate_dvgeo_dvcon("c172") DVCon.addCircularityConstraint( origin=[0.8, 0.0, 2.5], @@ -555,71 +529,59 @@ def test_8(self, train=False, refDeriv=False): nPts=10, ) - funcs, funcsSens = self.generic_test_base(DVGeo, DVCon, handler) + funcs, funcsSens = generic_test_base(DVGeo, DVCon, handler) handler.assert_allclose( funcs["DVCon1_circularity_constraints_0"], np.ones(9), name="circularity_base", rtol=1e-7, atol=1e-7 ) - funcs, funcsSens = self.c172_test_twist(DVGeo, DVCon, handler) + funcs, funcsSens = self.wing_test_twist(DVGeo, DVCon, handler) handler.assert_allclose( funcs["DVCon1_circularity_constraints_0"], np.ones(9), name="circularity_twisted", rtol=1e-7, atol=1e-7 ) - funcs, funcsSens = self.c172_test_deformed(DVGeo, DVCon, handler) - - def test_9(self, train=False, refDeriv=False): - """ - Test 9: Colinearity constraint + funcs, funcsSens = self.wing_test_deformed(DVGeo, DVCon, handler) - No need to test this with the rectangular box - because it only depends on the FFD, no projected points - """ - refFile = os.path.join(self.base_path, "ref/test_DVConstraints_09.ref") + def test_colinearity(self, train=False, refDeriv=False): + refFile = os.path.join(self.base_path, "ref/test_DVConstraints_colinearity.ref") with BaseRegTest(refFile, train=train) as handler: - handler.root_print("Test 9: Colinearity constraint, C172 wing") - - DVGeo, DVCon = self.generate_dvgeo_dvcon_c172() + DVGeo, DVCon = self.generate_dvgeo_dvcon("c172") DVCon.addColinearityConstraint( np.array([0.7, 0.0, 1.0]), lineAxis=np.array([0.0, 0.0, 1.0]), distances=[0.0, 1.0, 2.5] ) # Skip derivatives check here because true zero values cause difficulties for the partials - funcs, funcsSens = self.generic_test_base(DVGeo, DVCon, handler, checkDerivs=False) + funcs, funcsSens = generic_test_base(DVGeo, DVCon, handler, checkDerivs=False) handler.assert_allclose( funcs["DVCon1_colinearity_constraints_0"], np.zeros(3), name="colinearity_base", rtol=1e-7, atol=1e-7 ) - funcs, funcsSens = self.c172_test_twist(DVGeo, DVCon, handler) - funcs, funcsSens = self.c172_test_deformed(DVGeo, DVCon, handler) - - def test_10(self, train=False, refDeriv=False): - """ - Test 10: LinearConstraintShape + funcs, funcsSens = self.wing_test_twist(DVGeo, DVCon, handler) + funcs, funcsSens = self.wing_test_deformed(DVGeo, DVCon, handler) - No need to test this with the rectangular box - because it only depends on the FFD, no projected points - """ - refFile = os.path.join(self.base_path, "ref/test_DVConstraints_10.ref") + def test_linearConstraintShape(self, train=False, refDeriv=False): + refFile = os.path.join(self.base_path, "ref/test_DVConstraints_linearConstraintShape.ref") with BaseRegTest(refFile, train=train) as handler: - handler.root_print("Test 10: LinearConstraintShape, C172 wing") - - DVGeo, DVCon = self.generate_dvgeo_dvcon_c172() + DVGeo, DVCon = self.generate_dvgeo_dvcon("c172") lIndex = DVGeo.getLocalIndex(0) indSetA = [] indSetB = [] for i in range(lIndex.shape[0]): indSetA.append(lIndex[i, 0, 0]) indSetB.append(lIndex[i, 0, 1]) - DVCon.addLinearConstraintsShape(indSetA, indSetB, factorA=1.0, factorB=-1.0, lower=0, upper=0) - funcs, funcsSens = self.generic_test_base(DVGeo, DVCon, handler) - funcs, funcsSens = self.c172_test_twist(DVGeo, DVCon, handler) - funcs, funcsSens = self.c172_test_deformed(DVGeo, DVCon, handler) + if self.child: + DVCon.addLinearConstraintsShape( + indSetA, indSetB, factorA=1.0, factorB=-1.0, lower=0, upper=0, childIdx=0 + ) + else: + DVCon.addLinearConstraintsShape(indSetA, indSetB, factorA=1.0, factorB=-1.0, lower=0, upper=0) + funcs, funcsSens = generic_test_base(DVGeo, DVCon, handler) + funcs, funcsSens = self.wing_test_twist(DVGeo, DVCon, handler) + funcs, funcsSens = self.wing_test_deformed(DVGeo, DVCon, handler) - def test_11(self, train=False, refDeriv=False): - refFile = os.path.join(self.base_path, "ref/test_DVConstraints_11.ref") + def test_compositeVolume_box(self, train=False, refDeriv=False): + refFile = os.path.join(self.base_path, "ref/test_DVConstraints_compositeVolume_box.ref") with BaseRegTest(refFile, train=train) as handler: - handler.root_print("Test 11: CompositeVolumeConstraint, rectangular box") - DVGeo, DVCon = self.generate_dvgeo_dvcon_rect() + DVGeo, DVCon = self.generate_dvgeo_dvcon("box") # this projects in the z direction which is of dimension 8 # 1x0.5x8 = 4 @@ -635,8 +597,8 @@ def test_11(self, train=False, refDeriv=False): vols = ["DVCon1_volume_constraint_0", "DVCon1_volume_constraint_1"] DVCon.addCompositeVolumeConstraint(vols=vols, scaled=False) - funcs, funcsSens = self.generic_test_base(DVGeo, DVCon, handler) - # Volume should be normalized to 1 at the start + funcs, funcsSens = generic_test_base(DVGeo, DVCon, handler) + # Check that unscaled volumes are computed correctly at baseline handler.assert_allclose( funcs["DVCon1_volume_constraint_0"], 4.0 * np.ones(1), name="volume1_base", rtol=1e-7, atol=1e-7 ) @@ -651,11 +613,10 @@ def test_11(self, train=False, refDeriv=False): atol=1e-7, ) - def test_12(self, train=False, refDeriv=False): - refFile = os.path.join(self.base_path, "ref/test_DVConstraints_12.ref") + def test_location_box(self, train=False, refDeriv=False): + refFile = os.path.join(self.base_path, "ref/test_DVConstraints_location_box.ref") with BaseRegTest(refFile, train=train) as handler: - handler.root_print("Test 12: LocationConstraints1D, rectangular box") - DVGeo, DVCon = self.generate_dvgeo_dvcon_rect() + DVGeo, DVCon = self.generate_dvgeo_dvcon("box") ptList = [[0.0, 0.0, 0.0], [0.0, 0.0, 8.0]] ptList2 = [[0.0, 0.2, 0.0], [0.0, -0.2, 8.0]] @@ -663,7 +624,7 @@ def test_12(self, train=False, refDeriv=False): # TODO this constraint seems buggy. for example, when scaled, returns a bunch of NaNs DVCon.addLocationConstraints1D(ptList=ptList, nCon=10, scaled=False) DVCon.addProjectedLocationConstraints1D(ptList=ptList2, nCon=10, scaled=False, axis=[0.0, 1.0, 0.0]) - funcs, funcsSens = self.generic_test_base(DVGeo, DVCon, handler) + funcs, funcsSens = generic_test_base(DVGeo, DVCon, handler) exact_vals = np.zeros((30,)) exact_vals[2::3] = np.linspace(0, 8, 10) @@ -679,27 +640,21 @@ def test_12(self, train=False, refDeriv=False): atol=1e-7, ) - def test_13(self, train=False, refDeriv=False): - refFile = os.path.join(self.base_path, "ref/test_DVConstraints_13.ref") + def test_planarity_box(self, train=False, refDeriv=False): + refFile = os.path.join(self.base_path, "ref/test_DVConstraints_planarity_box.ref") with BaseRegTest(refFile, train=train) as handler: - handler.root_print("Test 13: PlanarityConstraint, rectangular box") - DVGeo, DVCon = self.generate_dvgeo_dvcon_rect() + DVGeo, DVCon = self.generate_dvgeo_dvcon("box") DVCon.addPlanarityConstraint(origin=[0.0, 0.5, 0.0], planeAxis=[0.0, 1.0, 0.0]) - funcs, funcsSens = self.generic_test_base(DVGeo, DVCon, handler) + funcs, funcsSens = generic_test_base(DVGeo, DVCon, handler) - def test_13b(self, train=False, refDeriv=False): - refFile = os.path.join(self.base_path, "ref/test_DVConstraints_13b.ref") + def test_planarity_tri(self, train=False, refDeriv=False): + refFile = os.path.join(self.base_path, "ref/test_DVConstraints_planarity_tri.ref") with BaseRegTest(refFile, train=train) as handler: - handler.root_print("Test 13: PlanarityConstraint, rectangular box") - ffdfile = os.path.join(self.base_path, "../../input_files/2x1x8_rectangle.xyz") - DVGeo = DVGeometry(ffdfile) - DVGeo.addLocalDV("local", lower=-0.5, upper=0.5, axis="y", scale=1) - - # create a DVConstraints object with a simple plane consisting of 2 triangles - DVCon = DVConstraints() - DVCon.setDVGeo(DVGeo) + # Set up a dummy DVGeo and DVCon + DVGeo, DVCon = self.generate_dvgeo_dvcon("box") + # Set a DVConstraints surface consisting of a simple plane with 2 triangles p0 = np.zeros(shape=(2, 3)) p1 = np.zeros(shape=(2, 3)) p2 = np.zeros(shape=(2, 3)) @@ -716,35 +671,34 @@ def test_13b(self, train=False, refDeriv=False): v1 = p1 - p0 v2 = p2 - p0 - DVCon.setSurface([p0, v1, v2]) + DVCon.setSurface([p0, v1, v2], name="tri") - DVCon.addPlanarityConstraint(origin=[0.0, -0.25, 2.0], planeAxis=[0.0, 1.0, 0.0]) + DVCon.addPlanarityConstraint(origin=[0.0, -0.25, 2.0], planeAxis=[0.0, 1.0, 0.0], surfaceName="tri") - funcs, funcsSens = self.generic_test_base(DVGeo, DVCon, handler, checkDerivs=False) + funcs, funcsSens = generic_test_base(DVGeo, DVCon, handler, checkDerivs=False) - # this should be coplanar and the planarity constraint shoudl be zero + # this should be coplanar and the planarity constraint should be zero handler.assert_allclose( funcs["DVCon1_planarity_constraints_0"], np.zeros(1), name="planarity", rtol=1e-7, atol=1e-7 ) - def test_14(self, train=False, refDeriv=False): - """ - Test 14: Monotonic constraint - """ - refFile = os.path.join(self.base_path, "ref/test_DVConstraints_14.ref") + def test_monotonic(self, train=False, refDeriv=False): + refFile = os.path.join(self.base_path, "ref/test_DVConstraints_monotonic.ref") with BaseRegTest(refFile, train=train) as handler: - handler.root_print("Test 14: Monotonic constraint, C172 wing") + DVGeo, DVCon = self.generate_dvgeo_dvcon("c172") - DVGeo, DVCon = self.generate_dvgeo_dvcon_c172() - - DVCon.addMonotonicConstraints("twist") - DVCon.addMonotonicConstraints("twist", start=1, stop=2) + if self.child: + DVCon.addMonotonicConstraints("twist", childIdx=0) + DVCon.addMonotonicConstraints("twist", start=1, stop=2, childIdx=0) + else: + DVCon.addMonotonicConstraints("twist") + DVCon.addMonotonicConstraints("twist", start=1, stop=2) - funcs, funcsSens = self.generic_test_base(DVGeo, DVCon, handler) + funcs, funcsSens = generic_test_base(DVGeo, DVCon, handler) handler.assert_allclose( funcs["DVCon1_monotonic_constraint_0"], np.zeros(2), name="monotonicity", rtol=1e-7, atol=1e-7 ) - funcs, funcsSens = self.c172_test_twist(DVGeo, DVCon, handler) + funcs, funcsSens = self.wing_test_twist(DVGeo, DVCon, handler) handler.assert_allclose( funcs["DVCon1_monotonic_constraint_0"], -5.0 * np.ones(2), @@ -784,126 +738,124 @@ def test_14(self, train=False, refDeriv=False): ) @unittest.skipIf(missing_geograd, "requires geograd") - def test_15(self, train=False, refDeriv=False): - """ - Test 15: Triangulated surface constraint - """ - refFile = os.path.join(self.base_path, "ref/test_DVConstraints_15.ref") + def test_triangulatedSurface(self, train=False, refDeriv=False): + refFile = os.path.join(self.base_path, "ref/test_DVConstraints_triangulatedSurface.ref") with BaseRegTest(refFile, train=train) as handler: - handler.root_print("Test 15: Triangulated surface constraint, BWB") - - meshfile = os.path.join(self.base_path, "../../input_files/bwb.stl") - objfile = os.path.join(self.base_path, "../../input_files/blob_bwb_wing.stl") - ffdfile = os.path.join(self.base_path, "../../input_files/bwb.xyz") - testmesh = mesh.Mesh.from_file(meshfile) - testobj = mesh.Mesh.from_file(objfile) - # test mesh dim 0 is triangle index - # dim 1 is each vertex of the triangle - # dim 2 is x, y, z dimension - - # create a DVGeo object with a few local thickness variables - DVGeo = DVGeometry(ffdfile) - nRefAxPts = DVGeo.addRefAxis("wing", xFraction=0.25, alignIndex="k") - self.nTwist = nRefAxPts - 1 - - def twist(val, geo): - for i in range(1, nRefAxPts): - geo.rot_z["wing"].coef[i] = val[i - 1] - - DVGeo.addGlobalDV(dvName="twist", value=[0] * self.nTwist, func=twist, lower=-10, upper=10, scale=1) - DVGeo.addLocalDV("local", lower=-0.5, upper=0.5, axis="y", scale=1) - - # create a DVConstraints object for the wing - DVCon = DVConstraints() - DVCon.setDVGeo(DVGeo) - p0 = testmesh.vectors[:, 0, :] - v1 = testmesh.vectors[:, 1, :] - p0 - v2 = testmesh.vectors[:, 2, :] - p0 - DVCon.setSurface([p0, v1, v2], addToDVGeo=True) - p0b = testobj.vectors[:, 0, :] - v1b = testobj.vectors[:, 1, :] - p0b - v2b = testobj.vectors[:, 2, :] - p0b - DVCon.setSurface([p0b, v1b, v2b], name="blob") + DVGeo, DVCon = self.generate_dvgeo_dvcon("bwb", addToDVGeo=True) DVCon.addTriangulatedSurfaceConstraint("default", "default", "blob", None, rho=10.0, addToPyOpt=True) DVCon.addTriangulatedSurfaceConstraint("default", "default", "blob", None, rho=1000.0, addToPyOpt=True) - funcs, funcsSens = self.generic_test_base(DVGeo, DVCon, handler, fdstep=1e-3) + funcs, funcsSens = generic_test_base(DVGeo, DVCon, handler, fdstep=1e-3) handler.assert_allclose( funcs["DVCon1_trisurf_constraint_0_KS"], 0.34660627481696404, name="KS", rtol=1e-7, atol=1e-7 ) handler.assert_allclose(funcs["DVCon1_trisurf_constraint_0_perim"], 0.0, name="perim", rtol=1e-7, atol=1e-7) - funcs, funcsSens = self.c172_test_twist(DVGeo, DVCon, handler) - funcs, funcsSens = self.c172_test_deformed(DVGeo, DVCon, handler) + funcs, funcsSens = self.wing_test_twist(DVGeo, DVCon, handler) + funcs, funcsSens = self.wing_test_deformed(DVGeo, DVCon, handler) @unittest.skipIf(missing_geograd, "requires geograd") - def test_16(self, train=False, refDeriv=False): - """ - Test 16: Triangulated surface constraint, intersected - """ - refFile = os.path.join(self.base_path, "ref/test_DVConstraints_16.ref") + def test_triangulatedSurface_intersected(self, train=False, refDeriv=False): + refFile = os.path.join(self.base_path, "ref/test_DVConstraints_triangulatedSurface_intersected.ref") with BaseRegTest(refFile, train=train) as handler: - handler.root_print("Test 16: Triangulated surface constraint, intersected") + DVGeo, DVCon = self.generate_dvgeo_dvcon("bwb", addToDVGeo=True, intersected=True) - meshfile = os.path.join(self.base_path, "../../input_files/bwb.stl") - objfile = os.path.join(self.base_path, "../../input_files/blob_bwb_wing.stl") - ffdfile = os.path.join(self.base_path, "../../input_files/bwb.xyz") - testmesh = mesh.Mesh.from_file(meshfile) - testobj = mesh.Mesh.from_file(objfile) - # test mesh dim 0 is triangle index - # dim 1 is each vertex of the triangle - # dim 2 is x, y, z dimension + DVCon.addTriangulatedSurfaceConstraint("default", "default", "blob", None, rho=10.0, addToPyOpt=True) - # create a DVGeo object with a few local thickness variables - DVGeo = DVGeometry(ffdfile) - nRefAxPts = DVGeo.addRefAxis("wing", xFraction=0.25, alignIndex="k") - self.nTwist = nRefAxPts - 1 + funcs, funcsSens = generic_test_base(DVGeo, DVCon, handler) + np.testing.assert_array_less(np.zeros(1), funcs["DVCon1_trisurf_constraint_0_perim"]) - def twist(val, geo): - for i in range(1, nRefAxPts): - geo.rot_z["wing"].coef[i] = val[i - 1] + def test_triangulatedVolume_box(self, train=False, refDeriv=False): + refFile = os.path.join(self.base_path, "ref/test_DVConstraints_triangulatedVolume_box.ref") + with BaseRegTest(refFile, train=train) as handler: + DVGeo, DVCon = self.generate_dvgeo_dvcon("box", addToDVGeo=True) - DVGeo.addGlobalDV(dvName="twist", value=[0] * self.nTwist, func=twist, lower=-10, upper=10, scale=1) - DVGeo.addLocalDV("local", lower=-0.5, upper=0.5, axis="y", scale=1) + DVCon.addTriangulatedVolumeConstraint(scaled=False, name="unscaled_vol_con") + DVCon.addTriangulatedVolumeConstraint(scaled=True) - # create a DVConstraints object for the wing - DVCon = DVConstraints() - DVCon.setDVGeo(DVGeo) - p0 = testmesh.vectors[:, 0, :] - v1 = testmesh.vectors[:, 1, :] - p0 - v2 = testmesh.vectors[:, 2, :] - p0 - DVCon.setSurface([p0, v1, v2], addToDVGeo=True) - p0b = testobj.vectors[:, 0, :] - v1b = testobj.vectors[:, 1, :] - p0b - v2b = testobj.vectors[:, 2, :] - p0b - p0b = p0b + np.array([0.0, 0.3, 0.0]) - DVCon.setSurface([p0b, v1b, v2b], name="blob") + funcs, funcsSens = generic_test_base(DVGeo, DVCon, handler) + # Check that the scaled and unscaled volumes are computed correctly at baseline + handler.assert_allclose( + funcs["DVCon1_trivolume_constraint_1"], 1.0, name="scaled_volume_base", rtol=1e-7, atol=1e-7 + ) + handler.assert_allclose(funcs["unscaled_vol_con"], 16.0, name="unscaled_volume_base", rtol=1e-7, atol=1e-7) - DVCon.addTriangulatedSurfaceConstraint("default", "default", "blob", None, rho=10.0, addToPyOpt=True) + def test_triangulatedVolume_bwb(self, train=False, refDeriv=False): + refFile = os.path.join(self.base_path, "ref/test_DVConstraints_triangulatedVolume_bwb.ref") + with BaseRegTest(refFile, train=train) as handler: + DVGeo, DVCon = self.generate_dvgeo_dvcon("bwb", addToDVGeo=True) - funcs, funcsSens = self.generic_test_base(DVGeo, DVCon, handler) - np.testing.assert_array_less(np.zeros(1), funcs["DVCon1_trisurf_constraint_0_perim"]) + DVCon.addTriangulatedVolumeConstraint(scaled=False, name="unscaled_vol_con") + DVCon.addTriangulatedVolumeConstraint(scaled=True) - @unittest.skipIf(missing_geograd, "requires geograd") - def test_17(self, train=False, refDeriv=False): - """ - Test 17: Triangulated surface constraint, intersected, two DVGeos - """ - refFile = os.path.join(self.base_path, "ref/test_DVConstraints_17.ref") + funcs, funcsSens = generic_test_base(DVGeo, DVCon, handler) + + # Check that the scaled and unscaled volumes are computed correctly at baseline + handler.assert_allclose( + funcs["DVCon1_trivolume_constraint_1"], 1.0, name="scaled_volume_base", rtol=1e-7, atol=1e-7 + ) + # BWB volume computed with meshmixer + handler.assert_allclose( + funcs["unscaled_vol_con"], 1103.57, name="unscaled_volume_base", rtol=1e-7, atol=1e-7 + ) + + def test_curvature(self, train=False, refDeriv=False): + refFile = os.path.join(self.base_path, "ref/test_DVConstraints_curvature.ref") with BaseRegTest(refFile, train=train) as handler: - handler.root_print("Test 17: Triangulated surface constraint, intersected, 2 DVGeos") - meshfile = os.path.join(self.base_path, "../../input_files/bwb.stl") - objfile = os.path.join(self.base_path, "../../input_files/blob_bwb_wing.stl") - ffdfile = os.path.join(self.base_path, "../../input_files/bwb.xyz") - testmesh = mesh.Mesh.from_file(meshfile) - testobj = mesh.Mesh.from_file(objfile) + # Use the RAE 2822 wing because we have a PLOT3D surface file for it + DVGeo, DVCon = self.generate_dvgeo_dvcon("rae2822", addToDVGeo=True) + surfFile = os.path.join(self.base_path, "../../input_files/deform_geometry_wing.xyz") + + # Add both scaled and unscaled curvature constraints + DVCon.addCurvatureConstraint(surfFile, curvatureType="mean") + DVCon.addCurvatureConstraint(surfFile, curvatureType="mean", scaled=False, name="unscaled_curvature_con") + + funcs, funcsSens = generic_test_base(DVGeo, DVCon, handler, fdstep=1e-5) + funcs, funcsSens = self.wing_test_twist(DVGeo, DVCon, handler) + funcs, funcsSens = self.wing_test_deformed(DVGeo, DVCon, handler) + + def test_LERadius(self, train=False, refDeriv=False): + refFile = os.path.join(self.base_path, "ref/test_DVConstraints_LERadius.ref") + with BaseRegTest(refFile, train=train) as handler: + DVGeo, DVCon = self.generate_dvgeo_dvcon("c172") + + leList = [[1e-4, 0, 1e-3], [1e-3, 0, 2.5], [0.15, 0, 5.0]] + + # Add both scaled and unscaled LE radius constraints + DVCon.addLERadiusConstraints(leList, 5, [0, 1, 0], [-1, 0, 0]) + DVCon.addLERadiusConstraints(leList, 5, [0, 1, 0], [-1, 0, 0], scaled=False, name="unscaled_radius_con") + + funcs, funcsSens = generic_test_base(DVGeo, DVCon, handler) + funcs, funcsSens = self.wing_test_twist(DVGeo, DVCon, handler) + funcs, funcsSens = self.wing_test_deformed(DVGeo, DVCon, handler) + + +@unittest.skipIf(missing_geograd, "requires geograd") +class RegTestGeograd(unittest.TestCase): + + N_PROCS = 1 + + def setUp(self): + # Store the path where this current script lives + # This all paths in the script are relative to this path + # This is needed to support testflo running directories and files as inputs + self.base_path = os.path.dirname(os.path.abspath(__file__)) + + def test_triangulatedSurface_intersected_2DVGeos(self, train=False, refDeriv=False): + refFile = os.path.join(self.base_path, "ref/test_DVConstraints_triangulatedSurface_intersected_2DVGeos.ref") + with BaseRegTest(refFile, train=train) as handler: + meshFile = os.path.join(self.base_path, "../../input_files/bwb.stl") + objFile = os.path.join(self.base_path, "../../input_files/blob_bwb_wing.stl") + ffdFile = os.path.join(self.base_path, "../../input_files/bwb.xyz") + testMesh = mesh.Mesh.from_file(meshFile) + testObj = mesh.Mesh.from_file(objFile) # test mesh dim 0 is triangle index # dim 1 is each vertex of the triangle # dim 2 is x, y, z dimension # create a DVGeo object with a few local thickness variables - DVGeo1 = DVGeometry(ffdfile) + DVGeo1 = DVGeometry(ffdFile) nRefAxPts = DVGeo1.addRefAxis("wing", xFraction=0.25, alignIndex="k") self.nTwist = nRefAxPts - 1 @@ -915,11 +867,11 @@ def twist(val, geo): DVGeo1.addLocalDV("local", lower=-0.5, upper=0.5, axis="y", scale=1) # create a DVGeo object with a few local thickness variables - DVGeo2 = DVGeometry(ffdfile, name="blobdvgeo") + DVGeo2 = DVGeometry(ffdFile, name="blobdvgeo") DVGeo2.addLocalDV("local_2", lower=-0.5, upper=0.5, axis="y", scale=1) # check that DVGeos with duplicate var names are not allowed - DVGeo3 = DVGeometry(ffdfile) + DVGeo3 = DVGeometry(ffdFile) DVGeo3.addLocalDV("local", lower=-0.5, upper=0.5, axis="y", scale=1) # create a DVConstraints object for the wing @@ -929,13 +881,13 @@ def twist(val, geo): with self.assertRaises(ValueError): DVCon.setDVGeo(DVGeo3, name="third") - p0 = testmesh.vectors[:, 0, :] - v1 = testmesh.vectors[:, 1, :] - p0 - v2 = testmesh.vectors[:, 2, :] - p0 + p0 = testMesh.vectors[:, 0, :] + v1 = testMesh.vectors[:, 1, :] - p0 + v2 = testMesh.vectors[:, 2, :] - p0 DVCon.setSurface([p0, v1, v2], addToDVGeo=True) - p0b = testobj.vectors[:, 0, :] - v1b = testobj.vectors[:, 1, :] - p0b - v2b = testobj.vectors[:, 2, :] - p0b + p0b = testObj.vectors[:, 0, :] + v1b = testObj.vectors[:, 1, :] - p0b + v2b = testObj.vectors[:, 2, :] - p0b p0b = p0b + np.array([0.0, 0.3, 0.0]) DVCon.setSurface([p0b, v1b, v2b], name="blob", addToDVGeo=True, DVGeoName="second") @@ -948,9 +900,9 @@ def twist(val, geo): DVCon.evalFunctionsSens(funcsSens, includeLinear=True) # regress the derivatives handler.root_add_dict("derivs_base", funcsSens, rtol=1e-6, atol=1e-6) - # FD check DVGeo1 - funcsSensFD = self.evalFunctionsSensFD(DVGeo1, DVCon, fdstep=1e-3) + # FD check DVGeo1 + funcsSensFD = evalFunctionsSensFD(DVGeo1, DVCon, fdstep=1e-3) at_least_one_var = False for outkey in funcs.keys(): for inkey in DVGeo1.getValues().keys(): @@ -962,9 +914,9 @@ def twist(val, geo): at_least_one_var = True self.assertTrue(at_least_one_var) - at_least_one_var = False # FD check DVGeo2 - funcsSensFD = self.evalFunctionsSensFD(DVGeo2, DVCon, fdstep=1e-3) + funcsSensFD = evalFunctionsSensFD(DVGeo2, DVCon, fdstep=1e-3) + at_least_one_var = False for outkey in funcs.keys(): for inkey in DVGeo2.getValues().keys(): analytic = funcsSens[outkey][inkey] @@ -974,99 +926,6 @@ def twist(val, geo): at_least_one_var = True self.assertTrue(at_least_one_var) - def test_18(self, train=False, refDeriv=False): - """ - Test 18: Triangulated volume constraint, rectangle - """ - refFile = os.path.join(self.base_path, "ref/test_DVConstraints_18.ref") - with BaseRegTest(refFile, train=train) as handler: - handler.root_print("Test 18: Triangulated volume constraint, rectangle") - - DVGeo, DVCon = self.generate_dvgeo_dvcon_rect(addToDVGeo=True) - - DVCon.addTriangulatedVolumeConstraint(scaled=False, name="unscaled_vol_con") - DVCon.addTriangulatedVolumeConstraint(scaled=True) - - funcs, funcsSens = self.generic_test_base(DVGeo, DVCon, handler) - # check that unscaled thicknesses are being computed correctly at baseline - handler.assert_allclose( - funcs["DVCon1_trivolume_constraint_1"], 1.0, name="scaled_volume_base", rtol=1e-7, atol=1e-7 - ) - handler.assert_allclose(funcs["unscaled_vol_con"], 16.0, name="unscaled_volume_base", rtol=1e-7, atol=1e-7) - - def test_19(self, train=False, refDeriv=False): - """ - Test 19: Triangulated volume constraint, bwb - """ - refFile = os.path.join(self.base_path, "ref/test_DVConstraints_19.ref") - with BaseRegTest(refFile, train=train) as handler: - handler.root_print("Test 17: Triangulated surface constraint, bwb") - - meshfile = os.path.join(self.base_path, "../../input_files/bwb.stl") - ffdfile = os.path.join(self.base_path, "../../input_files/bwb.xyz") - testmesh = mesh.Mesh.from_file(meshfile) - # test mesh dim 0 is triangle index - # dim 1 is each vertex of the triangle - # dim 2 is x, y, z dimension - - # create a DVGeo object with a few local thickness variables - DVGeo1 = DVGeometry(ffdfile) - nRefAxPts = DVGeo1.addRefAxis("wing", xFraction=0.25, alignIndex="k") - self.nTwist = nRefAxPts - 1 - - def twist(val, geo): - for i in range(1, nRefAxPts): - geo.rot_z["wing"].coef[i] = val[i - 1] - - DVGeo1.addGlobalDV(dvName="twist", value=[0] * self.nTwist, func=twist, lower=-10, upper=10, scale=1) - DVGeo1.addLocalDV("local", lower=-0.5, upper=0.5, axis="y", scale=1) - - # create a DVConstraints object for the wing - DVCon = DVConstraints() - DVCon.setDVGeo(DVGeo1) - - p0 = testmesh.vectors[:, 0, :] - v1 = testmesh.vectors[:, 1, :] - p0 - v2 = testmesh.vectors[:, 2, :] - p0 - DVCon.setSurface([p0, v1, v2], addToDVGeo=True) - - DVCon.addTriangulatedVolumeConstraint(scaled=False, name="unscaled_vol_con") - DVCon.addTriangulatedVolumeConstraint(scaled=True) - - funcs = {} - DVCon.evalFunctions(funcs, includeLinear=True) - handler.root_add_dict("funcs_base", funcs, rtol=1e-6, atol=1e-6) - - handler.assert_allclose( - funcs["DVCon1_trivolume_constraint_1"], 1.0, name="scaled_volume_base", rtol=1e-7, atol=1e-7 - ) - - # BWB volume computed with meshmixer - handler.assert_allclose( - funcs["unscaled_vol_con"], 1103.57, name="unscaled_volume_base", rtol=1e-7, atol=1e-7 - ) - - funcsSens = {} - DVCon.evalFunctionsSens(funcsSens, includeLinear=True) - # regress the derivatives - handler.root_add_dict("derivs_base", funcsSens, rtol=1e-6, atol=1e-6) - # FD check DVGeo1 - - funcsSensFD = self.evalFunctionsSensFD(DVGeo1, DVCon, fdstep=1e-6) - at_least_one_var = False - for outkey in funcs.keys(): - for inkey in DVGeo1.getValues().keys(): - analytic = funcsSens[outkey][inkey] - fd = funcsSensFD[outkey][inkey] - handler.assert_allclose(analytic, fd, name="finite_diff_check", rtol=1e-5, atol=1e-5) - # make sure there are actually checks happening - self.assertTrue(np.sum(np.abs(fd)) > 1e-10) - at_least_one_var = True - self.assertTrue(at_least_one_var) - if __name__ == "__main__": unittest.main() - - # import xmlrunner - # unittest.main(testRunner=xmlrunner.XMLTestRunner(output='test-reports'))