diff --git a/.github/workflows/build_test.yaml b/.github/workflows/build_test.yaml index 446acc3..da732fc 100644 --- a/.github/workflows/build_test.yaml +++ b/.github/workflows/build_test.yaml @@ -35,7 +35,7 @@ jobs: - uses: actions/checkout@v3 - name: Install prerequisites - run: ${{ matrix.config.pip }} install pytest numpy + run: ${{ matrix.config.pip }} install pytest numpy scipy h5py - name: Cache external libraries id: cache-ext-libs diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 88729d1..bf58ac2 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -75,6 +75,7 @@ if(OFT_PACKAGE_BUILD) else() set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) endif() +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin) ######################## # Required library detection and setup diff --git a/src/python/OpenFUSIONToolkit/CMakeLists.txt b/src/python/OpenFUSIONToolkit/CMakeLists.txt index c1b015c..8e991b7 100644 --- a/src/python/OpenFUSIONToolkit/CMakeLists.txt +++ b/src/python/OpenFUSIONToolkit/CMakeLists.txt @@ -1,3 +1,7 @@ install(PROGRAMS util.py DESTINATION python/OpenFUSIONToolkit COMPONENT app) install(PROGRAMS TokaMaker.py DESTINATION python/OpenFUSIONToolkit COMPONENT app) -install(PROGRAMS Marklin.py DESTINATION python/OpenFUSIONToolkit COMPONENT app) \ No newline at end of file +install(PROGRAMS Marklin.py DESTINATION python/OpenFUSIONToolkit COMPONENT app) + +configure_file( util.py ${CMAKE_CURRENT_BINARY_DIR}/util.py COPYONLY) +configure_file( TokaMaker.py ${CMAKE_CURRENT_BINARY_DIR}/TokaMaker.py COPYONLY) +configure_file( Marklin.py ${CMAKE_CURRENT_BINARY_DIR}/Marklin.py COPYONLY) \ No newline at end of file diff --git a/src/tests/physics/CMakeLists.txt b/src/tests/physics/CMakeLists.txt index 349ae36..2005494 100644 --- a/src/tests/physics/CMakeLists.txt +++ b/src/tests/physics/CMakeLists.txt @@ -2,7 +2,7 @@ if( OFT_BUILD_TESTS ) # Common file( COPY conftest.py DESTINATION ${CMAKE_CURRENT_BINARY_DIR} ) - # Taylor tests + # Marklin tests oft_add_test( test_taylor.F90 ) file( COPY test_taylor.py DESTINATION ${CMAKE_CURRENT_BINARY_DIR} ) oft_add_test( test_taylor_inj.F90 ) @@ -11,7 +11,7 @@ if( OFT_BUILD_TESTS ) #file( COPY torus_test.in.e DESTINATION ${CMAKE_CURRENT_BINARY_DIR} ) file( COPY torus_test.g DESTINATION ${CMAKE_CURRENT_BINARY_DIR} ) - # MHD tests + # MUG tests add_library( test_phys_helpers test_phys_helpers.F90 ) add_dependencies( test_phys_helpers oftphysics ) oft_add_test( test_sound.F90 test_phys_helpers ) @@ -31,4 +31,8 @@ if( OFT_BUILD_TESTS ) file( COPY tw_test-passive.h5 DESTINATION ${CMAKE_CURRENT_BINARY_DIR} ) file( COPY tw_test-plate.h5 DESTINATION ${CMAKE_CURRENT_BINARY_DIR} ) file( COPY tw_test-torus.h5 DESTINATION ${CMAKE_CURRENT_BINARY_DIR} ) + + # TokaMaker tests + file( COPY test_TokaMaker.py DESTINATION ${CMAKE_CURRENT_BINARY_DIR} ) + file( COPY ITER_geom.json DESTINATION ${CMAKE_CURRENT_BINARY_DIR} ) endif() \ No newline at end of file diff --git a/src/tests/physics/ITER_geom.json b/src/tests/physics/ITER_geom.json new file mode 100644 index 0000000..553c90d --- /dev/null +++ b/src/tests/physics/ITER_geom.json @@ -0,0 +1,1918 @@ +{ + "limiter": [ + [ + 4.0455, + -2.5063 + ], + [ + 4.0455, + -1.5 + ], + [ + 4.0455, + -0.4836 + ], + [ + 4.0455, + 0.5328 + ], + [ + 4.0455, + 1.5492 + ], + [ + 4.0455, + 2.5656 + ], + [ + 4.0455, + 3.582 + ], + [ + 4.3109, + 4.324 + ], + [ + 4.9037, + 4.7115 + ], + [ + 5.7538, + 4.5323 + ], + [ + 6.587, + 3.8934 + ], + [ + 7.4672, + 3.0833 + ], + [ + 7.9338, + 2.4024 + ], + [ + 8.2703, + 1.6814 + ], + [ + 8.3944, + 0.6329 + ], + [ + 8.3063, + -0.4215 + ], + [ + 7.8987, + -1.3417 + ], + [ + 7.2829, + -2.257 + ], + [ + 6.2665, + -3.0461 + ], + [ + 6.171, + -3.235 + ], + [ + 5.9821, + -3.2822 + ], + [ + 5.815, + -3.3823 + ], + [ + 5.6842, + -3.5265 + ], + [ + 5.6008, + -3.7024 + ], + [ + 5.572, + -3.895 + ], + [ + 5.572, + -3.896 + ], + [ + 5.572, + -3.9956 + ], + [ + 5.572, + -3.9961 + ], + [ + 5.565, + -4.0962 + ], + [ + 5.565, + -4.2494 + ], + [ + 5.565, + -4.4026 + ], + [ + 5.565, + -4.5559 + ], + [ + 5.2727, + -4.2636 + ], + [ + 5.2628, + -4.1244 + ], + [ + 5.2529, + -3.9852 + ], + [ + 5.1496, + -3.8382 + ], + [ + 4.9982, + -3.7414 + ], + [ + 4.8215, + -3.709 + ], + [ + 4.6456, + -3.746 + ], + [ + 4.5687, + -3.8276 + ], + [ + 4.4918, + -3.9092 + ], + [ + 4.1799, + -3.8847 + ], + [ + 4.2457, + -3.7497 + ], + [ + 4.3115, + -3.6148 + ], + [ + 4.3773, + -3.4799 + ], + [ + 4.4062, + -3.4048 + ], + [ + 4.4064, + -3.4043 + ], + [ + 4.467, + -3.2801 + ], + [ + 4.5157, + -3.1139 + ], + [ + 4.5066, + -2.941 + ], + [ + 4.4408, + -2.7808 + ], + [ + 4.3257, + -2.6514 + ], + [ + 4.1742, + -2.5674 + ], + [ + 4.0455, + -2.5063 + ] + ], + "inner_vv": [ + [ + [ + 3.5698, + 0.0282 + ], + [ + 3.5697982060934867, + 0.16848658069214842 + ], + [ + 3.5697987738978934, + 0.30955010068150957 + ], + [ + 3.5698003449130282, + 0.4527222313096951 + ], + [ + 3.5698015606386986, + 0.5993346439183167 + ], + [ + 3.5698010625747125, + 0.7507190098489861 + ], + [ + 3.5697977921733366, + 0.9082292993747595 + ], + [ + 3.5697956517889247, + 1.073588283930939 + ], + [ + 3.569802548544593, + 1.2488235999252806 + ], + [ + 3.5698131502761252, + 1.4363164539273845 + ], + [ + 3.569793293011115, + 1.639196690572136 + ], + [ + 3.569761892307504, + 1.8610880362901066 + ], + [ + 3.569866205515577, + 2.10665930335031 + ], + [ + 3.5698162412859538, + 2.3827183919528436 + ], + [ + 3.569532376583868, + 2.697912127922689 + ], + [ + 3.5706808296432495, + 3.061479856267723 + ], + [ + 3.5677914776296777, + 3.499183715768617 + ], + [ + 3.613915774661574, + 3.9433895250108 + ], + [ + 3.7490373508844406, + 4.307996409446838 + ], + [ + 3.9485538531281765, + 4.604165965032885 + ], + [ + 4.194454862410111, + 4.840137041843913 + ], + [ + 4.475678207599208, + 5.014547810520315 + ], + [ + 4.781844450827009, + 5.125961336111132 + ], + [ + 5.103043711428658, + 5.172172345468662 + ], + [ + 5.429518989898595, + 5.1518176676089595 + ], + [ + 5.7511252451128545, + 5.061693591203099 + ], + [ + 6.057400092625251, + 4.90116269277652 + ], + [ + 6.341696895217109, + 4.707913532169606 + ], + [ + 6.6072739643202425, + 4.522667888140409 + ], + [ + 6.8582106861087855, + 4.3494238703776436 + ], + [ + 7.094532564320162, + 4.175193459740509 + ], + [ + 7.314797967850618, + 3.9923928908615705 + ], + [ + 7.519196409419202, + 3.802599905964666 + ], + [ + 7.7081014406033885, + 3.607205383100166 + ], + [ + 7.881887634796991, + 3.407191007995272 + ], + [ + 8.04099396126968, + 3.2035445413040016 + ], + [ + 8.185997064864356, + 2.9972502294473236 + ], + [ + 8.317477057490462, + 2.7891005739679886 + ], + [ + 8.435978832926109, + 2.579725410841666 + ], + [ + 8.541976227114194, + 2.3696270368820422 + ], + [ + 8.6362040288325, + 2.1593751834435775 + ], + [ + 8.719560753965403, + 1.9495462098692549 + ], + [ + 8.79150522197334, + 1.739795762911382 + ], + [ + 8.85058013846689, + 1.5294240755021897 + ], + [ + 8.89475960592196, + 1.3183703879505666 + ], + [ + 8.923991352504675, + 1.1074220929968703 + ], + [ + 8.942580626318898, + 0.8987089111025235 + ], + [ + 8.953247544735072, + 0.6932227205529837 + ], + [ + 8.956627630677197, + 0.4906779825796096 + ], + [ + 8.953269878051449, + 0.29073639403414503 + ], + [ + 8.942888895053322, + 0.09309982232753936 + ], + [ + 8.922593474373214, + -0.1023912131651014 + ], + [ + 8.888334985328472, + -0.29494515161069645 + ], + [ + 8.835403300135027, + -0.48234184703790817 + ], + [ + 8.76618885061794, + -0.6635467614998659 + ], + [ + 8.688961822560893, + -0.83887267688837 + ], + [ + 8.60923460560663, + -1.0102484244180736 + ], + [ + 8.530661266939253, + -1.180229598897184 + ], + [ + 8.453205488366235, + -1.3503170435230734 + ], + [ + 8.375101139616635, + -1.5215197056126448 + ], + [ + 8.29552841441841, + -1.6951753940266168 + ], + [ + 8.214166374394702, + -1.872818513362791 + ], + [ + 8.130340688551053, + -2.056092976604347 + ], + [ + 8.043160456679642, + -2.2467420286769273 + ], + [ + 7.951638525725616, + -2.446789982962505 + ], + [ + 7.854694638436276, + -2.658601588156315 + ], + [ + 7.751049999746061, + -2.8853258878120345 + ], + [ + 7.638996951145279, + -3.130212090910009 + ], + [ + 7.516367898719492, + -3.3974418999031823 + ], + [ + 7.379773787661005, + -3.6918927884259802 + ], + [ + 7.213828913958135, + -3.983541565381332 + ], + [ + 7.011152938948012, + -4.247919573120384 + ], + [ + 6.776700456509743, + -4.482564802699621 + ], + [ + 6.514512189071218, + -4.68367681968514 + ], + [ + 6.228948471035897, + -4.847947783580575 + ], + [ + 5.925081718489305, + -4.972841852779714 + ], + [ + 5.608099966299022, + -5.056414591838187 + ], + [ + 5.283207668325241, + -5.098917370143298 + ], + [ + 4.957417647393269, + -5.0893763045015 + ], + [ + 4.640732536554927, + -5.016371391301368 + ], + [ + 4.34338355894484, + -4.877716224206483 + ], + [ + 4.075424667645325, + -4.676390480078515 + ], + [ + 3.848662964654347, + -4.412325345643149 + ], + [ + 3.675526296020217, + -4.084852501914371 + ], + [ + 3.579134786491363, + -3.681021548785755 + ], + [ + 3.569990716551405, + -3.215188964463319 + ], + [ + 3.5697349394736744, + -2.815538133016038 + ], + [ + 3.5698154883549162, + -2.4742311737814284 + ], + [ + 3.5698047700224858, + -2.1780459011445155 + ], + [ + 3.569792554665651, + -1.9164779990199752 + ], + [ + 3.569801937276859, + -1.6820628110338782 + ], + [ + 3.5698018753941687, + -1.4691953094366916 + ], + [ + 3.5697992430710985, + -1.273632006027228 + ], + [ + 3.5697992732958124, + -1.0919018806092444 + ], + [ + 3.5698001503841104, + -0.9213407128799617 + ], + [ + 3.569800378856253, + -0.7596382944949948 + ], + [ + 3.56980011268415, + -0.6051276035423366 + ], + [ + 3.5697997172375646, + -0.4562240504941642 + ], + [ + 3.5697995578862596, + -0.3113430458226596 + ], + [ + 3.5698, + -0.16890000000000002 + ] + ], + [ + [ + 3.5098, + 0.4225 + ], + [ + 3.5098056862256324, + 0.5684225196723655 + ], + [ + 3.509803345901457, + 0.7180094936467758 + ], + [ + 3.509798127208588, + 0.8728841344209068 + ], + [ + 3.509795178328141, + 1.0346696544924343 + ], + [ + 3.5097996474412296, + 1.2049892663590338 + ], + [ + 3.5098110599182415, + 1.3856360129431664 + ], + [ + 3.5098039686897695, + 1.5791572005176853 + ], + [ + 3.509766580164513, + 1.7884342639502369 + ], + [ + 3.5098091050983995, + 2.0170889795108904 + ], + [ + 3.5099019959519064, + 2.269763345053365 + ], + [ + 3.509539368792258, + 2.553420448086083 + ], + [ + 3.510230472641543, + 2.8739616652861413 + ], + [ + 3.5088910466491203, + 3.247259830027555 + ], + [ + 3.5152118428736627, + 3.6742772537824715 + ], + [ + 3.5856987128295543, + 4.073193112700134 + ], + [ + 3.7319453314277657, + 4.4021348253933335 + ], + [ + 3.93059293333339, + 4.676158045329384 + ], + [ + 4.1699482814582, + 4.897268276675808 + ], + [ + 4.440381343648856, + 5.065045775885089 + ], + [ + 4.734086907422469, + 5.175655812100314 + ], + [ + 5.042282676660218, + 5.229565912793534 + ], + [ + 5.356997360427628, + 5.2248062997000195 + ], + [ + 5.669555905770158, + 5.156214413128165 + ], + [ + 5.971240727964409, + 5.021134194784739 + ], + [ + 6.254213887899452, + 4.841887332812013 + ], + [ + 6.517877204164102, + 4.65731379524531 + ], + [ + 6.766459190411447, + 4.48662769466784 + ], + [ + 7.001861692163593, + 4.32085479948529 + ], + [ + 7.222832160052901, + 4.149386463906585 + ], + [ + 7.428996272872174, + 3.970650186406668 + ], + [ + 7.6206567471023146, + 3.7862515646124133 + ], + [ + 7.798174841625316, + 3.5972038526911825 + ], + [ + 7.961810722876376, + 3.4042105536963607 + ], + [ + 8.112062781559072, + 3.2082854867272905 + ], + [ + 8.249449842320113, + 3.0102447987669474 + ], + [ + 8.374492985685372, + 2.8107554106027175 + ], + [ + 8.487697750320308, + 2.610370023236824 + ], + [ + 8.5895055417453, + 2.4095242444365317 + ], + [ + 8.680499633653646, + 2.208671205792226 + ], + [ + 8.761524223385404, + 2.008330372392691 + ], + [ + 8.83249570455626, + 1.8084296966211144 + ], + [ + 8.892280024452736, + 1.6082887723547006 + ], + [ + 8.93936550049488, + 1.4076691572446802 + ], + [ + 8.972501964481078, + 1.2068376421571798 + ], + [ + 8.994241876058489, + 1.0072935044282747 + ], + [ + 9.008321352513171, + 0.8106936351808163 + ], + [ + 9.01612423669776, + 0.6170143913517083 + ], + [ + 9.017932429381288, + 0.4258703770741829 + ], + [ + 9.012948829127623, + 0.2370406620846308 + ], + [ + 9.00023266090121, + 0.050326215513517375 + ], + [ + 8.978743608602631, + -0.13442471186578026 + ], + [ + 8.945242370349467, + -0.31631935903935726 + ], + [ + 8.894920559411688, + -0.49353087675429647 + ], + [ + 8.830108712333066, + -0.6652737979058497 + ], + [ + 8.757752702583947, + -0.8316752639436301 + ], + [ + 8.682607948875319, + -0.9942990792137945 + ], + [ + 8.608097737055038, + -1.1553289463684868 + ], + [ + 8.534733830926582, + -1.3161748500002712 + ], + [ + 8.461097613158229, + -1.4777311683138867 + ], + [ + 8.386308388989933, + -1.641071599709595 + ], + [ + 8.310067049414043, + -1.8074640466428946 + ], + [ + 8.23191843840393, + -1.9782529644192592 + ], + [ + 8.151150185949131, + -2.1548805776543207 + ], + [ + 8.066975649571717, + -2.338928563277032 + ], + [ + 7.97852233421583, + -2.5321947324712193 + ], + [ + 7.884817947679039, + -2.736980205842318 + ], + [ + 7.784724043356735, + -2.9560820409814905 + ], + [ + 7.676552932833955, + -3.192069289796103 + ], + [ + 7.558647513794251, + -3.4496733091742944 + ], + [ + 7.427724800265232, + -3.732081703123098 + ], + [ + 7.268955036417483, + -4.00940791481632 + ], + [ + 7.077457670349567, + -4.263245869443726 + ], + [ + 6.857091201553553, + -4.491492528552748 + ], + [ + 6.61099151605751, + -4.6904158300830705 + ], + [ + 6.342908296752797, + -4.856999500005877 + ], + [ + 6.056898616737887, + -4.989129695177786 + ], + [ + 5.757439619325101, + -5.084669506646486 + ], + [ + 5.448459916078364, + -5.143300177024136 + ], + [ + 5.1351389668969, + -5.1615551116309595 + ], + [ + 4.825393004785534, + -5.129221186935955 + ], + [ + 4.527299205790369, + -5.037842502646077 + ], + [ + 4.248878796573625, + -4.890450415601747 + ], + [ + 4.000156220007862, + -4.685693470966861 + ], + [ + 3.7877027180692613, + -4.430981119030759 + ], + [ + 3.624586339353853, + -4.120193725718438 + ], + [ + 3.525763333125453, + -3.749651130895818 + ], + [ + 3.509826763290541, + -3.3160551104620377 + ], + [ + 3.5097986485175894, + -2.927961185755916 + ], + [ + 3.509769796195843, + -2.5935133841533484 + ], + [ + 3.509827664832162, + -2.300170610840925 + ], + [ + 3.5097900902648607, + -2.039457802419715 + ], + [ + 3.5097964916707207, + -1.8043720525713132 + ], + [ + 3.509803861160502, + -1.5899432122292243 + ], + [ + 3.509800830901334, + -1.3922835520414831 + ], + [ + 3.5097985085394297, + -1.2081288927266833 + ], + [ + 3.5097991903055203, + -1.0351044789915753 + ], + [ + 3.5098009596224737, + -0.8712481132932347 + ], + [ + 3.509801876263048, + -0.7145999141299489 + ], + [ + 3.5098, + -0.5631999999999999 + ] + ] + ], + "outer_vv": [ + [ + [ + 3.2924, + 0.0297 + ], + [ + 3.2924001417950675, + 0.194070402801176 + ], + [ + 3.2924000583289303, + 0.359119744014732 + ], + [ + 3.2923999147583705, + 0.5262650487663812 + ], + [ + 3.292399876240172, + 0.6969233421818373 + ], + [ + 3.2924001029580836, + 0.8725140035052569 + ], + [ + 3.2924003726667426, + 1.0546374451130998 + ], + [ + 3.2923998197134017, + 1.245200862774541 + ], + [ + 3.2923988250145286, + 1.4463430245195135 + ], + [ + 3.2924009814639117, + 1.660709074540891 + ], + [ + 3.2924033702945588, + 1.8914311751901196 + ], + [ + 3.2923917640177245, + 2.1425130812438677 + ], + [ + 3.292403394903505, + 2.41893001476685 + ], + [ + 3.2924225606577937, + 2.727210380434049 + ], + [ + 3.2923083456098046, + 3.076353534057958 + ], + [ + 3.2926719344359126, + 3.4770364119684785 + ], + [ + 3.2999814282199, + 3.9372253757201316 + ], + [ + 3.3864965130507803, + 4.355238165424347 + ], + [ + 3.549058382184427, + 4.711026313220083 + ], + [ + 3.7695843531356505, + 5.0093195159046635 + ], + [ + 4.035866458370897, + 5.250220344053313 + ], + [ + 4.336976933582633, + 5.432120378463416 + ], + [ + 4.663750683914568, + 5.55214406631211 + ], + [ + 5.005397726614705, + 5.6158030275409345 + ], + [ + 5.35307512786357, + 5.6293971893033214 + ], + [ + 5.700103598288791, + 5.592115280673396 + ], + [ + 6.039742865547401, + 5.505191794145803 + ], + [ + 6.3656528794151725, + 5.372509112256678 + ], + [ + 6.675185999701907, + 5.217989095073511 + ], + [ + 6.968066666901133, + 5.049888705798858 + ], + [ + 7.243979860896658, + 4.869077205579605 + ], + [ + 7.5028384051518895, + 4.6773429676830265 + ], + [ + 7.744704250442496, + 4.4762544154008985 + ], + [ + 7.9698041298333075, + 4.267317176430791 + ], + [ + 8.178491949620602, + 4.051918826577348 + ], + [ + 8.371178635145853, + 3.8311626895409403 + ], + [ + 8.548287313666275, + 3.6060993059976627 + ], + [ + 8.710289541154703, + 3.377601666249995 + ], + [ + 8.857740963417655, + 3.1464843173876007 + ], + [ + 8.991245614319732, + 2.9135087044059524 + ], + [ + 9.111320801460796, + 2.6792159436405676 + ], + [ + 9.218475557717532, + 2.4440669333617877 + ], + [ + 9.313232658015602, + 2.2084757345698196 + ], + [ + 9.396120322687747, + 1.972772606287417 + ], + [ + 9.467592175944747, + 1.7372174406402843 + ], + [ + 9.528026561822973, + 1.5019975373322902 + ], + [ + 9.577944792506312, + 1.2672168952852265 + ], + [ + 9.617010170849298, + 1.0328313102168154 + ], + [ + 9.642540636844618, + 0.7985309373252611 + ], + [ + 9.6530405141372, + 0.5646205694809434 + ], + [ + 9.648637163135838, + 0.33208747031690417 + ], + [ + 9.629533099850143, + 0.10195003324289746 + ], + [ + 9.596153367084264, + -0.12485879325959491 + ], + [ + 9.549448988272957, + -0.34761284251656793 + ], + [ + 9.489625998845488, + -0.5654313344873759 + ], + [ + 9.41639896611018, + -0.7773682537115613 + ], + [ + 9.333103685620987, + -0.9836952255558293 + ], + [ + 9.244734525257716, + -1.185680737021479 + ], + [ + 9.155342700908774, + -1.3859950577750288 + ], + [ + 9.066739662254234, + -1.586993713533827 + ], + [ + 8.977374358350737, + -1.7899424945088276 + ], + [ + 8.886211800644581, + -1.9963792714865924 + ], + [ + 8.792799588425234, + -2.208144790964847 + ], + [ + 8.696233068659696, + -2.427096547479001 + ], + [ + 8.59550330620767, + -2.655385210831303 + ], + [ + 8.489601203391102, + -2.895611894088492 + ], + [ + 8.376951159938754, + -3.1502373495421607 + ], + [ + 8.256626924732288, + -3.424004656620487 + ], + [ + 8.125538056269216, + -3.7193191948955655 + ], + [ + 7.9715523379158215, + -4.021808818931218 + ], + [ + 7.784462153526943, + -4.310147667958624 + ], + [ + 7.564561084030378, + -4.57764411656543 + ], + [ + 7.315048327117228, + -4.821772638025878 + ], + [ + 7.038334622215387, + -5.038175480542423 + ], + [ + 6.737608670900265, + -5.223171079906471 + ], + [ + 6.416708643234255, + -5.373838186943995 + ], + [ + 6.079726153576485, + -5.48790066091868 + ], + [ + 5.731125015555946, + -5.563135807994369 + ], + [ + 5.3753978008384244, + -5.599083262151607 + ], + [ + 5.017675539044369, + -5.592853254763617 + ], + [ + 4.666398994461813, + -5.529442790599571 + ], + [ + 4.332465093613656, + -5.399860835111304 + ], + [ + 4.025669382375353, + -5.206381183760577 + ], + [ + 3.755521206241005, + -4.95217343646723 + ], + [ + 3.533830494257671, + -4.637743881547641 + ], + [ + 3.3734652870833006, + -4.262846781193734 + ], + [ + 3.296196566614805, + -3.818921060226862 + ], + [ + 3.2926640188634217, + -3.3444047864824595 + ], + [ + 3.2923145493375694, + -2.9372232593771352 + ], + [ + 3.2924293907732833, + -2.5830721371113787 + ], + [ + 3.2923931597945906, + -2.2709458334229575 + ], + [ + 3.2923975797641716, + -1.9914389302167932 + ], + [ + 3.2924030313636132, + -1.7378896471235215 + ], + [ + 3.292399460279025, + -1.5052112092009535 + ], + [ + 3.292399219210358, + -1.289255637059969 + ], + [ + 3.292400264074154, + -1.0868056112959326 + ], + [ + 3.2924003308570673, + -0.895183546404802 + ], + [ + 3.29239986252524, + -0.7123398740210598 + ], + [ + 3.292399528949332, + -0.5362776674507724 + ], + [ + 3.2924, + -0.36500000000000005 + ] + ], + [ + [ + 3.2324, + 0.4244 + ], + [ + 3.2323994689363262, + 0.593448522675906 + ], + [ + 3.2323998248606993, + 0.7659931956017213 + ], + [ + 3.2324003588287975, + 0.94366039695058 + ], + [ + 3.2324003618963006, + 1.1280765048956163 + ], + [ + 3.2323992601877527, + 1.320889225273017 + ], + [ + 3.2323989738816863, + 1.5241400803809435 + ], + [ + 3.232402776346135, + 1.740255268644115 + ], + [ + 3.232401490967386, + 1.9722398542526203 + ], + [ + 3.232388012362964, + 2.2236856354757846 + ], + [ + 3.2324202026072, + 2.4991141544557025 + ], + [ + 3.232393753302974, + 2.8045705581828932 + ], + [ + 3.2323482281992795, + 3.1476666619259595 + ], + [ + 3.2325689933696267, + 3.5382269173957788 + ], + [ + 3.242879776960705, + 3.976926757578233 + ], + [ + 3.3289162744384497, + 4.373117379405051 + ], + [ + 3.482577434361936, + 4.717140645427759 + ], + [ + 3.690276730959956, + 5.010049019965525 + ], + [ + 3.9406597490775916, + 5.252708465814603 + ], + [ + 4.224987312137911, + 5.4429912892195 + ], + [ + 4.535674325175798, + 5.57669766006781 + ], + [ + 4.863223049739604, + 5.6570175027859815 + ], + [ + 5.19927985721743, + 5.689403210261371 + ], + [ + 5.5372448046817535, + 5.676245222879066 + ], + [ + 5.871439674337, + 5.616762266327598 + ], + [ + 6.196046742463822, + 5.511178839699204 + ], + [ + 6.506259967975187, + 5.372284156841952 + ], + [ + 6.800967069111577, + 5.217449850254592 + ], + [ + 7.079906270735805, + 5.050779235418278 + ], + [ + 7.342862295084994, + 4.872636009263188 + ], + [ + 7.589826619106312, + 4.6849421450103215 + ], + [ + 7.820912428569607, + 4.489008468465176 + ], + [ + 8.036249197238648, + 4.285968299603563 + ], + [ + 8.236495262489978, + 4.077628394022815 + ], + [ + 8.421704335524458, + 3.8643924840479946 + ], + [ + 8.592400434510381, + 3.6473408170170227 + ], + [ + 8.749124084897161, + 3.4274344387071705 + ], + [ + 8.892290597382651, + 3.2052375940714444 + ], + [ + 9.022497243098531, + 2.981477962997199 + ], + [ + 9.140250437421953, + 2.756670305239043 + ], + [ + 9.246011873442674, + 2.5312048024423914 + ], + [ + 9.340267996343952, + 2.305450287799206 + ], + [ + 9.42350753144046, + 2.079709741653991 + ], + [ + 9.496194108227312, + 1.8542219654116967 + ], + [ + 9.558682098850962, + 1.6291520817293714 + ], + [ + 9.611359081366837, + 1.4046136303103367 + ], + [ + 9.654646978350646, + 1.1806508138777292 + ], + [ + 9.687358375378333, + 0.9570760756176734 + ], + [ + 9.707092339814556, + 0.7336172249466513 + ], + [ + 9.713228357186953, + 0.510866376556824 + ], + [ + 9.706023099156015, + 0.28974105300373043 + ], + [ + 9.685937187031158, + 0.0709551661427174 + ], + [ + 9.653472187525276, + -0.14481937531757433 + ], + [ + 9.609102875590537, + -0.3569052957203031 + ], + [ + 9.552771146359362, + -0.5645185724716664 + ], + [ + 9.484244219428312, + -0.766878818178949 + ], + [ + 9.406195353379115, + -0.9641456350319028 + ], + [ + 9.322783302877006, + -1.1572315665311719 + ], + [ + 9.23766240083204, + -1.3483246128799606 + ], + [ + 9.153152654656882, + -1.539669182809145 + ], + [ + 9.068287263083432, + -1.7324955500133643 + ], + [ + 8.981961882306688, + -1.9280530108699516 + ], + [ + 8.89376007135348, + -2.127907885332831 + ], + [ + 8.80302985094719, + -2.3336676818858515 + ], + [ + 8.708879865221165, + -2.5470342283177905 + ], + [ + 8.610483089566628, + -2.7701871132457465 + ], + [ + 8.506730705800416, + -3.0053250336314945 + ], + [ + 8.396199270444647, + -3.2549101240274143 + ], + [ + 8.278632303773799, + -3.524547617828168 + ], + [ + 8.148534538660526, + -3.812035649086182 + ], + [ + 7.99475752173606, + -4.1019613503850145 + ], + [ + 7.809784617253002, + -4.376776065182815 + ], + [ + 7.595389539472153, + -4.633107160065585 + ], + [ + 7.3536964963785865, + -4.867851049613064 + ], + [ + 7.087032547862238, + -5.077575793006204 + ], + [ + 6.79805886212445, + -5.258636027190928 + ], + [ + 6.490090565868895, + -5.408619775356435 + ], + [ + 6.1666452452138625, + -5.525329116089619 + ], + [ + 5.831551966659515, + -5.606941437844758 + ], + [ + 5.488846916430312, + -5.652074562835017 + ], + [ + 5.142102331276796, + -5.660479896144169 + ], + [ + 4.798614755295874, + -5.622523095851336 + ], + [ + 4.467058541134741, + -5.526055994638236 + ], + [ + 4.155844310112352, + -5.370531866792327 + ], + [ + 3.8743448332440122, + -5.157506831569739 + ], + [ + 3.6292141006580265, + -4.893230540525843 + ], + [ + 3.4323254775289205, + -4.574375679604763 + ], + [ + 3.293915890359742, + -4.203787732491791 + ], + [ + 3.2340209482785482, + -3.7733167120523565 + ], + [ + 3.232695216662664, + -3.3289502788222647 + ], + [ + 3.2323008923321868, + -2.9444189421772737 + ], + [ + 3.2324323583731345, + -2.605586371178579 + ], + [ + 3.2323954170648097, + -2.303770718482734 + ], + [ + 3.2323948078900355, + -2.0310865463205907 + ], + [ + 3.2324036477754663, + -1.7819016135841252 + ], + [ + 3.232400046674498, + -1.5517889495107018 + ], + [ + 3.232398647044993, + -1.3370932941964657 + ], + [ + 3.2324001968461653, + -1.1351337444466194 + ], + [ + 3.2324016598945056, + -0.9434795597436345 + ], + [ + 3.2323999999999997, + -0.7597 + ] + ] + ], + "coils": { + "CS3U": { + "rc": 1.696, + "zc": 5.435, + "w": 0.734, + "h": 2.12 + }, + "CS2U": { + "rc": 1.696, + "zc": 3.265, + "w": 0.734, + "h": 2.12 + }, + "CS1U": { + "rc": 1.696, + "zc": 1.095, + "w": 0.734, + "h": 2.12 + }, + "CS1L": { + "rc": 1.696, + "zc": -1.075, + "w": 0.734, + "h": 2.12 + }, + "CS2L": { + "rc": 1.696, + "zc": -3.245, + "w": 0.734, + "h": 2.12 + }, + "CS3L": { + "rc": 1.696, + "zc": -5.415, + "w": 0.734, + "h": 2.12 + }, + "PF1": { + "rc": 3.9431, + "zc": 7.5741, + "w": 0.959, + "h": 0.9841 + }, + "PF2": { + "rc": 8.2851, + "zc": 6.5398, + "w": 0.5801, + "h": 0.7146 + }, + "PF3": { + "rc": 11.9919, + "zc": 3.2752, + "w": 0.6963, + "h": 0.9538 + }, + "PF4": { + "rc": 11.963, + "zc": -2.2336, + "w": 0.6382, + "h": 0.9538 + }, + "PF5": { + "rc": 8.3908, + "zc": -6.7269, + "w": 0.8125, + "h": 0.9538 + }, + "PF6": { + "rc": 4.334, + "zc": -7.4665, + "w": 1.559, + "h": 1.1075 + }, + "VSU": { + "rc": 5.8261, + "zc": 4.9249, + "w": 0.129, + "h": 0.109 + }, + "VSL": { + "rc": 7.5222, + "zc": -2.4912, + "w": 0.129, + "h": 0.129 + } + } +} \ No newline at end of file diff --git a/src/tests/physics/test_TokaMaker.py b/src/tests/physics/test_TokaMaker.py new file mode 100644 index 0000000..dffc1e7 --- /dev/null +++ b/src/tests/physics/test_TokaMaker.py @@ -0,0 +1,424 @@ +from __future__ import print_function +import os +import sys +import multiprocessing +import json +import pytest +import numpy as np +from scipy.special import jv, jn_zeros +from scipy.integrate import dblquad +test_dir = os.path.abspath(os.path.dirname(__file__)) +sys.path.append(os.path.abspath(os.path.join(test_dir, '..','..','python'))) +from OpenFUSIONToolkit.TokaMaker import TokaMaker, gs_Domain, save_gs_mesh, load_gs_mesh + + +def mp_run(target,args): + mp_q = multiprocessing.Queue() + p = multiprocessing.Process(target=target, args=args + (mp_q,)) + p.start() + test_result = mp_q.get() + p.join() + return test_result + + +#============================================================================ +def run_solo_case(mesh_resolution,fe_order,mp_q): + def solovev_psi(r_grid, z_grid,R,a,b,c0): + # psi = np.zeros_like(r_grid) + zeta = (np.power(r_grid,2)-np.power(R,2))/(2.0*R) + psi_x = (a-c0)*np.power(b+c0,2)*np.power(R,4)/(8.0*np.power(c0,2)) + zeta_x = -(b+c0)*R/(2*c0) + Z_x = np.sqrt((b+c0)*(a-c0)/(2*c0*c0))*R + psi_grid = (b+c0)*np.power(R,2)*np.power(z_grid,2)/2.0 + c0*R*zeta*np.power(z_grid,2) + (a-c0)*np.power(R,2)*np.power(zeta,2)/2.0 + return psi_grid, psi_x, [np.sqrt(zeta_x*2*R+R*R), Z_x] + # Fixed parameters + R=1.0 + a=1.2 + b=-1.0 + c0=1.1 + # Build mesh + gs_mesh = gs_Domain() + gs_mesh.define_region('plasma',mesh_resolution,'plasma') + gs_mesh.add_rectangle(R,0.0,0.12,0.15,'plasma') + mesh_pts, mesh_lc, _ = gs_mesh.build_mesh() + # Run EQ + mygs = TokaMaker() + mygs.setup_mesh(mesh_pts,mesh_lc) + mygs.settings.free_boundary = False + mygs.setup(order=fe_order,F0=1.0,full_domain=True) + mygs.pnorm=a + mygs.alam=b*R*R*2.0 + mygs.set_profiles(ffp_prof={'type': 'flat'},pp_prof={'type': 'flat'}) + mygs.init_psi() + psi_solovev_TM, _, rz_x = solovev_psi(mygs.r[:,0], mygs.r[:,1],R,a,b,c0) + mygs.set_psi(-psi_solovev_TM) + mygs.settings.nl_tol = 1.E-14 + mygs.update_settings() + err_flag = mygs.solve() + if err_flag != 0: + mp_q.put(None) + return + psi_TM = mygs.get_psi(False) + # Compute error in psi + psi_err = np.linalg.norm(psi_TM+psi_solovev_TM) + # Compute error in X-points + x_points, _ = mygs.get_xpoints() + X_err = 0.0 + for i in range(2): + diff = x_points[i,:]-rz_x + if x_points[i,1] < 0.0: + diff[1] = x_points[i,1]+rz_x[1] + X_err += np.linalg.norm(diff) + mp_q.put([psi_err, X_err]) + + +def validate_solo(results,psi_err_exp,X_err_exp): + if results is None: + print("FAILED: error in solve!") + return False + test_result = True + if abs((results[0]-psi_err_exp)/psi_err_exp) > 1.E-4: + print("FAILED: psi error too high!") + print(" Expected = {0}".format(psi_err_exp)) + print(" Actual = {0}".format(results[0])) + test_result = False + if abs((results[1]-X_err_exp)/X_err_exp) > 1.E-4: + print("FAILED: X-point error too high!") + print(" Expected = {0}".format(X_err_exp)) + print(" Actual = {0}".format(results[1])) + test_result = False + return test_result + + +# Test runners for Solov'ev cases +@pytest.mark.parametrize("order", (2,3,4)) +def test_solo_h1(order): + errs = [ + [3.2048631614233643e-07,0.00014929412629149645], + [8.919954733021135e-10,4.659825491095631e-07], + [5.084454462338564e-15,3.1842881888709607e-12] + ] + results = mp_run(run_solo_case,(0.015,order)) + assert validate_solo(results,errs[order-2][0],errs[order-2][1]) +@pytest.mark.parametrize("order", (2,3,4)) +def test_solo_h2(order): + errs = [ + [7.725262474858205e-08,4.9243688140144384e-05], + [1.1190059530634016e-10,2.919838380657025e-08], + [1.0424769098635496e-14,3.434564147191569e-12] + ] + results = mp_run(run_solo_case,(0.015/2.0,order)) + assert validate_solo(results,errs[order-2][0],errs[order-2][1]) +@pytest.mark.parametrize("order", (2,3,4)) +def test_solo_h3(order): + errs = [ + [2.0607919004158514e-08,5.955338556344096e-06], + [1.3950375633902016e-11,1.154542061756696e-09], + [2.0552832098467707e-14,6.859186868795993e-12] + ] + results = mp_run(run_solo_case,(0.015/4.0,order)) + assert validate_solo(results,errs[order-2][0],errs[order-2][1]) + +#============================================================================ +def run_sph_case(mesh_resolution,fe_order,mp_q): + def spheromak_psi(r_grid,z_grid,a,h): + gamma_11 = jn_zeros(1,1)[0]*r_grid/a + x_01 = jn_zeros(0,1)[0] + norm = x_01*jv(1,x_01) + return gamma_11*jv(1,gamma_11)*np.sin(np.pi*z_grid/h)/norm + # Build mesh + gs_mesh = gs_Domain() + gs_mesh.define_region('plasma',mesh_resolution,'plasma') + gs_mesh.add_rectangle(0.5,0.5,1.0,1.0,'plasma') + mesh_pts, mesh_lc, _ = gs_mesh.build_mesh() + # Run EQ + mygs = TokaMaker() + mygs.setup_mesh(mesh_pts,mesh_lc) + mygs.settings.free_boundary = False + mygs.setup(order=fe_order) + mygs.pnorm=0.0 + ffp_prof={ + 'type': 'linterp', + 'x': [0.0,1.0], + 'y': [1.0,0.0], + } + mygs.set_profiles(ffp_prof=ffp_prof,pp_prof={'type': 'flat'}) + mygs.settings.nl_tol = 1.E-12 + mygs.settings.maxits = 100 + mygs.urf = 0.0 + mygs.update_settings() + mygs.init_psi() + err_flag = mygs.solve() + if err_flag != 0: + mp_q.put(None) + return + psi_TM = mygs.get_psi(False) + psi_eig_TM = spheromak_psi(mygs.r[:,0], mygs.r[:,1],1.0,1.0) + psi_TM /= psi_TM.dot(psi_eig_TM)/psi_eig_TM.dot(psi_eig_TM) + # Compute error in psi + psi_err = np.linalg.norm(psi_TM-psi_eig_TM)/np.linalg.norm(psi_eig_TM) + mp_q.put([psi_err]) + + +def validate_sph(results,psi_err_exp): + if results is None: + print("FAILED: error in solve!") + return False + test_result = True + if abs((results[0]-psi_err_exp)/psi_err_exp) > 1.E-4: + print("FAILED: psi error too high!") + print(" Expected = {0}".format(psi_err_exp)) + print(" Actual = {0}".format(results[0])) + test_result = False + return test_result + + +# Test runners for Spheromak cases +@pytest.mark.parametrize("order", (2,3,4)) +def test_spheromak_h1(order): + errs = [2.039674417912789e-05, 5.103597862537552e-07, 8.088772274705608e-09] + results = mp_run(run_sph_case,(0.05,order)) + assert validate_sph(results,errs[order-2]) +@pytest.mark.parametrize("order", (2,3,4)) +def test_spheromak_h2(order): + errs = [2.5203856661960034e-06, 3.279268054674832e-08, 2.5185712724779513e-10] + results = mp_run(run_sph_case,(0.05/2.0,order)) + assert validate_sph(results,errs[order-2]) +@pytest.mark.parametrize("order", (2,3,4)) +def test_spheromak_h3(order): + errs = [3.257155111957006e-07, 2.090369020180253e-09, 8.601148342547016e-12] + results = mp_run(run_sph_case,(0.05/4.0,order)) + assert validate_sph(results,errs[order-2]) + + +#============================================================================ +def run_coil_case(mesh_resolution,fe_order,mp_q): + def coil_green(rc,zc,r,z,gs_obj): + return gs_obj.eval_green(np.array([[r,z]]),np.array([rc,zc]))[0] + def masked_err(point_mask,gs_obj,psi,sort_ind): + bdry_points = gs_obj.r[point_mask,:] + sort_ind = bdry_points[:,sort_ind].argsort() + psi_bdry = psi[point_mask] + psi_bdry = psi_bdry[sort_ind] + bdry_points = bdry_points[sort_ind] + green = np.zeros((bdry_points.shape[0],)) + for i in range(bdry_points.shape[0]): + green[i], _ = dblquad(coil_green,0.75,0.85,0.75,0.85,args=(bdry_points[i,0],bdry_points[i,1],gs_obj)) + return green, psi_bdry + # Build mesh + gs_mesh = gs_Domain(rextent=1.0,zextents=[0.0,1.0]) + gs_mesh.define_region('air',mesh_resolution,'boundary') + gs_mesh.define_region('plasma',mesh_resolution,'plasma') + gs_mesh.define_region('coil',0.01,'coil') + gs_mesh.add_rectangle(0.4,0.4,0.2,0.2,'plasma') + gs_mesh.add_rectangle(0.8,0.8,0.1,0.1,'coil') + mesh_pts, mesh_lc, mesh_reg = gs_mesh.build_mesh() + coil_dict = gs_mesh.get_coils() + cond_dict = gs_mesh.get_conductors() + # Run EQ + mygs = TokaMaker() + mygs.setup_mesh(mesh_pts,mesh_lc,mesh_reg) + mygs.setup_regions(cond_dict=cond_dict) + mygs.setup(order=fe_order) + mygs.set_coil_currents(np.array([1.E-2])) + err_flag = mygs.solve(True) + if err_flag != 0: + mp_q.put(None) + return + psi0 = mygs.get_psi(False) + # Get analytic result + green1, psi1 = masked_err(mygs.r[:,1]==1.0,mygs,psi0,0) + green2, psi2 = masked_err(mygs.r[:,0]==1.0,mygs,psi0,1) + green3, psi3 = masked_err(mygs.r[:,1]==-1.0,mygs,psi0,0) + # Compute error in psi + green_full = np.hstack((green1[1:], green2, green3[1:])) + psi_full = np.hstack((psi1[1:], psi2, psi3[1:])) + psi_err = np.linalg.norm(green_full+psi_full)/np.linalg.norm(green_full) + mp_q.put([psi_err]) + + +def validate_coil(results,psi_err_exp): + if results is None: + print("FAILED: error in solve!") + return False + test_result = True + if abs((results[0]-psi_err_exp)/psi_err_exp) > 1.E-4: + print("FAILED: psi error too high!") + print(" Expected = {0}".format(psi_err_exp)) + print(" Actual = {0}".format(results[0])) + test_result = False + return test_result + + +# Test runners for vacuum coil cases +@pytest.mark.parametrize("order", (2,3,4)) +def test_coil_h1(order): + errs = [0.010800921782063938, 0.0002851010669736233, 1.8185396736818836e-05] + results = mp_run(run_coil_case,(0.1,order)) + assert validate_coil(results,errs[order-2]) +@pytest.mark.parametrize("order", (2,3,4)) +def test_coil_h2(order): + errs = [0.0032993582771277, 2.725546769847347e-05, 8.670511127765199e-07] + results = mp_run(run_coil_case,(0.1/2.0,order)) + assert validate_coil(results,errs[order-2]) +@pytest.mark.parametrize("order", (2,3,4)) +def test_coil_h3(order): + errs = [0.0008175212508035045, 1.921137561342415e-06, 4.4282752350112954e-07] + results = mp_run(run_coil_case,(0.1/4.0,order)) + assert validate_coil(results,errs[order-2]) + + +#============================================================================ +def run_ITER_case(mesh_resolution,fe_order,mp_q): + def create_mesh(): + with open('ITER_geom.json','r') as fid: + ITER_geom = json.load(fid) + plasma_dx = 0.15/mesh_resolution + coil_dx = 0.2/mesh_resolution + vv_dx = 0.3/mesh_resolution + vac_dx = 0.6/mesh_resolution + gs_mesh = gs_Domain() + gs_mesh.define_region('air',vac_dx,'boundary') + gs_mesh.define_region('plasma',plasma_dx,'plasma') + gs_mesh.define_region('vacuum1',vv_dx,'vacuum') + gs_mesh.define_region('vacuum2',vv_dx,'vacuum') + gs_mesh.define_region('vv1',vv_dx,'conductor',eta=6.9E-7) + gs_mesh.define_region('vv2',vv_dx,'conductor',eta=6.9E-7) + for key, coil in ITER_geom['coils'].items(): + gs_mesh.define_region(key,coil_dx,'coil') + gs_mesh.add_polygon(ITER_geom['limiter'],'plasma',parent_name='vacuum1') # Define the shape of the limiter + gs_mesh.add_annulus(ITER_geom['inner_vv'][0],'vacuum1',ITER_geom['inner_vv'][1],'vv1',parent_name='vacuum2') # Define the shape of the VV + gs_mesh.add_annulus(ITER_geom['outer_vv'][0],'vacuum2',ITER_geom['outer_vv'][1],'vv2',parent_name='air') # Define the shape of the VV + for key, coil in ITER_geom['coils'].items(): + if key.startswith('VS'): + gs_mesh.add_rectangle(coil['rc'],coil['zc'],coil['w'],coil['h'],key,parent_name='vacuum1') + else: + gs_mesh.add_rectangle(coil['rc'],coil['zc'],coil['w'],coil['h'],key,parent_name='air') + mesh_pts, mesh_lc, mesh_reg = gs_mesh.build_mesh() + coil_dict = gs_mesh.get_coils() + cond_dict = gs_mesh.get_conductors() + save_gs_mesh(mesh_pts,mesh_lc,mesh_reg,coil_dict,cond_dict,'ITER_mesh.h5') + if not os.path.exists('ITER_mesh.h5'): + create_mesh() + # Run EQ + mygs = TokaMaker() + mesh_pts,mesh_lc,mesh_reg,coil_dict,cond_dict = load_gs_mesh('ITER_mesh.h5') + mygs.setup_mesh(mesh_pts,mesh_lc,mesh_reg) + mygs.setup_regions(cond_dict=cond_dict) + mygs.setup(order=fe_order,F0=5.3*6.2) + vsc_signs = np.zeros((mygs.ncoils,), dtype=np.float64) + vsc_signs[[coil_dict['VSU']['coil_id'], coil_dict['VSL']['coil_id']]] = [1.0,-1.0] + mygs.set_coil_vsc(vsc_signs) + coil_bounds = np.zeros((mygs.ncoils+1,2), dtype=np.float64) + coil_bounds[:,0] = -50.E6; coil_bounds[:,1] = 50.E6 + mygs.set_coil_bounds(coil_bounds) + Ip_target=15.6E6 + P0_target=6.2E5 + mygs.set_targets(Ip=Ip_target, pax=P0_target) + isoflux_pts = np.array([ + [ 8.20, 0.41], + [ 8.06, 1.46], + [ 7.51, 2.62], + [ 6.14, 3.78], + [ 4.51, 3.02], + [ 4.26, 1.33], + [ 4.28, 0.08], + [ 4.49, -1.34], + [ 7.28, -1.89], + [ 8.00, -0.68] + ]) + x_point = np.array([[5.125, -3.4],]) + mygs.set_isoflux(np.vstack((isoflux_pts,x_point))) + mygs.set_saddles(x_point) + coil_reg_mat = np.eye(mygs.ncoils+1, dtype=np.float64) + coil_reg_weights = np.ones((mygs.ncoils+1,)) + coil_reg_targets = np.zeros((mygs.ncoils+1,)) + for key, coil in coil_dict.items(): + if key.startswith('CS'): + if key.startswith('CS1'): + coil_reg_weights[coil['coil_id']] = 2.E-2 + else: + coil_reg_weights[coil['coil_id']] = 1.E-2 + elif key.startswith('PF'): + coil_reg_weights[coil['coil_id']] = 1.E-2 + elif key.startswith('VS'): + coil_reg_weights[coil['coil_id']] = 1.E2 + coil_reg_weights[-1] = 1.E-2 + mygs.set_coil_reg(coil_reg_mat, reg_weights=coil_reg_weights, reg_targets=coil_reg_targets) + n_sample = 40 + psi_sample = np.linspace(0.0,1.0,n_sample) + alpha = 1.5 + gamma = 2.0 + ffp_prof = { + 'type': 'linterp', + 'x': psi_sample, + 'y': np.power(1.0-np.power(psi_sample,alpha),gamma) + } + ffp_prof['y'] /= ffp_prof['y'][0] + alpha = 4.0 + gamma = 1.0 + pp_prof = { + 'type': 'linterp', + 'x': psi_sample, + 'y': np.power(1.0-np.power(psi_sample,alpha),gamma) + } + pp_prof['y'] /= pp_prof['y'][0] + mygs.set_profiles(ffp_prof=ffp_prof,pp_prof=pp_prof) + R0 = 6.3 + Z0 = 0.5 + a = 2.0 + kappa = 1.4 + delta = 0.0 + err_flag = mygs.init_psi(R0, Z0, a, kappa, delta) + err_flag = mygs.solve() + if err_flag != 0: + mp_q.put(None) + return + eq_info = mygs.get_stats() + mp_q.put([eq_info]) + + +def validate_ITER(results,dict_exp): + if results is None: + print("FAILED: error in solve!") + return False + test_result = True + for key, exp_val in dict_exp.items(): + result_val = results[0].get(key,None) + if result_val is None: + print('FAILED: key "{0}" not present!'.format(key)) + else: + if type(exp_val) is not list: + if abs((result_val-exp_val)/exp_val) > 1.E-2: + print("FAILED: {0} error too high!".format(key)) + print(" Expected = {0}".format(exp_val)) + print(" Actual = {0}".format(result_val)) + test_result = False + return test_result + + +# Test runners for ITER test cases +@pytest.mark.parametrize("order", (2,3,4)) +def test_ITER(order): + exp_dict = { + 'Ip': 15599996.700479196, + 'Ip_centroid': [6.20274133, 0.5296048], + 'kappa': 1.86799695311941, + 'kappaU': 1.7388335731481432, + 'kappaL': 1.997160333090677, + 'delta': 0.4642130933423834, + 'deltaU': 0.3840631923067706, + 'deltaL': 0.5443629943779958, + 'vol': 820.0973897169655, + 'q_0': 0.8234473499435633, + 'q_95': 2.76048354704068, + 'P_ax': 619225.0167519478, + 'W_MHD': 242986888.67690986, + 'beta_pol': 39.73860565406112, + 'dflux': 1.5402746036620532, + 'tflux': 121.86870301036512, + 'l_i': 0.9048845463517069, + 'beta_tor': 1.768879437469196 + } + results = mp_run(run_ITER_case,(1.0,order)) + assert validate_ITER(results,exp_dict) \ No newline at end of file diff --git a/src/tests/physics/test_gs.py b/src/tests/physics/test_gs.py deleted file mode 100644 index 2c38919..0000000 --- a/src/tests/physics/test_gs.py +++ /dev/null @@ -1,134 +0,0 @@ -from __future__ import print_function -import os -import sys -import pytest -import numpy as np -test_dir = os.path.abspath(os.path.dirname(__file__)) -sys.path.append(os.path.abspath(os.path.join(test_dir, '..'))) -from oft_testing import run_OFT - -# Basic template for input file -oft_in_template = """ -&runtime_options - ppn=1 - debug=0 - test_run=T -/ - -&mesh_options - meshname='square' - cad_type=92 - nlevels=1 - nbase=1 - grid_order=1 -/ - -&cube_options - mesh_type=1 - ni=5,5,0 - shift=0.0,-0.5,0.0 -/ - -&tokamaker_options - order=2 - pm=T - alam=4.9 - pnorm={0} - urf=0.1 - maxits=50 - has_plasma=T - nl_tol=1.E-11 -/ -""" - -def gs_setup(pnorm,f_prof="flat\n",p_prof="flat\n"): - """ - Common setup and run operations for thin-wall physics module test cases - """ - # Create main input file from template - os.chdir(test_dir) - with open('oft.in','w+') as fid: - fid.write(oft_in_template.format(pnorm)) - # Create F profile specification - with open('f_prof.in','w+') as fid: - fid.write(f_prof) - # Create P profile specification - with open('p_prof.in','w+') as fid: - fid.write(p_prof) - # Run gs driver - return run_OFT("../../tokamaker_gs oft.in", 1, 180, return_stdout=True) - -def validate_gs(run_output, expected, tol=1.E-2): - """ - Helper function to validate G-S run output for test case. - """ - map_dict = { - "q_0, q_95, q_a": ("q_0", "q_95"), - "Toroidal Current": ("Ip",), - "Magnetic Axis": ("R_0", "Z_0"), - "Elongation": ("kappa",), - "Triangularity": ("delta",), - "Stored Energy": ("W_MHD",), - "": ("beta_p",) - } - gs_data = {key: None for key in expected} - found_stats=False - for line in run_output.splitlines(): - line_stripped = line.strip() - if line_stripped.startswith("Equilibrium Statistics:"): - found_stats=True - continue - if found_stats: - for key in map_dict: - if line_stripped.startswith(key): - vals = line_stripped.split("=")[1].split() - for (i, key_inner) in enumerate(map_dict[key]): - gs_data[key_inner] = float(vals[i]) - retval = True - for key in expected: - if gs_data[key] is None: - print('FAILED: Variable "{0}" not found in output!'.format(key)) - retval = False - continue - if abs(gs_data[key]-expected[key])/max(1.E-10,abs(expected[key])) > tol: - print('FAILED: Variable "{0}" incorrect!'.format(key)) - print(" Expected = {0}".format(expected[key])) - print(" Actual = {0}".format(gs_data[key])) - retval = False - return retval - -#============================================================================ -# Test runners for time-dependent cases -def test_taylor(): - expected_values = { - "q_0": 0.648, "q_95": 0.444, - "Ip": 1.405E+07, - "R_0": 0.627, "Z_0": 0.0, - "kappa": 1.341, "delta": -0.168, - "W_MHD": 0.0, "beta_p": 0.0 - } - succ_flag, run_output = gs_setup(0.0) - assert succ_flag - assert validate_gs(run_output, expected_values) -def test_sph_pressure(): - expected_values = { - "q_0": 0.640, "q_95": 0.438, - "Ip": 1.415E+07, - "R_0": 0.631, "Z_0": 0.0, - "kappa": 1.354, "delta": -0.168, - "W_MHD": 1.561E+06, "beta_p": 3.281 - } - succ_flag, run_output = gs_setup(1.0) - assert succ_flag - assert validate_gs(run_output, expected_values) -def test_sph_linlam(): - expected_values = { - "q_0": 0.527, "q_95": 0.357, - "Ip": 1.174E+07, - "R_0": 0.636, "Z_0": 0.0, - "kappa": 1.373, "delta": -0.164, - "W_MHD": 0.0, "beta_p": 0.0 - } - succ_flag, run_output = gs_setup(0.0,f_prof="linear\n 1\n 0.2\n") - assert succ_flag - assert validate_gs(run_output, expected_values) \ No newline at end of file