From 82d22ce68f47f06ac083c505dd9b586c11f33a55 Mon Sep 17 00:00:00 2001 From: jasontruong2707 Date: Mon, 9 Mar 2026 15:09:17 -0400 Subject: [PATCH 1/5] Add Herschel-Bulkley and power-law non-Newtonian viscosity models --- .github/workflows/frontier_amd/bench.sh | 0 .github/workflows/frontier_amd/build.sh | 0 .github/workflows/frontier_amd/submit.sh | 0 .github/workflows/frontier_amd/test.sh | 0 .../Re_100_n_0.5/x_vy.csv | 257 + .../Re_100_n_0.5/y_vx.csv | 257 + examples/2D_lid_driven_cavity_nn/case.py | 116 + examples/2D_poiseuille_nn/case.py | 158 + examples/2D_poiseuille_nn/velocity_0.25.csv | 83 + examples/2D_poiseuille_nn/velocity_0.5.csv | 83 + examples/2D_poiseuille_nn/velocity_0.75.csv | 83 + examples/2D_poiseuille_nn/velocity_1.0.csv | 83 + examples/2D_poiseuille_nn/velocity_1.25.csv | 83 + examples/2D_poiseuille_nn/velocity_1.5.csv | 83 + examples/2D_poiseuille_nn/velocity_1.75.csv | 83 + examples/2D_poiseuille_nn/velocity_2.0.csv | 83 + .../2D_poiseuille_nn/velocity_profile.png | Bin 0 -> 74689 bytes src/common/m_derived_types.fpp | 8 + src/post_process/m_global_parameters.fpp | 8 + src/post_process/m_mpi_proxy.fpp | 4 + src/pre_process/m_global_parameters.fpp | 8 + src/pre_process/m_mpi_proxy.fpp | 5 + src/simulation/m_checker.fpp | 27 + src/simulation/m_data_output.fpp | 3958 +++--- src/simulation/m_global_parameters.fpp | 22 +- src/simulation/m_hb_function.fpp | 77 + src/simulation/m_ibm.fpp | 10 +- src/simulation/m_mpi_proxy.fpp | 4 + src/simulation/m_pressure_relaxation.fpp | 587 +- src/simulation/m_re_visc.fpp | 346 + src/simulation/m_riemann_solvers.fpp | 10529 ++++++++-------- src/simulation/m_time_steppers.fpp | 2136 ++-- src/simulation/m_viscous.fpp | 3200 +++-- toolchain/mfc/params/definitions.py | 3 + 34 files changed, 12159 insertions(+), 10225 deletions(-) mode change 120000 => 100644 .github/workflows/frontier_amd/bench.sh mode change 120000 => 100644 .github/workflows/frontier_amd/build.sh mode change 120000 => 100644 .github/workflows/frontier_amd/submit.sh mode change 120000 => 100644 .github/workflows/frontier_amd/test.sh create mode 100644 examples/2D_lid_driven_cavity_nn/Re_100_n_0.5/x_vy.csv create mode 100644 examples/2D_lid_driven_cavity_nn/Re_100_n_0.5/y_vx.csv create mode 100644 examples/2D_lid_driven_cavity_nn/case.py create mode 100644 examples/2D_poiseuille_nn/case.py create mode 100644 examples/2D_poiseuille_nn/velocity_0.25.csv create mode 100644 examples/2D_poiseuille_nn/velocity_0.5.csv create mode 100644 examples/2D_poiseuille_nn/velocity_0.75.csv create mode 100644 examples/2D_poiseuille_nn/velocity_1.0.csv create mode 100644 examples/2D_poiseuille_nn/velocity_1.25.csv create mode 100644 examples/2D_poiseuille_nn/velocity_1.5.csv create mode 100644 examples/2D_poiseuille_nn/velocity_1.75.csv create mode 100644 examples/2D_poiseuille_nn/velocity_2.0.csv create mode 100644 examples/2D_poiseuille_nn/velocity_profile.png create mode 100644 src/simulation/m_hb_function.fpp create mode 100644 src/simulation/m_re_visc.fpp diff --git a/.github/workflows/frontier_amd/bench.sh b/.github/workflows/frontier_amd/bench.sh deleted file mode 120000 index 2ac24c7604..0000000000 --- a/.github/workflows/frontier_amd/bench.sh +++ /dev/null @@ -1 +0,0 @@ -../frontier/bench.sh \ No newline at end of file diff --git a/.github/workflows/frontier_amd/bench.sh b/.github/workflows/frontier_amd/bench.sh new file mode 100644 index 0000000000..2ac24c7604 --- /dev/null +++ b/.github/workflows/frontier_amd/bench.sh @@ -0,0 +1 @@ +../frontier/bench.sh \ No newline at end of file diff --git a/.github/workflows/frontier_amd/build.sh b/.github/workflows/frontier_amd/build.sh deleted file mode 120000 index 40fec10411..0000000000 --- a/.github/workflows/frontier_amd/build.sh +++ /dev/null @@ -1 +0,0 @@ -../frontier/build.sh \ No newline at end of file diff --git a/.github/workflows/frontier_amd/build.sh b/.github/workflows/frontier_amd/build.sh new file mode 100644 index 0000000000..40fec10411 --- /dev/null +++ b/.github/workflows/frontier_amd/build.sh @@ -0,0 +1 @@ +../frontier/build.sh \ No newline at end of file diff --git a/.github/workflows/frontier_amd/submit.sh b/.github/workflows/frontier_amd/submit.sh deleted file mode 120000 index 11890c4fcd..0000000000 --- a/.github/workflows/frontier_amd/submit.sh +++ /dev/null @@ -1 +0,0 @@ -../frontier/submit.sh \ No newline at end of file diff --git a/.github/workflows/frontier_amd/submit.sh b/.github/workflows/frontier_amd/submit.sh new file mode 100644 index 0000000000..11890c4fcd --- /dev/null +++ b/.github/workflows/frontier_amd/submit.sh @@ -0,0 +1 @@ +../frontier/submit.sh \ No newline at end of file diff --git a/.github/workflows/frontier_amd/test.sh b/.github/workflows/frontier_amd/test.sh deleted file mode 120000 index 8878e823b2..0000000000 --- a/.github/workflows/frontier_amd/test.sh +++ /dev/null @@ -1 +0,0 @@ -../frontier/test.sh \ No newline at end of file diff --git a/.github/workflows/frontier_amd/test.sh b/.github/workflows/frontier_amd/test.sh new file mode 100644 index 0000000000..8878e823b2 --- /dev/null +++ b/.github/workflows/frontier_amd/test.sh @@ -0,0 +1 @@ +../frontier/test.sh \ No newline at end of file diff --git a/examples/2D_lid_driven_cavity_nn/Re_100_n_0.5/x_vy.csv b/examples/2D_lid_driven_cavity_nn/Re_100_n_0.5/x_vy.csv new file mode 100644 index 0000000000..599178e586 --- /dev/null +++ b/examples/2D_lid_driven_cavity_nn/Re_100_n_0.5/x_vy.csv @@ -0,0 +1,257 @@ +Points_0,Points_1,Points_2,vel1,vel2 +0,0.5,0,-1.20002e-05,0.00106367 +0.00392157,0.5,0,-3.40767e-05,0.00126476 +0.00784314,0.5,0,-8.11084e-05,0.00328905 +0.0117647,0.5,0,-0.000150072,0.00348328 +0.0156863,0.5,0,-0.000239757,0.00538111 +0.0196078,0.5,0,-0.000350073,0.00557266 +0.0235294,0.5,0,-0.000478899,0.00736609 +0.027451,0.5,0,-0.000626775,0.00755538 +0.0313726,0.5,0,-0.00079154,0.00925918 +0.0352941,0.5,0,-0.000973761,0.00944647 +0.0392157,0.5,0,-0.00117144,0.011071 +0.0431373,0.5,0,-0.0013851,0.0112563 +0.0470588,0.5,0,-0.00161289,0.0128094 +0.0509804,0.5,0,-0.00185534,0.0129896 +0.054902,0.5,0,-0.00211077,0.014481 +0.0588235,0.5,0,-0.0023802,0.0146548 +0.0627451,0.5,0,-0.00265682,0.0160115 +0.0666667,0.5,0,-0.00295543,0.016436 +0.0705882,0.5,0,-0.00326297,0.0174414 +0.0745098,0.5,0,-0.00357758,0.0180124 +0.0784314,0.5,0,-0.00390546,0.0189127 +0.0823529,0.5,0,-0.00424314,0.0194912 +0.0862745,0.5,0,-0.00459071,0.0203378 +0.0901961,0.5,0,-0.00494773,0.0209076 +0.0941176,0.5,0,-0.00531355,0.0217063 +0.0980392,0.5,0,-0.00568833,0.0222635 +0.101961,0.5,0,-0.0060713,0.0230174 +0.105882,0.5,0,-0.00646246,0.0235599 +0.109804,0.5,0,-0.00686119,0.0242711 +0.113725,0.5,0,-0.00726742,0.0247975 +0.117647,0.5,0,-0.00768072,0.0254674 +0.121569,0.5,0,-0.00810092,0.0259765 +0.12549,0.5,0,-0.00852752,0.0266063 +0.129412,0.5,0,-0.00896057,0.0270975 +0.133333,0.5,0,-0.00939943,0.0276882 +0.137255,0.5,0,-0.00984415,0.0281611 +0.141176,0.5,0,-0.0102942,0.0287135 +0.145098,0.5,0,-0.0107495,0.0291682 +0.14902,0.5,0,-0.01121,0.0296839 +0.152941,0.5,0,-0.0116751,0.0301156 +0.156863,0.5,0,-0.0121448,0.0305996 +0.160784,0.5,0,-0.0126188,0.0310065 +0.164706,0.5,0,-0.0130969,0.0314597 +0.168627,0.5,0,-0.0135789,0.0318417 +0.172549,0.5,0,-0.0140646,0.0322647 +0.176471,0.5,0,-0.0145538,0.0326218 +0.180392,0.5,0,-0.0150463,0.0330151 +0.184314,0.5,0,-0.015542,0.0333475 +0.188235,0.5,0,-0.0160406,0.0337115 +0.192157,0.5,0,-0.0165421,0.0340193 +0.196078,0.5,0,-0.0170463,0.0343546 +0.2,0.5,0,-0.0175529,0.0346379 +0.203922,0.5,0,-0.018062,0.034945 +0.207843,0.5,0,-0.0185732,0.035204 +0.211765,0.5,0,-0.0190866,0.0354833 +0.215686,0.5,0,-0.0196019,0.0357183 +0.219608,0.5,0,-0.0201191,0.0359703 +0.223529,0.5,0,-0.020638,0.0361815 +0.227451,0.5,0,-0.0211585,0.0364068 +0.231373,0.5,0,-0.0216805,0.0365942 +0.235294,0.5,0,-0.022204,0.0367932 +0.239216,0.5,0,-0.0227287,0.0369573 +0.243137,0.5,0,-0.0232547,0.0371306 +0.247059,0.5,0,-0.0237819,0.0372715 +0.25098,0.5,0,-0.0243102,0.0374194 +0.254902,0.5,0,-0.0248394,0.0375374 +0.258824,0.5,0,-0.0253696,0.0376604 +0.262745,0.5,0,-0.0259007,0.0377558 +0.266667,0.5,0,-0.0264326,0.0378543 +0.270588,0.5,0,-0.0269652,0.0379275 +0.27451,0.5,0,-0.0274986,0.0380018 +0.278431,0.5,0,-0.0280327,0.038053 +0.282353,0.5,0,-0.0285674,0.0381033 +0.286275,0.5,0,-0.0291028,0.0381332 +0.290196,0.5,0,-0.0296388,0.0381596 +0.294118,0.5,0,-0.0301753,0.0381689 +0.298039,0.5,0,-0.0307124,0.0381717 +0.301961,0.5,0,-0.0312501,0.0381585 +0.305882,0.5,0,-0.0317884,0.0381403 +0.309804,0.5,0,-0.0323272,0.0381052 +0.313726,0.5,0,-0.0328665,0.0380649 +0.317647,0.5,0,-0.0334065,0.0380085 +0.321569,0.5,0,-0.033947,0.0379463 +0.32549,0.5,0,-0.0344881,0.0378688 +0.329412,0.5,0,-0.0350298,0.0377849 +0.333333,0.5,0,-0.0355722,0.0376865 +0.337255,0.5,0,-0.0361153,0.0375809 +0.341176,0.5,0,-0.0366591,0.0374616 +0.345098,0.5,0,-0.0372036,0.0373347 +0.34902,0.5,0,-0.0377488,0.0371944 +0.352941,0.5,0,-0.0382949,0.0370461 +0.356863,0.5,0,-0.0388418,0.0368849 +0.360784,0.5,0,-0.0393896,0.0367153 +0.364706,0.5,0,-0.0399383,0.036533 +0.368627,0.5,0,-0.040488,0.0363419 +0.372549,0.5,0,-0.0410386,0.0361384 +0.376471,0.5,0,-0.0415903,0.0359258 +0.380392,0.5,0,-0.0421431,0.0357008 +0.384314,0.5,0,-0.042697,0.0354664 +0.388235,0.5,0,-0.0432521,0.0352197 +0.392157,0.5,0,-0.0438083,0.0349633 +0.396078,0.5,0,-0.0443657,0.0346946 +0.4,0.5,0,-0.0449244,0.0344157 +0.403922,0.5,0,-0.0454843,0.0341245 +0.407843,0.5,0,-0.0460455,0.0338227 +0.411765,0.5,0,-0.046608,0.0335085 +0.415686,0.5,0,-0.0471718,0.0331834 +0.419608,0.5,0,-0.047737,0.0328457 +0.423529,0.5,0,-0.0483034,0.0324967 +0.427451,0.5,0,-0.0488711,0.0321348 +0.431373,0.5,0,-0.0494401,0.0317612 +0.435294,0.5,0,-0.0500104,0.0313745 +0.439216,0.5,0,-0.0505819,0.0309755 +0.443137,0.5,0,-0.0511547,0.0305632 +0.447059,0.5,0,-0.0517287,0.0301382 +0.45098,0.5,0,-0.0523037,0.0296994 +0.454902,0.5,0,-0.0528799,0.0292475 +0.458824,0.5,0,-0.0534571,0.0287814 +0.462745,0.5,0,-0.0540353,0.0283016 +0.466667,0.5,0,-0.0546143,0.0278073 +0.470588,0.5,0,-0.0551941,0.0272987 +0.47451,0.5,0,-0.0557747,0.0267752 +0.478431,0.5,0,-0.0563558,0.0262369 +0.482353,0.5,0,-0.0569375,0.0256832 +0.486275,0.5,0,-0.0575195,0.0251141 +0.490196,0.5,0,-0.0581017,0.0245291 +0.494118,0.5,0,-0.0586841,0.0239282 +0.498039,0.5,0,-0.0592663,0.0233109 +0.501961,0.5,0,-0.0598484,0.0226771 +0.505882,0.5,0,-0.06043,0.0220264 +0.509804,0.5,0,-0.0610111,0.0213587 +0.513726,0.5,0,-0.0615913,0.0206736 +0.517647,0.5,0,-0.0621705,0.0199709 +0.521569,0.5,0,-0.0627485,0.0192503 +0.52549,0.5,0,-0.063325,0.0185116 +0.529412,0.5,0,-0.0638998,0.0177545 +0.533333,0.5,0,-0.0644726,0.0169788 +0.537255,0.5,0,-0.065043,0.0161841 +0.541176,0.5,0,-0.0656109,0.0153705 +0.545098,0.5,0,-0.0661759,0.0145374 +0.54902,0.5,0,-0.0667377,0.0136849 +0.552941,0.5,0,-0.0672959,0.0128126 +0.556863,0.5,0,-0.0678502,0.0119204 +0.560784,0.5,0,-0.0684001,0.0110081 +0.564706,0.5,0,-0.0689453,0.0100756 +0.568627,0.5,0,-0.0694854,0.00912265 +0.572549,0.5,0,-0.0700199,0.00814927 +0.576471,0.5,0,-0.0705484,0.00715524 +0.580392,0.5,0,-0.0710703,0.00614059 +0.584314,0.5,0,-0.0715853,0.00510516 +0.588235,0.5,0,-0.0720927,0.00404905 +0.592157,0.5,0,-0.072592,0.00297213 +0.596078,0.5,0,-0.0730826,0.00187457 +0.6,0.5,0,-0.0735641,0.000756279 +0.603922,0.5,0,-0.0740357,-0.000382484 +0.607843,0.5,0,-0.0744968,-0.00154175 +0.611765,0.5,0,-0.0749467,-0.00272117 +0.615686,0.5,0,-0.0753849,-0.00392073 +0.619608,0.5,0,-0.0758105,-0.00513998 +0.623529,0.5,0,-0.0762228,-0.00637884 +0.627451,0.5,0,-0.0766211,-0.00763674 +0.631373,0.5,0,-0.0770046,-0.00891352 +0.635294,0.5,0,-0.0773725,-0.0102085 +0.639216,0.5,0,-0.077724,-0.0115215 +0.643137,0.5,0,-0.0780582,-0.0128516 +0.647059,0.5,0,-0.0783742,-0.0141986 +0.65098,0.5,0,-0.0786711,-0.0155615 +0.654902,0.5,0,-0.078948,-0.0169398 +0.658824,0.5,0,-0.079204,-0.0183325 +0.662745,0.5,0,-0.079438,-0.0197391 +0.666667,0.5,0,-0.0796491,-0.0211583 +0.670588,0.5,0,-0.0798363,-0.0225895 +0.67451,0.5,0,-0.0799985,-0.0240311 +0.678431,0.5,0,-0.0801347,-0.0254827 +0.682353,0.5,0,-0.0802438,-0.0269422 +0.686275,0.5,0,-0.0803247,-0.0284093 +0.690196,0.5,0,-0.0803763,-0.0298817 +0.694118,0.5,0,-0.0803975,-0.0313589 +0.698039,0.5,0,-0.0803872,-0.0328382 +0.701961,0.5,0,-0.0803443,-0.0343193 +0.705882,0.5,0,-0.0802675,-0.0357991 +0.709804,0.5,0,-0.0801559,-0.0372773 +0.713726,0.5,0,-0.0800081,-0.0387503 +0.717647,0.5,0,-0.0798232,-0.040218 +0.721569,0.5,0,-0.0795999,-0.0416763 +0.72549,0.5,0,-0.0793371,-0.0431253 +0.729412,0.5,0,-0.0790338,-0.0445601 +0.733333,0.5,0,-0.0786888,-0.0459813 +0.737255,0.5,0,-0.0783011,-0.0473832 +0.741176,0.5,0,-0.0778696,-0.0487668 +0.745098,0.5,0,-0.0773934,-0.0501254 +0.74902,0.5,0,-0.0768714,-0.0514609 +0.752941,0.5,0,-0.0763028,-0.0527652 +0.756863,0.5,0,-0.0756867,-0.0540414 +0.760784,0.5,0,-0.0750222,-0.0552796 +0.764706,0.5,0,-0.0743088,-0.0564845 +0.768627,0.5,0,-0.0735456,-0.0576442 +0.772549,0.5,0,-0.0727322,-0.0587653 +0.776471,0.5,0,-0.071868,-0.0598335 +0.780392,0.5,0,-0.0709528,-0.0608579 +0.784314,0.5,0,-0.0699861,-0.0618209 +0.788235,0.5,0,-0.068968,-0.0627353 +0.792157,0.5,0,-0.0678983,-0.0635792 +0.796078,0.5,0,-0.0667774,-0.0643701 +0.8,0.5,0,-0.0656053,-0.0650808 +0.803922,0.5,0,-0.0643829,-0.0657349 +0.807843,0.5,0,-0.0631104,-0.0662984 +0.811765,0.5,0,-0.061789,-0.0668027 +0.815686,0.5,0,-0.0604195,-0.0672053 +0.819608,0.5,0,-0.0590037,-0.0675479 +0.823529,0.5,0,-0.0575424,-0.0677759 +0.827451,0.5,0,-0.0560383,-0.0679457 +0.831373,0.5,0,-0.0544922,-0.0679905 +0.835294,0.5,0,-0.0529078,-0.0679762 +0.839216,0.5,0,-0.0512854,-0.0678192 +0.843137,0.5,0,-0.0496297,-0.0676237 +0.847059,0.5,0,-0.0479436,-0.0672554 +0.85098,0.5,0,-0.0462297,-0.0668712 +0.854902,0.5,0,-0.0444915,-0.0662867 +0.858824,0.5,0,-0.0427327,-0.065711 +0.862745,0.5,0,-0.0409572,-0.0649066 +0.866667,0.5,0,-0.0391694,-0.0641417 +0.870588,0.5,0,-0.0373733,-0.0631161 +0.87451,0.5,0,-0.0355735,-0.0621687 +0.878431,0.5,0,-0.0337746,-0.060923 +0.882353,0.5,0,-0.0319814,-0.0598043 +0.886275,0.5,0,-0.0301979,-0.0583406 +0.890196,0.5,0,-0.0284307,-0.0570708 +0.894118,0.5,0,-0.0266832,-0.0553859 +0.898039,0.5,0,-0.0249613,-0.0540064 +0.901961,0.5,0,-0.0232697,-0.0521023 +0.905882,0.5,0,-0.0216116,-0.0506363 +0.909804,0.5,0,-0.0199929,-0.0485204 +0.913725,0.5,0,-0.0184171,-0.0469952 +0.917647,0.5,0,-0.0168868,-0.0446766 +0.921569,0.5,0,-0.0154071,-0.0431278 +0.92549,0.5,0,-0.0139764,-0.0405911 +0.929412,0.5,0,-0.0126168,-0.0391321 +0.933333,0.5,0,-0.0112971,-0.0361733 +0.937255,0.5,0,-0.0100511,-0.0351866 +0.941176,0.5,0,-0.00891779,-0.0316462 +0.945098,0.5,0,-0.0078093,-0.031129 +0.94902,0.5,0,-0.00677682,-0.0273183 +0.952941,0.5,0,-0.00580795,-0.026878 +0.956863,0.5,0,-0.00491938,-0.0229149 +0.960784,0.5,0,-0.00409967,-0.0225932 +0.964706,0.5,0,-0.00335785,-0.0185373 +0.968627,0.5,0,-0.00268756,-0.0183334 +0.972549,0.5,0,-0.00209488,-0.0142276 +0.976471,0.5,0,-0.00157565,-0.0141272 +0.980392,0.5,0,-0.00113244,-0.0100088 +0.984314,0.5,0,-0.000763013,-0.00998629 +0.988235,0.5,0,-0.000465282,-0.00585201 +0.992157,0.5,0,-0.000246904,-0.00597637 +0.996078,0.5,0,-0.000100304,-0.0018689 +1,0.5,0,nan,nan diff --git a/examples/2D_lid_driven_cavity_nn/Re_100_n_0.5/y_vx.csv b/examples/2D_lid_driven_cavity_nn/Re_100_n_0.5/y_vx.csv new file mode 100644 index 0000000000..c4a1fea6da --- /dev/null +++ b/examples/2D_lid_driven_cavity_nn/Re_100_n_0.5/y_vx.csv @@ -0,0 +1,257 @@ +Points_0,Points_1,Points_2,vel1,vel2 +0.5,0,0,-0.000226951,1.87729e-07 +0.5,0.00392157,0,-0.000652445,8.69614e-07 +0.5,0.00784314,0,-0.00108222,2.32409e-06 +0.5,0.0117647,0,-0.00148558,4.42463e-06 +0.5,0.0156863,0,-0.00189039,7.19262e-06 +0.5,0.0196078,0,-0.00227497,1.05649e-05 +0.5,0.0235294,0,-0.00266029,1.45335e-05 +0.5,0.027451,0,-0.0030304,1.9076e-05 +0.5,0.0313726,0,-0.00340114,2.41794e-05 +0.5,0.0352941,0,-0.00376061,2.98373e-05 +0.5,0.0392157,0,-0.00412091,3.60402e-05 +0.5,0.0431373,0,-0.00447296,4.27896e-05 +0.5,0.0470588,0,-0.00482626,5.00824e-05 +0.5,0.0509804,0,-0.00517361,5.79253e-05 +0.5,0.054902,0,-0.00552279,6.63227e-05 +0.5,0.0588235,0,-0.00586773,7.52857e-05 +0.5,0.0627451,0,-0.00621517,8.48279e-05 +0.5,0.0666667,0,-0.00655963,9.4966e-05 +0.5,0.0705882,0,-0.00690736,0.000105722 +0.5,0.0745098,0,-0.00725311,0.000117116 +0.5,0.0784314,0,-0.0076027,0.000129179 +0.5,0.0823529,0,-0.00795121,0.000141937 +0.5,0.0862745,0,-0.00830404,0.000155424 +0.5,0.0901961,0,-0.00865662,0.000169672 +0.5,0.0941176,0,-0.0090139,0.000184714 +0.5,0.0980392,0,-0.00937166,0.000200589 +0.5,0.101961,0,-0.00973446,0.000217331 +0.5,0.105882,0,-0.0100984,0.000234981 +0.5,0.109804,0,-0.0104677,0.00025358 +0.5,0.113725,0,-0.0108387,0.000273173 +0.5,0.117647,0,-0.0112153,0.000293805 +0.5,0.121569,0,-0.0115942,0.000315527 +0.5,0.12549,0,-0.0119789,0.000338392 +0.5,0.129412,0,-0.0123665,0.000362455 +0.5,0.133333,0,-0.01276,0.000387775 +0.5,0.137255,0,-0.0131568,0.000414413 +0.5,0.141176,0,-0.0135598,0.000442432 +0.5,0.145098,0,-0.0139666,0.000471896 +0.5,0.14902,0,-0.0143796,0.000502873 +0.5,0.152941,0,-0.0147967,0.000535433 +0.5,0.156863,0,-0.0152203,0.000569648 +0.5,0.160784,0,-0.0156484,0.000605592 +0.5,0.164706,0,-0.0160831,0.000643343 +0.5,0.168627,0,-0.0165226,0.000682983 +0.5,0.172549,0,-0.0169688,0.000724597 +0.5,0.176471,0,-0.01742,0.000768273 +0.5,0.180392,0,-0.0178781,0.000814103 +0.5,0.184314,0,-0.0183415,0.000862183 +0.5,0.188235,0,-0.0188117,0.00091261 +0.5,0.192157,0,-0.0192876,0.000965486 +0.5,0.196078,0,-0.0197702,0.00102092 +0.5,0.2,0,-0.0202588,0.00107901 +0.5,0.203922,0,-0.0207541,0.00113987 +0.5,0.207843,0,-0.0212555,0.00120362 +0.5,0.211765,0,-0.0217636,0.00127037 +0.5,0.215686,0,-0.0222779,0.00134025 +0.5,0.219608,0,-0.022799,0.00141337 +0.5,0.223529,0,-0.0233262,0.00148987 +0.5,0.227451,0,-0.0238602,0.00156989 +0.5,0.231373,0,-0.0244004,0.00165354 +0.5,0.235294,0,-0.0249471,0.00174098 +0.5,0.239216,0,-0.0255001,0.00183234 +0.5,0.243137,0,-0.0260595,0.00192777 +0.5,0.247059,0,-0.026625,0.00202742 +0.5,0.25098,0,-0.0271967,0.00213144 +0.5,0.254902,0,-0.0277744,0.00223998 +0.5,0.258824,0,-0.0283581,0.00235319 +0.5,0.262745,0,-0.0289476,0.00247124 +0.5,0.266667,0,-0.0295428,0.00259428 +0.5,0.270588,0,-0.0301435,0.00272248 +0.5,0.27451,0,-0.0307495,0.002856 +0.5,0.278431,0,-0.0313608,0.002995 +0.5,0.282353,0,-0.0319769,0.00313967 +0.5,0.286275,0,-0.0325978,0.00329015 +0.5,0.290196,0,-0.0332231,0.00344664 +0.5,0.294118,0,-0.0338528,0.0036093 +0.5,0.298039,0,-0.0344862,0.0037783 +0.5,0.301961,0,-0.0351234,0.00395383 +0.5,0.305882,0,-0.0357638,0.00413603 +0.5,0.309804,0,-0.0364074,0.0043251 +0.5,0.313726,0,-0.0370533,0.00452119 +0.5,0.317647,0,-0.0377017,0.00472448 +0.5,0.321569,0,-0.0383517,0.00493513 +0.5,0.32549,0,-0.0390033,0.0051533 +0.5,0.329412,0,-0.0396556,0.00537915 +0.5,0.333333,0,-0.0403085,0.00561284 +0.5,0.337255,0,-0.0409612,0.00585453 +0.5,0.341176,0,-0.0416136,0.00610436 +0.5,0.345098,0,-0.0422646,0.00636248 +0.5,0.34902,0,-0.0429142,0.00662902 +0.5,0.352941,0,-0.0435613,0.00690411 +0.5,0.356863,0,-0.0442058,0.00718788 +0.5,0.360784,0,-0.0448465,0.00748045 +0.5,0.364706,0,-0.0454834,0.00778191 +0.5,0.368627,0,-0.0461152,0.00809236 +0.5,0.372549,0,-0.0467417,0.0084119 +0.5,0.376471,0,-0.0473617,0.00874061 +0.5,0.380392,0,-0.0479751,0.00907854 +0.5,0.384314,0,-0.0485805,0.00942576 +0.5,0.388235,0,-0.0491778,0.00978233 +0.5,0.392157,0,-0.0497655,0.0101483 +0.5,0.396078,0,-0.0503436,0.0105236 +0.5,0.4,0,-0.0509105,0.0109083 +0.5,0.403922,0,-0.0514662,0.0113025 +0.5,0.407843,0,-0.0520091,0.011706 +0.5,0.411765,0,-0.0525391,0.0121188 +0.5,0.415686,0,-0.0530548,0.012541 +0.5,0.419608,0,-0.0535559,0.0129724 +0.5,0.423529,0,-0.054041,0.013413 +0.5,0.427451,0,-0.0545098,0.0138626 +0.5,0.431373,0,-0.0549611,0.0143212 +0.5,0.435294,0,-0.0553945,0.0147887 +0.5,0.439216,0,-0.0558087,0.0152648 +0.5,0.443137,0,-0.0562034,0.0157495 +0.5,0.447059,0,-0.0565774,0.0162426 +0.5,0.45098,0,-0.0569304,0.0167439 +0.5,0.454902,0,-0.0572612,0.0172531 +0.5,0.458824,0,-0.0575695,0.0177702 +0.5,0.462745,0,-0.0578543,0.0182948 +0.5,0.466667,0,-0.0581152,0.0188267 +0.5,0.470588,0,-0.0583512,0.0193656 +0.5,0.47451,0,-0.0585621,0.0199113 +0.5,0.478431,0,-0.058747,0.0204635 +0.5,0.482353,0,-0.0589057,0.0210219 +0.5,0.486275,0,-0.0590373,0.0215862 +0.5,0.490196,0,-0.0591417,0.022156 +0.5,0.494118,0,-0.059218,0.022731 +0.5,0.498039,0,-0.0592663,0.0233109 +0.5,0.501961,0,-0.0592858,0.0238952 +0.5,0.505882,0,-0.0592766,0.0244837 +0.5,0.509804,0,-0.0592379,0.0250759 +0.5,0.513726,0,-0.05917,0.0256714 +0.5,0.517647,0,-0.0590721,0.0262699 +0.5,0.521569,0,-0.0589446,0.0268709 +0.5,0.52549,0,-0.0587868,0.0274739 +0.5,0.529412,0,-0.0585992,0.0280786 +0.5,0.533333,0,-0.0583811,0.0286845 +0.5,0.537255,0,-0.0581331,0.0292912 +0.5,0.541176,0,-0.0578546,0.0298982 +0.5,0.545098,0,-0.0575464,0.030505 +0.5,0.54902,0,-0.0572078,0.0311111 +0.5,0.552941,0,-0.0568396,0.0317162 +0.5,0.556863,0,-0.0564413,0.0323196 +0.5,0.560784,0,-0.056014,0.032921 +0.5,0.564706,0,-0.0555568,0.0335198 +0.5,0.568627,0,-0.0550712,0.0341156 +0.5,0.572549,0,-0.0545563,0.0347078 +0.5,0.576471,0,-0.0540136,0.0352959 +0.5,0.580392,0,-0.0534423,0.0358795 +0.5,0.584314,0,-0.0528441,0.036458 +0.5,0.588235,0,-0.0522181,0.037031 +0.5,0.592157,0,-0.051566,0.037598 +0.5,0.596078,0,-0.0508871,0.0381584 +0.5,0.6,0,-0.0501833,0.0387117 +0.5,0.603922,0,-0.0494536,0.0392575 +0.5,0.607843,0,-0.0487003,0.0397953 +0.5,0.611765,0,-0.0479222,0.0403246 +0.5,0.615686,0,-0.0471218,0.0408448 +0.5,0.619608,0,-0.0462978,0.0413556 +0.5,0.623529,0,-0.0454531,0.0418564 +0.5,0.627451,0,-0.044586,0.0423468 +0.5,0.631373,0,-0.0436997,0.0428262 +0.5,0.635294,0,-0.0427924,0.0432943 +0.5,0.639216,0,-0.0418677,0.0437505 +0.5,0.643137,0,-0.0409234,0.0441944 +0.5,0.647059,0,-0.0399635,0.0446257 +0.5,0.65098,0,-0.0389853,0.0450437 +0.5,0.654902,0,-0.0379934,0.0454481 +0.5,0.658824,0,-0.0369848,0.0458385 +0.5,0.662745,0,-0.0359644,0.0462144 +0.5,0.666667,0,-0.0349285,0.0465755 +0.5,0.670588,0,-0.033883,0.0469213 +0.5,0.67451,0,-0.0328233,0.0472514 +0.5,0.678431,0,-0.031756,0.0475654 +0.5,0.682353,0,-0.0306756,0.0478629 +0.5,0.686275,0,-0.0295895,0.0481436 +0.5,0.690196,0,-0.0284913,0.0484071 +0.5,0.694118,0,-0.0273891,0.048653 +0.5,0.698039,0,-0.0262753,0.0488809 +0.5,0.701961,0,-0.0251589,0.0490904 +0.5,0.705882,0,-0.0240308,0.0492813 +0.5,0.709804,0,-0.0229011,0.0494532 +0.5,0.713726,0,-0.0217585,0.0496056 +0.5,0.717647,0,-0.0206145,0.0497384 +0.5,0.721569,0,-0.0194555,0.0498511 +0.5,0.72549,0,-0.0182944,0.0499435 +0.5,0.729412,0,-0.0171148,0.0500152 +0.5,0.733333,0,-0.0159318,0.0500661 +0.5,0.737255,0,-0.0147256,0.0500957 +0.5,0.741176,0,-0.0135142,0.0501038 +0.5,0.745098,0,-0.0122744,0.0500903 +0.5,0.74902,0,-0.0110277,0.0500548 +0.5,0.752941,0,-0.00974723,0.0499972 +0.5,0.756863,0,-0.00845855,0.0499172 +0.5,0.760784,0,-0.00713093,0.0498146 +0.5,0.764706,0,-0.00579462,0.0496892 +0.5,0.768627,0,-0.00441407,0.0495408 +0.5,0.772549,0,-0.0030251,0.0493691 +0.5,0.776471,0,-0.00158642,0.0491741 +0.5,0.780392,0,-0.000140163,0.0489554 +0.5,0.784314,0,0.00136171,0.0487128 +0.5,0.788235,0,0.00286986,0.0484463 +0.5,0.792157,0,0.0044403,0.0481556 +0.5,0.796078,0,0.00601536,0.0478405 +0.5,0.8,0,0.00766041,0.0475007 +0.5,0.803922,0,0.00930818,0.0471364 +0.5,0.807843,0,0.011035,0.0467471 +0.5,0.811765,0,0.0127625,0.0463328 +0.5,0.815686,0,0.0145797,0.0458932 +0.5,0.819608,0,0.0163955,0.0454284 +0.5,0.823529,0,0.0183136,0.0449381 +0.5,0.827451,0,0.020228,0.0444221 +0.5,0.831373,0,0.0222602,0.0438804 +0.5,0.835294,0,0.0242861,0.0433126 +0.5,0.839216,0,0.0264487,0.0427189 +0.5,0.843137,0,0.0286021,0.0420988 +0.5,0.847059,0,0.0309154,0.0414526 +0.5,0.85098,0,0.0332161,0.0407796 +0.5,0.854902,0,0.0357053,0.0400802 +0.5,0.858824,0,0.0381781,0.0393537 +0.5,0.862745,0,0.040875,0.0386003 +0.5,0.866667,0,0.043551,0.0378194 +0.5,0.870588,0,0.0464951,0.0370113 +0.5,0.87451,0,0.0494134,0.0361752 +0.5,0.878431,0,0.052655,0.0353113 +0.5,0.882353,0,0.0558652,0.034419 +0.5,0.886275,0,0.0594682,0.0334982 +0.5,0.890196,0,0.0630335,0.0325484 +0.5,0.894118,0,0.06708,0.0315694 +0.5,0.898039,0,0.0710816,0.0305607 +0.5,0.901961,0,0.0756778,0.0295221 +0.5,0.905882,0,0.0802206,0.0284529 +0.5,0.909804,0,0.0855046,0.0273533 +0.5,0.913725,0,0.0907252,0.0262224 +0.5,0.917647,0,0.0968781,0.0250604 +0.5,0.921569,0,0.102954,0.0238669 +0.5,0.92549,0,0.110214,0.0226424 +0.5,0.929412,0,0.117376,0.0213866 +0.5,0.933333,0,0.126056,0.0201008 +0.5,0.937255,0,0.134601,0.0187856 +0.5,0.941176,0,0.145108,0.0174435 +0.5,0.945098,0,0.155397,0.0160768 +0.5,0.94902,0,0.168241,0.01469 +0.5,0.952941,0,0.180676,0.0132884 +0.5,0.956863,0,0.196652,0.0118649 +0.5,0.960784,0,0.211105,0.0104442 +0.5,0.964706,0,0.231766,0.00904004 +0.5,0.968627,0,0.247928,0.0076539 +0.5,0.972549,0,0.27408,0.00631128 +0.5,0.976471,0,0.289063,0.00501808 +0.5,0.980392,0,0.33281,0.00382616 +0.5,0.984314,0,0.337636,0.00267429 +0.5,0.988235,0,0.394435,0.00172012 +0.5,0.992157,0,0.399317,0.000924857 +0.5,0.996078,0,0.462849,0.000391529 +0.5,1,0,nan,nan diff --git a/examples/2D_lid_driven_cavity_nn/case.py b/examples/2D_lid_driven_cavity_nn/case.py new file mode 100644 index 0000000000..cef8312ef1 --- /dev/null +++ b/examples/2D_lid_driven_cavity_nn/case.py @@ -0,0 +1,116 @@ +#!/usr/bin/env python3 +""" +2D Lid-Driven Cavity Flow with Herschel-Bulkley Non-Newtonian Fluid + +Re = 5000, n = 1.5 (shear-thickening) with mesh stretching near walls. + +HB model: mu = (tau0/gdot)*(1 - exp(-m*gdot)) + K * gdot^(n-1) +Re_gen = rho * U^(2-n) * L^n / K = 1 * 1^0.5 * 1^1.5 / 0.0002 = 5000 + +Mesh stretching: cosh-based clustering near all 4 walls (x_a, x_b, y_a, y_b). +""" +import json + +eps = 1e-6 + +# HB model parameters +tau0 = 0.0 # Yield stress (set to 0 for power-law fluid) +K = 0.0002 # Consistency index (Re=5000: K = 1/5000) +nn = 1.5 # Flow behavior index (shear-thickening) +mu_min = 0.00002 # K * gdot_min^(n-1) = 0.0002 * (0.01)^0.5 +mu_max = 0.0632 # K * gdot_max^(n-1) = 0.0002 * (1e5)^0.5 +hb_m = 1000.0 # Papanastasiou regularization parameter +mu_bulk = 0.0 + +lid_velocity = 1.0 # Lid velocity (m/s) + +# Configuring case dictionary +print( + json.dumps( + { + # Logistics + "run_time_info": "T", + # Computational Domain Parameters + "x_domain%beg": 0.0, + "x_domain%end": 1.0, + "y_domain%beg": 0.0, + "y_domain%end": 1.0, + "m": 255, + "n": 255, + "p": 0, + "cfl_adap_dt": "T", + "cfl_target": 0.5, + "n_start": 0, + "t_stop": 50.0, + "t_save": 25.0, + # Simulation Algorithm Parameters + "num_patches": 1, + "model_eqns": 2, + "alt_soundspeed": "F", + "num_fluids": 2, + "mpp_lim": "F", + "mixture_err": "T", + "time_stepper": 3, + "weno_order": 5, + "weno_eps": 1e-16, + "mapped_weno": "T", + "weno_Re_flux": "T", + "mp_weno": "T", + "weno_avg": "T", + "riemann_solver": 2, + "wave_speeds": 1, + "avg_state": 2, + "bc_x%beg": -16, + "bc_x%end": -16, + "bc_y%beg": -16, + "bc_y%end": -16, + "bc_y%ve1": lid_velocity, + "viscous": "T", + # Formatted Database Files Structure Parameters + "format": 1, + "precision": 2, + "prim_vars_wrt": "T", + "omega_wrt(3)": "T", + "fd_order": 4, + "parallel_io": "T", + # Patch 1: Base + "patch_icpp(1)%geometry": 3, + "patch_icpp(1)%x_centroid": 0.5, + "patch_icpp(1)%y_centroid": 0.5, + "patch_icpp(1)%length_x": 1.0, + "patch_icpp(1)%length_y": 1.0, + "patch_icpp(1)%vel(1)": 0, + "patch_icpp(1)%vel(2)": 0.0, + "patch_icpp(1)%pres": 1e3, + "patch_icpp(1)%alpha_rho(1)": 0.5, + "patch_icpp(1)%alpha(1)": 0.5, + "patch_icpp(1)%alpha_rho(2)": 0.5, + "patch_icpp(1)%alpha(2)": 0.5, + # Fluids Physical Parameters + # Fluid 1: + "fluid_pp(1)%gamma": 1.0 / (1.4 - 1.0), + "fluid_pp(1)%pi_inf": 0.0, + "fluid_pp(1)%Re(1)": 1.0 / K, + "fluid_pp(1)%non_newtonian": "T", + "fluid_pp(1)%tau0": tau0, + "fluid_pp(1)%K": K, + "fluid_pp(1)%nn": nn, + "fluid_pp(1)%mu_max": mu_max, + "fluid_pp(1)%mu_min": mu_min, + "fluid_pp(1)%mu_bulk": mu_bulk, + "fluid_pp(1)%hb_m": hb_m, + # Fluid 2: + "fluid_pp(2)%gamma": 1.0 / (1.4 - 1.0), + "fluid_pp(2)%pi_inf": 0.0, + "fluid_pp(2)%Re(1)": 1.0 / K, + "fluid_pp(2)%non_newtonian": "T", + "fluid_pp(2)%tau0": tau0, + "fluid_pp(2)%K": K, + "fluid_pp(2)%nn": nn, + "fluid_pp(2)%mu_max": mu_max, + "fluid_pp(2)%mu_min": mu_min, + "fluid_pp(2)%mu_bulk": mu_bulk, + "fluid_pp(2)%hb_m": hb_m, + } + ) +) diff --git a/examples/2D_poiseuille_nn/case.py b/examples/2D_poiseuille_nn/case.py new file mode 100644 index 0000000000..b99500a6ad --- /dev/null +++ b/examples/2D_poiseuille_nn/case.py @@ -0,0 +1,158 @@ +#!/usr/bin/env python3 +""" +2D Poiseuille Flow with Herschel-Bulkley Non-Newtonian Fluid + +Pressure-driven channel flow between two no-slip walls, driven by a constant +body force in the streamwise (x) direction. Periodic BCs in x, no-slip in y. + +HB model: mu = (tau0/gdot)*(1 - exp(-m*gdot)) + K * gdot^(n-1) + - tau0: yield stress + - K: consistency index + - n: flow behavior index (< 1 shear-thinning, > 1 shear-thickening) + - m: Papanastasiou regularization parameter + +For Newtonian Poiseuille validation, set tau0=0, nn=1, K=mu. +The analytical solution is: u(y) = (G/(2*mu)) * y * (H - y) +where G = rho * g_x is the effective pressure gradient. +""" +import json +import math + +# === Channel geometry (square domain) === +L = 1.0 # Channel length (streamwise, x) +H = 1.0 # Channel height (wall-normal, y) + +# === Grid resolution === +Nx = 24 # Cells in x (streamwise, minimal — periodic) +Ny = 81 # Cells in y (wall-normal) + +# === Fluid properties === +rho = 1.0 # Density +p0 = 1e5 # Reference pressure (high for low Mach) +gamma = 1.4 # Ratio of specific heats + +# Sound speed and CFL +c = math.sqrt(gamma * p0 / rho) +dx = L / (Nx + 1) +cfl = 0.3 +dt = cfl * dx / c + +# === Body force (pressure gradient substitute) === +# G = rho * g_x acts as dp/dx driving force +g_x = 0.5 + +# === HB non-Newtonian model parameters === +tau0 = 0.0 # Yield stress (set 0 for power-law) +K = 0.1 # Consistency index +nn = 2.0 # Flow behavior index (< 1 = shear-thinning) +hb_m = 1000.0 # Papanastasiou regularization parameter +mu_min = 1e-4 # Minimum viscosity bound +mu_max = 10.0 # Maximum viscosity bound +mu_bulk = 0.0 # Bulk viscosity + +# Reference Re based on consistency index (used as baseline) +Re_ref = 1.0 / K # = 100 + +# === Time control === +t_end = 10.0 # End time (allow flow to reach steady state) +t_save = 5.0 # Save interval + +eps = 1e-6 + +# Configuring case dictionary +print( + json.dumps( + { + # Logistics + "run_time_info": "T", + # Computational Domain Parameters + "x_domain%beg": 0.0, + "x_domain%end": L, + "y_domain%beg": 0.0, + "y_domain%end": H, + "m": Nx, + "n": Ny, + "p": 0, + "cfl_adap_dt": "T", + "cfl_target": cfl, + "n_start": 0, + "t_stop": t_end, + "t_save": t_save, + # Simulation Algorithm Parameters + "num_patches": 1, + "model_eqns": 2, + "alt_soundspeed": "F", + "num_fluids": 2, + "mpp_lim": "F", + "mixture_err": "T", + "time_stepper": 3, + "weno_order": 5, + "weno_eps": 1e-16, + "mapped_weno": "T", + "weno_Re_flux": "T", + "mp_weno": "T", + "weno_avg": "T", + "riemann_solver": 2, + "wave_speeds": 1, + "avg_state": 2, + # Boundary Conditions + # Periodic in x (streamwise), no-slip walls in y + "bc_x%beg": -1, + "bc_x%end": -1, + "bc_y%beg": -16, + "bc_y%end": -16, + # Viscous + "viscous": "T", + # Body Force (drives the flow like a pressure gradient) + "bf_x": "T", + "g_x": g_x, + "k_x": 0.0, + "w_x": 0.0, + "p_x": 0.0, + # Formatted Database Files Structure Parameters + "format": 1, + "precision": 2, + "prim_vars_wrt": "T", + "omega_wrt(3)": "T", + "fd_order": 4, + "parallel_io": "T", + # Patch 1: Entire channel domain (initially at rest) + "patch_icpp(1)%geometry": 3, + "patch_icpp(1)%x_centroid": L / 2.0, + "patch_icpp(1)%y_centroid": H / 2.0, + "patch_icpp(1)%length_x": L, + "patch_icpp(1)%length_y": H, + "patch_icpp(1)%vel(1)": 0.0, + "patch_icpp(1)%vel(2)": 0.0, + "patch_icpp(1)%pres": p0, + "patch_icpp(1)%alpha_rho(1)": rho * 0.5, + "patch_icpp(1)%alpha(1)": 0.5, + "patch_icpp(1)%alpha_rho(2)": rho * 0.5, + "patch_icpp(1)%alpha(2)": 0.5, + # Fluid 1: HB non-Newtonian fluid + "fluid_pp(1)%gamma": 1.0 / (gamma - 1.0), + "fluid_pp(1)%pi_inf": 0.0, + "fluid_pp(1)%Re(1)": Re_ref, + "fluid_pp(1)%non_newtonian": "T", + "fluid_pp(1)%tau0": tau0, + "fluid_pp(1)%K": K, + "fluid_pp(1)%nn": nn, + "fluid_pp(1)%hb_m": hb_m, + "fluid_pp(1)%mu_min": mu_min, + "fluid_pp(1)%mu_max": mu_max, + "fluid_pp(1)%mu_bulk": mu_bulk, + # Fluid 2: same properties (single-phase effectively) + "fluid_pp(2)%gamma": 1.0 / (gamma - 1.0), + "fluid_pp(2)%pi_inf": 0.0, + "fluid_pp(2)%Re(1)": Re_ref, + "fluid_pp(2)%non_newtonian": "T", + "fluid_pp(2)%tau0": tau0, + "fluid_pp(2)%K": K, + "fluid_pp(2)%nn": nn, + "fluid_pp(2)%hb_m": hb_m, + "fluid_pp(2)%mu_min": mu_min, + "fluid_pp(2)%mu_max": mu_max, + "fluid_pp(2)%mu_bulk": mu_bulk, + } + ) +) diff --git a/examples/2D_poiseuille_nn/velocity_0.25.csv b/examples/2D_poiseuille_nn/velocity_0.25.csv new file mode 100644 index 0000000000..bc00d5dd59 --- /dev/null +++ b/examples/2D_poiseuille_nn/velocity_0.25.csv @@ -0,0 +1,83 @@ +Points_0,Points_1,Points_2,vel1 +0.5,0,0,0.128128 +0.5,0.0182927,0,0.278543 +0.5,0.0304878,0,0.487773 +0.5,0.0426829,0,0.616024 +0.5,0.054878,0,0.77915 +0.5,0.0670732,0,0.882687 +0.5,0.0792683,0,1.00915 +0.5,0.0914634,0,1.09088 +0.5,0.103659,0,1.18826 +0.5,0.115854,0,1.25181 +0.5,0.128049,0,1.3261 +0.5,0.140244,0,1.37482 +0.5,0.152439,0,1.43082 +0.5,0.164634,0,1.46757 +0.5,0.176829,0,1.50914 +0.5,0.189024,0,1.53636 +0.5,0.20122,0,1.56662 +0.5,0.213415,0,1.58634 +0.5,0.22561,0,1.60787 +0.5,0.237805,0,1.62179 +0.5,0.25,0,1.63668 +0.5,0.262195,0,1.64618 +0.5,0.27439,0,1.65613 +0.5,0.286585,0,1.66238 +0.5,0.298781,0,1.66874 +0.5,0.310976,0,1.67265 +0.5,0.323171,0,1.67651 +0.5,0.335366,0,1.67881 +0.5,0.347561,0,1.68099 +0.5,0.359756,0,1.68225 +0.5,0.371951,0,1.68336 +0.5,0.384146,0,1.68398 +0.5,0.396341,0,1.68449 +0.5,0.408537,0,1.68476 +0.5,0.420732,0,1.68495 +0.5,0.432927,0,1.68507 +0.5,0.445122,0,1.68517 +0.5,0.457317,0,1.68524 +0.5,0.469512,0,1.6853 +0.5,0.481707,0,1.68534 +0.5,0.493902,0,1.68536 +0.5,0.506098,0,1.68536 +0.5,0.518293,0,1.68534 +0.5,0.530488,0,1.6853 +0.5,0.542683,0,1.68524 +0.5,0.554878,0,1.68517 +0.5,0.567073,0,1.68507 +0.5,0.579268,0,1.68495 +0.5,0.591463,0,1.68476 +0.5,0.603659,0,1.68449 +0.5,0.615854,0,1.68398 +0.5,0.628049,0,1.68336 +0.5,0.640244,0,1.68225 +0.5,0.652439,0,1.68099 +0.5,0.664634,0,1.67881 +0.5,0.676829,0,1.67651 +0.5,0.689024,0,1.67265 +0.5,0.701219,0,1.66874 +0.5,0.713415,0,1.66238 +0.5,0.72561,0,1.65613 +0.5,0.737805,0,1.64618 +0.5,0.75,0,1.63668 +0.5,0.762195,0,1.62179 +0.5,0.77439,0,1.60788 +0.5,0.786585,0,1.58634 +0.5,0.798781,0,1.56662 +0.5,0.810976,0,1.53636 +0.5,0.823171,0,1.50914 +0.5,0.835366,0,1.46757 +0.5,0.847561,0,1.43082 +0.5,0.859756,0,1.37482 +0.5,0.871951,0,1.32611 +0.5,0.884146,0,1.25181 +0.5,0.896341,0,1.18827 +0.5,0.908537,0,1.09088 +0.5,0.920732,0,1.00917 +0.5,0.932927,0,0.88268 +0.5,0.945122,0,0.779157 +0.5,0.957317,0,0.616 +0.5,0.969512,0,0.487768 +0.5,0.981707,0,0.278502 +0.5,1,0,nan diff --git a/examples/2D_poiseuille_nn/velocity_0.5.csv b/examples/2D_poiseuille_nn/velocity_0.5.csv new file mode 100644 index 0000000000..4b0f00d06b --- /dev/null +++ b/examples/2D_poiseuille_nn/velocity_0.5.csv @@ -0,0 +1,83 @@ +Points_0,Points_1,Points_2,vel1 +0.5,0,0,0.0510423 +0.5,0.0182927,0,0.0973209 +0.5,0.0304878,0,0.178706 +0.5,0.0426829,0,0.227382 +0.5,0.054878,0,0.299133 +0.5,0.0670732,0,0.343899 +0.5,0.0792683,0,0.407402 +0.5,0.0914634,0,0.447754 +0.5,0.103659,0,0.503805 +0.5,0.115854,0,0.539743 +0.5,0.128049,0,0.588971 +0.5,0.140244,0,0.620646 +0.5,0.152439,0,0.663585 +0.5,0.164634,0,0.691216 +0.5,0.176829,0,0.72835 +0.5,0.189024,0,0.752188 +0.5,0.20122,0,0.783971 +0.5,0.213415,0,0.804283 +0.5,0.22561,0,0.831151 +0.5,0.237805,0,0.848216 +0.5,0.25,0,0.870595 +0.5,0.262195,0,0.884693 +0.5,0.27439,0,0.903001 +0.5,0.286585,0,0.914415 +0.5,0.298781,0,0.929066 +0.5,0.310976,0,0.93808 +0.5,0.323171,0,0.949486 +0.5,0.335366,0,0.956381 +0.5,0.347561,0,0.964951 +0.5,0.359756,0,0.970011 +0.5,0.371951,0,0.976151 +0.5,0.384146,0,0.979659 +0.5,0.396341,0,0.983777 +0.5,0.408537,0,0.986015 +0.5,0.420732,0,0.988517 +0.5,0.432927,0,0.989771 +0.5,0.445122,0,0.991061 +0.5,0.457317,0,0.991621 +0.5,0.469512,0,0.992095 +0.5,0.481707,0,0.992256 +0.5,0.493902,0,0.992334 +0.5,0.506098,0,0.992334 +0.5,0.518293,0,0.992256 +0.5,0.530488,0,0.992095 +0.5,0.542683,0,0.991621 +0.5,0.554878,0,0.991061 +0.5,0.567073,0,0.989771 +0.5,0.579268,0,0.988517 +0.5,0.591463,0,0.986015 +0.5,0.603659,0,0.983777 +0.5,0.615854,0,0.979659 +0.5,0.628049,0,0.976151 +0.5,0.640244,0,0.970011 +0.5,0.652439,0,0.964951 +0.5,0.664634,0,0.956381 +0.5,0.676829,0,0.949486 +0.5,0.689024,0,0.93808 +0.5,0.701219,0,0.929066 +0.5,0.713415,0,0.914415 +0.5,0.72561,0,0.903001 +0.5,0.737805,0,0.884693 +0.5,0.75,0,0.870595 +0.5,0.762195,0,0.848216 +0.5,0.77439,0,0.831151 +0.5,0.786585,0,0.804283 +0.5,0.798781,0,0.783971 +0.5,0.810976,0,0.752188 +0.5,0.823171,0,0.72835 +0.5,0.835366,0,0.691216 +0.5,0.847561,0,0.663585 +0.5,0.859756,0,0.620646 +0.5,0.871951,0,0.588971 +0.5,0.884146,0,0.539742 +0.5,0.896341,0,0.503805 +0.5,0.908537,0,0.447754 +0.5,0.920732,0,0.407402 +0.5,0.932927,0,0.343899 +0.5,0.945122,0,0.299133 +0.5,0.957317,0,0.227382 +0.5,0.969512,0,0.178706 +0.5,0.981707,0,0.0973208 +0.5,1,0,nan diff --git a/examples/2D_poiseuille_nn/velocity_0.75.csv b/examples/2D_poiseuille_nn/velocity_0.75.csv new file mode 100644 index 0000000000..eb19ce7143 --- /dev/null +++ b/examples/2D_poiseuille_nn/velocity_0.75.csv @@ -0,0 +1,83 @@ +Points_0,Points_1,Points_2,vel1 +0.5,0,0,0.0226916 +0.5,0.0182927,0,0.0583759 +0.5,0.0304878,0,0.101109 +0.5,0.0426829,0,0.134514 +0.5,0.054878,0,0.174312 +0.5,0.0670732,0,0.205431 +0.5,0.0792683,0,0.242348 +0.5,0.0914634,0,0.271215 +0.5,0.103659,0,0.305313 +0.5,0.115854,0,0.331967 +0.5,0.128049,0,0.363308 +0.5,0.140244,0,0.387789 +0.5,0.152439,0,0.416437 +0.5,0.164634,0,0.438789 +0.5,0.176829,0,0.46481 +0.5,0.189024,0,0.485079 +0.5,0.20122,0,0.508542 +0.5,0.213415,0,0.526776 +0.5,0.22561,0,0.547752 +0.5,0.237805,0,0.564004 +0.5,0.25,0,0.582569 +0.5,0.262195,0,0.596895 +0.5,0.27439,0,0.613127 +0.5,0.286585,0,0.625587 +0.5,0.298781,0,0.639569 +0.5,0.310976,0,0.65023 +0.5,0.323171,0,0.662052 +0.5,0.335366,0,0.670983 +0.5,0.347561,0,0.680743 +0.5,0.359756,0,0.688023 +0.5,0.371951,0,0.695825 +0.5,0.384146,0,0.701541 +0.5,0.396341,0,0.707505 +0.5,0.408537,0,0.711756 +0.5,0.420732,0,0.716015 +0.5,0.432927,0,0.718917 +0.5,0.445122,0,0.721631 +0.5,0.457317,0,0.723326 +0.5,0.469512,0,0.724694 +0.5,0.481707,0,0.725375 +0.5,0.493902,0,0.725687 +0.5,0.506098,0,0.725687 +0.5,0.518293,0,0.725375 +0.5,0.530488,0,0.724694 +0.5,0.542683,0,0.723326 +0.5,0.554878,0,0.721631 +0.5,0.567073,0,0.718917 +0.5,0.579268,0,0.716015 +0.5,0.591463,0,0.711756 +0.5,0.603659,0,0.707505 +0.5,0.615854,0,0.701541 +0.5,0.628049,0,0.695825 +0.5,0.640244,0,0.688023 +0.5,0.652439,0,0.680743 +0.5,0.664634,0,0.670983 +0.5,0.676829,0,0.662052 +0.5,0.689024,0,0.65023 +0.5,0.701219,0,0.63957 +0.5,0.713415,0,0.625587 +0.5,0.72561,0,0.613127 +0.5,0.737805,0,0.596895 +0.5,0.75,0,0.582569 +0.5,0.762195,0,0.564004 +0.5,0.77439,0,0.547752 +0.5,0.786585,0,0.526776 +0.5,0.798781,0,0.508542 +0.5,0.810976,0,0.485078 +0.5,0.823171,0,0.46481 +0.5,0.835366,0,0.438789 +0.5,0.847561,0,0.416437 +0.5,0.859756,0,0.387789 +0.5,0.871951,0,0.363308 +0.5,0.884146,0,0.331967 +0.5,0.896341,0,0.305313 +0.5,0.908537,0,0.271215 +0.5,0.920732,0,0.242348 +0.5,0.932927,0,0.20543 +0.5,0.945122,0,0.174313 +0.5,0.957317,0,0.134514 +0.5,0.969512,0,0.101109 +0.5,0.981707,0,0.0583757 +0.5,1,0,nan diff --git a/examples/2D_poiseuille_nn/velocity_1.0.csv b/examples/2D_poiseuille_nn/velocity_1.0.csv new file mode 100644 index 0000000000..befbf5b50f --- /dev/null +++ b/examples/2D_poiseuille_nn/velocity_1.0.csv @@ -0,0 +1,83 @@ +Points_0,Points_1,Points_2,vel1 +0.5,0,0,0.017793 +0.5,0.0182927,0,0.0425431 +0.5,0.0304878,0,0.0763191 +0.5,0.0426829,0,0.0999762 +0.5,0.054878,0,0.131908 +0.5,0.0670732,0,0.154428 +0.5,0.0792683,0,0.184533 +0.5,0.0914634,0,0.205896 +0.5,0.103659,0,0.234193 +0.5,0.115854,0,0.254382 +0.5,0.128049,0,0.280885 +0.5,0.140244,0,0.299887 +0.5,0.152439,0,0.324611 +0.5,0.164634,0,0.342411 +0.5,0.176829,0,0.365368 +0.5,0.189024,0,0.381955 +0.5,0.20122,0,0.403156 +0.5,0.213415,0,0.41852 +0.5,0.22561,0,0.437975 +0.5,0.237805,0,0.452105 +0.5,0.25,0,0.469825 +0.5,0.262195,0,0.482712 +0.5,0.27439,0,0.498704 +0.5,0.286585,0,0.510341 +0.5,0.298781,0,0.524613 +0.5,0.310976,0,0.534991 +0.5,0.323171,0,0.547552 +0.5,0.335366,0,0.556663 +0.5,0.347561,0,0.567521 +0.5,0.359756,0,0.575357 +0.5,0.371951,0,0.584519 +0.5,0.384146,0,0.591073 +0.5,0.396341,0,0.598546 +0.5,0.408537,0,0.60381 +0.5,0.420732,0,0.609604 +0.5,0.432927,0,0.613569 +0.5,0.445122,0,0.617692 +0.5,0.457317,0,0.620348 +0.5,0.469512,0,0.622812 +0.5,0.481707,0,0.624145 +0.5,0.493902,0,0.624963 +0.5,0.506098,0,0.624963 +0.5,0.518293,0,0.624145 +0.5,0.530488,0,0.622812 +0.5,0.542683,0,0.620348 +0.5,0.554878,0,0.617692 +0.5,0.567073,0,0.613569 +0.5,0.579268,0,0.609604 +0.5,0.591463,0,0.60381 +0.5,0.603659,0,0.598546 +0.5,0.615854,0,0.591073 +0.5,0.628049,0,0.584519 +0.5,0.640244,0,0.575357 +0.5,0.652439,0,0.567521 +0.5,0.664634,0,0.556663 +0.5,0.676829,0,0.547552 +0.5,0.689024,0,0.534991 +0.5,0.701219,0,0.524613 +0.5,0.713415,0,0.510341 +0.5,0.72561,0,0.498704 +0.5,0.737805,0,0.482712 +0.5,0.75,0,0.469825 +0.5,0.762195,0,0.452105 +0.5,0.77439,0,0.437975 +0.5,0.786585,0,0.41852 +0.5,0.798781,0,0.403156 +0.5,0.810976,0,0.381955 +0.5,0.823171,0,0.365368 +0.5,0.835366,0,0.342411 +0.5,0.847561,0,0.324611 +0.5,0.859756,0,0.299887 +0.5,0.871951,0,0.280885 +0.5,0.884146,0,0.254382 +0.5,0.896341,0,0.234193 +0.5,0.908537,0,0.205896 +0.5,0.920732,0,0.184533 +0.5,0.932927,0,0.154428 +0.5,0.945122,0,0.131908 +0.5,0.957317,0,0.0999762 +0.5,0.969512,0,0.0763191 +0.5,0.981707,0,0.0425431 +0.5,1,0,nan diff --git a/examples/2D_poiseuille_nn/velocity_1.25.csv b/examples/2D_poiseuille_nn/velocity_1.25.csv new file mode 100644 index 0000000000..7ee6089c96 --- /dev/null +++ b/examples/2D_poiseuille_nn/velocity_1.25.csv @@ -0,0 +1,83 @@ +Points_0,Points_1,Points_2,vel1 +0.5,0,0,0.022313 +0.5,0.0182927,0,0.0282156 +0.5,0.0304878,0,0.071155 +0.5,0.0426829,0,0.0769046 +0.5,0.054878,0,0.118003 +0.5,0.0670732,0,0.123595 +0.5,0.0792683,0,0.161767 +0.5,0.0914634,0,0.170789 +0.5,0.103659,0,0.201364 +0.5,0.115854,0,0.21596 +0.5,0.128049,0,0.241107 +0.5,0.140244,0,0.256518 +0.5,0.152439,0,0.279824 +0.5,0.164634,0,0.294712 +0.5,0.176829,0,0.316481 +0.5,0.189024,0,0.330717 +0.5,0.20122,0,0.351011 +0.5,0.213415,0,0.364516 +0.5,0.22561,0,0.383366 +0.5,0.237805,0,0.396083 +0.5,0.25,0,0.413505 +0.5,0.262195,0,0.425382 +0.5,0.27439,0,0.441379 +0.5,0.286585,0,0.452372 +0.5,0.298781,0,0.466939 +0.5,0.310976,0,0.477005 +0.5,0.323171,0,0.490128 +0.5,0.335366,0,0.499225 +0.5,0.347561,0,0.510884 +0.5,0.359756,0,0.518966 +0.5,0.371951,0,0.529131 +0.5,0.384146,0,0.536148 +0.5,0.396341,0,0.544777 +0.5,0.408537,0,0.550672 +0.5,0.420732,0,0.55771 +0.5,0.432927,0,0.562409 +0.5,0.445122,0,0.567776 +0.5,0.457317,0,0.57118 +0.5,0.469512,0,0.574754 +0.5,0.481707,0,0.576699 +0.5,0.493902,0,0.578266 +0.5,0.506098,0,0.578266 +0.5,0.518293,0,0.576699 +0.5,0.530488,0,0.574754 +0.5,0.542683,0,0.57118 +0.5,0.554878,0,0.567776 +0.5,0.567073,0,0.562409 +0.5,0.579268,0,0.55771 +0.5,0.591463,0,0.550672 +0.5,0.603659,0,0.544777 +0.5,0.615854,0,0.536148 +0.5,0.628049,0,0.529131 +0.5,0.640244,0,0.518966 +0.5,0.652439,0,0.510884 +0.5,0.664634,0,0.499225 +0.5,0.676829,0,0.490128 +0.5,0.689024,0,0.477005 +0.5,0.701219,0,0.466939 +0.5,0.713415,0,0.452372 +0.5,0.72561,0,0.441379 +0.5,0.737805,0,0.425382 +0.5,0.75,0,0.413505 +0.5,0.762195,0,0.396083 +0.5,0.77439,0,0.383366 +0.5,0.786585,0,0.364516 +0.5,0.798781,0,0.351011 +0.5,0.810976,0,0.330717 +0.5,0.823171,0,0.316481 +0.5,0.835366,0,0.294712 +0.5,0.847561,0,0.279824 +0.5,0.859756,0,0.256518 +0.5,0.871951,0,0.241107 +0.5,0.884146,0,0.21596 +0.5,0.896341,0,0.201364 +0.5,0.908537,0,0.170789 +0.5,0.920732,0,0.161767 +0.5,0.932927,0,0.123595 +0.5,0.945122,0,0.118003 +0.5,0.957317,0,0.0769046 +0.5,0.969512,0,0.071155 +0.5,0.981707,0,0.0282156 +0.5,1,0,nan diff --git a/examples/2D_poiseuille_nn/velocity_1.5.csv b/examples/2D_poiseuille_nn/velocity_1.5.csv new file mode 100644 index 0000000000..70b7a238a0 --- /dev/null +++ b/examples/2D_poiseuille_nn/velocity_1.5.csv @@ -0,0 +1,83 @@ +Points_0,Points_1,Points_2,vel1 +0.5,0,0,0.0620315 +0.5,0.0182927,0,0.140214 +0.5,0.0304878,0,0.258876 +0.5,0.0426829,0,0.335437 +0.5,0.054878,0,0.448953 +0.5,0.0670732,0,0.523516 +0.5,0.0792683,0,0.632039 +0.5,0.0914634,0,0.704373 +0.5,0.103659,0,0.807998 +0.5,0.115854,0,0.877916 +0.5,0.128049,0,0.976695 +0.5,0.140244,0,1.04403 +0.5,0.152439,0,1.13799 +0.5,0.164634,0,1.2026 +0.5,0.176829,0,1.29172 +0.5,0.189024,0,1.35348 +0.5,0.20122,0,1.43774 +0.5,0.213415,0,1.4965 +0.5,0.22561,0,1.57585 +0.5,0.237805,0,1.63148 +0.5,0.25,0,1.70586 +0.5,0.262195,0,1.75822 +0.5,0.27439,0,1.82753 +0.5,0.286585,0,1.87647 +0.5,0.298781,0,1.94059 +0.5,0.310976,0,1.98595 +0.5,0.323171,0,2.04474 +0.5,0.335366,0,2.08633 +0.5,0.347561,0,2.13961 +0.5,0.359756,0,2.17721 +0.5,0.371951,0,2.22474 +0.5,0.384146,0,2.25811 +0.5,0.396341,0,2.29958 +0.5,0.408537,0,2.32838 +0.5,0.420732,0,2.3634 +0.5,0.432927,0,2.38719 +0.5,0.445122,0,2.41516 +0.5,0.457317,0,2.43328 +0.5,0.469512,0,2.45327 +0.5,0.481707,0,2.46458 +0.5,0.493902,0,2.47501 +0.5,0.506098,0,2.47501 +0.5,0.518293,0,2.46458 +0.5,0.530488,0,2.45327 +0.5,0.542683,0,2.43328 +0.5,0.554878,0,2.41516 +0.5,0.567073,0,2.38719 +0.5,0.579268,0,2.3634 +0.5,0.591463,0,2.32838 +0.5,0.603659,0,2.29958 +0.5,0.615854,0,2.25811 +0.5,0.628049,0,2.22474 +0.5,0.640244,0,2.17721 +0.5,0.652439,0,2.13961 +0.5,0.664634,0,2.08633 +0.5,0.676829,0,2.04474 +0.5,0.689024,0,1.98595 +0.5,0.701219,0,1.94059 +0.5,0.713415,0,1.87647 +0.5,0.72561,0,1.82753 +0.5,0.737805,0,1.75822 +0.5,0.75,0,1.70586 +0.5,0.762195,0,1.63148 +0.5,0.77439,0,1.57585 +0.5,0.786585,0,1.4965 +0.5,0.798781,0,1.43774 +0.5,0.810976,0,1.35348 +0.5,0.823171,0,1.29172 +0.5,0.835366,0,1.2026 +0.5,0.847561,0,1.13799 +0.5,0.859756,0,1.04403 +0.5,0.871951,0,0.976695 +0.5,0.884146,0,0.877916 +0.5,0.896341,0,0.807998 +0.5,0.908537,0,0.704373 +0.5,0.920732,0,0.632039 +0.5,0.932927,0,0.523516 +0.5,0.945122,0,0.448953 +0.5,0.957317,0,0.335438 +0.5,0.969512,0,0.258876 +0.5,0.981707,0,0.140214 +0.5,1,0,nan diff --git a/examples/2D_poiseuille_nn/velocity_1.75.csv b/examples/2D_poiseuille_nn/velocity_1.75.csv new file mode 100644 index 0000000000..8c042c9217 --- /dev/null +++ b/examples/2D_poiseuille_nn/velocity_1.75.csv @@ -0,0 +1,83 @@ +Points_0,Points_1,Points_2,vel1 +0.5,0,0,0.0177912 +0.5,0.0182927,0,0.0234005 +0.5,0.0304878,0,0.0559056 +0.5,0.0426829,0,0.0663383 +0.5,0.054878,0,0.0928299 +0.5,0.0670732,0,0.106361 +0.5,0.0792683,0,0.12996 +0.5,0.0914634,0,0.14401 +0.5,0.103659,0,0.166409 +0.5,0.115854,0,0.180259 +0.5,0.128049,0,0.201647 +0.5,0.140244,0,0.21519 +0.5,0.152439,0,0.235607 +0.5,0.164634,0,0.24878 +0.5,0.176829,0,0.268242 +0.5,0.189024,0,0.280993 +0.5,0.20122,0,0.299505 +0.5,0.213415,0,0.311789 +0.5,0.22561,0,0.329345 +0.5,0.237805,0,0.34112 +0.5,0.25,0,0.357708 +0.5,0.262195,0,0.368932 +0.5,0.27439,0,0.38453 +0.5,0.286585,0,0.395161 +0.5,0.298781,0,0.409742 +0.5,0.310976,0,0.419732 +0.5,0.323171,0,0.43326 +0.5,0.335366,0,0.442559 +0.5,0.347561,0,0.454988 +0.5,0.359756,0,0.463537 +0.5,0.371951,0,0.474804 +0.5,0.384146,0,0.482533 +0.5,0.396341,0,0.49256 +0.5,0.408537,0,0.49938 +0.5,0.420732,0,0.508057 +0.5,0.432927,0,0.513847 +0.5,0.445122,0,0.521014 +0.5,0.457317,0,0.525594 +0.5,0.469512,0,0.53098 +0.5,0.481707,0,0.534027 +0.5,0.493902,0,0.537185 +0.5,0.506098,0,0.537185 +0.5,0.518293,0,0.534027 +0.5,0.530488,0,0.53098 +0.5,0.542683,0,0.525594 +0.5,0.554878,0,0.521014 +0.5,0.567073,0,0.513847 +0.5,0.579268,0,0.508057 +0.5,0.591463,0,0.49938 +0.5,0.603659,0,0.49256 +0.5,0.615854,0,0.482533 +0.5,0.628049,0,0.474804 +0.5,0.640244,0,0.463537 +0.5,0.652439,0,0.454988 +0.5,0.664634,0,0.442559 +0.5,0.676829,0,0.43326 +0.5,0.689024,0,0.419732 +0.5,0.701219,0,0.409742 +0.5,0.713415,0,0.395161 +0.5,0.72561,0,0.38453 +0.5,0.737805,0,0.368932 +0.5,0.75,0,0.357708 +0.5,0.762195,0,0.34112 +0.5,0.77439,0,0.329345 +0.5,0.786585,0,0.311789 +0.5,0.798781,0,0.299505 +0.5,0.810976,0,0.280993 +0.5,0.823171,0,0.268242 +0.5,0.835366,0,0.24878 +0.5,0.847561,0,0.235607 +0.5,0.859756,0,0.21519 +0.5,0.871951,0,0.201647 +0.5,0.884146,0,0.180259 +0.5,0.896341,0,0.166409 +0.5,0.908537,0,0.14401 +0.5,0.920732,0,0.12996 +0.5,0.932927,0,0.106361 +0.5,0.945122,0,0.0928298 +0.5,0.957317,0,0.0663383 +0.5,0.969512,0,0.0559056 +0.5,0.981707,0,0.0234005 +0.5,1,0,nan diff --git a/examples/2D_poiseuille_nn/velocity_2.0.csv b/examples/2D_poiseuille_nn/velocity_2.0.csv new file mode 100644 index 0000000000..9e1971037c --- /dev/null +++ b/examples/2D_poiseuille_nn/velocity_2.0.csv @@ -0,0 +1,83 @@ +Points_0,Points_1,Points_2,vel1 +0.5,0,0,0.0166349 +0.5,0.0182927,0,0.0218547 +0.5,0.0304878,0,0.0542806 +0.5,0.0426829,0,0.0594262 +0.5,0.054878,0,0.0909551 +0.5,0.0670732,0,0.0960212 +0.5,0.0792683,0,0.126627 +0.5,0.0914634,0,0.13161 +0.5,0.103659,0,0.16129 +0.5,0.115854,0,0.166218 +0.5,0.128049,0,0.19418 +0.5,0.140244,0,0.200771 +0.5,0.152439,0,0.22512 +0.5,0.164634,0,0.234854 +0.5,0.176829,0,0.255533 +0.5,0.189024,0,0.266594 +0.5,0.20122,0,0.285514 +0.5,0.213415,0,0.296644 +0.5,0.22561,0,0.314511 +0.5,0.237805,0,0.32538 +0.5,0.25,0,0.342281 +0.5,0.262195,0,0.35279 +0.5,0.27439,0,0.368741 +0.5,0.286585,0,0.378821 +0.5,0.298781,0,0.393813 +0.5,0.310976,0,0.403401 +0.5,0.323171,0,0.41741 +0.5,0.335366,0,0.426445 +0.5,0.347561,0,0.439428 +0.5,0.359756,0,0.447844 +0.5,0.371951,0,0.459744 +0.5,0.384146,0,0.467465 +0.5,0.396341,0,0.478197 +0.5,0.408537,0,0.485131 +0.5,0.420732,0,0.494577 +0.5,0.432927,0,0.500596 +0.5,0.445122,0,0.508577 +0.5,0.457317,0,0.51349 +0.5,0.469512,0,0.519692 +0.5,0.481707,0,0.523146 +0.5,0.493902,0,0.527086 +0.5,0.506098,0,0.527086 +0.5,0.518293,0,0.523146 +0.5,0.530488,0,0.519692 +0.5,0.542683,0,0.51349 +0.5,0.554878,0,0.508577 +0.5,0.567073,0,0.500596 +0.5,0.579268,0,0.494577 +0.5,0.591463,0,0.485131 +0.5,0.603659,0,0.478197 +0.5,0.615854,0,0.467465 +0.5,0.628049,0,0.459744 +0.5,0.640244,0,0.447844 +0.5,0.652439,0,0.439428 +0.5,0.664634,0,0.426445 +0.5,0.676829,0,0.41741 +0.5,0.689024,0,0.403401 +0.5,0.701219,0,0.393813 +0.5,0.713415,0,0.378821 +0.5,0.72561,0,0.368741 +0.5,0.737805,0,0.35279 +0.5,0.75,0,0.342281 +0.5,0.762195,0,0.32538 +0.5,0.77439,0,0.314511 +0.5,0.786585,0,0.296644 +0.5,0.798781,0,0.285514 +0.5,0.810976,0,0.266594 +0.5,0.823171,0,0.255533 +0.5,0.835366,0,0.234854 +0.5,0.847561,0,0.22512 +0.5,0.859756,0,0.200771 +0.5,0.871951,0,0.19418 +0.5,0.884146,0,0.166218 +0.5,0.896341,0,0.16129 +0.5,0.908537,0,0.13161 +0.5,0.920732,0,0.126627 +0.5,0.932927,0,0.0960212 +0.5,0.945122,0,0.0909551 +0.5,0.957317,0,0.0594262 +0.5,0.969512,0,0.0542805 +0.5,0.981707,0,0.0218547 +0.5,1,0,nan diff --git a/examples/2D_poiseuille_nn/velocity_profile.png b/examples/2D_poiseuille_nn/velocity_profile.png new file mode 100644 index 0000000000000000000000000000000000000000..eac48fa148049bdff209d8f4d1ddbb9b3f44f228 GIT binary patch literal 74689 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𝔬&Gz>9tuAJhfGxD`IF$a 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%0D;vrH#WFsd6jrS*Te9_i)u^1O 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 i@z)tnx8Z+whW80IWeb( Derived type annexing the physical parameters required for sub-grid bubble models diff --git a/src/post_process/m_global_parameters.fpp b/src/post_process/m_global_parameters.fpp index 219667a158..f842cc5bd7 100644 --- a/src/post_process/m_global_parameters.fpp +++ b/src/post_process/m_global_parameters.fpp @@ -434,6 +434,14 @@ contains fluid_pp(i)%qv = 0._wp fluid_pp(i)%qvp = 0._wp fluid_pp(i)%G = dflt_real + fluid_pp(i)%non_newtonian = .false. + fluid_pp(i)%tau0 = 0._wp + fluid_pp(i)%K = 0._wp + fluid_pp(i)%nn = 1._wp + fluid_pp(i)%mu_max = dflt_real + fluid_pp(i)%mu_min = 0._wp + fluid_pp(i)%mu_bulk = 0._wp + fluid_pp(i)%hb_m = 1000._wp end do ! Subgrid bubble parameters diff --git a/src/post_process/m_mpi_proxy.fpp b/src/post_process/m_mpi_proxy.fpp index 29e65942c6..a019d33f86 100644 --- a/src/post_process/m_mpi_proxy.fpp +++ b/src/post_process/m_mpi_proxy.fpp @@ -130,6 +130,10 @@ contains call MPI_BCAST(fluid_pp(i)%qv, 1, mpi_p, 0, MPI_COMM_WORLD, ierr) call MPI_BCAST(fluid_pp(i)%qvp, 1, mpi_p, 0, MPI_COMM_WORLD, ierr) call MPI_BCAST(fluid_pp(i)%G, 1, mpi_p, 0, MPI_COMM_WORLD, ierr) + call MPI_BCAST(fluid_pp(i)%non_newtonian, 1, MPI_LOGICAL, 0, MPI_COMM_WORLD, ierr) + #:for VAR in ['tau0', 'K', 'nn', 'mu_max', 'mu_min', 'mu_bulk', 'hb_m'] + call MPI_BCAST(fluid_pp(i)%${VAR}$, 1, mpi_p, 0, MPI_COMM_WORLD, ierr) + #:endfor end do ! Subgrid bubble parameters diff --git a/src/pre_process/m_global_parameters.fpp b/src/pre_process/m_global_parameters.fpp index 11fa95e124..1df860d2b4 100644 --- a/src/pre_process/m_global_parameters.fpp +++ b/src/pre_process/m_global_parameters.fpp @@ -592,6 +592,14 @@ contains fluid_pp(i)%qv = 0._wp fluid_pp(i)%qvp = 0._wp fluid_pp(i)%G = 0._wp + fluid_pp(i)%non_newtonian = .false. + fluid_pp(i)%tau0 = 0._wp + fluid_pp(i)%K = 0._wp + fluid_pp(i)%nn = 1._wp + fluid_pp(i)%mu_max = dflt_real + fluid_pp(i)%mu_min = 0._wp + fluid_pp(i)%mu_bulk = 0._wp + fluid_pp(i)%hb_m = 1000._wp end do Bx0 = dflt_real diff --git a/src/pre_process/m_mpi_proxy.fpp b/src/pre_process/m_mpi_proxy.fpp index cbfac0571b..6225ac0222 100644 --- a/src/pre_process/m_mpi_proxy.fpp +++ b/src/pre_process/m_mpi_proxy.fpp @@ -143,6 +143,11 @@ contains call MPI_BCAST(fluid_pp(i)%${VAR}$, 1, mpi_p, 0, MPI_COMM_WORLD, ierr) #:endfor + call MPI_BCAST(fluid_pp(i)%non_newtonian, 1, MPI_LOGICAL, 0, MPI_COMM_WORLD, ierr) + #:for VAR in ['tau0', 'K', 'nn', 'mu_max', 'mu_min', 'mu_bulk', 'hb_m'] + call MPI_BCAST(fluid_pp(i)%${VAR}$, 1, mpi_p, 0, MPI_COMM_WORLD, ierr) + #:endfor + call MPI_BCAST(simplex_params%perturb_dens(i), 1, MPI_LOGICAL, 0, MPI_COMM_WORLD, ierr) call MPI_BCAST(simplex_params%perturb_dens_freq(i), 1, mpi_p, 0, MPI_COMM_WORLD, ierr) call MPI_BCAST(simplex_params%perturb_dens_scale(i), 1, mpi_p, 0, MPI_COMM_WORLD, ierr) diff --git a/src/simulation/m_checker.fpp b/src/simulation/m_checker.fpp index ed694c449d..3c44b7d7a1 100644 --- a/src/simulation/m_checker.fpp +++ b/src/simulation/m_checker.fpp @@ -39,6 +39,7 @@ contains end if call s_check_inputs_time_stepping + call s_check_inputs_non_newtonian end subroutine s_check_inputs @@ -91,4 +92,30 @@ contains #endif end subroutine s_check_inputs_nvidia_uvm + !> Checks constraints on non-Newtonian fluid parameters + impure subroutine s_check_inputs_non_newtonian + integer :: i + + do i = 1, num_fluids + if (fluid_pp(i)%non_newtonian) then + @:PROHIBIT(.not. viscous, & + "Non-Newtonian fluid requires viscosity to be enabled") + @:PROHIBIT(fluid_pp(i)%K <= 0._wp, & + "Non-Newtonian fluid consistency index K must be > 0") + @:PROHIBIT(fluid_pp(i)%nn <= 0._wp, & + "Non-Newtonian fluid flow behavior index nn must be > 0") + @:PROHIBIT(fluid_pp(i)%tau0 < 0._wp, & + "Non-Newtonian fluid yield stress tau0 must be >= 0") + @:PROHIBIT(fluid_pp(i)%mu_min < 0._wp, & + "Non-Newtonian fluid mu_min must be >= 0") + @:PROHIBIT(fluid_pp(i)%mu_max < dflt_real .and. & + fluid_pp(i)%mu_max <= fluid_pp(i)%mu_min, & + "Non-Newtonian fluid mu_max must be > mu_min when set") + @:PROHIBIT(fluid_pp(i)%hb_m <= 0._wp, & + "Non-Newtonian Papanastasiou parameter hb_m must be > 0") + end if + end do + + end subroutine s_check_inputs_non_newtonian + end module m_checker diff --git a/src/simulation/m_data_output.fpp b/src/simulation/m_data_output.fpp index 068fcb38b1..83498bf851 100644 --- a/src/simulation/m_data_output.fpp +++ b/src/simulation/m_data_output.fpp @@ -1,1974 +1,1984 @@ -!> -!! @file -!! @brief Contains module m_data_output - -#:include 'macros.fpp' -#:include 'case.fpp' - -!> @brief Writes solution data, run-time stability diagnostics (ICFL, VCFL, CCFL, Rc), and probe/center-of-mass files -module m_data_output - - use m_derived_types !< Definitions of the derived types - - use m_global_parameters !< Definitions of the global parameters - - use m_mpi_proxy !< Message passing interface (MPI) module proxy - - use m_variables_conversion !< State variables type conversion procedures - - use m_compile_specific - - use m_helper - - use m_helper_basic !< Functions to compare floating point numbers - - use m_sim_helpers - - use m_delay_file_access - - use m_ibm - - use m_boundary_common - - implicit none - - private; - public :: s_initialize_data_output_module, & - s_open_run_time_information_file, & - s_open_com_files, & - s_open_probe_files, & - s_write_run_time_information, & - s_write_data_files, & - s_write_serial_data_files, & - s_write_parallel_data_files, & - s_write_com_files, & - s_write_probe_files, & - s_close_run_time_information_file, & - s_close_com_files, & - s_close_probe_files, & - s_finalize_data_output_module, & - s_write_ib_data_file - - real(wp), allocatable, dimension(:, :, :) :: icfl_sf !< ICFL stability criterion - real(wp), allocatable, dimension(:, :, :) :: vcfl_sf !< VCFL stability criterion - real(wp), allocatable, dimension(:, :, :) :: ccfl_sf !< CCFL stability criterion - real(wp), allocatable, dimension(:, :, :) :: Rc_sf !< Rc stability criterion - real(wp), public, allocatable, dimension(:, :) :: c_mass - $:GPU_DECLARE(create='[icfl_sf,vcfl_sf,ccfl_sf,Rc_sf,c_mass]') - - real(wp) :: icfl_max_loc, icfl_max_glb !< ICFL stability extrema on local and global grids - real(wp) :: vcfl_max_loc, vcfl_max_glb !< VCFL stability extrema on local and global grids - real(wp) :: ccfl_max_loc, ccfl_max_glb !< CCFL stability extrema on local and global grids - real(wp) :: Rc_min_loc, Rc_min_glb !< Rc stability extrema on local and global grids - $:GPU_DECLARE(create='[icfl_max_loc,icfl_max_glb,vcfl_max_loc,vcfl_max_glb]') - $:GPU_DECLARE(create='[ccfl_max_loc,ccfl_max_glb,Rc_min_loc,Rc_min_glb]') - - !> @name ICFL, VCFL, CCFL and Rc stability criteria extrema over all the time-steps - !> @{ - real(wp) :: icfl_max !< ICFL criterion maximum - real(wp) :: vcfl_max !< VCFL criterion maximum - real(wp) :: ccfl_max !< CCFL criterion maximum - real(wp) :: Rc_min !< Rc criterion maximum - !> @} - - type(scalar_field), allocatable, dimension(:) :: q_cons_temp_ds - -contains - - !> Write data files. Dispatch subroutine that replaces procedure pointer. - !! @param q_cons_vf Conservative variables - !! @param q_T_sf Temperature scalar field - !! @param q_prim_vf Primitive variables - !! @param t_step Current time step - !! @param bc_type Boundary condition type - !! @param beta Eulerian void fraction from lagrangian bubbles - impure subroutine s_write_data_files(q_cons_vf, q_T_sf, q_prim_vf, t_step, bc_type, beta) - - type(scalar_field), & - dimension(sys_size), & - intent(inout) :: q_cons_vf - - type(scalar_field), & - intent(inout) :: q_T_sf - - type(scalar_field), & - dimension(sys_size), & - intent(inout) :: q_prim_vf - - integer, intent(in) :: t_step - - type(scalar_field), & - intent(inout), optional :: beta - - type(integer_field), & - dimension(1:num_dims, -1:1), & - intent(in) :: bc_type - - if (.not. parallel_io) then - call s_write_serial_data_files(q_cons_vf, q_T_sf, q_prim_vf, t_step, bc_type, beta) - else - call s_write_parallel_data_files(q_cons_vf, t_step, bc_type, beta) - end if - - end subroutine s_write_data_files - - !> The purpose of this subroutine is to open a new or pre- - !! existing run-time information file and append to it the - !! basic header information relevant to current simulation. - !! In general, this requires generating a table header for - !! those stability criteria which will be written at every - !! time-step. - impure subroutine s_open_run_time_information_file - - character(LEN=name_len), parameter :: file_name = 'run_time.inf' !< - !! Name of the run-time information file - - character(LEN=path_len + name_len) :: file_path !< - !! Relative path to a file in the case directory - - character(LEN=8) :: file_date !< - !! Creation date of the run-time information file - - ! Opening the run-time information file - file_path = trim(case_dir)//'/'//trim(file_name) - - open (3, FILE=trim(file_path), & - FORM='formatted', & - STATUS='replace') - - write (3, '(A)') 'Description: Stability information at '// & - 'each time-step of the simulation. This' - write (3, '(13X,A)') 'data is composed of the inviscid '// & - 'Courant–Friedrichs–Lewy (ICFL)' - write (3, '(13X,A)') 'number, the viscous CFL (VCFL) number, '// & - 'the capillary CFL (CCFL)' - write (3, '(13X,A)') 'number and the cell Reynolds (Rc) '// & - 'number. Please note that only' - write (3, '(13X,A)') 'those stability conditions pertinent '// & - 'to the physics included in' - write (3, '(13X,A)') 'the current computation are displayed.' - - call date_and_time(DATE=file_date) - - write (3, '(A)') 'Date: '//file_date(5:6)//'/'// & - file_date(7:8)//'/'// & - file_date(3:4) - - write (3, '(A)') ''; write (3, '(A)') '' - - ! Generating table header for the stability criteria to be outputted - write (3, '(13X,A9,13X,A10,13X,A10,13X,A10)', advance="no") & - trim('Time-step'), trim('dt'), trim('Time'), trim('ICFL Max') - - if (viscous) then - write (3, '(13X,A10,13X,A16)', advance="no") & - trim('VCFL Max'), trim('Rc Min') - end if - - write (3, *) ! new line - - end subroutine s_open_run_time_information_file - - !> This opens a formatted data file where the root processor - !! can write out the CoM information - impure subroutine s_open_com_files() - - character(len=path_len + 3*name_len) :: file_path !< - !! Relative path to the CoM file in the case directory - integer :: i !< Generic loop iterator - - do i = 1, num_fluids - ! Generating the relative path to the CoM data file - write (file_path, '(A,I0,A)') '/fluid', i, '_com.dat' - file_path = trim(case_dir)//trim(file_path) - ! Creating the formatted data file and setting up its - ! structure - open (i + 120, file=trim(file_path), & - form='formatted', & - position='append', & - status='unknown') - if (n == 0) then - write (i + 120, '(A)') ' Non-Dimensional Time '// & - ' Total Mass '// & - ' x-loc '// & - ' Total Volume ' - elseif (p == 0) then - write (i + 120, '(A)') ' Non-Dimensional Time '// & - ' Total Mass '// & - ' x-loc '// & - ' y-loc '// & - ' Total Volume ' - else - write (i + 120, '(A)') ' Non-Dimensional Time '// & - ' Total Mass '// & - ' x-loc '// & - ' y-loc '// & - ' z-loc '// & - ' Total Volume ' - end if - end do - end subroutine s_open_com_files - - !> This opens a formatted data file where the root processor - !! can write out flow probe information - impure subroutine s_open_probe_files - - character(LEN=path_len + 3*name_len) :: file_path !< - !! Relative path to the probe data file in the case directory - - integer :: i !< Generic loop iterator - logical :: file_exist - - do i = 1, num_probes - ! Generating the relative path to the data file - write (file_path, '(A,I0,A)') '/D/probe', i, '_prim.dat' - file_path = trim(case_dir)//trim(file_path) - - ! Creating the formatted data file and setting up its - ! structure - inquire (file=trim(file_path), exist=file_exist) - - if (file_exist) then - open (i + 30, FILE=trim(file_path), & - FORM='formatted', & - STATUS='old', & - POSITION='append') - else - open (i + 30, FILE=trim(file_path), & - FORM='formatted', & - STATUS='unknown') - end if - end do - - if (integral_wrt) then - do i = 1, num_integrals - write (file_path, '(A,I0,A)') '/D/integral', i, '_prim.dat' - file_path = trim(case_dir)//trim(file_path) - - open (i + 70, FILE=trim(file_path), & - FORM='formatted', & - POSITION='append', & - STATUS='unknown') - end do - end if - - end subroutine s_open_probe_files - - !> The goal of the procedure is to output to the run-time - !! information file the stability criteria extrema in the - !! entire computational domain and at the given time-step. - !! Moreover, the subroutine is also in charge of tracking - !! these stability criteria extrema over all time-steps. - !! @param q_prim_vf Cell-average primitive variables - !! @param t_step Current time step - impure subroutine s_write_run_time_information(q_prim_vf, t_step) - - type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf - integer, intent(in) :: t_step - - real(wp) :: rho !< Cell-avg. density - #:if not MFC_CASE_OPTIMIZATION and USING_AMD - real(wp), dimension(3) :: alpha !< Cell-avg. volume fraction - real(wp), dimension(3) :: vel !< Cell-avg. velocity - #:else - real(wp), dimension(num_fluids) :: alpha !< Cell-avg. volume fraction - real(wp), dimension(num_vels) :: vel !< Cell-avg. velocity - #:endif - real(wp) :: vel_sum !< Cell-avg. velocity sum - real(wp) :: pres !< Cell-avg. pressure - real(wp) :: gamma !< Cell-avg. sp. heat ratio - real(wp) :: pi_inf !< Cell-avg. liquid stiffness function - real(wp) :: qv !< Cell-avg. internal energy reference value - real(wp) :: c !< Cell-avg. sound speed - real(wp) :: H !< Cell-avg. enthalpy - real(wp), dimension(2) :: Re !< Cell-avg. Reynolds numbers - integer :: j, k, l - - ! Computing Stability Criteria at Current Time-step - $:GPU_PARALLEL_LOOP(collapse=3, private='[j,k,l,vel, alpha, Re, rho, vel_sum, pres, gamma, pi_inf, c, H, qv]') - do l = 0, p - do k = 0, n - do j = 0, m - call s_compute_enthalpy(q_prim_vf, pres, rho, gamma, pi_inf, Re, H, alpha, vel, vel_sum, qv, j, k, l) - - call s_compute_speed_of_sound(pres, rho, gamma, pi_inf, H, alpha, vel_sum, 0._wp, c, qv) - - if (viscous) then - call s_compute_stability_from_dt(vel, c, rho, Re, j, k, l, icfl_sf, vcfl_sf, Rc_sf) - else - call s_compute_stability_from_dt(vel, c, rho, Re, j, k, l, icfl_sf) - end if - - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - - ! end: Computing Stability Criteria at Current Time-step - - ! Determining local stability criteria extrema at current time-step - -#ifdef _CRAYFTN - $:GPU_UPDATE(host='[icfl_sf]') - - if (viscous) then - $:GPU_UPDATE(host='[vcfl_sf,Rc_sf]') - end if - - icfl_max_loc = maxval(icfl_sf) - - if (viscous) then - vcfl_max_loc = maxval(vcfl_sf) - Rc_min_loc = minval(Rc_sf) - end if -#else - #:call GPU_PARALLEL(copyout='[icfl_max_loc]', copyin='[icfl_sf]') - icfl_max_loc = maxval(icfl_sf) - #:endcall GPU_PARALLEL - if (viscous .or. dummy) then - #:call GPU_PARALLEL(copyout='[vcfl_max_loc, Rc_min_loc]', copyin='[vcfl_sf,Rc_sf]') - vcfl_max_loc = maxval(vcfl_sf) - Rc_min_loc = minval(Rc_sf) - #:endcall GPU_PARALLEL - end if -#endif - - ! Determining global stability criteria extrema at current time-step - if (num_procs > 1) then - call s_mpi_reduce_stability_criteria_extrema(icfl_max_loc, & - vcfl_max_loc, & - Rc_min_loc, & - icfl_max_glb, & - vcfl_max_glb, & - Rc_min_glb) - else - icfl_max_glb = icfl_max_loc - if (viscous) vcfl_max_glb = vcfl_max_loc - if (viscous) Rc_min_glb = Rc_min_loc - end if - - ! Determining the stability criteria extrema over all the time-steps - if (icfl_max_glb > icfl_max) icfl_max = icfl_max_glb - - if (viscous) then - if (vcfl_max_glb > vcfl_max) vcfl_max = vcfl_max_glb - if (Rc_min_glb < Rc_min) Rc_min = Rc_min_glb - end if - - ! Outputting global stability criteria extrema at current time-step - if (proc_rank == 0) then - write (3, '(13X,I9,13X,F10.6,13X,F10.6,13X,F10.6)', advance="no") & - t_step, dt, mytime, icfl_max_glb - - if (viscous) then - write (3, '(13X,F10.6,13X,ES16.6)', advance="no") & - vcfl_max_glb, & - Rc_min_glb - end if - - write (3, *) ! new line - - if (.not. f_approx_equal(icfl_max_glb, icfl_max_glb)) then - call s_mpi_abort('ICFL is NaN. Exiting.') - elseif (icfl_max_glb > 1._wp) then - print *, 'icfl', icfl_max_glb - call s_mpi_abort('ICFL is greater than 1.0. Exiting.') - end if - - if (viscous) then - if (.not. f_approx_equal(vcfl_max_glb, vcfl_max_glb)) then - call s_mpi_abort('VCFL is NaN. Exiting.') - elseif (vcfl_max_glb > 1._wp) then - print *, 'vcfl', vcfl_max_glb - call s_mpi_abort('VCFL is greater than 1.0. Exiting.') - end if - end if - end if - - call s_mpi_barrier() - - end subroutine s_write_run_time_information - - !> The goal of this subroutine is to output the grid and - !! conservative variables data files for given time-step. - !! @param q_cons_vf Cell-average conservative variables - !! @param q_T_sf Temperature scalar field - !! @param q_prim_vf Cell-average primitive variables - !! @param t_step Current time-step - !! @param bc_type Boundary condition type - !! @param beta Eulerian void fraction from lagrangian bubbles - impure subroutine s_write_serial_data_files(q_cons_vf, q_T_sf, q_prim_vf, t_step, bc_type, beta) - - type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf - type(scalar_field), intent(inout) :: q_T_sf - type(scalar_field), dimension(sys_size), intent(inout) :: q_prim_vf - integer, intent(in) :: t_step - type(scalar_field), intent(inout), optional :: beta - type(integer_field), dimension(1:num_dims, -1:1), intent(in) :: bc_type - - character(LEN=path_len + 2*name_len) :: t_step_dir !< - !! Relative path to the current time-step directory - - character(LEN=path_len + 3*name_len) :: file_path !< - !! Relative path to the grid and conservative variables data files - - logical :: file_exist !< - !! Logical used to check existence of current time-step directory - - character(LEN=15) :: FMT - - integer :: i, j, k, l, r - - real(wp) :: gamma, lit_gamma, pi_inf, qv !< Temporary EOS params - - ! Creating or overwriting the time-step root directory - write (t_step_dir, '(A,I0,A,I0)') trim(case_dir)//'/p_all' - - ! Creating or overwriting the current time-step directory - write (t_step_dir, '(a,i0,a,i0)') trim(case_dir)//'/p_all/p', & - proc_rank, '/', t_step - - file_path = trim(t_step_dir)//'/.' - call my_inquire(file_path, file_exist) - if (file_exist) call s_delete_directory(trim(t_step_dir)) - call s_create_directory(trim(t_step_dir)) - - ! Writing the grid data file in the x-direction - file_path = trim(t_step_dir)//'/x_cb.dat' - - open (2, FILE=trim(file_path), & - FORM='unformatted', & - STATUS='new') - write (2) x_cb(-1:m); close (2) - - ! Writing the grid data files in the y- and z-directions - if (n > 0) then - - file_path = trim(t_step_dir)//'/y_cb.dat' - - open (2, FILE=trim(file_path), & - FORM='unformatted', & - STATUS='new') - write (2) y_cb(-1:n); close (2) - - if (p > 0) then - - file_path = trim(t_step_dir)//'/z_cb.dat' - - open (2, FILE=trim(file_path), & - FORM='unformatted', & - STATUS='new') - write (2) z_cb(-1:p); close (2) - - end if - - end if - - ! Writing the conservative variables data files - do i = 1, sys_size - write (file_path, '(A,I0,A)') trim(t_step_dir)//'/q_cons_vf', & - i, '.dat' - - open (2, FILE=trim(file_path), & - FORM='unformatted', & - STATUS='new') - - write (2) q_cons_vf(i)%sf(0:m, 0:n, 0:p); close (2) - end do - - ! Lagrangian beta (void fraction) written as q_cons_vf(sys_size+1) to - ! match the parallel I/O path and allow post_process to read it. - if (bubbles_lagrange) then - write (file_path, '(A,I0,A)') trim(t_step_dir)//'/q_cons_vf', & - sys_size + 1, '.dat' - - open (2, FILE=trim(file_path), & - FORM='unformatted', & - STATUS='new') - - write (2) beta%sf(0:m, 0:n, 0:p); close (2) - end if - - if (qbmm .and. .not. polytropic) then - do i = 1, nb - do r = 1, nnode - write (file_path, '(A,I0,A)') trim(t_step_dir)//'/pb', & - sys_size + (i - 1)*nnode + r, '.dat' - - open (2, FILE=trim(file_path), & - FORM='unformatted', & - STATUS='new') - - write (2) pb_ts(1)%sf(0:m, 0:n, 0:p, r, i); close (2) - end do - end do - - do i = 1, nb - do r = 1, nnode - write (file_path, '(A,I0,A)') trim(t_step_dir)//'/mv', & - sys_size + (i - 1)*nnode + r, '.dat' - - open (2, FILE=trim(file_path), & - FORM='unformatted', & - STATUS='new') - - write (2) mv_ts(1)%sf(0:m, 0:n, 0:p, r, i); close (2) - end do - end do - end if - - ! Writing the IB markers - if (ib) then - call s_write_serial_ib_data(t_step) - ! write (file_path, '(A,I0,A)') trim(t_step_dir)//'/ib.dat' - - ! open (2, FILE=trim(file_path), & - ! FORM='unformatted', & - ! STATUS='new') - - ! write (2) ib_markers%sf(0:m, 0:n, 0:p); close (2) - end if - - gamma = gammas(1) - lit_gamma = gs_min(1) - pi_inf = pi_infs(1) - qv = qvs(1) - - if (precision == 1) then - FMT = "(2F30.3)" - else - FMT = "(2F40.14)" - end if - - ! writing an output directory - write (t_step_dir, '(A,I0,A,I0)') trim(case_dir)//'/D' - file_path = trim(t_step_dir)//'/.' - - inquire (FILE=trim(file_path), EXIST=file_exist) - - if (.not. file_exist) call s_create_directory(trim(t_step_dir)) - - if ((prim_vars_wrt .or. (n == 0 .and. p == 0)) .and. (.not. igr)) then - call s_convert_conservative_to_primitive_variables(q_cons_vf, q_T_sf, q_prim_vf, idwint) - do i = 1, sys_size - $:GPU_UPDATE(host='[q_prim_vf(i)%sf(:,:,:)]') - end do - ! q_prim_vf(bubxb) stores the value of nb needed in riemann solvers, so replace with true primitive value (=1._wp) - if (qbmm) then - q_prim_vf(bubxb)%sf = 1._wp - end if - end if - - !1D - if (n == 0 .and. p == 0) then - - if (model_eqns == 2 .and. (.not. igr)) then - do i = 1, sys_size - write (file_path, '(A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir)//'/prim.', i, '.', proc_rank, '.', t_step, '.dat' - - open (2, FILE=trim(file_path)) - do j = 0, m - ! todo: revisit change here - if (((i >= adv_idx%beg) .and. (i <= adv_idx%end))) then - write (2, FMT) x_cb(j), q_cons_vf(i)%sf(j, 0, 0) - else - write (2, FMT) x_cb(j), q_prim_vf(i)%sf(j, 0, 0) - end if - end do - close (2) - end do - end if - - do i = 1, sys_size - write (file_path, '(A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir)//'/cons.', i, '.', proc_rank, '.', t_step, '.dat' - - open (2, FILE=trim(file_path)) - do j = 0, m - write (2, FMT) x_cb(j), q_cons_vf(i)%sf(j, 0, 0) - end do - close (2) - end do - - if (qbmm .and. .not. polytropic) then - do i = 1, nb - do r = 1, nnode - write (file_path, '(A,I0,A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir)//'/pres.', i, '.', r, '.', proc_rank, '.', t_step, '.dat' - - open (2, FILE=trim(file_path)) - do j = 0, m - write (2, FMT) x_cb(j), pb_ts(1)%sf(j, 0, 0, r, i) - end do - close (2) - end do - end do - do i = 1, nb - do r = 1, nnode - write (file_path, '(A,I0,A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir)//'/mv.', i, '.', r, '.', proc_rank, '.', t_step, '.dat' - - open (2, FILE=trim(file_path)) - do j = 0, m - write (2, FMT) x_cb(j), mv_ts(1)%sf(j, 0, 0, r, i) - end do - close (2) - end do - end do - end if - end if - - if (precision == 1) then - FMT = "(3F30.7)" - else - FMT = "(3F40.14)" - end if - - ! 2D - if ((n > 0) .and. (p == 0)) then - do i = 1, sys_size - write (file_path, '(A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir)//'/cons.', i, '.', proc_rank, '.', t_step, '.dat' - open (2, FILE=trim(file_path)) - do j = 0, m - do k = 0, n - write (2, FMT) x_cb(j), y_cb(k), q_cons_vf(i)%sf(j, k, 0) - end do - write (2, *) - end do - close (2) - end do - - if (present(beta)) then - write (file_path, '(A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir)//'/beta.', i, '.', proc_rank, '.', t_step, '.dat' - open (2, FILE=trim(file_path)) - do j = 0, m - do k = 0, n - write (2, FMT) x_cb(j), y_cb(k), beta%sf(j, k, 0) - end do - write (2, *) - end do - close (2) - end if - - if (qbmm .and. .not. polytropic) then - do i = 1, nb - do r = 1, nnode - write (file_path, '(A,I0,A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir)//'/pres.', i, '.', r, '.', proc_rank, '.', t_step, '.dat' - - open (2, FILE=trim(file_path)) - do j = 0, m - do k = 0, n - write (2, FMT) x_cb(j), y_cb(k), pb_ts(1)%sf(j, k, 0, r, i) - end do - end do - close (2) - end do - end do - do i = 1, nb - do r = 1, nnode - write (file_path, '(A,I0,A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir)//'/mv.', i, '.', r, '.', proc_rank, '.', t_step, '.dat' - - open (2, FILE=trim(file_path)) - do j = 0, m - do k = 0, n - write (2, FMT) x_cb(j), y_cb(k), mv_ts(1)%sf(j, k, 0, r, i) - end do - end do - close (2) - end do - end do - end if - - if (prim_vars_wrt .and. (.not. igr)) then - do i = 1, sys_size - write (file_path, '(A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir)//'/prim.', i, '.', proc_rank, '.', t_step, '.dat' - - open (2, FILE=trim(file_path)) - - do j = 0, m - do k = 0, n - if (((i >= cont_idx%beg) .and. (i <= cont_idx%end)) & - .or. & - ((i >= adv_idx%beg) .and. (i <= adv_idx%end)) & - ) then - write (2, FMT) x_cb(j), y_cb(k), q_cons_vf(i)%sf(j, k, 0) - else - write (2, FMT) x_cb(j), y_cb(k), q_prim_vf(i)%sf(j, k, 0) - end if - end do - write (2, *) - end do - close (2) - end do - end if - end if - - if (precision == 1) then - FMT = "(4F30.7)" - else - FMT = "(4F40.14)" - end if - - ! 3D - if (p > 0) then - do i = 1, sys_size - write (file_path, '(A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir)//'/cons.', i, '.', proc_rank, '.', t_step, '.dat' - open (2, FILE=trim(file_path)) - do j = 0, m - do k = 0, n - do l = 0, p - write (2, FMT) x_cb(j), y_cb(k), z_cb(l), q_cons_vf(i)%sf(j, k, l) - end do - write (2, *) - end do - write (2, *) - end do - close (2) - end do - - if (present(beta)) then - write (file_path, '(A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir)//'/beta.', i, '.', proc_rank, '.', t_step, '.dat' - open (2, FILE=trim(file_path)) - do j = 0, m - do k = 0, n - do l = 0, p - write (2, FMT) x_cb(j), y_cb(k), z_cb(l), beta%sf(j, k, l) - end do - write (2, *) - end do - write (2, *) - end do - close (2) - end if - - if (qbmm .and. .not. polytropic) then - do i = 1, nb - do r = 1, nnode - write (file_path, '(A,I0,A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir)//'/pres.', i, '.', r, '.', proc_rank, '.', t_step, '.dat' - - open (2, FILE=trim(file_path)) - do j = 0, m - do k = 0, n - do l = 0, p - write (2, FMT) x_cb(j), y_cb(k), z_cb(l), pb_ts(1)%sf(j, k, l, r, i) - end do - end do - end do - close (2) - end do - end do - do i = 1, nb - do r = 1, nnode - write (file_path, '(A,I0,A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir)//'/mv.', i, '.', r, '.', proc_rank, '.', t_step, '.dat' - - open (2, FILE=trim(file_path)) - do j = 0, m - do k = 0, n - do l = 0, p - write (2, FMT) x_cb(j), y_cb(k), z_cb(l), mv_ts(1)%sf(j, k, l, r, i) - end do - end do - end do - close (2) - end do - end do - end if - - if (prim_vars_wrt .and. (.not. igr)) then - do i = 1, sys_size - write (file_path, '(A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir)//'/prim.', i, '.', proc_rank, '.', t_step, '.dat' - - open (2, FILE=trim(file_path)) - - do j = 0, m - do k = 0, n - do l = 0, p - if (((i >= cont_idx%beg) .and. (i <= cont_idx%end)) & - .or. & - ((i >= adv_idx%beg) .and. (i <= adv_idx%end)) & - .or. & - ((i >= chemxb) .and. (i <= chemxe)) & - ) then - write (2, FMT) x_cb(j), y_cb(k), z_cb(l), q_cons_vf(i)%sf(j, k, l) - else - write (2, FMT) x_cb(j), y_cb(k), z_cb(l), q_prim_vf(i)%sf(j, k, l) - end if - end do - write (2, *) - end do - write (2, *) - end do - close (2) - end do - end if - end if - - end subroutine s_write_serial_data_files - - !> The goal of this subroutine is to output the grid and - !! conservative variables data files for given time-step. - !! @param q_cons_vf Cell-average conservative variables - !! @param t_step Current time-step - !! @param bc_type Boundary condition type - !! @param beta Eulerian void fraction from lagrangian bubbles - impure subroutine s_write_parallel_data_files(q_cons_vf, t_step, bc_type, beta) - - type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf - integer, intent(in) :: t_step - type(scalar_field), intent(inout), optional :: beta - type(integer_field), & - dimension(1:num_dims, -1:1), & - intent(in) :: bc_type - -#ifdef MFC_MPI - - integer :: ifile, ierr, data_size - integer, dimension(MPI_STATUS_SIZE) :: status - integer(kind=MPI_OFFSET_kind) :: disp - integer(kind=MPI_OFFSET_kind) :: m_MOK, n_MOK, p_MOK - integer(kind=MPI_OFFSET_kind) :: WP_MOK, var_MOK, str_MOK - integer(kind=MPI_OFFSET_kind) :: NVARS_MOK - integer(kind=MPI_OFFSET_kind) :: MOK - - character(LEN=path_len + 2*name_len) :: file_loc - logical :: file_exist, dir_check - character(len=10) :: t_step_string - - integer :: i !< Generic loop iterator - - integer :: alt_sys !< Altered system size for the lagrangian subgrid bubble model - - ! Down sampling variables - integer :: m_ds, n_ds, p_ds - integer :: m_glb_ds, n_glb_ds, p_glb_ds - integer :: m_glb_save, n_glb_save, p_glb_save ! Global save size - - if (down_sample) then - call s_downsample_data(q_cons_vf, q_cons_temp_ds, & - m_ds, n_ds, p_ds, m_glb_ds, n_glb_ds, p_glb_ds) - end if - - if (present(beta)) then - alt_sys = sys_size + 1 - else - alt_sys = sys_size - end if - - if (file_per_process) then - - call s_int_to_str(t_step, t_step_string) - - ! Initialize MPI data I/O - if (down_sample) then - call s_initialize_mpi_data_ds(q_cons_temp_ds) - else - if (ib) then - call s_initialize_mpi_data(q_cons_vf, ib_markers) - else - call s_initialize_mpi_data(q_cons_vf) - end if - end if - - if (proc_rank == 0) then - file_loc = trim(case_dir)//'/restart_data/lustre_'//trim(t_step_string) - call my_inquire(file_loc, dir_check) - if (dir_check .neqv. .true.) then - call s_create_directory(trim(file_loc)) - end if - call s_create_directory(trim(file_loc)) - end if - call s_mpi_barrier() - call DelayFileAccess(proc_rank) - - ! Initialize MPI data I/O - call s_initialize_mpi_data(q_cons_vf) - - ! Open the file to write all flow variables - write (file_loc, '(I0,A,i7.7,A)') t_step, '_', proc_rank, '.dat' - file_loc = trim(case_dir)//'/restart_data/lustre_'//trim(t_step_string)//trim(mpiiofs)//trim(file_loc) - inquire (FILE=trim(file_loc), EXIST=file_exist) - if (file_exist .and. proc_rank == 0) then - call MPI_FILE_DELETE(file_loc, mpi_info_int, ierr) - end if - call MPI_FILE_OPEN(MPI_COMM_SELF, file_loc, ior(MPI_MODE_WRONLY, MPI_MODE_CREATE), & - mpi_info_int, ifile, ierr) - - if (down_sample) then - ! Size of local arrays - data_size = (m_ds + 3)*(n_ds + 3)*(p_ds + 3) - m_glb_save = m_glb_ds + 1 - n_glb_save = n_glb_ds + 1 - p_glb_save = p_glb_ds + 1 - else - ! Size of local arrays - data_size = (m + 1)*(n + 1)*(p + 1) - m_glb_save = m_glb + 1 - n_glb_save = n_glb + 1 - p_glb_save = p_glb + 1 - end if - - ! Resize some integers so MPI can write even the biggest files - m_MOK = int(m_glb_save + 1, MPI_OFFSET_KIND) - n_MOK = int(n_glb_save + 1, MPI_OFFSET_KIND) - p_MOK = int(p_glb_save + 1, MPI_OFFSET_KIND) - WP_MOK = int(8._wp, MPI_OFFSET_KIND) - MOK = int(1._wp, MPI_OFFSET_KIND) - str_MOK = int(name_len, MPI_OFFSET_KIND) - NVARS_MOK = int(sys_size, MPI_OFFSET_KIND) - - if (bubbles_euler) then - ! Write the data for each variable - do i = 1, sys_size - var_MOK = int(i, MPI_OFFSET_KIND) - - call MPI_FILE_WRITE_ALL(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, & - mpi_io_p, status, ierr) - end do - !Write pb and mv for non-polytropic qbmm - if (qbmm .and. .not. polytropic) then - do i = sys_size + 1, sys_size + 2*nb*nnode - var_MOK = int(i, MPI_OFFSET_KIND) - - call MPI_FILE_WRITE_ALL(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, & - mpi_io_p, status, ierr) - end do - end if - else - if (down_sample) then - do i = 1, sys_size !TODO: check if correct (sys_size - var_MOK = int(i, MPI_OFFSET_KIND) - - call MPI_FILE_WRITE_ALL(ifile, q_cons_temp_ds(i)%sf, data_size*mpi_io_type, & - mpi_io_p, status, ierr) - end do - else - do i = 1, sys_size !TODO: check if correct (sys_size - var_MOK = int(i, MPI_OFFSET_KIND) - - call MPI_FILE_WRITE_ALL(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, & - mpi_io_p, status, ierr) - end do - end if - end if - - call MPI_FILE_CLOSE(ifile, ierr) - else - ! Initialize MPI data I/O - - if (ib) then - call s_initialize_mpi_data(q_cons_vf, ib_markers) - elseif (present(beta)) then - call s_initialize_mpi_data(q_cons_vf, beta=beta) - else - call s_initialize_mpi_data(q_cons_vf) - end if - - write (file_loc, '(I0,A)') t_step, '.dat' - file_loc = trim(case_dir)//'/restart_data'//trim(mpiiofs)//trim(file_loc) - inquire (FILE=trim(file_loc), EXIST=file_exist) - if (file_exist .and. proc_rank == 0) then - call MPI_FILE_DELETE(file_loc, mpi_info_int, ierr) - end if - call MPI_FILE_OPEN(MPI_COMM_WORLD, file_loc, ior(MPI_MODE_WRONLY, MPI_MODE_CREATE), & - mpi_info_int, ifile, ierr) - - ! Size of local arrays - data_size = (m + 1)*(n + 1)*(p + 1) - - ! Resize some integers so MPI can write even the biggest files - m_MOK = int(m_glb + 1, MPI_OFFSET_KIND) - n_MOK = int(n_glb + 1, MPI_OFFSET_KIND) - p_MOK = int(p_glb + 1, MPI_OFFSET_KIND) - WP_MOK = int(8._wp, MPI_OFFSET_KIND) - MOK = int(1._wp, MPI_OFFSET_KIND) - str_MOK = int(name_len, MPI_OFFSET_KIND) - NVARS_MOK = int(alt_sys, MPI_OFFSET_KIND) - - if (bubbles_euler) then - ! Write the data for each variable - do i = 1, sys_size - var_MOK = int(i, MPI_OFFSET_KIND) - - ! Initial displacement to skip at beginning of file - disp = m_MOK*max(MOK, n_MOK)*max(MOK, p_MOK)*WP_MOK*(var_MOK - 1) - - call MPI_FILE_SET_VIEW(ifile, disp, mpi_p, MPI_IO_DATA%view(i), & - 'native', mpi_info_int, ierr) - call MPI_FILE_WRITE_ALL(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, & - mpi_io_p, status, ierr) - end do - !Write pb and mv for non-polytropic qbmm - if (qbmm .and. .not. polytropic) then - do i = sys_size + 1, sys_size + 2*nb*nnode - var_MOK = int(i, MPI_OFFSET_KIND) - - ! Initial displacement to skip at beginning of file - disp = m_MOK*max(MOK, n_MOK)*max(MOK, p_MOK)*WP_MOK*(var_MOK - 1) - - call MPI_FILE_SET_VIEW(ifile, disp, mpi_p, MPI_IO_DATA%view(i), & - 'native', mpi_info_int, ierr) - call MPI_FILE_WRITE_ALL(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, & - mpi_io_p, status, ierr) - end do - end if - else - do i = 1, sys_size !TODO: check if correct (sys_size - var_MOK = int(i, MPI_OFFSET_KIND) - - ! Initial displacement to skip at beginning of file - disp = m_MOK*max(MOK, n_MOK)*max(MOK, p_MOK)*WP_MOK*(var_MOK - 1) - - call MPI_FILE_SET_VIEW(ifile, disp, mpi_p, MPI_IO_DATA%view(i), & - 'native', mpi_info_int, ierr) - call MPI_FILE_WRITE_ALL(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, & - mpi_io_p, status, ierr) - end do - end if - - ! Correction for the lagrangian subgrid bubble model - if (present(beta)) then - var_MOK = int(sys_size + 1, MPI_OFFSET_KIND) - - ! Initial displacement to skip at beginning of file - disp = m_MOK*max(MOK, n_MOK)*max(MOK, p_MOK)*WP_MOK*(var_MOK - 1) - - call MPI_FILE_SET_VIEW(ifile, disp, mpi_p, MPI_IO_DATA%view(sys_size + 1), & - 'native', mpi_info_int, ierr) - call MPI_FILE_WRITE_ALL(ifile, MPI_IO_DATA%var(sys_size + 1)%sf, data_size*mpi_io_type, & - mpi_io_p, status, ierr) - end if - - call MPI_FILE_CLOSE(ifile, ierr) - - !Write ib data - if (ib) then - call s_write_parallel_ib_data(t_step) - ! write (file_loc, '(A)') 'ib.dat' - ! file_loc = trim(case_dir)//'/restart_data'//trim(mpiiofs)//trim(file_loc) - ! call MPI_FILE_OPEN(MPI_COMM_WORLD, file_loc, ior(MPI_MODE_WRONLY, MPI_MODE_CREATE), & - ! mpi_info_int, ifile, ierr) - - ! var_MOK = int(sys_size + 1, MPI_OFFSET_KIND) - ! disp = m_MOK*max(MOK, n_MOK)*max(MOK, p_MOK)*WP_MOK*(var_MOK - 1 + int(t_step/t_step_save)) - - ! call MPI_FILE_SET_VIEW(ifile, disp, MPI_INTEGER, MPI_IO_IB_DATA%view, & - ! 'native', mpi_info_int, ierr) - ! call MPI_FILE_WRITE_ALL(ifile, MPI_IO_IB_DATA%var%sf, data_size, & - ! MPI_INTEGER, status, ierr) - ! call MPI_FILE_CLOSE(ifile, ierr) - end if - - end if -#endif - - end subroutine s_write_parallel_data_files - - !> @brief Writes immersed boundary marker data to a serial (per-processor) unformatted file. - subroutine s_write_serial_ib_data(time_step) - - integer, intent(in) :: time_step - character(LEN=path_len + 2*name_len) :: file_path - character(LEN=path_len + 2*name_len) :: t_step_dir - - ! Creating or overwriting the time-step root directory - write (t_step_dir, '(A,I0,A,I0)') trim(case_dir)//'/p_all' - write (t_step_dir, '(a,i0,a,i0)') trim(case_dir)//'/p_all/p', & - proc_rank, '/', time_step - write (file_path, '(A,I0,A)') trim(t_step_dir)//'/ib.dat' - - open (2, FILE=trim(file_path), & - FORM='unformatted', & - STATUS='new') - - $:GPU_UPDATE(host='[ib_markers%sf]') - write (2) ib_markers%sf(0:m, 0:n, 0:p); close (2) - - end subroutine - - !> @brief Writes immersed boundary marker data in parallel using MPI I/O. - subroutine s_write_parallel_ib_data(time_step) - - integer, intent(in) :: time_step - -#ifdef MFC_MPI - - character(LEN=path_len + 2*name_len) :: file_loc - integer(kind=MPI_OFFSET_kind) :: disp - integer(kind=MPI_OFFSET_kind) :: m_MOK, n_MOK, p_MOK - integer(kind=MPI_OFFSET_kind) :: WP_MOK, var_MOK, MOK - integer :: ifile, ierr, data_size - integer, dimension(MPI_STATUS_SIZE) :: status - - $:GPU_UPDATE(host='[ib_markers%sf]') - - ! Size of local arrays - data_size = (m + 1)*(n + 1)*(p + 1) - m_MOK = int(m_glb + 1, MPI_OFFSET_KIND) - n_MOK = int(n_glb + 1, MPI_OFFSET_KIND) - p_MOK = int(p_glb + 1, MPI_OFFSET_KIND) - WP_MOK = int(8._wp, MPI_OFFSET_KIND) - MOK = int(1._wp, MPI_OFFSET_KIND) - - write (file_loc, '(A)') 'ib.dat' - file_loc = trim(case_dir)//'/restart_data'//trim(mpiiofs)//trim(file_loc) - call MPI_FILE_OPEN(MPI_COMM_WORLD, file_loc, ior(MPI_MODE_WRONLY, MPI_MODE_CREATE), & - mpi_info_int, ifile, ierr) - - var_MOK = int(sys_size + 1, MPI_OFFSET_KIND) - disp = m_MOK*max(MOK, n_MOK)*max(MOK, p_MOK)*WP_MOK*(var_MOK - 1 + int(time_step/t_step_save)) - if (time_step == 0) disp = 0 - - call MPI_FILE_SET_VIEW(ifile, disp, MPI_INTEGER, MPI_IO_IB_DATA%view, & - 'native', mpi_info_int, ierr) - call MPI_FILE_WRITE_ALL(ifile, MPI_IO_IB_DATA%var%sf, data_size, & - MPI_INTEGER, status, ierr) - call MPI_FILE_CLOSE(ifile, ierr) - -#endif - - end subroutine s_write_parallel_ib_data - - !> @brief Dispatches immersed boundary data output to the serial or parallel writer. - subroutine s_write_ib_data_file(time_step) - - integer, intent(in) :: time_step - - if (parallel_io) then - call s_write_parallel_ib_data(time_step) - else - call s_write_serial_ib_data(time_step) - end if - - end subroutine - - !> This writes a formatted data file where the root processor - !! can write out the CoM information - !! @param t_step Current time-step - !! @param c_mass_in Center of mass information - impure subroutine s_write_com_files(t_step, c_mass_in) - - integer, intent(in) :: t_step - real(wp), dimension(num_fluids, 5), intent(in) :: c_mass_in - integer :: i !< Generic loop iterator - real(wp) :: nondim_time !< Non-dimensional time - - ! Non-dimensional time calculation - if (t_step_old /= dflt_int) then - nondim_time = real(t_step + t_step_old, wp)*dt - else - nondim_time = real(t_step, wp)*dt - end if - - if (proc_rank == 0) then - if (n == 0) then ! 1D simulation - do i = 1, num_fluids ! Loop through fluids - write (i + 120, '(6X,4F24.12)') & - nondim_time, & - c_mass_in(i, 1), & - c_mass_in(i, 2), & - c_mass_in(i, 5) - end do - elseif (p == 0) then ! 2D simulation - do i = 1, num_fluids ! Loop through fluids - write (i + 120, '(6X,5F24.12)') & - nondim_time, & - c_mass_in(i, 1), & - c_mass_in(i, 2), & - c_mass_in(i, 3), & - c_mass_in(i, 5) - end do - else ! 3D simulation - do i = 1, num_fluids ! Loop through fluids - write (i + 120, '(6X,6F24.12)') & - nondim_time, & - c_mass_in(i, 1), & - c_mass_in(i, 2), & - c_mass_in(i, 3), & - c_mass_in(i, 4), & - c_mass_in(i, 5) - end do - end if - end if - - end subroutine s_write_com_files - - !> This writes a formatted data file for the flow probe information - !! @param t_step Current time-step - !! @param q_cons_vf Conservative variables - !! @param accel_mag Acceleration magnitude information - impure subroutine s_write_probe_files(t_step, q_cons_vf, accel_mag) - - integer, intent(in) :: t_step - type(scalar_field), dimension(sys_size), intent(in) :: q_cons_vf - real(wp), dimension(0:m, 0:n, 0:p), intent(in) :: accel_mag - - real(wp), dimension(-1:m) :: distx - real(wp), dimension(-1:n) :: disty - real(wp), dimension(-1:p) :: distz - - ! The cell-averaged partial densities, density, velocity, pressure, - ! volume fractions, specific heat ratio function, liquid stiffness - ! function, and sound speed. - real(wp) :: lit_gamma, nbub - real(wp) :: rho - real(wp), dimension(num_vels) :: vel - real(wp) :: pres - real(wp) :: ptilde - real(wp) :: ptot - real(wp) :: alf - real(wp) :: alfgr - real(wp), dimension(num_fluids) :: alpha - real(wp) :: gamma - real(wp) :: pi_inf - real(wp) :: qv - real(wp) :: c - real(wp) :: M00, M10, M01, M20, M11, M02 - real(wp) :: varR, varV - real(wp), dimension(Nb) :: nR, R, nRdot, Rdot - real(wp) :: nR3 - real(wp) :: accel - real(wp) :: int_pres - real(wp) :: max_pres - real(wp), dimension(2) :: Re - real(wp), dimension(6) :: tau_e - real(wp) :: G_local - real(wp) :: dyn_p, T - real(wp) :: damage_state - - integer :: i, j, k, l, s, d !< Generic loop iterator - - real(wp) :: nondim_time !< Non-dimensional time - - real(wp) :: tmp !< - !! Temporary variable to store quantity for mpi_allreduce - - integer :: npts !< Number of included integral points - real(wp) :: rad, thickness !< For integral quantities - logical :: trigger !< For integral quantities - - real(wp) :: rhoYks(1:num_species) - - T = dflt_T_guess - - ! Non-dimensional time calculation - if (time_stepper == 23) then - nondim_time = mytime - else - if (t_step_old /= dflt_int) then - nondim_time = real(t_step + t_step_old, wp)*dt - else - nondim_time = real(t_step, wp)*dt - end if - end if - - do i = 1, num_probes - ! Zeroing out flow variables for all processors - rho = 0._wp - do s = 1, num_vels - vel(s) = 0._wp - end do - pres = 0._wp - gamma = 0._wp - pi_inf = 0._wp - qv = 0._wp - c = 0._wp - accel = 0._wp - nR = 0._wp; R = 0._wp - nRdot = 0._wp; Rdot = 0._wp - nbub = 0._wp - M00 = 0._wp - M10 = 0._wp - M01 = 0._wp - M20 = 0._wp - M11 = 0._wp - M02 = 0._wp - varR = 0._wp; varV = 0._wp - alf = 0._wp - do s = 1, (num_dims*(num_dims + 1))/2 - tau_e(s) = 0._wp - end do - damage_state = 0._wp - - ! Find probe location in terms of indices on a - ! specific processor - if (n == 0) then ! 1D simulation - if ((probe(i)%x >= x_cb(-1)) .and. (probe(i)%x <= x_cb(m))) then - do s = -1, m - distx(s) = x_cb(s) - probe(i)%x - if (distx(s) < 0._wp) distx(s) = 1000._wp - end do - j = minloc(distx, 1) - if (j == 1) j = 2 ! Pick first point if probe is at edge - k = 0 - l = 0 - - if (chemistry) then - do d = 1, num_species - rhoYks(d) = q_cons_vf(chemxb + d - 1)%sf(j - 2, k, l) - end do - end if - - ! Computing/Sharing necessary state variables - if (elasticity) then - call s_convert_to_mixture_variables(q_cons_vf, j - 2, k, l, & - rho, gamma, pi_inf, qv, & - Re, G_local, fluid_pp(:)%G) - else - call s_convert_to_mixture_variables(q_cons_vf, j - 2, k, l, & - rho, gamma, pi_inf, qv) - end if - do s = 1, num_vels - vel(s) = q_cons_vf(cont_idx%end + s)%sf(j - 2, k, l)/rho - end do - - dyn_p = 0.5_wp*rho*dot_product(vel, vel) - - if (elasticity) then - if (cont_damage) then - damage_state = q_cons_vf(damage_idx)%sf(j - 2, k, l) - G_local = G_local*max((1._wp - damage_state), 0._wp) - end if - - call s_compute_pressure( & - q_cons_vf(1)%sf(j - 2, k, l), & - q_cons_vf(alf_idx)%sf(j - 2, k, l), & - dyn_p, pi_inf, gamma, rho, qv, rhoYks(:), pres, T, & - q_cons_vf(stress_idx%beg)%sf(j - 2, k, l), & - q_cons_vf(mom_idx%beg)%sf(j - 2, k, l), G_local) - else - call s_compute_pressure( & - q_cons_vf(E_idx)%sf(j - 2, k, l), & - q_cons_vf(alf_idx)%sf(j - 2, k, l), & - dyn_p, pi_inf, gamma, rho, qv, rhoYks, pres, T) - end if - - if (model_eqns == 4) then - lit_gamma = gammas(1) - else if (elasticity) then - tau_e(1) = q_cons_vf(stress_idx%end)%sf(j - 2, k, l)/rho - end if - - if (bubbles_euler) then - alf = q_cons_vf(alf_idx)%sf(j - 2, k, l) - if (num_fluids == 3) then - alfgr = q_cons_vf(alf_idx - 1)%sf(j - 2, k, l) - end if - do s = 1, nb - nR(s) = q_cons_vf(bub_idx%rs(s))%sf(j - 2, k, l) - nRdot(s) = q_cons_vf(bub_idx%vs(s))%sf(j - 2, k, l) - end do - - if (adv_n) then - nbub = q_cons_vf(n_idx)%sf(j - 2, k, l) - else - nR3 = 0._wp - do s = 1, nb - nR3 = nR3 + weight(s)*(nR(s)**3._wp) - end do - - nbub = sqrt((4._wp*pi/3._wp)*nR3/alf) - end if -#ifdef DEBUG - print *, 'In probe, nbub: ', nbub -#endif - if (qbmm) then - M00 = q_cons_vf(bub_idx%moms(1, 1))%sf(j - 2, k, l)/nbub - M10 = q_cons_vf(bub_idx%moms(1, 2))%sf(j - 2, k, l)/nbub - M01 = q_cons_vf(bub_idx%moms(1, 3))%sf(j - 2, k, l)/nbub - M20 = q_cons_vf(bub_idx%moms(1, 4))%sf(j - 2, k, l)/nbub - M11 = q_cons_vf(bub_idx%moms(1, 5))%sf(j - 2, k, l)/nbub - M02 = q_cons_vf(bub_idx%moms(1, 6))%sf(j - 2, k, l)/nbub - - M10 = M10/M00 - M01 = M01/M00 - M20 = M20/M00 - M11 = M11/M00 - M02 = M02/M00 - - varR = M20 - M10**2._wp - varV = M02 - M01**2._wp - end if - R(:) = nR(:)/nbub - Rdot(:) = nRdot(:)/nbub - - ptilde = ptil(j - 2, k, l) - ptot = pres - ptilde - end if - - ! Compute mixture sound Speed - call s_compute_speed_of_sound(pres, rho, gamma, pi_inf, & - ((gamma + 1._wp)*pres + pi_inf)/rho, alpha, 0._wp, 0._wp, c, qv) - - accel = accel_mag(j - 2, k, l) - end if - elseif (p == 0) then ! 2D simulation - if (chemistry) then - do d = 1, num_species - rhoYks(d) = q_cons_vf(chemxb + d - 1)%sf(j - 2, k - 2, l) - end do - end if - - if ((probe(i)%x >= x_cb(-1)) .and. (probe(i)%x <= x_cb(m))) then - if ((probe(i)%y >= y_cb(-1)) .and. (probe(i)%y <= y_cb(n))) then - do s = -1, m - distx(s) = x_cb(s) - probe(i)%x - if (distx(s) < 0._wp) distx(s) = 1000._wp - end do - do s = -1, n - disty(s) = y_cb(s) - probe(i)%y - if (disty(s) < 0._wp) disty(s) = 1000._wp - end do - j = minloc(distx, 1) - k = minloc(disty, 1) - if (j == 1) j = 2 ! Pick first point if probe is at edge - if (k == 1) k = 2 ! Pick first point if probe is at edge - l = 0 - - ! Computing/Sharing necessary state variables - call s_convert_to_mixture_variables(q_cons_vf, j - 2, k - 2, l, & - rho, gamma, pi_inf, qv, & - Re, G_local, fluid_pp(:)%G) - do s = 1, num_vels - vel(s) = q_cons_vf(cont_idx%end + s)%sf(j - 2, k - 2, l)/rho - end do - - dyn_p = 0.5_wp*rho*dot_product(vel, vel) - - if (elasticity) then - if (cont_damage) then - damage_state = q_cons_vf(damage_idx)%sf(j - 2, k - 2, l) - G_local = G_local*max((1._wp - damage_state), 0._wp) - end if - - call s_compute_pressure( & - q_cons_vf(1)%sf(j - 2, k - 2, l), & - q_cons_vf(alf_idx)%sf(j - 2, k - 2, l), & - dyn_p, pi_inf, gamma, rho, qv, & - rhoYks, & - pres, & - T, & - q_cons_vf(stress_idx%beg)%sf(j - 2, k - 2, l), & - q_cons_vf(mom_idx%beg)%sf(j - 2, k - 2, l), G_local) - else - call s_compute_pressure(q_cons_vf(E_idx)%sf(j - 2, k - 2, l), & - q_cons_vf(alf_idx)%sf(j - 2, k - 2, l), & - dyn_p, pi_inf, gamma, rho, qv, & - rhoYks, pres, T) - end if - - if (model_eqns == 4) then - lit_gamma = gs_min(1) - else if (elasticity) then - do s = 1, 3 - tau_e(s) = q_cons_vf(s)%sf(j - 2, k - 2, l)/rho - end do - end if - - if (bubbles_euler) then - alf = q_cons_vf(alf_idx)%sf(j - 2, k - 2, l) - do s = 1, nb - nR(s) = q_cons_vf(bub_idx%rs(s))%sf(j - 2, k - 2, l) - nRdot(s) = q_cons_vf(bub_idx%vs(s))%sf(j - 2, k - 2, l) - end do - - if (adv_n) then - nbub = q_cons_vf(n_idx)%sf(j - 2, k - 2, l) - else - nR3 = 0._wp - do s = 1, nb - nR3 = nR3 + weight(s)*(nR(s)**3._wp) - end do - - nbub = sqrt((4._wp*pi/3._wp)*nR3/alf) - end if - - R(:) = nR(:)/nbub - Rdot(:) = nRdot(:)/nbub - end if - ! Compute mixture sound speed - call s_compute_speed_of_sound(pres, rho, gamma, pi_inf, & - ((gamma + 1._wp)*pres + pi_inf)/rho, alpha, 0._wp, 0._wp, c, qv) - - end if - end if - else ! 3D - if ((probe(i)%x >= x_cb(-1)) .and. (probe(i)%x <= x_cb(m))) then - if ((probe(i)%y >= y_cb(-1)) .and. (probe(i)%y <= y_cb(n))) then - if ((probe(i)%z >= z_cb(-1)) .and. (probe(i)%z <= z_cb(p))) then - do s = -1, m - distx(s) = x_cb(s) - probe(i)%x - if (distx(s) < 0._wp) distx(s) = 1000._wp - end do - do s = -1, n - disty(s) = y_cb(s) - probe(i)%y - if (disty(s) < 0._wp) disty(s) = 1000._wp - end do - do s = -1, p - distz(s) = z_cb(s) - probe(i)%z - if (distz(s) < 0._wp) distz(s) = 1000._wp - end do - j = minloc(distx, 1) - k = minloc(disty, 1) - l = minloc(distz, 1) - if (j == 1) j = 2 ! Pick first point if probe is at edge - if (k == 1) k = 2 ! Pick first point if probe is at edge - if (l == 1) l = 2 ! Pick first point if probe is at edge - - ! Computing/Sharing necessary state variables - call s_convert_to_mixture_variables(q_cons_vf, j - 2, k - 2, l - 2, & - rho, gamma, pi_inf, qv, & - Re, G_local, fluid_pp(:)%G) - do s = 1, num_vels - vel(s) = q_cons_vf(cont_idx%end + s)%sf(j - 2, k - 2, l - 2)/rho - end do - - dyn_p = 0.5_wp*rho*dot_product(vel, vel) - - if (chemistry) then - do d = 1, num_species - rhoYks(d) = q_cons_vf(chemxb + d - 1)%sf(j - 2, k - 2, l - 2) - end do - end if - - if (elasticity) then - if (cont_damage) then - damage_state = q_cons_vf(damage_idx)%sf(j - 2, k - 2, l - 2) - G_local = G_local*max((1._wp - damage_state), 0._wp) - end if - - call s_compute_pressure( & - q_cons_vf(1)%sf(j - 2, k - 2, l - 2), & - q_cons_vf(alf_idx)%sf(j - 2, k - 2, l - 2), & - dyn_p, pi_inf, gamma, rho, qv, & - rhoYks, pres, T, & - q_cons_vf(stress_idx%beg)%sf(j - 2, k - 2, l - 2), & - q_cons_vf(mom_idx%beg)%sf(j - 2, k - 2, l - 2), G_local) - else - call s_compute_pressure(q_cons_vf(E_idx)%sf(j - 2, k - 2, l - 2), & - q_cons_vf(alf_idx)%sf(j - 2, k - 2, l - 2), & - dyn_p, pi_inf, gamma, rho, qv, & - rhoYks, pres, T) - end if - - ! Compute mixture sound speed - call s_compute_speed_of_sound(pres, rho, gamma, pi_inf, & - ((gamma + 1._wp)*pres + pi_inf)/rho, alpha, 0._wp, 0._wp, c, qv) - - accel = accel_mag(j - 2, k - 2, l - 2) - end if - end if - end if - end if - if (num_procs > 1) then - #:for VAR in ['rho','pres','gamma','pi_inf','qv','c','accel'] - tmp = ${VAR}$ - call s_mpi_allreduce_sum(tmp, ${VAR}$) - #:endfor - - do s = 1, num_vels - tmp = vel(s) - call s_mpi_allreduce_sum(tmp, vel(s)) - end do - - if (bubbles_euler) then - #:for VAR in ['alf','alfgr','nbub','nR(1)','nRdot(1)','M00','R(1)','Rdot(1)','ptilde','ptot'] - tmp = ${VAR}$ - call s_mpi_allreduce_sum(tmp, ${VAR}$) - #:endfor - - if (qbmm) then - #:for VAR in ['varR','varV','M10','M01','M20','M02'] - tmp = ${VAR}$ - call s_mpi_allreduce_sum(tmp, ${VAR}$) - #:endfor - end if - end if - - if (elasticity) then - do s = 1, (num_dims*(num_dims + 1))/2 - tmp = tau_e(s) - call s_mpi_allreduce_sum(tmp, tau_e(s)) - end do - end if - - if (cont_damage) then - tmp = damage_state - call s_mpi_allreduce_sum(tmp, damage_state) - end if - end if - if (proc_rank == 0) then - if (n == 0) then - if (bubbles_euler .and. (num_fluids <= 2)) then - if (qbmm) then - write (i + 30, '(6x,f12.6,14f28.16)') & - nondim_time, & - rho, & - vel(1), & - pres, & - alf, & - R(1), & - Rdot(1), & - nR(1), & - nRdot(1), & - varR, & - varV, & - M10, & - M01, & - M20, & - M02 - else - write (i + 30, '(6x,f12.6,8f24.8)') & - nondim_time, & - rho, & - vel(1), & - pres, & - alf, & - R(1), & - Rdot(1), & - nR(1), & - nRdot(1) - ! ptilde, & - ! ptot - end if - else if (bubbles_euler .and. (num_fluids == 3)) then - write (i + 30, '(6x,f12.6,f24.8,f24.8,f24.8,f24.8,f24.8,'// & - 'f24.8,f24.8,f24.8,f24.8,f24.8, f24.8)') & - nondim_time, & - rho, & - vel(1), & - pres, & - alf, & - alfgr, & - nR(1), & - nRdot(1), & - R(1), & - Rdot(1), & - ptilde, & - ptot - else if (bubbles_euler .and. num_fluids == 4) then - write (i + 30, '(6x,f12.6,f24.8,f24.8,f24.8,f24.8,'// & - 'f24.8,f24.8,f24.8,f24.8,f24.8,f24.8,f24.8,f24.8,f24.8)') & - nondim_time, & - q_cons_vf(1)%sf(j - 2, 0, 0), & - q_cons_vf(2)%sf(j - 2, 0, 0), & - q_cons_vf(3)%sf(j - 2, 0, 0), & - q_cons_vf(4)%sf(j - 2, 0, 0), & - q_cons_vf(5)%sf(j - 2, 0, 0), & - q_cons_vf(6)%sf(j - 2, 0, 0), & - q_cons_vf(7)%sf(j - 2, 0, 0), & - q_cons_vf(8)%sf(j - 2, 0, 0), & - q_cons_vf(9)%sf(j - 2, 0, 0), & - q_cons_vf(10)%sf(j - 2, 0, 0), & - nbub, & - R(1), & - Rdot(1) - else - write (i + 30, '(6X,F12.6,F24.8,F24.8,F24.8)') & - nondim_time, & - rho, & - vel(1), & - pres - end if - elseif (p == 0) then - if (bubbles_euler) then - #:if not MFC_CASE_OPTIMIZATION or num_dims > 1 - write (i + 30, '(6X,10F24.8)') & - nondim_time, & - rho, & - vel(1), & - vel(2), & - pres, & - alf, & - nR(1), & - nRdot(1), & - R(1), & - Rdot(1) - #:endif - else if (elasticity) then - #:if not MFC_CASE_OPTIMIZATION or num_dims > 1 - write (i + 30, '(6X,F12.6,F24.8,F24.8,F24.8,F24.8,'// & - 'F24.8,F24.8,F24.8)') & - nondim_time, & - rho, & - vel(1), & - vel(2), & - pres, & - tau_e(1), & - tau_e(2), & - tau_e(3) - #:endif - else - write (i + 30, '(6X,F12.6,F24.8,F24.8,F24.8)') & - nondim_time, & - rho, & - vel(1), & - pres - print *, 'time =', nondim_time, 'rho =', rho, 'pres =', pres - end if - else - #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 - write (i + 30, '(6X,F12.6,F24.8,F24.8,F24.8,F24.8,'// & - 'F24.8,F24.8,F24.8,F24.8,F24.8,'// & - 'F24.8)') & - nondim_time, & - rho, & - vel(1), & - vel(2), & - vel(3), & - pres, & - gamma, & - pi_inf, & - qv, & - c, & - accel - #:endif - end if - end if - end do - - if (integral_wrt .and. bubbles_euler) then - if (n == 0) then ! 1D simulation - do i = 1, num_integrals - int_pres = 0._wp - max_pres = 0._wp - k = 0; l = 0 - npts = 0 - do j = 1, m - pres = 0._wp - do s = 1, num_vels - vel(s) = 0._wp - end do - rho = 0._wp - pres = 0._wp - gamma = 0._wp - pi_inf = 0._wp - qv = 0._wp - - if ((integral(i)%xmin <= x_cb(j)) .and. (integral(i)%xmax >= x_cb(j))) then - npts = npts + 1 - call s_convert_to_mixture_variables(q_cons_vf, j, k, l, & - rho, gamma, pi_inf, qv, Re) - do s = 1, num_vels - vel(s) = q_cons_vf(cont_idx%end + s)%sf(j, k, l)/rho - end do - - pres = ( & - (q_cons_vf(E_idx)%sf(j, k, l) - & - 0.5_wp*(q_cons_vf(mom_idx%beg)%sf(j, k, l)**2._wp)/rho)/ & - (1._wp - q_cons_vf(alf_idx)%sf(j, k, l)) - & - pi_inf - qv & - )/gamma - int_pres = int_pres + (pres - 1._wp)**2._wp - end if - end do - int_pres = sqrt(int_pres/(1._wp*npts)) - - if (num_procs > 1) then - tmp = int_pres - call s_mpi_allreduce_sum(tmp, int_pres) - end if - - if (proc_rank == 0) then - if (bubbles_euler .and. (num_fluids <= 2)) then - write (i + 70, '(6x,f12.6,f24.8)') & - nondim_time, int_pres - end if - end if - end do - elseif (p == 0) then - if (num_integrals /= 3) then - call s_mpi_abort('Incorrect number of integrals') - end if - - rad = integral(1)%xmax - thickness = integral(1)%xmin - - do i = 1, num_integrals - int_pres = 0._wp - max_pres = 0._wp - l = 0 - npts = 0 - do j = 1, m - do k = 1, n - trigger = .false. - if (i == 1) then - !inner portion - if (sqrt(x_cb(j)**2._wp + y_cb(k)**2._wp) < (rad - 0.5_wp*thickness)) & - trigger = .true. - elseif (i == 2) then - !net region - if (sqrt(x_cb(j)**2._wp + y_cb(k)**2._wp) > (rad - 0.5_wp*thickness) .and. & - sqrt(x_cb(j)**2._wp + y_cb(k)**2._wp) < (rad + 0.5_wp*thickness)) & - trigger = .true. - elseif (i == 3) then - !everything else - if (sqrt(x_cb(j)**2._wp + y_cb(k)**2._wp) > (rad + 0.5_wp*thickness)) & - trigger = .true. - end if - - pres = 0._wp - do s = 1, num_vels - vel(s) = 0._wp - end do - rho = 0._wp - pres = 0._wp - gamma = 0._wp - pi_inf = 0._wp - qv = 0._wp - - if (trigger) then - npts = npts + 1 - call s_convert_to_mixture_variables(q_cons_vf, j, k, l, & - rho, gamma, pi_inf, qv, Re) - do s = 1, num_vels - vel(s) = q_cons_vf(cont_idx%end + s)%sf(j, k, l)/rho - end do - - pres = ( & - (q_cons_vf(E_idx)%sf(j, k, l) - & - 0.5_wp*(q_cons_vf(mom_idx%beg)%sf(j, k, l)**2._wp)/rho)/ & - (1._wp - q_cons_vf(alf_idx)%sf(j, k, l)) - & - pi_inf - qv & - )/gamma - int_pres = int_pres + abs(pres - 1._wp) - max_pres = max(max_pres, abs(pres - 1._wp)) - end if - - end do - end do - - if (npts > 0) then - int_pres = int_pres/(1._wp*npts) - else - int_pres = 0._wp - end if - - if (num_procs > 1) then - tmp = int_pres - call s_mpi_allreduce_sum(tmp, int_pres) - - tmp = max_pres - call s_mpi_allreduce_max(tmp, max_pres) - end if - - if (proc_rank == 0) then - if (bubbles_euler .and. (num_fluids <= 2)) then - write (i + 70, '(6x,f12.6,f24.8,f24.8)') & - nondim_time, int_pres, max_pres - end if - end if - end do - end if - end if - - end subroutine s_write_probe_files - - !> The goal of this subroutine is to write to the run-time - !! information file basic footer information applicable to - !! the current computation and to close the file when done. - !! The footer contains the stability criteria extrema over - !! all of the time-steps and the simulation run-time. - impure subroutine s_close_run_time_information_file - - real(wp) :: run_time !< Run-time of the simulation - - ! Writing the footer of and closing the run-time information file - write (3, '(A)') ' ' - write (3, '(A)') '' - - write (3, '(A,F9.6)') 'ICFL Max: ', icfl_max - if (viscous) write (3, '(A,F9.6)') 'VCFL Max: ', vcfl_max - if (viscous) write (3, '(A,F10.6)') 'Rc Min: ', Rc_min - - call cpu_time(run_time) - - write (3, '(A)') '' - write (3, '(A,I0,A)') 'Run-time: ', int(anint(run_time)), 's' - write (3, '(A)') ' ' - close (3) - - end subroutine s_close_run_time_information_file - - !> Closes communication files - impure subroutine s_close_com_files() - - integer :: i !< Generic loop iterator - do i = 1, num_fluids - close (i + 120) - end do - - end subroutine s_close_com_files - - !> Closes probe files - impure subroutine s_close_probe_files - - integer :: i !< Generic loop iterator - - do i = 1, num_probes - close (i + 30) - end do - - end subroutine s_close_probe_files - - !> The computation of parameters, the allocation of memory, - !! the association of pointers and/or the execution of any - !! other procedures that are necessary to setup the module. - impure subroutine s_initialize_data_output_module - - integer :: i, m_ds, n_ds, p_ds - - ! Allocating/initializing ICFL, VCFL, CCFL and Rc stability criteria - if (run_time_info) then - @:ALLOCATE(icfl_sf(0:m, 0:n, 0:p)) - icfl_max = 0._wp - - if (viscous) then - @:ALLOCATE(vcfl_sf(0:m, 0:n, 0:p)) - @:ALLOCATE(Rc_sf (0:m, 0:n, 0:p)) - - vcfl_max = 0._wp - Rc_min = 1.e3_wp - end if - end if - - if (probe_wrt) then - @:ALLOCATE(c_mass(num_fluids,5)) - end if - - if (down_sample) then - m_ds = int((m + 1)/3) - 1 - n_ds = int((n + 1)/3) - 1 - p_ds = int((p + 1)/3) - 1 - - allocate (q_cons_temp_ds(1:sys_size)) - do i = 1, sys_size - allocate (q_cons_temp_ds(i)%sf(-1:m_ds + 1, -1:n_ds + 1, -1:p_ds + 1)) - end do - end if - - end subroutine s_initialize_data_output_module - - !> Module deallocation and/or disassociation procedures - impure subroutine s_finalize_data_output_module - - integer :: i - - if (probe_wrt) then - @:DEALLOCATE(c_mass) - end if - - if (run_time_info) then - ! Deallocating the ICFL, VCFL, CCFL, and Rc stability criteria - @:DEALLOCATE(icfl_sf) - if (viscous) then - @:DEALLOCATE(vcfl_sf, Rc_sf) - end if - end if - - if (down_sample) then - do i = 1, sys_size - deallocate (q_cons_temp_ds(i)%sf) - end do - deallocate (q_cons_temp_ds) - end if - - end subroutine s_finalize_data_output_module - -end module m_data_output +!> +!! @file +!! @brief Contains module m_data_output + +#:include 'macros.fpp' +#:include 'case.fpp' + +!> @brief Writes solution data, run-time stability diagnostics (ICFL, VCFL, CCFL, Rc), and probe/center-of-mass files +module m_data_output + + use m_derived_types !< Definitions of the derived types + + use m_global_parameters !< Definitions of the global parameters + + use m_mpi_proxy !< Message passing interface (MPI) module proxy + + use m_variables_conversion !< State variables type conversion procedures + + use m_compile_specific + + use m_helper + + use m_helper_basic !< Functions to compare floating point numbers + + use m_sim_helpers + + use m_delay_file_access + + use m_ibm + + use m_boundary_common + + use m_re_visc !< Non-Newtonian viscosity computations + + implicit none + + private; + public :: s_initialize_data_output_module, & + s_open_run_time_information_file, & + s_open_com_files, & + s_open_probe_files, & + s_write_run_time_information, & + s_write_data_files, & + s_write_serial_data_files, & + s_write_parallel_data_files, & + s_write_com_files, & + s_write_probe_files, & + s_close_run_time_information_file, & + s_close_com_files, & + s_close_probe_files, & + s_finalize_data_output_module, & + s_write_ib_data_file + + real(wp), allocatable, dimension(:, :, :) :: icfl_sf !< ICFL stability criterion + real(wp), allocatable, dimension(:, :, :) :: vcfl_sf !< VCFL stability criterion + real(wp), allocatable, dimension(:, :, :) :: ccfl_sf !< CCFL stability criterion + real(wp), allocatable, dimension(:, :, :) :: Rc_sf !< Rc stability criterion + real(wp), public, allocatable, dimension(:, :) :: c_mass + $:GPU_DECLARE(create='[icfl_sf,vcfl_sf,ccfl_sf,Rc_sf,c_mass]') + + real(wp) :: icfl_max_loc, icfl_max_glb !< ICFL stability extrema on local and global grids + real(wp) :: vcfl_max_loc, vcfl_max_glb !< VCFL stability extrema on local and global grids + real(wp) :: ccfl_max_loc, ccfl_max_glb !< CCFL stability extrema on local and global grids + real(wp) :: Rc_min_loc, Rc_min_glb !< Rc stability extrema on local and global grids + $:GPU_DECLARE(create='[icfl_max_loc,icfl_max_glb,vcfl_max_loc,vcfl_max_glb]') + $:GPU_DECLARE(create='[ccfl_max_loc,ccfl_max_glb,Rc_min_loc,Rc_min_glb]') + + !> @name ICFL, VCFL, CCFL and Rc stability criteria extrema over all the time-steps + !> @{ + real(wp) :: icfl_max !< ICFL criterion maximum + real(wp) :: vcfl_max !< VCFL criterion maximum + real(wp) :: ccfl_max !< CCFL criterion maximum + real(wp) :: Rc_min !< Rc criterion maximum + !> @} + + type(scalar_field), allocatable, dimension(:) :: q_cons_temp_ds + +contains + + !> Write data files. Dispatch subroutine that replaces procedure pointer. + !! @param q_cons_vf Conservative variables + !! @param q_T_sf Temperature scalar field + !! @param q_prim_vf Primitive variables + !! @param t_step Current time step + !! @param bc_type Boundary condition type + !! @param beta Eulerian void fraction from lagrangian bubbles + impure subroutine s_write_data_files(q_cons_vf, q_T_sf, q_prim_vf, t_step, bc_type, beta) + + type(scalar_field), & + dimension(sys_size), & + intent(inout) :: q_cons_vf + + type(scalar_field), & + intent(inout) :: q_T_sf + + type(scalar_field), & + dimension(sys_size), & + intent(inout) :: q_prim_vf + + integer, intent(in) :: t_step + + type(scalar_field), & + intent(inout), optional :: beta + + type(integer_field), & + dimension(1:num_dims, -1:1), & + intent(in) :: bc_type + + if (.not. parallel_io) then + call s_write_serial_data_files(q_cons_vf, q_T_sf, q_prim_vf, t_step, bc_type, beta) + else + call s_write_parallel_data_files(q_cons_vf, t_step, bc_type, beta) + end if + + end subroutine s_write_data_files + + !> The purpose of this subroutine is to open a new or pre- + !! existing run-time information file and append to it the + !! basic header information relevant to current simulation. + !! In general, this requires generating a table header for + !! those stability criteria which will be written at every + !! time-step. + impure subroutine s_open_run_time_information_file + + character(LEN=name_len), parameter :: file_name = 'run_time.inf' !< + !! Name of the run-time information file + + character(LEN=path_len + name_len) :: file_path !< + !! Relative path to a file in the case directory + + character(LEN=8) :: file_date !< + !! Creation date of the run-time information file + + ! Opening the run-time information file + file_path = trim(case_dir)//'/'//trim(file_name) + + open (3, FILE=trim(file_path), & + FORM='formatted', & + STATUS='replace') + + write (3, '(A)') 'Description: Stability information at '// & + 'each time-step of the simulation. This' + write (3, '(13X,A)') 'data is composed of the inviscid '// & + 'Courant–Friedrichs–Lewy (ICFL)' + write (3, '(13X,A)') 'number, the viscous CFL (VCFL) number, '// & + 'the capillary CFL (CCFL)' + write (3, '(13X,A)') 'number and the cell Reynolds (Rc) '// & + 'number. Please note that only' + write (3, '(13X,A)') 'those stability conditions pertinent '// & + 'to the physics included in' + write (3, '(13X,A)') 'the current computation are displayed.' + + call date_and_time(DATE=file_date) + + write (3, '(A)') 'Date: '//file_date(5:6)//'/'// & + file_date(7:8)//'/'// & + file_date(3:4) + + write (3, '(A)') ''; write (3, '(A)') '' + + ! Generating table header for the stability criteria to be outputted + write (3, '(13X,A9,13X,A10,13X,A10,13X,A10)', advance="no") & + trim('Time-step'), trim('dt'), trim('Time'), trim('ICFL Max') + + if (viscous) then + write (3, '(13X,A10,13X,A16)', advance="no") & + trim('VCFL Max'), trim('Rc Min') + end if + + write (3, *) ! new line + + end subroutine s_open_run_time_information_file + + !> This opens a formatted data file where the root processor + !! can write out the CoM information + impure subroutine s_open_com_files() + + character(len=path_len + 3*name_len) :: file_path !< + !! Relative path to the CoM file in the case directory + integer :: i !< Generic loop iterator + + do i = 1, num_fluids + ! Generating the relative path to the CoM data file + write (file_path, '(A,I0,A)') '/fluid', i, '_com.dat' + file_path = trim(case_dir)//trim(file_path) + ! Creating the formatted data file and setting up its + ! structure + open (i + 120, file=trim(file_path), & + form='formatted', & + position='append', & + status='unknown') + if (n == 0) then + write (i + 120, '(A)') ' Non-Dimensional Time '// & + ' Total Mass '// & + ' x-loc '// & + ' Total Volume ' + elseif (p == 0) then + write (i + 120, '(A)') ' Non-Dimensional Time '// & + ' Total Mass '// & + ' x-loc '// & + ' y-loc '// & + ' Total Volume ' + else + write (i + 120, '(A)') ' Non-Dimensional Time '// & + ' Total Mass '// & + ' x-loc '// & + ' y-loc '// & + ' z-loc '// & + ' Total Volume ' + end if + end do + end subroutine s_open_com_files + + !> This opens a formatted data file where the root processor + !! can write out flow probe information + impure subroutine s_open_probe_files + + character(LEN=path_len + 3*name_len) :: file_path !< + !! Relative path to the probe data file in the case directory + + integer :: i !< Generic loop iterator + logical :: file_exist + + do i = 1, num_probes + ! Generating the relative path to the data file + write (file_path, '(A,I0,A)') '/D/probe', i, '_prim.dat' + file_path = trim(case_dir)//trim(file_path) + + ! Creating the formatted data file and setting up its + ! structure + inquire (file=trim(file_path), exist=file_exist) + + if (file_exist) then + open (i + 30, FILE=trim(file_path), & + FORM='formatted', & + STATUS='old', & + POSITION='append') + else + open (i + 30, FILE=trim(file_path), & + FORM='formatted', & + STATUS='unknown') + end if + end do + + if (integral_wrt) then + do i = 1, num_integrals + write (file_path, '(A,I0,A)') '/D/integral', i, '_prim.dat' + file_path = trim(case_dir)//trim(file_path) + + open (i + 70, FILE=trim(file_path), & + FORM='formatted', & + POSITION='append', & + STATUS='unknown') + end do + end if + + end subroutine s_open_probe_files + + !> The goal of the procedure is to output to the run-time + !! information file the stability criteria extrema in the + !! entire computational domain and at the given time-step. + !! Moreover, the subroutine is also in charge of tracking + !! these stability criteria extrema over all time-steps. + !! @param q_prim_vf Cell-average primitive variables + !! @param t_step Current time step + impure subroutine s_write_run_time_information(q_prim_vf, t_step) + + type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf + integer, intent(in) :: t_step + + real(wp) :: rho !< Cell-avg. density + #:if not MFC_CASE_OPTIMIZATION and USING_AMD + real(wp), dimension(3) :: alpha !< Cell-avg. volume fraction + real(wp), dimension(3) :: vel !< Cell-avg. velocity + real(wp), dimension(3, 2) :: Re_visc_per_phase !< Per-phase Re_visc + #:else + real(wp), dimension(num_fluids) :: alpha !< Cell-avg. volume fraction + real(wp), dimension(num_vels) :: vel !< Cell-avg. velocity + real(wp), dimension(num_fluids, 2) :: Re_visc_per_phase !< Per-phase Re_visc + #:endif + real(wp) :: vel_sum !< Cell-avg. velocity sum + real(wp) :: pres !< Cell-avg. pressure + real(wp) :: gamma !< Cell-avg. sp. heat ratio + real(wp) :: pi_inf !< Cell-avg. liquid stiffness function + real(wp) :: qv !< Cell-avg. internal energy reference value + real(wp) :: c !< Cell-avg. sound speed + real(wp) :: H !< Cell-avg. enthalpy + real(wp), dimension(2) :: Re !< Cell-avg. Reynolds numbers + integer :: j, k, l + + ! Computing Stability Criteria at Current Time-step + $:GPU_PARALLEL_LOOP(collapse=3, private='[j,k,l,vel, alpha, Re, Re_visc_per_phase, rho, vel_sum, pres, gamma, pi_inf, c, H, qv]') + do l = 0, p + do k = 0, n + do j = 0, m + call s_compute_enthalpy(q_prim_vf, pres, rho, gamma, pi_inf, Re, H, alpha, vel, vel_sum, qv, j, k, l) + + ! For non-Newtonian fluids, compute variable Re based on shear rate + if (any_non_newtonian) then + call s_compute_re_visc(q_prim_vf, alpha, j, k, l, Re_visc_per_phase) + call s_compute_mixture_re(alpha, Re_visc_per_phase, Re) + end if + + call s_compute_speed_of_sound(pres, rho, gamma, pi_inf, H, alpha, vel_sum, 0._wp, c, qv) + + if (viscous) then + call s_compute_stability_from_dt(vel, c, rho, Re, j, k, l, icfl_sf, vcfl_sf, Rc_sf) + else + call s_compute_stability_from_dt(vel, c, rho, Re, j, k, l, icfl_sf) + end if + + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + + ! end: Computing Stability Criteria at Current Time-step + + ! Determining local stability criteria extrema at current time-step + +#ifdef _CRAYFTN + $:GPU_UPDATE(host='[icfl_sf]') + + if (viscous) then + $:GPU_UPDATE(host='[vcfl_sf,Rc_sf]') + end if + + icfl_max_loc = maxval(icfl_sf) + + if (viscous) then + vcfl_max_loc = maxval(vcfl_sf) + Rc_min_loc = minval(Rc_sf) + end if +#else + #:call GPU_PARALLEL(copyout='[icfl_max_loc]', copyin='[icfl_sf]') + icfl_max_loc = maxval(icfl_sf) + #:endcall GPU_PARALLEL + if (viscous .or. dummy) then + #:call GPU_PARALLEL(copyout='[vcfl_max_loc, Rc_min_loc]', copyin='[vcfl_sf,Rc_sf]') + vcfl_max_loc = maxval(vcfl_sf) + Rc_min_loc = minval(Rc_sf) + #:endcall GPU_PARALLEL + end if +#endif + + ! Determining global stability criteria extrema at current time-step + if (num_procs > 1) then + call s_mpi_reduce_stability_criteria_extrema(icfl_max_loc, & + vcfl_max_loc, & + Rc_min_loc, & + icfl_max_glb, & + vcfl_max_glb, & + Rc_min_glb) + else + icfl_max_glb = icfl_max_loc + if (viscous) vcfl_max_glb = vcfl_max_loc + if (viscous) Rc_min_glb = Rc_min_loc + end if + + ! Determining the stability criteria extrema over all the time-steps + if (icfl_max_glb > icfl_max) icfl_max = icfl_max_glb + + if (viscous) then + if (vcfl_max_glb > vcfl_max) vcfl_max = vcfl_max_glb + if (Rc_min_glb < Rc_min) Rc_min = Rc_min_glb + end if + + ! Outputting global stability criteria extrema at current time-step + if (proc_rank == 0) then + write (3, '(13X,I9,13X,F10.6,13X,F10.6,13X,F10.6)', advance="no") & + t_step, dt, mytime, icfl_max_glb + + if (viscous) then + write (3, '(13X,F10.6,13X,ES16.6)', advance="no") & + vcfl_max_glb, & + Rc_min_glb + end if + + write (3, *) ! new line + + if (.not. f_approx_equal(icfl_max_glb, icfl_max_glb)) then + call s_mpi_abort('ICFL is NaN. Exiting.') + elseif (icfl_max_glb > 1._wp) then + print *, 'icfl', icfl_max_glb + call s_mpi_abort('ICFL is greater than 1.0. Exiting.') + end if + + if (viscous) then + if (.not. f_approx_equal(vcfl_max_glb, vcfl_max_glb)) then + call s_mpi_abort('VCFL is NaN. Exiting.') + elseif (vcfl_max_glb > 1._wp) then + print *, 'vcfl', vcfl_max_glb + call s_mpi_abort('VCFL is greater than 1.0. Exiting.') + end if + end if + end if + + call s_mpi_barrier() + + end subroutine s_write_run_time_information + + !> The goal of this subroutine is to output the grid and + !! conservative variables data files for given time-step. + !! @param q_cons_vf Cell-average conservative variables + !! @param q_T_sf Temperature scalar field + !! @param q_prim_vf Cell-average primitive variables + !! @param t_step Current time-step + !! @param bc_type Boundary condition type + !! @param beta Eulerian void fraction from lagrangian bubbles + impure subroutine s_write_serial_data_files(q_cons_vf, q_T_sf, q_prim_vf, t_step, bc_type, beta) + + type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf + type(scalar_field), intent(inout) :: q_T_sf + type(scalar_field), dimension(sys_size), intent(inout) :: q_prim_vf + integer, intent(in) :: t_step + type(scalar_field), intent(inout), optional :: beta + type(integer_field), dimension(1:num_dims, -1:1), intent(in) :: bc_type + + character(LEN=path_len + 2*name_len) :: t_step_dir !< + !! Relative path to the current time-step directory + + character(LEN=path_len + 3*name_len) :: file_path !< + !! Relative path to the grid and conservative variables data files + + logical :: file_exist !< + !! Logical used to check existence of current time-step directory + + character(LEN=15) :: FMT + + integer :: i, j, k, l, r + + real(wp) :: gamma, lit_gamma, pi_inf, qv !< Temporary EOS params + + ! Creating or overwriting the time-step root directory + write (t_step_dir, '(A,I0,A,I0)') trim(case_dir)//'/p_all' + + ! Creating or overwriting the current time-step directory + write (t_step_dir, '(a,i0,a,i0)') trim(case_dir)//'/p_all/p', & + proc_rank, '/', t_step + + file_path = trim(t_step_dir)//'/.' + call my_inquire(file_path, file_exist) + if (file_exist) call s_delete_directory(trim(t_step_dir)) + call s_create_directory(trim(t_step_dir)) + + ! Writing the grid data file in the x-direction + file_path = trim(t_step_dir)//'/x_cb.dat' + + open (2, FILE=trim(file_path), & + FORM='unformatted', & + STATUS='new') + write (2) x_cb(-1:m); close (2) + + ! Writing the grid data files in the y- and z-directions + if (n > 0) then + + file_path = trim(t_step_dir)//'/y_cb.dat' + + open (2, FILE=trim(file_path), & + FORM='unformatted', & + STATUS='new') + write (2) y_cb(-1:n); close (2) + + if (p > 0) then + + file_path = trim(t_step_dir)//'/z_cb.dat' + + open (2, FILE=trim(file_path), & + FORM='unformatted', & + STATUS='new') + write (2) z_cb(-1:p); close (2) + + end if + + end if + + ! Writing the conservative variables data files + do i = 1, sys_size + write (file_path, '(A,I0,A)') trim(t_step_dir)//'/q_cons_vf', & + i, '.dat' + + open (2, FILE=trim(file_path), & + FORM='unformatted', & + STATUS='new') + + write (2) q_cons_vf(i)%sf(0:m, 0:n, 0:p); close (2) + end do + + ! Lagrangian beta (void fraction) written as q_cons_vf(sys_size+1) to + ! match the parallel I/O path and allow post_process to read it. + if (bubbles_lagrange) then + write (file_path, '(A,I0,A)') trim(t_step_dir)//'/q_cons_vf', & + sys_size + 1, '.dat' + + open (2, FILE=trim(file_path), & + FORM='unformatted', & + STATUS='new') + + write (2) beta%sf(0:m, 0:n, 0:p); close (2) + end if + + if (qbmm .and. .not. polytropic) then + do i = 1, nb + do r = 1, nnode + write (file_path, '(A,I0,A)') trim(t_step_dir)//'/pb', & + sys_size + (i - 1)*nnode + r, '.dat' + + open (2, FILE=trim(file_path), & + FORM='unformatted', & + STATUS='new') + + write (2) pb_ts(1)%sf(0:m, 0:n, 0:p, r, i); close (2) + end do + end do + + do i = 1, nb + do r = 1, nnode + write (file_path, '(A,I0,A)') trim(t_step_dir)//'/mv', & + sys_size + (i - 1)*nnode + r, '.dat' + + open (2, FILE=trim(file_path), & + FORM='unformatted', & + STATUS='new') + + write (2) mv_ts(1)%sf(0:m, 0:n, 0:p, r, i); close (2) + end do + end do + end if + + ! Writing the IB markers + if (ib) then + call s_write_serial_ib_data(t_step) + ! write (file_path, '(A,I0,A)') trim(t_step_dir)//'/ib.dat' + + ! open (2, FILE=trim(file_path), & + ! FORM='unformatted', & + ! STATUS='new') + + ! write (2) ib_markers%sf(0:m, 0:n, 0:p); close (2) + end if + + gamma = gammas(1) + lit_gamma = gs_min(1) + pi_inf = pi_infs(1) + qv = qvs(1) + + if (precision == 1) then + FMT = "(2F30.3)" + else + FMT = "(2F40.14)" + end if + + ! writing an output directory + write (t_step_dir, '(A,I0,A,I0)') trim(case_dir)//'/D' + file_path = trim(t_step_dir)//'/.' + + inquire (FILE=trim(file_path), EXIST=file_exist) + + if (.not. file_exist) call s_create_directory(trim(t_step_dir)) + + if ((prim_vars_wrt .or. (n == 0 .and. p == 0)) .and. (.not. igr)) then + call s_convert_conservative_to_primitive_variables(q_cons_vf, q_T_sf, q_prim_vf, idwint) + do i = 1, sys_size + $:GPU_UPDATE(host='[q_prim_vf(i)%sf(:,:,:)]') + end do + ! q_prim_vf(bubxb) stores the value of nb needed in riemann solvers, so replace with true primitive value (=1._wp) + if (qbmm) then + q_prim_vf(bubxb)%sf = 1._wp + end if + end if + + !1D + if (n == 0 .and. p == 0) then + + if (model_eqns == 2 .and. (.not. igr)) then + do i = 1, sys_size + write (file_path, '(A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir)//'/prim.', i, '.', proc_rank, '.', t_step, '.dat' + + open (2, FILE=trim(file_path)) + do j = 0, m + ! todo: revisit change here + if (((i >= adv_idx%beg) .and. (i <= adv_idx%end))) then + write (2, FMT) x_cb(j), q_cons_vf(i)%sf(j, 0, 0) + else + write (2, FMT) x_cb(j), q_prim_vf(i)%sf(j, 0, 0) + end if + end do + close (2) + end do + end if + + do i = 1, sys_size + write (file_path, '(A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir)//'/cons.', i, '.', proc_rank, '.', t_step, '.dat' + + open (2, FILE=trim(file_path)) + do j = 0, m + write (2, FMT) x_cb(j), q_cons_vf(i)%sf(j, 0, 0) + end do + close (2) + end do + + if (qbmm .and. .not. polytropic) then + do i = 1, nb + do r = 1, nnode + write (file_path, '(A,I0,A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir)//'/pres.', i, '.', r, '.', proc_rank, '.', t_step, '.dat' + + open (2, FILE=trim(file_path)) + do j = 0, m + write (2, FMT) x_cb(j), pb_ts(1)%sf(j, 0, 0, r, i) + end do + close (2) + end do + end do + do i = 1, nb + do r = 1, nnode + write (file_path, '(A,I0,A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir)//'/mv.', i, '.', r, '.', proc_rank, '.', t_step, '.dat' + + open (2, FILE=trim(file_path)) + do j = 0, m + write (2, FMT) x_cb(j), mv_ts(1)%sf(j, 0, 0, r, i) + end do + close (2) + end do + end do + end if + end if + + if (precision == 1) then + FMT = "(3F30.7)" + else + FMT = "(3F40.14)" + end if + + ! 2D + if ((n > 0) .and. (p == 0)) then + do i = 1, sys_size + write (file_path, '(A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir)//'/cons.', i, '.', proc_rank, '.', t_step, '.dat' + open (2, FILE=trim(file_path)) + do j = 0, m + do k = 0, n + write (2, FMT) x_cb(j), y_cb(k), q_cons_vf(i)%sf(j, k, 0) + end do + write (2, *) + end do + close (2) + end do + + if (present(beta)) then + write (file_path, '(A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir)//'/beta.', i, '.', proc_rank, '.', t_step, '.dat' + open (2, FILE=trim(file_path)) + do j = 0, m + do k = 0, n + write (2, FMT) x_cb(j), y_cb(k), beta%sf(j, k, 0) + end do + write (2, *) + end do + close (2) + end if + + if (qbmm .and. .not. polytropic) then + do i = 1, nb + do r = 1, nnode + write (file_path, '(A,I0,A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir)//'/pres.', i, '.', r, '.', proc_rank, '.', t_step, '.dat' + + open (2, FILE=trim(file_path)) + do j = 0, m + do k = 0, n + write (2, FMT) x_cb(j), y_cb(k), pb_ts(1)%sf(j, k, 0, r, i) + end do + end do + close (2) + end do + end do + do i = 1, nb + do r = 1, nnode + write (file_path, '(A,I0,A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir)//'/mv.', i, '.', r, '.', proc_rank, '.', t_step, '.dat' + + open (2, FILE=trim(file_path)) + do j = 0, m + do k = 0, n + write (2, FMT) x_cb(j), y_cb(k), mv_ts(1)%sf(j, k, 0, r, i) + end do + end do + close (2) + end do + end do + end if + + if (prim_vars_wrt .and. (.not. igr)) then + do i = 1, sys_size + write (file_path, '(A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir)//'/prim.', i, '.', proc_rank, '.', t_step, '.dat' + + open (2, FILE=trim(file_path)) + + do j = 0, m + do k = 0, n + if (((i >= cont_idx%beg) .and. (i <= cont_idx%end)) & + .or. & + ((i >= adv_idx%beg) .and. (i <= adv_idx%end)) & + ) then + write (2, FMT) x_cb(j), y_cb(k), q_cons_vf(i)%sf(j, k, 0) + else + write (2, FMT) x_cb(j), y_cb(k), q_prim_vf(i)%sf(j, k, 0) + end if + end do + write (2, *) + end do + close (2) + end do + end if + end if + + if (precision == 1) then + FMT = "(4F30.7)" + else + FMT = "(4F40.14)" + end if + + ! 3D + if (p > 0) then + do i = 1, sys_size + write (file_path, '(A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir)//'/cons.', i, '.', proc_rank, '.', t_step, '.dat' + open (2, FILE=trim(file_path)) + do j = 0, m + do k = 0, n + do l = 0, p + write (2, FMT) x_cb(j), y_cb(k), z_cb(l), q_cons_vf(i)%sf(j, k, l) + end do + write (2, *) + end do + write (2, *) + end do + close (2) + end do + + if (present(beta)) then + write (file_path, '(A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir)//'/beta.', i, '.', proc_rank, '.', t_step, '.dat' + open (2, FILE=trim(file_path)) + do j = 0, m + do k = 0, n + do l = 0, p + write (2, FMT) x_cb(j), y_cb(k), z_cb(l), beta%sf(j, k, l) + end do + write (2, *) + end do + write (2, *) + end do + close (2) + end if + + if (qbmm .and. .not. polytropic) then + do i = 1, nb + do r = 1, nnode + write (file_path, '(A,I0,A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir)//'/pres.', i, '.', r, '.', proc_rank, '.', t_step, '.dat' + + open (2, FILE=trim(file_path)) + do j = 0, m + do k = 0, n + do l = 0, p + write (2, FMT) x_cb(j), y_cb(k), z_cb(l), pb_ts(1)%sf(j, k, l, r, i) + end do + end do + end do + close (2) + end do + end do + do i = 1, nb + do r = 1, nnode + write (file_path, '(A,I0,A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir)//'/mv.', i, '.', r, '.', proc_rank, '.', t_step, '.dat' + + open (2, FILE=trim(file_path)) + do j = 0, m + do k = 0, n + do l = 0, p + write (2, FMT) x_cb(j), y_cb(k), z_cb(l), mv_ts(1)%sf(j, k, l, r, i) + end do + end do + end do + close (2) + end do + end do + end if + + if (prim_vars_wrt .and. (.not. igr)) then + do i = 1, sys_size + write (file_path, '(A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir)//'/prim.', i, '.', proc_rank, '.', t_step, '.dat' + + open (2, FILE=trim(file_path)) + + do j = 0, m + do k = 0, n + do l = 0, p + if (((i >= cont_idx%beg) .and. (i <= cont_idx%end)) & + .or. & + ((i >= adv_idx%beg) .and. (i <= adv_idx%end)) & + .or. & + ((i >= chemxb) .and. (i <= chemxe)) & + ) then + write (2, FMT) x_cb(j), y_cb(k), z_cb(l), q_cons_vf(i)%sf(j, k, l) + else + write (2, FMT) x_cb(j), y_cb(k), z_cb(l), q_prim_vf(i)%sf(j, k, l) + end if + end do + write (2, *) + end do + write (2, *) + end do + close (2) + end do + end if + end if + + end subroutine s_write_serial_data_files + + !> The goal of this subroutine is to output the grid and + !! conservative variables data files for given time-step. + !! @param q_cons_vf Cell-average conservative variables + !! @param t_step Current time-step + !! @param bc_type Boundary condition type + !! @param beta Eulerian void fraction from lagrangian bubbles + impure subroutine s_write_parallel_data_files(q_cons_vf, t_step, bc_type, beta) + + type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf + integer, intent(in) :: t_step + type(scalar_field), intent(inout), optional :: beta + type(integer_field), & + dimension(1:num_dims, -1:1), & + intent(in) :: bc_type + +#ifdef MFC_MPI + + integer :: ifile, ierr, data_size + integer, dimension(MPI_STATUS_SIZE) :: status + integer(kind=MPI_OFFSET_kind) :: disp + integer(kind=MPI_OFFSET_kind) :: m_MOK, n_MOK, p_MOK + integer(kind=MPI_OFFSET_kind) :: WP_MOK, var_MOK, str_MOK + integer(kind=MPI_OFFSET_kind) :: NVARS_MOK + integer(kind=MPI_OFFSET_kind) :: MOK + + character(LEN=path_len + 2*name_len) :: file_loc + logical :: file_exist, dir_check + character(len=10) :: t_step_string + + integer :: i !< Generic loop iterator + + integer :: alt_sys !< Altered system size for the lagrangian subgrid bubble model + + ! Down sampling variables + integer :: m_ds, n_ds, p_ds + integer :: m_glb_ds, n_glb_ds, p_glb_ds + integer :: m_glb_save, n_glb_save, p_glb_save ! Global save size + + if (down_sample) then + call s_downsample_data(q_cons_vf, q_cons_temp_ds, & + m_ds, n_ds, p_ds, m_glb_ds, n_glb_ds, p_glb_ds) + end if + + if (present(beta)) then + alt_sys = sys_size + 1 + else + alt_sys = sys_size + end if + + if (file_per_process) then + + call s_int_to_str(t_step, t_step_string) + + ! Initialize MPI data I/O + if (down_sample) then + call s_initialize_mpi_data_ds(q_cons_temp_ds) + else + if (ib) then + call s_initialize_mpi_data(q_cons_vf, ib_markers) + else + call s_initialize_mpi_data(q_cons_vf) + end if + end if + + if (proc_rank == 0) then + file_loc = trim(case_dir)//'/restart_data/lustre_'//trim(t_step_string) + call my_inquire(file_loc, dir_check) + if (dir_check .neqv. .true.) then + call s_create_directory(trim(file_loc)) + end if + call s_create_directory(trim(file_loc)) + end if + call s_mpi_barrier() + call DelayFileAccess(proc_rank) + + ! Initialize MPI data I/O + call s_initialize_mpi_data(q_cons_vf) + + ! Open the file to write all flow variables + write (file_loc, '(I0,A,i7.7,A)') t_step, '_', proc_rank, '.dat' + file_loc = trim(case_dir)//'/restart_data/lustre_'//trim(t_step_string)//trim(mpiiofs)//trim(file_loc) + inquire (FILE=trim(file_loc), EXIST=file_exist) + if (file_exist .and. proc_rank == 0) then + call MPI_FILE_DELETE(file_loc, mpi_info_int, ierr) + end if + call MPI_FILE_OPEN(MPI_COMM_SELF, file_loc, ior(MPI_MODE_WRONLY, MPI_MODE_CREATE), & + mpi_info_int, ifile, ierr) + + if (down_sample) then + ! Size of local arrays + data_size = (m_ds + 3)*(n_ds + 3)*(p_ds + 3) + m_glb_save = m_glb_ds + 1 + n_glb_save = n_glb_ds + 1 + p_glb_save = p_glb_ds + 1 + else + ! Size of local arrays + data_size = (m + 1)*(n + 1)*(p + 1) + m_glb_save = m_glb + 1 + n_glb_save = n_glb + 1 + p_glb_save = p_glb + 1 + end if + + ! Resize some integers so MPI can write even the biggest files + m_MOK = int(m_glb_save + 1, MPI_OFFSET_KIND) + n_MOK = int(n_glb_save + 1, MPI_OFFSET_KIND) + p_MOK = int(p_glb_save + 1, MPI_OFFSET_KIND) + WP_MOK = int(8._wp, MPI_OFFSET_KIND) + MOK = int(1._wp, MPI_OFFSET_KIND) + str_MOK = int(name_len, MPI_OFFSET_KIND) + NVARS_MOK = int(sys_size, MPI_OFFSET_KIND) + + if (bubbles_euler) then + ! Write the data for each variable + do i = 1, sys_size + var_MOK = int(i, MPI_OFFSET_KIND) + + call MPI_FILE_WRITE_ALL(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, & + mpi_io_p, status, ierr) + end do + !Write pb and mv for non-polytropic qbmm + if (qbmm .and. .not. polytropic) then + do i = sys_size + 1, sys_size + 2*nb*nnode + var_MOK = int(i, MPI_OFFSET_KIND) + + call MPI_FILE_WRITE_ALL(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, & + mpi_io_p, status, ierr) + end do + end if + else + if (down_sample) then + do i = 1, sys_size !TODO: check if correct (sys_size + var_MOK = int(i, MPI_OFFSET_KIND) + + call MPI_FILE_WRITE_ALL(ifile, q_cons_temp_ds(i)%sf, data_size*mpi_io_type, & + mpi_io_p, status, ierr) + end do + else + do i = 1, sys_size !TODO: check if correct (sys_size + var_MOK = int(i, MPI_OFFSET_KIND) + + call MPI_FILE_WRITE_ALL(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, & + mpi_io_p, status, ierr) + end do + end if + end if + + call MPI_FILE_CLOSE(ifile, ierr) + else + ! Initialize MPI data I/O + + if (ib) then + call s_initialize_mpi_data(q_cons_vf, ib_markers) + elseif (present(beta)) then + call s_initialize_mpi_data(q_cons_vf, beta=beta) + else + call s_initialize_mpi_data(q_cons_vf) + end if + + write (file_loc, '(I0,A)') t_step, '.dat' + file_loc = trim(case_dir)//'/restart_data'//trim(mpiiofs)//trim(file_loc) + inquire (FILE=trim(file_loc), EXIST=file_exist) + if (file_exist .and. proc_rank == 0) then + call MPI_FILE_DELETE(file_loc, mpi_info_int, ierr) + end if + call MPI_FILE_OPEN(MPI_COMM_WORLD, file_loc, ior(MPI_MODE_WRONLY, MPI_MODE_CREATE), & + mpi_info_int, ifile, ierr) + + ! Size of local arrays + data_size = (m + 1)*(n + 1)*(p + 1) + + ! Resize some integers so MPI can write even the biggest files + m_MOK = int(m_glb + 1, MPI_OFFSET_KIND) + n_MOK = int(n_glb + 1, MPI_OFFSET_KIND) + p_MOK = int(p_glb + 1, MPI_OFFSET_KIND) + WP_MOK = int(8._wp, MPI_OFFSET_KIND) + MOK = int(1._wp, MPI_OFFSET_KIND) + str_MOK = int(name_len, MPI_OFFSET_KIND) + NVARS_MOK = int(alt_sys, MPI_OFFSET_KIND) + + if (bubbles_euler) then + ! Write the data for each variable + do i = 1, sys_size + var_MOK = int(i, MPI_OFFSET_KIND) + + ! Initial displacement to skip at beginning of file + disp = m_MOK*max(MOK, n_MOK)*max(MOK, p_MOK)*WP_MOK*(var_MOK - 1) + + call MPI_FILE_SET_VIEW(ifile, disp, mpi_p, MPI_IO_DATA%view(i), & + 'native', mpi_info_int, ierr) + call MPI_FILE_WRITE_ALL(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, & + mpi_io_p, status, ierr) + end do + !Write pb and mv for non-polytropic qbmm + if (qbmm .and. .not. polytropic) then + do i = sys_size + 1, sys_size + 2*nb*nnode + var_MOK = int(i, MPI_OFFSET_KIND) + + ! Initial displacement to skip at beginning of file + disp = m_MOK*max(MOK, n_MOK)*max(MOK, p_MOK)*WP_MOK*(var_MOK - 1) + + call MPI_FILE_SET_VIEW(ifile, disp, mpi_p, MPI_IO_DATA%view(i), & + 'native', mpi_info_int, ierr) + call MPI_FILE_WRITE_ALL(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, & + mpi_io_p, status, ierr) + end do + end if + else + do i = 1, sys_size !TODO: check if correct (sys_size + var_MOK = int(i, MPI_OFFSET_KIND) + + ! Initial displacement to skip at beginning of file + disp = m_MOK*max(MOK, n_MOK)*max(MOK, p_MOK)*WP_MOK*(var_MOK - 1) + + call MPI_FILE_SET_VIEW(ifile, disp, mpi_p, MPI_IO_DATA%view(i), & + 'native', mpi_info_int, ierr) + call MPI_FILE_WRITE_ALL(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, & + mpi_io_p, status, ierr) + end do + end if + + ! Correction for the lagrangian subgrid bubble model + if (present(beta)) then + var_MOK = int(sys_size + 1, MPI_OFFSET_KIND) + + ! Initial displacement to skip at beginning of file + disp = m_MOK*max(MOK, n_MOK)*max(MOK, p_MOK)*WP_MOK*(var_MOK - 1) + + call MPI_FILE_SET_VIEW(ifile, disp, mpi_p, MPI_IO_DATA%view(sys_size + 1), & + 'native', mpi_info_int, ierr) + call MPI_FILE_WRITE_ALL(ifile, MPI_IO_DATA%var(sys_size + 1)%sf, data_size*mpi_io_type, & + mpi_io_p, status, ierr) + end if + + call MPI_FILE_CLOSE(ifile, ierr) + + !Write ib data + if (ib) then + call s_write_parallel_ib_data(t_step) + ! write (file_loc, '(A)') 'ib.dat' + ! file_loc = trim(case_dir)//'/restart_data'//trim(mpiiofs)//trim(file_loc) + ! call MPI_FILE_OPEN(MPI_COMM_WORLD, file_loc, ior(MPI_MODE_WRONLY, MPI_MODE_CREATE), & + ! mpi_info_int, ifile, ierr) + + ! var_MOK = int(sys_size + 1, MPI_OFFSET_KIND) + ! disp = m_MOK*max(MOK, n_MOK)*max(MOK, p_MOK)*WP_MOK*(var_MOK - 1 + int(t_step/t_step_save)) + + ! call MPI_FILE_SET_VIEW(ifile, disp, MPI_INTEGER, MPI_IO_IB_DATA%view, & + ! 'native', mpi_info_int, ierr) + ! call MPI_FILE_WRITE_ALL(ifile, MPI_IO_IB_DATA%var%sf, data_size, & + ! MPI_INTEGER, status, ierr) + ! call MPI_FILE_CLOSE(ifile, ierr) + end if + + end if +#endif + + end subroutine s_write_parallel_data_files + + !> @brief Writes immersed boundary marker data to a serial (per-processor) unformatted file. + subroutine s_write_serial_ib_data(time_step) + + integer, intent(in) :: time_step + character(LEN=path_len + 2*name_len) :: file_path + character(LEN=path_len + 2*name_len) :: t_step_dir + + ! Creating or overwriting the time-step root directory + write (t_step_dir, '(A,I0,A,I0)') trim(case_dir)//'/p_all' + write (t_step_dir, '(a,i0,a,i0)') trim(case_dir)//'/p_all/p', & + proc_rank, '/', time_step + write (file_path, '(A,I0,A)') trim(t_step_dir)//'/ib.dat' + + open (2, FILE=trim(file_path), & + FORM='unformatted', & + STATUS='new') + + $:GPU_UPDATE(host='[ib_markers%sf]') + write (2) ib_markers%sf(0:m, 0:n, 0:p); close (2) + + end subroutine + + !> @brief Writes immersed boundary marker data in parallel using MPI I/O. + subroutine s_write_parallel_ib_data(time_step) + + integer, intent(in) :: time_step + +#ifdef MFC_MPI + + character(LEN=path_len + 2*name_len) :: file_loc + integer(kind=MPI_OFFSET_kind) :: disp + integer(kind=MPI_OFFSET_kind) :: m_MOK, n_MOK, p_MOK + integer(kind=MPI_OFFSET_kind) :: WP_MOK, var_MOK, MOK + integer :: ifile, ierr, data_size + integer, dimension(MPI_STATUS_SIZE) :: status + + $:GPU_UPDATE(host='[ib_markers%sf]') + + ! Size of local arrays + data_size = (m + 1)*(n + 1)*(p + 1) + m_MOK = int(m_glb + 1, MPI_OFFSET_KIND) + n_MOK = int(n_glb + 1, MPI_OFFSET_KIND) + p_MOK = int(p_glb + 1, MPI_OFFSET_KIND) + WP_MOK = int(8._wp, MPI_OFFSET_KIND) + MOK = int(1._wp, MPI_OFFSET_KIND) + + write (file_loc, '(A)') 'ib.dat' + file_loc = trim(case_dir)//'/restart_data'//trim(mpiiofs)//trim(file_loc) + call MPI_FILE_OPEN(MPI_COMM_WORLD, file_loc, ior(MPI_MODE_WRONLY, MPI_MODE_CREATE), & + mpi_info_int, ifile, ierr) + + var_MOK = int(sys_size + 1, MPI_OFFSET_KIND) + disp = m_MOK*max(MOK, n_MOK)*max(MOK, p_MOK)*WP_MOK*(var_MOK - 1 + int(time_step/t_step_save)) + if (time_step == 0) disp = 0 + + call MPI_FILE_SET_VIEW(ifile, disp, MPI_INTEGER, MPI_IO_IB_DATA%view, & + 'native', mpi_info_int, ierr) + call MPI_FILE_WRITE_ALL(ifile, MPI_IO_IB_DATA%var%sf, data_size, & + MPI_INTEGER, status, ierr) + call MPI_FILE_CLOSE(ifile, ierr) + +#endif + + end subroutine s_write_parallel_ib_data + + !> @brief Dispatches immersed boundary data output to the serial or parallel writer. + subroutine s_write_ib_data_file(time_step) + + integer, intent(in) :: time_step + + if (parallel_io) then + call s_write_parallel_ib_data(time_step) + else + call s_write_serial_ib_data(time_step) + end if + + end subroutine + + !> This writes a formatted data file where the root processor + !! can write out the CoM information + !! @param t_step Current time-step + !! @param c_mass_in Center of mass information + impure subroutine s_write_com_files(t_step, c_mass_in) + + integer, intent(in) :: t_step + real(wp), dimension(num_fluids, 5), intent(in) :: c_mass_in + integer :: i !< Generic loop iterator + real(wp) :: nondim_time !< Non-dimensional time + + ! Non-dimensional time calculation + if (t_step_old /= dflt_int) then + nondim_time = real(t_step + t_step_old, wp)*dt + else + nondim_time = real(t_step, wp)*dt + end if + + if (proc_rank == 0) then + if (n == 0) then ! 1D simulation + do i = 1, num_fluids ! Loop through fluids + write (i + 120, '(6X,4F24.12)') & + nondim_time, & + c_mass_in(i, 1), & + c_mass_in(i, 2), & + c_mass_in(i, 5) + end do + elseif (p == 0) then ! 2D simulation + do i = 1, num_fluids ! Loop through fluids + write (i + 120, '(6X,5F24.12)') & + nondim_time, & + c_mass_in(i, 1), & + c_mass_in(i, 2), & + c_mass_in(i, 3), & + c_mass_in(i, 5) + end do + else ! 3D simulation + do i = 1, num_fluids ! Loop through fluids + write (i + 120, '(6X,6F24.12)') & + nondim_time, & + c_mass_in(i, 1), & + c_mass_in(i, 2), & + c_mass_in(i, 3), & + c_mass_in(i, 4), & + c_mass_in(i, 5) + end do + end if + end if + + end subroutine s_write_com_files + + !> This writes a formatted data file for the flow probe information + !! @param t_step Current time-step + !! @param q_cons_vf Conservative variables + !! @param accel_mag Acceleration magnitude information + impure subroutine s_write_probe_files(t_step, q_cons_vf, accel_mag) + + integer, intent(in) :: t_step + type(scalar_field), dimension(sys_size), intent(in) :: q_cons_vf + real(wp), dimension(0:m, 0:n, 0:p), intent(in) :: accel_mag + + real(wp), dimension(-1:m) :: distx + real(wp), dimension(-1:n) :: disty + real(wp), dimension(-1:p) :: distz + + ! The cell-averaged partial densities, density, velocity, pressure, + ! volume fractions, specific heat ratio function, liquid stiffness + ! function, and sound speed. + real(wp) :: lit_gamma, nbub + real(wp) :: rho + real(wp), dimension(num_vels) :: vel + real(wp) :: pres + real(wp) :: ptilde + real(wp) :: ptot + real(wp) :: alf + real(wp) :: alfgr + real(wp), dimension(num_fluids) :: alpha + real(wp) :: gamma + real(wp) :: pi_inf + real(wp) :: qv + real(wp) :: c + real(wp) :: M00, M10, M01, M20, M11, M02 + real(wp) :: varR, varV + real(wp), dimension(Nb) :: nR, R, nRdot, Rdot + real(wp) :: nR3 + real(wp) :: accel + real(wp) :: int_pres + real(wp) :: max_pres + real(wp), dimension(2) :: Re + real(wp), dimension(6) :: tau_e + real(wp) :: G_local + real(wp) :: dyn_p, T + real(wp) :: damage_state + + integer :: i, j, k, l, s, d !< Generic loop iterator + + real(wp) :: nondim_time !< Non-dimensional time + + real(wp) :: tmp !< + !! Temporary variable to store quantity for mpi_allreduce + + integer :: npts !< Number of included integral points + real(wp) :: rad, thickness !< For integral quantities + logical :: trigger !< For integral quantities + + real(wp) :: rhoYks(1:num_species) + + T = dflt_T_guess + + ! Non-dimensional time calculation + if (time_stepper == 23) then + nondim_time = mytime + else + if (t_step_old /= dflt_int) then + nondim_time = real(t_step + t_step_old, wp)*dt + else + nondim_time = real(t_step, wp)*dt + end if + end if + + do i = 1, num_probes + ! Zeroing out flow variables for all processors + rho = 0._wp + do s = 1, num_vels + vel(s) = 0._wp + end do + pres = 0._wp + gamma = 0._wp + pi_inf = 0._wp + qv = 0._wp + c = 0._wp + accel = 0._wp + nR = 0._wp; R = 0._wp + nRdot = 0._wp; Rdot = 0._wp + nbub = 0._wp + M00 = 0._wp + M10 = 0._wp + M01 = 0._wp + M20 = 0._wp + M11 = 0._wp + M02 = 0._wp + varR = 0._wp; varV = 0._wp + alf = 0._wp + do s = 1, (num_dims*(num_dims + 1))/2 + tau_e(s) = 0._wp + end do + damage_state = 0._wp + + ! Find probe location in terms of indices on a + ! specific processor + if (n == 0) then ! 1D simulation + if ((probe(i)%x >= x_cb(-1)) .and. (probe(i)%x <= x_cb(m))) then + do s = -1, m + distx(s) = x_cb(s) - probe(i)%x + if (distx(s) < 0._wp) distx(s) = 1000._wp + end do + j = minloc(distx, 1) + if (j == 1) j = 2 ! Pick first point if probe is at edge + k = 0 + l = 0 + + if (chemistry) then + do d = 1, num_species + rhoYks(d) = q_cons_vf(chemxb + d - 1)%sf(j - 2, k, l) + end do + end if + + ! Computing/Sharing necessary state variables + if (elasticity) then + call s_convert_to_mixture_variables(q_cons_vf, j - 2, k, l, & + rho, gamma, pi_inf, qv, & + Re, G_local, fluid_pp(:)%G) + else + call s_convert_to_mixture_variables(q_cons_vf, j - 2, k, l, & + rho, gamma, pi_inf, qv) + end if + do s = 1, num_vels + vel(s) = q_cons_vf(cont_idx%end + s)%sf(j - 2, k, l)/rho + end do + + dyn_p = 0.5_wp*rho*dot_product(vel, vel) + + if (elasticity) then + if (cont_damage) then + damage_state = q_cons_vf(damage_idx)%sf(j - 2, k, l) + G_local = G_local*max((1._wp - damage_state), 0._wp) + end if + + call s_compute_pressure( & + q_cons_vf(1)%sf(j - 2, k, l), & + q_cons_vf(alf_idx)%sf(j - 2, k, l), & + dyn_p, pi_inf, gamma, rho, qv, rhoYks(:), pres, T, & + q_cons_vf(stress_idx%beg)%sf(j - 2, k, l), & + q_cons_vf(mom_idx%beg)%sf(j - 2, k, l), G_local) + else + call s_compute_pressure( & + q_cons_vf(E_idx)%sf(j - 2, k, l), & + q_cons_vf(alf_idx)%sf(j - 2, k, l), & + dyn_p, pi_inf, gamma, rho, qv, rhoYks, pres, T) + end if + + if (model_eqns == 4) then + lit_gamma = gammas(1) + else if (elasticity) then + tau_e(1) = q_cons_vf(stress_idx%end)%sf(j - 2, k, l)/rho + end if + + if (bubbles_euler) then + alf = q_cons_vf(alf_idx)%sf(j - 2, k, l) + if (num_fluids == 3) then + alfgr = q_cons_vf(alf_idx - 1)%sf(j - 2, k, l) + end if + do s = 1, nb + nR(s) = q_cons_vf(bub_idx%rs(s))%sf(j - 2, k, l) + nRdot(s) = q_cons_vf(bub_idx%vs(s))%sf(j - 2, k, l) + end do + + if (adv_n) then + nbub = q_cons_vf(n_idx)%sf(j - 2, k, l) + else + nR3 = 0._wp + do s = 1, nb + nR3 = nR3 + weight(s)*(nR(s)**3._wp) + end do + + nbub = sqrt((4._wp*pi/3._wp)*nR3/alf) + end if +#ifdef DEBUG + print *, 'In probe, nbub: ', nbub +#endif + if (qbmm) then + M00 = q_cons_vf(bub_idx%moms(1, 1))%sf(j - 2, k, l)/nbub + M10 = q_cons_vf(bub_idx%moms(1, 2))%sf(j - 2, k, l)/nbub + M01 = q_cons_vf(bub_idx%moms(1, 3))%sf(j - 2, k, l)/nbub + M20 = q_cons_vf(bub_idx%moms(1, 4))%sf(j - 2, k, l)/nbub + M11 = q_cons_vf(bub_idx%moms(1, 5))%sf(j - 2, k, l)/nbub + M02 = q_cons_vf(bub_idx%moms(1, 6))%sf(j - 2, k, l)/nbub + + M10 = M10/M00 + M01 = M01/M00 + M20 = M20/M00 + M11 = M11/M00 + M02 = M02/M00 + + varR = M20 - M10**2._wp + varV = M02 - M01**2._wp + end if + R(:) = nR(:)/nbub + Rdot(:) = nRdot(:)/nbub + + ptilde = ptil(j - 2, k, l) + ptot = pres - ptilde + end if + + ! Compute mixture sound Speed + call s_compute_speed_of_sound(pres, rho, gamma, pi_inf, & + ((gamma + 1._wp)*pres + pi_inf)/rho, alpha, 0._wp, 0._wp, c, qv) + + accel = accel_mag(j - 2, k, l) + end if + elseif (p == 0) then ! 2D simulation + if (chemistry) then + do d = 1, num_species + rhoYks(d) = q_cons_vf(chemxb + d - 1)%sf(j - 2, k - 2, l) + end do + end if + + if ((probe(i)%x >= x_cb(-1)) .and. (probe(i)%x <= x_cb(m))) then + if ((probe(i)%y >= y_cb(-1)) .and. (probe(i)%y <= y_cb(n))) then + do s = -1, m + distx(s) = x_cb(s) - probe(i)%x + if (distx(s) < 0._wp) distx(s) = 1000._wp + end do + do s = -1, n + disty(s) = y_cb(s) - probe(i)%y + if (disty(s) < 0._wp) disty(s) = 1000._wp + end do + j = minloc(distx, 1) + k = minloc(disty, 1) + if (j == 1) j = 2 ! Pick first point if probe is at edge + if (k == 1) k = 2 ! Pick first point if probe is at edge + l = 0 + + ! Computing/Sharing necessary state variables + call s_convert_to_mixture_variables(q_cons_vf, j - 2, k - 2, l, & + rho, gamma, pi_inf, qv, & + Re, G_local, fluid_pp(:)%G) + do s = 1, num_vels + vel(s) = q_cons_vf(cont_idx%end + s)%sf(j - 2, k - 2, l)/rho + end do + + dyn_p = 0.5_wp*rho*dot_product(vel, vel) + + if (elasticity) then + if (cont_damage) then + damage_state = q_cons_vf(damage_idx)%sf(j - 2, k - 2, l) + G_local = G_local*max((1._wp - damage_state), 0._wp) + end if + + call s_compute_pressure( & + q_cons_vf(1)%sf(j - 2, k - 2, l), & + q_cons_vf(alf_idx)%sf(j - 2, k - 2, l), & + dyn_p, pi_inf, gamma, rho, qv, & + rhoYks, & + pres, & + T, & + q_cons_vf(stress_idx%beg)%sf(j - 2, k - 2, l), & + q_cons_vf(mom_idx%beg)%sf(j - 2, k - 2, l), G_local) + else + call s_compute_pressure(q_cons_vf(E_idx)%sf(j - 2, k - 2, l), & + q_cons_vf(alf_idx)%sf(j - 2, k - 2, l), & + dyn_p, pi_inf, gamma, rho, qv, & + rhoYks, pres, T) + end if + + if (model_eqns == 4) then + lit_gamma = gs_min(1) + else if (elasticity) then + do s = 1, 3 + tau_e(s) = q_cons_vf(s)%sf(j - 2, k - 2, l)/rho + end do + end if + + if (bubbles_euler) then + alf = q_cons_vf(alf_idx)%sf(j - 2, k - 2, l) + do s = 1, nb + nR(s) = q_cons_vf(bub_idx%rs(s))%sf(j - 2, k - 2, l) + nRdot(s) = q_cons_vf(bub_idx%vs(s))%sf(j - 2, k - 2, l) + end do + + if (adv_n) then + nbub = q_cons_vf(n_idx)%sf(j - 2, k - 2, l) + else + nR3 = 0._wp + do s = 1, nb + nR3 = nR3 + weight(s)*(nR(s)**3._wp) + end do + + nbub = sqrt((4._wp*pi/3._wp)*nR3/alf) + end if + + R(:) = nR(:)/nbub + Rdot(:) = nRdot(:)/nbub + end if + ! Compute mixture sound speed + call s_compute_speed_of_sound(pres, rho, gamma, pi_inf, & + ((gamma + 1._wp)*pres + pi_inf)/rho, alpha, 0._wp, 0._wp, c, qv) + + end if + end if + else ! 3D + if ((probe(i)%x >= x_cb(-1)) .and. (probe(i)%x <= x_cb(m))) then + if ((probe(i)%y >= y_cb(-1)) .and. (probe(i)%y <= y_cb(n))) then + if ((probe(i)%z >= z_cb(-1)) .and. (probe(i)%z <= z_cb(p))) then + do s = -1, m + distx(s) = x_cb(s) - probe(i)%x + if (distx(s) < 0._wp) distx(s) = 1000._wp + end do + do s = -1, n + disty(s) = y_cb(s) - probe(i)%y + if (disty(s) < 0._wp) disty(s) = 1000._wp + end do + do s = -1, p + distz(s) = z_cb(s) - probe(i)%z + if (distz(s) < 0._wp) distz(s) = 1000._wp + end do + j = minloc(distx, 1) + k = minloc(disty, 1) + l = minloc(distz, 1) + if (j == 1) j = 2 ! Pick first point if probe is at edge + if (k == 1) k = 2 ! Pick first point if probe is at edge + if (l == 1) l = 2 ! Pick first point if probe is at edge + + ! Computing/Sharing necessary state variables + call s_convert_to_mixture_variables(q_cons_vf, j - 2, k - 2, l - 2, & + rho, gamma, pi_inf, qv, & + Re, G_local, fluid_pp(:)%G) + do s = 1, num_vels + vel(s) = q_cons_vf(cont_idx%end + s)%sf(j - 2, k - 2, l - 2)/rho + end do + + dyn_p = 0.5_wp*rho*dot_product(vel, vel) + + if (chemistry) then + do d = 1, num_species + rhoYks(d) = q_cons_vf(chemxb + d - 1)%sf(j - 2, k - 2, l - 2) + end do + end if + + if (elasticity) then + if (cont_damage) then + damage_state = q_cons_vf(damage_idx)%sf(j - 2, k - 2, l - 2) + G_local = G_local*max((1._wp - damage_state), 0._wp) + end if + + call s_compute_pressure( & + q_cons_vf(1)%sf(j - 2, k - 2, l - 2), & + q_cons_vf(alf_idx)%sf(j - 2, k - 2, l - 2), & + dyn_p, pi_inf, gamma, rho, qv, & + rhoYks, pres, T, & + q_cons_vf(stress_idx%beg)%sf(j - 2, k - 2, l - 2), & + q_cons_vf(mom_idx%beg)%sf(j - 2, k - 2, l - 2), G_local) + else + call s_compute_pressure(q_cons_vf(E_idx)%sf(j - 2, k - 2, l - 2), & + q_cons_vf(alf_idx)%sf(j - 2, k - 2, l - 2), & + dyn_p, pi_inf, gamma, rho, qv, & + rhoYks, pres, T) + end if + + ! Compute mixture sound speed + call s_compute_speed_of_sound(pres, rho, gamma, pi_inf, & + ((gamma + 1._wp)*pres + pi_inf)/rho, alpha, 0._wp, 0._wp, c, qv) + + accel = accel_mag(j - 2, k - 2, l - 2) + end if + end if + end if + end if + if (num_procs > 1) then + #:for VAR in ['rho','pres','gamma','pi_inf','qv','c','accel'] + tmp = ${VAR}$ + call s_mpi_allreduce_sum(tmp, ${VAR}$) + #:endfor + + do s = 1, num_vels + tmp = vel(s) + call s_mpi_allreduce_sum(tmp, vel(s)) + end do + + if (bubbles_euler) then + #:for VAR in ['alf','alfgr','nbub','nR(1)','nRdot(1)','M00','R(1)','Rdot(1)','ptilde','ptot'] + tmp = ${VAR}$ + call s_mpi_allreduce_sum(tmp, ${VAR}$) + #:endfor + + if (qbmm) then + #:for VAR in ['varR','varV','M10','M01','M20','M02'] + tmp = ${VAR}$ + call s_mpi_allreduce_sum(tmp, ${VAR}$) + #:endfor + end if + end if + + if (elasticity) then + do s = 1, (num_dims*(num_dims + 1))/2 + tmp = tau_e(s) + call s_mpi_allreduce_sum(tmp, tau_e(s)) + end do + end if + + if (cont_damage) then + tmp = damage_state + call s_mpi_allreduce_sum(tmp, damage_state) + end if + end if + if (proc_rank == 0) then + if (n == 0) then + if (bubbles_euler .and. (num_fluids <= 2)) then + if (qbmm) then + write (i + 30, '(6x,f12.6,14f28.16)') & + nondim_time, & + rho, & + vel(1), & + pres, & + alf, & + R(1), & + Rdot(1), & + nR(1), & + nRdot(1), & + varR, & + varV, & + M10, & + M01, & + M20, & + M02 + else + write (i + 30, '(6x,f12.6,8f24.8)') & + nondim_time, & + rho, & + vel(1), & + pres, & + alf, & + R(1), & + Rdot(1), & + nR(1), & + nRdot(1) + ! ptilde, & + ! ptot + end if + else if (bubbles_euler .and. (num_fluids == 3)) then + write (i + 30, '(6x,f12.6,f24.8,f24.8,f24.8,f24.8,f24.8,'// & + 'f24.8,f24.8,f24.8,f24.8,f24.8, f24.8)') & + nondim_time, & + rho, & + vel(1), & + pres, & + alf, & + alfgr, & + nR(1), & + nRdot(1), & + R(1), & + Rdot(1), & + ptilde, & + ptot + else if (bubbles_euler .and. num_fluids == 4) then + write (i + 30, '(6x,f12.6,f24.8,f24.8,f24.8,f24.8,'// & + 'f24.8,f24.8,f24.8,f24.8,f24.8,f24.8,f24.8,f24.8,f24.8)') & + nondim_time, & + q_cons_vf(1)%sf(j - 2, 0, 0), & + q_cons_vf(2)%sf(j - 2, 0, 0), & + q_cons_vf(3)%sf(j - 2, 0, 0), & + q_cons_vf(4)%sf(j - 2, 0, 0), & + q_cons_vf(5)%sf(j - 2, 0, 0), & + q_cons_vf(6)%sf(j - 2, 0, 0), & + q_cons_vf(7)%sf(j - 2, 0, 0), & + q_cons_vf(8)%sf(j - 2, 0, 0), & + q_cons_vf(9)%sf(j - 2, 0, 0), & + q_cons_vf(10)%sf(j - 2, 0, 0), & + nbub, & + R(1), & + Rdot(1) + else + write (i + 30, '(6X,F12.6,F24.8,F24.8,F24.8)') & + nondim_time, & + rho, & + vel(1), & + pres + end if + elseif (p == 0) then + if (bubbles_euler) then + #:if not MFC_CASE_OPTIMIZATION or num_dims > 1 + write (i + 30, '(6X,10F24.8)') & + nondim_time, & + rho, & + vel(1), & + vel(2), & + pres, & + alf, & + nR(1), & + nRdot(1), & + R(1), & + Rdot(1) + #:endif + else if (elasticity) then + #:if not MFC_CASE_OPTIMIZATION or num_dims > 1 + write (i + 30, '(6X,F12.6,F24.8,F24.8,F24.8,F24.8,'// & + 'F24.8,F24.8,F24.8)') & + nondim_time, & + rho, & + vel(1), & + vel(2), & + pres, & + tau_e(1), & + tau_e(2), & + tau_e(3) + #:endif + else + write (i + 30, '(6X,F12.6,F24.8,F24.8,F24.8)') & + nondim_time, & + rho, & + vel(1), & + pres + print *, 'time =', nondim_time, 'rho =', rho, 'pres =', pres + end if + else + #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 + write (i + 30, '(6X,F12.6,F24.8,F24.8,F24.8,F24.8,'// & + 'F24.8,F24.8,F24.8,F24.8,F24.8,'// & + 'F24.8)') & + nondim_time, & + rho, & + vel(1), & + vel(2), & + vel(3), & + pres, & + gamma, & + pi_inf, & + qv, & + c, & + accel + #:endif + end if + end if + end do + + if (integral_wrt .and. bubbles_euler) then + if (n == 0) then ! 1D simulation + do i = 1, num_integrals + int_pres = 0._wp + max_pres = 0._wp + k = 0; l = 0 + npts = 0 + do j = 1, m + pres = 0._wp + do s = 1, num_vels + vel(s) = 0._wp + end do + rho = 0._wp + pres = 0._wp + gamma = 0._wp + pi_inf = 0._wp + qv = 0._wp + + if ((integral(i)%xmin <= x_cb(j)) .and. (integral(i)%xmax >= x_cb(j))) then + npts = npts + 1 + call s_convert_to_mixture_variables(q_cons_vf, j, k, l, & + rho, gamma, pi_inf, qv, Re) + do s = 1, num_vels + vel(s) = q_cons_vf(cont_idx%end + s)%sf(j, k, l)/rho + end do + + pres = ( & + (q_cons_vf(E_idx)%sf(j, k, l) - & + 0.5_wp*(q_cons_vf(mom_idx%beg)%sf(j, k, l)**2._wp)/rho)/ & + (1._wp - q_cons_vf(alf_idx)%sf(j, k, l)) - & + pi_inf - qv & + )/gamma + int_pres = int_pres + (pres - 1._wp)**2._wp + end if + end do + int_pres = sqrt(int_pres/(1._wp*npts)) + + if (num_procs > 1) then + tmp = int_pres + call s_mpi_allreduce_sum(tmp, int_pres) + end if + + if (proc_rank == 0) then + if (bubbles_euler .and. (num_fluids <= 2)) then + write (i + 70, '(6x,f12.6,f24.8)') & + nondim_time, int_pres + end if + end if + end do + elseif (p == 0) then + if (num_integrals /= 3) then + call s_mpi_abort('Incorrect number of integrals') + end if + + rad = integral(1)%xmax + thickness = integral(1)%xmin + + do i = 1, num_integrals + int_pres = 0._wp + max_pres = 0._wp + l = 0 + npts = 0 + do j = 1, m + do k = 1, n + trigger = .false. + if (i == 1) then + !inner portion + if (sqrt(x_cb(j)**2._wp + y_cb(k)**2._wp) < (rad - 0.5_wp*thickness)) & + trigger = .true. + elseif (i == 2) then + !net region + if (sqrt(x_cb(j)**2._wp + y_cb(k)**2._wp) > (rad - 0.5_wp*thickness) .and. & + sqrt(x_cb(j)**2._wp + y_cb(k)**2._wp) < (rad + 0.5_wp*thickness)) & + trigger = .true. + elseif (i == 3) then + !everything else + if (sqrt(x_cb(j)**2._wp + y_cb(k)**2._wp) > (rad + 0.5_wp*thickness)) & + trigger = .true. + end if + + pres = 0._wp + do s = 1, num_vels + vel(s) = 0._wp + end do + rho = 0._wp + pres = 0._wp + gamma = 0._wp + pi_inf = 0._wp + qv = 0._wp + + if (trigger) then + npts = npts + 1 + call s_convert_to_mixture_variables(q_cons_vf, j, k, l, & + rho, gamma, pi_inf, qv, Re) + do s = 1, num_vels + vel(s) = q_cons_vf(cont_idx%end + s)%sf(j, k, l)/rho + end do + + pres = ( & + (q_cons_vf(E_idx)%sf(j, k, l) - & + 0.5_wp*(q_cons_vf(mom_idx%beg)%sf(j, k, l)**2._wp)/rho)/ & + (1._wp - q_cons_vf(alf_idx)%sf(j, k, l)) - & + pi_inf - qv & + )/gamma + int_pres = int_pres + abs(pres - 1._wp) + max_pres = max(max_pres, abs(pres - 1._wp)) + end if + + end do + end do + + if (npts > 0) then + int_pres = int_pres/(1._wp*npts) + else + int_pres = 0._wp + end if + + if (num_procs > 1) then + tmp = int_pres + call s_mpi_allreduce_sum(tmp, int_pres) + + tmp = max_pres + call s_mpi_allreduce_max(tmp, max_pres) + end if + + if (proc_rank == 0) then + if (bubbles_euler .and. (num_fluids <= 2)) then + write (i + 70, '(6x,f12.6,f24.8,f24.8)') & + nondim_time, int_pres, max_pres + end if + end if + end do + end if + end if + + end subroutine s_write_probe_files + + !> The goal of this subroutine is to write to the run-time + !! information file basic footer information applicable to + !! the current computation and to close the file when done. + !! The footer contains the stability criteria extrema over + !! all of the time-steps and the simulation run-time. + impure subroutine s_close_run_time_information_file + + real(wp) :: run_time !< Run-time of the simulation + + ! Writing the footer of and closing the run-time information file + write (3, '(A)') ' ' + write (3, '(A)') '' + + write (3, '(A,F9.6)') 'ICFL Max: ', icfl_max + if (viscous) write (3, '(A,F9.6)') 'VCFL Max: ', vcfl_max + if (viscous) write (3, '(A,F10.6)') 'Rc Min: ', Rc_min + + call cpu_time(run_time) + + write (3, '(A)') '' + write (3, '(A,I0,A)') 'Run-time: ', int(anint(run_time)), 's' + write (3, '(A)') ' ' + close (3) + + end subroutine s_close_run_time_information_file + + !> Closes communication files + impure subroutine s_close_com_files() + + integer :: i !< Generic loop iterator + do i = 1, num_fluids + close (i + 120) + end do + + end subroutine s_close_com_files + + !> Closes probe files + impure subroutine s_close_probe_files + + integer :: i !< Generic loop iterator + + do i = 1, num_probes + close (i + 30) + end do + + end subroutine s_close_probe_files + + !> The computation of parameters, the allocation of memory, + !! the association of pointers and/or the execution of any + !! other procedures that are necessary to setup the module. + impure subroutine s_initialize_data_output_module + + integer :: i, m_ds, n_ds, p_ds + + ! Allocating/initializing ICFL, VCFL, CCFL and Rc stability criteria + if (run_time_info) then + @:ALLOCATE(icfl_sf(0:m, 0:n, 0:p)) + icfl_max = 0._wp + + if (viscous) then + @:ALLOCATE(vcfl_sf(0:m, 0:n, 0:p)) + @:ALLOCATE(Rc_sf (0:m, 0:n, 0:p)) + + vcfl_max = 0._wp + Rc_min = 1.e3_wp + end if + end if + + if (probe_wrt) then + @:ALLOCATE(c_mass(num_fluids,5)) + end if + + if (down_sample) then + m_ds = int((m + 1)/3) - 1 + n_ds = int((n + 1)/3) - 1 + p_ds = int((p + 1)/3) - 1 + + allocate (q_cons_temp_ds(1:sys_size)) + do i = 1, sys_size + allocate (q_cons_temp_ds(i)%sf(-1:m_ds + 1, -1:n_ds + 1, -1:p_ds + 1)) + end do + end if + + end subroutine s_initialize_data_output_module + + !> Module deallocation and/or disassociation procedures + impure subroutine s_finalize_data_output_module + + integer :: i + + if (probe_wrt) then + @:DEALLOCATE(c_mass) + end if + + if (run_time_info) then + ! Deallocating the ICFL, VCFL, CCFL, and Rc stability criteria + @:DEALLOCATE(icfl_sf) + if (viscous) then + @:DEALLOCATE(vcfl_sf, Rc_sf) + end if + end if + + if (down_sample) then + do i = 1, sys_size + deallocate (q_cons_temp_ds(i)%sf) + end do + deallocate (q_cons_temp_ds) + end if + + end subroutine s_finalize_data_output_module + +end module m_data_output diff --git a/src/simulation/m_global_parameters.fpp b/src/simulation/m_global_parameters.fpp index c1be537ecd..1e129754f2 100644 --- a/src/simulation/m_global_parameters.fpp +++ b/src/simulation/m_global_parameters.fpp @@ -184,6 +184,7 @@ module m_global_parameters logical :: bulk_stress !< Bulk stresses logical :: cont_damage !< Continuum damage modeling logical :: hyper_cleaning !< Hyperbolic cleaning for MHD for divB=0 + logical :: any_non_newtonian !< True if any fluid is non-Newtonian integer :: num_igr_iters !< number of iterations for elliptic solve integer :: num_igr_warm_start_iters !< number of warm start iterations for elliptic solve real(wp) :: alf_factor !< alpha factor for IGR @@ -213,7 +214,7 @@ module m_global_parameters $:GPU_DECLARE(create='[mpp_lim,model_eqns,mixture_err,alt_soundspeed]') $:GPU_DECLARE(create='[avg_state,mp_weno,weno_eps,teno_CT,hypoelasticity]') $:GPU_DECLARE(create='[hyperelasticity,hyper_model,elasticity,low_Mach]') - $:GPU_DECLARE(create='[shear_stress,bulk_stress,cont_damage,hyper_cleaning]') + $:GPU_DECLARE(create='[shear_stress,bulk_stress,cont_damage,hyper_cleaning,any_non_newtonian]') logical :: relax !< activate phase change integer :: relax_model !< Relaxation model @@ -636,6 +637,7 @@ contains bulk_stress = .false. cont_damage = .false. hyper_cleaning = .false. + any_non_newtonian = .false. num_igr_iters = dflt_num_igr_iters num_igr_warm_start_iters = dflt_num_igr_warm_start_iters alf_factor = dflt_alf_factor @@ -684,6 +686,14 @@ contains fluid_pp(i)%qvp = 0._wp fluid_pp(i)%Re(:) = dflt_real fluid_pp(i)%G = 0._wp + fluid_pp(i)%non_newtonian = .false. + fluid_pp(i)%tau0 = 0._wp + fluid_pp(i)%K = 0._wp + fluid_pp(i)%nn = 1._wp + fluid_pp(i)%mu_max = dflt_real + fluid_pp(i)%mu_min = 0._wp + fluid_pp(i)%mu_bulk = 0._wp + fluid_pp(i)%hb_m = 1000._wp end do ! Subgrid bubble parameters @@ -1120,7 +1130,15 @@ contains Re_size_max = maxval(Re_size) - $:GPU_UPDATE(device='[Re_size,Re_size_max,shear_stress,bulk_stress]') + ! Detect non-Newtonian fluids + any_non_newtonian = .false. + do i = 1, num_fluids + if (fluid_pp(i)%non_newtonian) then + any_non_newtonian = .true. + end if + end do + + $:GPU_UPDATE(device='[Re_size,Re_size_max,shear_stress,bulk_stress,any_non_newtonian]') ! Bookkeeping the indexes of any viscous fluids and any pairs of ! fluids whose interface will support effects of surface tension diff --git a/src/simulation/m_hb_function.fpp b/src/simulation/m_hb_function.fpp new file mode 100644 index 0000000000..6f56bc5717 --- /dev/null +++ b/src/simulation/m_hb_function.fpp @@ -0,0 +1,77 @@ +!> +!! @file m_hb_function.f90 +!! @brief Contains module m_hb_function + +#:include 'macros.fpp' + +!> @brief The module contains functions to compute Herschel-Bulkley +!! non-Newtonian viscosity with Papanastasiou regularization. +!! mu = (tau0/gdot)*(1 - exp(-m*gdot)) + K*gdot^(nn-1) +module m_hb_function + + use m_derived_types !< Definitions of the derived types + + use m_global_parameters !< Definitions of the global parameters + + implicit none + + private; public :: f_compute_hb_viscosity, & + f_compute_shear_rate_from_components + +contains + + !> Computes Herschel-Bulkley viscosity with Papanastasiou regularization + !! @param tau0 Yield stress + !! @param K_val Consistency index + !! @param nn_val Flow behavior index + !! @param mu_min_val Minimum viscosity limit + !! @param mu_max_val Maximum viscosity limit + !! @param shear_rate Shear rate magnitude + !! @param hb_m_val Papanastasiou regularization parameter + !! @return Viscosity + pure function f_compute_hb_viscosity(tau0, K_val, nn_val, & + mu_min_val, mu_max_val, shear_rate, hb_m_val) result(mu) + $:GPU_ROUTINE(parallelism='[seq]') + + real(wp), intent(in) :: tau0, K_val, nn_val + real(wp), intent(in) :: mu_min_val, mu_max_val + real(wp), intent(in) :: shear_rate, hb_m_val + real(wp) :: mu + real(wp) :: yield_term, power_law_term, exp_term + + exp_term = exp(-hb_m_val*shear_rate) + yield_term = tau0*(1._wp - exp_term)/shear_rate + power_law_term = K_val*(shear_rate**(nn_val - 1._wp)) + + mu = yield_term + power_law_term + mu = min(max(mu, mu_min_val), mu_max_val) + + end function f_compute_hb_viscosity + + !> Computes shear rate from strain rate tensor components. + !! gdot = sqrt(2*D_ij*D_ij) where D_ij is the strain rate tensor. + !! Set D_zz, D_xz, D_yz to 0 for 2D/1D cases. + !! @param D_xx Normal strain rate du/dx + !! @param D_yy Normal strain rate dv/dy + !! @param D_zz Normal strain rate dw/dz + !! @param D_xy Shear strain rate 0.5*(du/dy + dv/dx) + !! @param D_xz Shear strain rate 0.5*(du/dz + dw/dx) + !! @param D_yz Shear strain rate 0.5*(dv/dz + dw/dy) + !! @return Shear rate magnitude + pure function f_compute_shear_rate_from_components( & + D_xx, D_yy, D_zz, D_xy, D_xz, D_yz) result(shear_rate) + $:GPU_ROUTINE(parallelism='[seq]') + + real(wp), intent(in) :: D_xx, D_yy, D_zz, D_xy, D_xz, D_yz + real(wp) :: shear_rate + + ! 2*D_ij*D_ij = 2*(D_xx^2+D_yy^2+D_zz^2+2*(D_xy^2+D_xz^2+D_yz^2)) + shear_rate = sqrt(2._wp*(D_xx*D_xx + D_yy*D_yy + D_zz*D_zz + & + 2._wp*(D_xy*D_xy + D_xz*D_xz + D_yz*D_yz))) + + ! Clamp for numerical safety + shear_rate = min(max(shear_rate, 1.0e-2_wp), 1.0e5_wp) + + end function f_compute_shear_rate_from_components + +end module m_hb_function diff --git a/src/simulation/m_ibm.fpp b/src/simulation/m_ibm.fpp index b87f5a1b19..9394bcf06a 100644 --- a/src/simulation/m_ibm.fpp +++ b/src/simulation/m_ibm.fpp @@ -1013,7 +1013,15 @@ contains if (viscous) then do fluid_idx = 1, num_fluids - if (fluid_pp(fluid_idx)%Re(1) /= 0._wp) then + if (fluid_pp(fluid_idx)%non_newtonian) then + ! Non-Newtonian: use mu_max as reference viscosity for IBM + if (fluid_pp(fluid_idx)%mu_max < dflt_real .and. & + fluid_pp(fluid_idx)%mu_max > sgm_eps) then + dynamic_viscosities(fluid_idx) = fluid_pp(fluid_idx)%mu_max + else + dynamic_viscosities(fluid_idx) = fluid_pp(fluid_idx)%K + end if + else if (fluid_pp(fluid_idx)%Re(1) /= 0._wp) then dynamic_viscosities(fluid_idx) = 1._wp/fluid_pp(fluid_idx)%Re(1) else dynamic_viscosities(fluid_idx) = 0._wp diff --git a/src/simulation/m_mpi_proxy.fpp b/src/simulation/m_mpi_proxy.fpp index a684c79ec4..57ed18a3d3 100644 --- a/src/simulation/m_mpi_proxy.fpp +++ b/src/simulation/m_mpi_proxy.fpp @@ -190,6 +190,10 @@ contains call MPI_BCAST(fluid_pp(i)%${VAR}$, 1, mpi_p, 0, MPI_COMM_WORLD, ierr) #:endfor call MPI_BCAST(fluid_pp(i)%Re(1), 2, mpi_p, 0, MPI_COMM_WORLD, ierr) + call MPI_BCAST(fluid_pp(i)%non_newtonian, 1, MPI_LOGICAL, 0, MPI_COMM_WORLD, ierr) + #:for VAR in ['tau0', 'K', 'nn', 'mu_max', 'mu_min', 'mu_bulk', 'hb_m'] + call MPI_BCAST(fluid_pp(i)%${VAR}$, 1, mpi_p, 0, MPI_COMM_WORLD, ierr) + #:endfor end do if (bubbles_euler .or. bubbles_lagrange) then diff --git a/src/simulation/m_pressure_relaxation.fpp b/src/simulation/m_pressure_relaxation.fpp index 69689de06c..92a39724d0 100644 --- a/src/simulation/m_pressure_relaxation.fpp +++ b/src/simulation/m_pressure_relaxation.fpp @@ -1,308 +1,279 @@ -!> -!! @file -!! @brief Contains module m_pressure_relaxation - -#:include 'case.fpp' -#:include 'macros.fpp' - -!> @brief Pressure relaxation for the six-equation multi-component model via Newton--Raphson equilibration and volume-fraction correction -module m_pressure_relaxation - - use m_derived_types !< Definitions of the derived types - use m_global_parameters !< Definitions of the global parameters - - implicit none - - private; public :: s_pressure_relaxation_procedure, & - s_initialize_pressure_relaxation_module, & - s_finalize_pressure_relaxation_module - - real(wp), allocatable, dimension(:, :) :: Res_pr - $:GPU_DECLARE(create='[Res_pr]') - -contains - - !> Initialize the pressure relaxation module - impure subroutine s_initialize_pressure_relaxation_module - - integer :: i, j - - if (viscous) then - @:ALLOCATE(Res_pr(1:2, 1:Re_size_max)) - do i = 1, 2 - do j = 1, Re_size(i) - Res_pr(i, j) = fluid_pp(Re_idx(i, j))%Re(i) - end do - end do - $:GPU_UPDATE(device='[Res_pr, Re_idx, Re_size]') - end if - - end subroutine s_initialize_pressure_relaxation_module - - !> Finalize the pressure relaxation module - impure subroutine s_finalize_pressure_relaxation_module - - if (viscous) then - @:DEALLOCATE(Res_pr) - end if - - end subroutine s_finalize_pressure_relaxation_module - - !> The main pressure relaxation procedure - !! @param q_cons_vf Cell-average conservative variables - subroutine s_pressure_relaxation_procedure(q_cons_vf) - - type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf - integer :: j, k, l - - $:GPU_PARALLEL_LOOP(private='[j,k,l]', collapse=3) - do l = 0, p - do k = 0, n - do j = 0, m - call s_relax_cell_pressure(q_cons_vf, j, k, l) - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - - end subroutine s_pressure_relaxation_procedure - - !> Process pressure relaxation for a single cell - subroutine s_relax_cell_pressure(q_cons_vf, j, k, l) - $:GPU_ROUTINE(parallelism='[seq]') - - type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf - integer, intent(in) :: j, k, l - - ! Volume fraction correction - if (mpp_lim) call s_correct_volume_fractions(q_cons_vf, j, k, l) - - ! Pressure equilibration - if (s_needs_pressure_relaxation(q_cons_vf, j, k, l)) then - call s_equilibrate_pressure(q_cons_vf, j, k, l) - end if - - ! Internal energy correction - call s_correct_internal_energies(q_cons_vf, j, k, l) - - end subroutine s_relax_cell_pressure - - !> Check if pressure relaxation is needed for this cell - logical function s_needs_pressure_relaxation(q_cons_vf, j, k, l) - $:GPU_ROUTINE(parallelism='[seq]') - - type(scalar_field), dimension(sys_size), intent(in) :: q_cons_vf - integer, intent(in) :: j, k, l - integer :: i - - s_needs_pressure_relaxation = .true. - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_fluids - if (q_cons_vf(i + advxb - 1)%sf(j, k, l) > (1._wp - sgm_eps)) then - s_needs_pressure_relaxation = .false. - end if - end do - - end function s_needs_pressure_relaxation - - !> Correct volume fractions to physical bounds - subroutine s_correct_volume_fractions(q_cons_vf, j, k, l) - $:GPU_ROUTINE(parallelism='[seq]') - - type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf - integer, intent(in) :: j, k, l - real(wp) :: sum_alpha - integer :: i - - sum_alpha = 0._wp - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_fluids - if ((q_cons_vf(i + contxb - 1)%sf(j, k, l) < 0._wp) .or. & - (q_cons_vf(i + advxb - 1)%sf(j, k, l) < 0._wp)) then - q_cons_vf(i + contxb - 1)%sf(j, k, l) = 0._wp - q_cons_vf(i + advxb - 1)%sf(j, k, l) = 0._wp - q_cons_vf(i + intxb - 1)%sf(j, k, l) = 0._wp - end if - if (q_cons_vf(i + advxb - 1)%sf(j, k, l) > 1._wp) & - q_cons_vf(i + advxb - 1)%sf(j, k, l) = 1._wp - sum_alpha = sum_alpha + q_cons_vf(i + advxb - 1)%sf(j, k, l) - end do - - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_fluids - q_cons_vf(i + advxb - 1)%sf(j, k, l) = q_cons_vf(i + advxb - 1)%sf(j, k, l)/sum_alpha - end do - - end subroutine s_correct_volume_fractions - - !> Main pressure equilibration using Newton-Raphson - subroutine s_equilibrate_pressure(q_cons_vf, j, k, l) - $:GPU_ROUTINE(parallelism='[seq]') - - type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf - integer, intent(in) :: j, k, l - - real(wp) :: pres_relax, f_pres, df_pres - #:if not MFC_CASE_OPTIMIZATION and USING_AMD - real(wp), dimension(3) :: pres_K_init, rho_K_s - #:else - real(wp), dimension(num_fluids) :: pres_K_init, rho_K_s - #:endif - integer, parameter :: MAX_ITER = 50 - real(wp), parameter :: TOLERANCE = 1.e-10_wp - integer :: iter, i - - ! Initialize pressures - pres_relax = 0._wp - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_fluids - if (q_cons_vf(i + advxb - 1)%sf(j, k, l) > sgm_eps) then - pres_K_init(i) = (q_cons_vf(i + intxb - 1)%sf(j, k, l)/ & - q_cons_vf(i + advxb - 1)%sf(j, k, l) - pi_infs(i))/gammas(i) - if (pres_K_init(i) <= -(1._wp - 1.e-8_wp)*ps_inf(i) + 1.e-8_wp) & - pres_K_init(i) = -(1._wp - 1.e-8_wp)*ps_inf(i) + 1.e-8_wp - else - pres_K_init(i) = 0._wp - end if - pres_relax = pres_relax + q_cons_vf(i + advxb - 1)%sf(j, k, l)*pres_K_init(i) - end do - - ! Newton-Raphson iteration - f_pres = 1.e-9_wp - df_pres = 1.e9_wp - $:GPU_LOOP(parallelism='[seq]') - do iter = 0, MAX_ITER - 1 - if (abs(f_pres) > TOLERANCE) then - pres_relax = pres_relax - f_pres/df_pres - - ! Enforce pressure bounds - do i = 1, num_fluids - if (pres_relax <= -(1._wp - 1.e-8_wp)*ps_inf(i) + 1.e-8_wp) & - pres_relax = -(1._wp - 1.e-8_wp)*ps_inf(i) + 1.e-8_wp - end do - - ! Newton-Raphson step - f_pres = -1._wp - df_pres = 0._wp - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_fluids - if (q_cons_vf(i + advxb - 1)%sf(j, k, l) > sgm_eps) then - rho_K_s(i) = q_cons_vf(i + contxb - 1)%sf(j, k, l)/ & - max(q_cons_vf(i + advxb - 1)%sf(j, k, l), sgm_eps) & - *((pres_relax + ps_inf(i))/(pres_K_init(i) + & - ps_inf(i)))**(1._wp/gs_min(i)) - f_pres = f_pres + q_cons_vf(i + contxb - 1)%sf(j, k, l)/rho_K_s(i) - df_pres = df_pres - q_cons_vf(i + contxb - 1)%sf(j, k, l) & - /(gs_min(i)*rho_K_s(i)*(pres_relax + ps_inf(i))) - end if - end do - end if - end do - - ! Update volume fractions - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_fluids - if (q_cons_vf(i + advxb - 1)%sf(j, k, l) > sgm_eps) & - q_cons_vf(i + advxb - 1)%sf(j, k, l) = q_cons_vf(i + contxb - 1)%sf(j, k, l)/rho_K_s(i) - end do - - end subroutine s_equilibrate_pressure - - !> Correct internal energies using equilibrated pressure - subroutine s_correct_internal_energies(q_cons_vf, j, k, l) - $:GPU_ROUTINE(parallelism='[seq]') - - type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf - integer, intent(in) :: j, k, l - #:if not MFC_CASE_OPTIMIZATION and USING_AMD - real(wp), dimension(2) :: alpha_rho, alpha - #:else - real(wp), dimension(num_fluids) :: alpha_rho, alpha - #:endif - real(wp) :: rho, dyn_pres, gamma, pi_inf, pres_relax, sum_alpha - real(wp), dimension(2) :: Re - integer :: i, q - - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_fluids - alpha_rho(i) = q_cons_vf(i)%sf(j, k, l) - alpha(i) = q_cons_vf(E_idx + i)%sf(j, k, l) - end do - - ! Compute mixture properties (combined bubble and standard logic) - rho = 0._wp - gamma = 0._wp - pi_inf = 0._wp - - if (bubbles_euler) then - if (mpp_lim .and. (model_eqns == 2) .and. (num_fluids > 2)) then - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_fluids - rho = rho + alpha_rho(i) - gamma = gamma + alpha(i)*gammas(i) - pi_inf = pi_inf + alpha(i)*pi_infs(i) - end do - else if ((model_eqns == 2) .and. (num_fluids > 2)) then - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_fluids - 1 - rho = rho + alpha_rho(i) - gamma = gamma + alpha(i)*gammas(i) - pi_inf = pi_inf + alpha(i)*pi_infs(i) - end do - else - rho = alpha_rho(1) - gamma = gammas(1) - pi_inf = pi_infs(1) - end if - else - sum_alpha = 0._wp - if (mpp_lim) then - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_fluids - alpha_rho(i) = max(0._wp, alpha_rho(i)) - alpha(i) = min(max(0._wp, alpha(i)), 1._wp) - sum_alpha = sum_alpha + alpha(i) - end do - alpha = alpha/max(sum_alpha, sgm_eps) - end if - - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_fluids - rho = rho + alpha_rho(i) - gamma = gamma + alpha(i)*gammas(i) - pi_inf = pi_inf + alpha(i)*pi_infs(i) - end do - - if (viscous) then - $:GPU_LOOP(parallelism='[seq]') - do i = 1, 2 - Re(i) = dflt_real - if (Re_size(i) > 0) Re(i) = 0._wp - $:GPU_LOOP(parallelism='[seq]') - do q = 1, Re_size(i) - Re(i) = alpha(Re_idx(i, q))/Res_pr(i, q) + Re(i) - end do - Re(i) = 1._wp/max(Re(i), sgm_eps) - end do - end if - end if - - ! Compute dynamic pressure and update internal energies - dyn_pres = 0._wp - $:GPU_LOOP(parallelism='[seq]') - do i = momxb, momxe - dyn_pres = dyn_pres + 5.e-1_wp*q_cons_vf(i)%sf(j, k, l)* & - q_cons_vf(i)%sf(j, k, l)/max(rho, sgm_eps) - end do - - pres_relax = (q_cons_vf(E_idx)%sf(j, k, l) - dyn_pres - pi_inf)/gamma - - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_fluids - q_cons_vf(i + intxb - 1)%sf(j, k, l) = & - q_cons_vf(i + advxb - 1)%sf(j, k, l)*(gammas(i)*pres_relax + pi_infs(i)) - end do - - end subroutine s_correct_internal_energies - -end module m_pressure_relaxation +!> +!! @file +!! @brief Contains module m_pressure_relaxation + +#:include 'case.fpp' +#:include 'macros.fpp' + +!> @brief Pressure relaxation for the six-equation multi-component model via Newton--Raphson equilibration and volume-fraction correction +module m_pressure_relaxation + + use m_derived_types !< Definitions of the derived types + use m_global_parameters !< Definitions of the global parameters + + implicit none + + private; public :: s_pressure_relaxation_procedure, & + s_initialize_pressure_relaxation_module, & + s_finalize_pressure_relaxation_module + +contains + + !> Initialize the pressure relaxation module + impure subroutine s_initialize_pressure_relaxation_module + + ! Nothing to initialize - Re is computed dynamically via m_re_visc + + end subroutine s_initialize_pressure_relaxation_module + + !> Finalize the pressure relaxation module + impure subroutine s_finalize_pressure_relaxation_module + + ! Nothing to finalize + + end subroutine s_finalize_pressure_relaxation_module + + !> The main pressure relaxation procedure + !! @param q_cons_vf Cell-average conservative variables + subroutine s_pressure_relaxation_procedure(q_cons_vf) + + type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf + integer :: j, k, l + + $:GPU_PARALLEL_LOOP(private='[j,k,l]', collapse=3) + do l = 0, p + do k = 0, n + do j = 0, m + call s_relax_cell_pressure(q_cons_vf, j, k, l) + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + + end subroutine s_pressure_relaxation_procedure + + !> Process pressure relaxation for a single cell + subroutine s_relax_cell_pressure(q_cons_vf, j, k, l) + $:GPU_ROUTINE(parallelism='[seq]') + + type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf + integer, intent(in) :: j, k, l + + ! Volume fraction correction + if (mpp_lim) call s_correct_volume_fractions(q_cons_vf, j, k, l) + + ! Pressure equilibration + if (s_needs_pressure_relaxation(q_cons_vf, j, k, l)) then + call s_equilibrate_pressure(q_cons_vf, j, k, l) + end if + + ! Internal energy correction + call s_correct_internal_energies(q_cons_vf, j, k, l) + + end subroutine s_relax_cell_pressure + + !> Check if pressure relaxation is needed for this cell + logical function s_needs_pressure_relaxation(q_cons_vf, j, k, l) + $:GPU_ROUTINE(parallelism='[seq]') + + type(scalar_field), dimension(sys_size), intent(in) :: q_cons_vf + integer, intent(in) :: j, k, l + integer :: i + + s_needs_pressure_relaxation = .true. + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_fluids + if (q_cons_vf(i + advxb - 1)%sf(j, k, l) > (1._wp - sgm_eps)) then + s_needs_pressure_relaxation = .false. + end if + end do + + end function s_needs_pressure_relaxation + + !> Correct volume fractions to physical bounds + subroutine s_correct_volume_fractions(q_cons_vf, j, k, l) + $:GPU_ROUTINE(parallelism='[seq]') + + type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf + integer, intent(in) :: j, k, l + real(wp) :: sum_alpha + integer :: i + + sum_alpha = 0._wp + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_fluids + if ((q_cons_vf(i + contxb - 1)%sf(j, k, l) < 0._wp) .or. & + (q_cons_vf(i + advxb - 1)%sf(j, k, l) < 0._wp)) then + q_cons_vf(i + contxb - 1)%sf(j, k, l) = 0._wp + q_cons_vf(i + advxb - 1)%sf(j, k, l) = 0._wp + q_cons_vf(i + intxb - 1)%sf(j, k, l) = 0._wp + end if + if (q_cons_vf(i + advxb - 1)%sf(j, k, l) > 1._wp) & + q_cons_vf(i + advxb - 1)%sf(j, k, l) = 1._wp + sum_alpha = sum_alpha + q_cons_vf(i + advxb - 1)%sf(j, k, l) + end do + + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_fluids + q_cons_vf(i + advxb - 1)%sf(j, k, l) = q_cons_vf(i + advxb - 1)%sf(j, k, l)/sum_alpha + end do + + end subroutine s_correct_volume_fractions + + !> Main pressure equilibration using Newton-Raphson + subroutine s_equilibrate_pressure(q_cons_vf, j, k, l) + $:GPU_ROUTINE(parallelism='[seq]') + + type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf + integer, intent(in) :: j, k, l + + real(wp) :: pres_relax, f_pres, df_pres + #:if not MFC_CASE_OPTIMIZATION and USING_AMD + real(wp), dimension(3) :: pres_K_init, rho_K_s + #:else + real(wp), dimension(num_fluids) :: pres_K_init, rho_K_s + #:endif + integer, parameter :: MAX_ITER = 50 + real(wp), parameter :: TOLERANCE = 1.e-10_wp + integer :: iter, i + + ! Initialize pressures + pres_relax = 0._wp + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_fluids + if (q_cons_vf(i + advxb - 1)%sf(j, k, l) > sgm_eps) then + pres_K_init(i) = (q_cons_vf(i + intxb - 1)%sf(j, k, l)/ & + q_cons_vf(i + advxb - 1)%sf(j, k, l) - pi_infs(i))/gammas(i) + if (pres_K_init(i) <= -(1._wp - 1.e-8_wp)*ps_inf(i) + 1.e-8_wp) & + pres_K_init(i) = -(1._wp - 1.e-8_wp)*ps_inf(i) + 1.e-8_wp + else + pres_K_init(i) = 0._wp + end if + pres_relax = pres_relax + q_cons_vf(i + advxb - 1)%sf(j, k, l)*pres_K_init(i) + end do + + ! Newton-Raphson iteration + f_pres = 1.e-9_wp + df_pres = 1.e9_wp + $:GPU_LOOP(parallelism='[seq]') + do iter = 0, MAX_ITER - 1 + if (abs(f_pres) > TOLERANCE) then + pres_relax = pres_relax - f_pres/df_pres + + ! Enforce pressure bounds + do i = 1, num_fluids + if (pres_relax <= -(1._wp - 1.e-8_wp)*ps_inf(i) + 1.e-8_wp) & + pres_relax = -(1._wp - 1.e-8_wp)*ps_inf(i) + 1.e-8_wp + end do + + ! Newton-Raphson step + f_pres = -1._wp + df_pres = 0._wp + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_fluids + if (q_cons_vf(i + advxb - 1)%sf(j, k, l) > sgm_eps) then + rho_K_s(i) = q_cons_vf(i + contxb - 1)%sf(j, k, l)/ & + max(q_cons_vf(i + advxb - 1)%sf(j, k, l), sgm_eps) & + *((pres_relax + ps_inf(i))/(pres_K_init(i) + & + ps_inf(i)))**(1._wp/gs_min(i)) + f_pres = f_pres + q_cons_vf(i + contxb - 1)%sf(j, k, l)/rho_K_s(i) + df_pres = df_pres - q_cons_vf(i + contxb - 1)%sf(j, k, l) & + /(gs_min(i)*rho_K_s(i)*(pres_relax + ps_inf(i))) + end if + end do + end if + end do + + ! Update volume fractions + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_fluids + if (q_cons_vf(i + advxb - 1)%sf(j, k, l) > sgm_eps) & + q_cons_vf(i + advxb - 1)%sf(j, k, l) = q_cons_vf(i + contxb - 1)%sf(j, k, l)/rho_K_s(i) + end do + + end subroutine s_equilibrate_pressure + + !> Correct internal energies using equilibrated pressure + subroutine s_correct_internal_energies(q_cons_vf, j, k, l) + $:GPU_ROUTINE(parallelism='[seq]') + + type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf + integer, intent(in) :: j, k, l + #:if not MFC_CASE_OPTIMIZATION and USING_AMD + real(wp), dimension(2) :: alpha_rho, alpha + #:else + real(wp), dimension(num_fluids) :: alpha_rho, alpha + #:endif + real(wp) :: rho, dyn_pres, gamma, pi_inf, pres_relax, sum_alpha + integer :: i + + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_fluids + alpha_rho(i) = q_cons_vf(i)%sf(j, k, l) + alpha(i) = q_cons_vf(E_idx + i)%sf(j, k, l) + end do + + ! Compute mixture properties (combined bubble and standard logic) + rho = 0._wp + gamma = 0._wp + pi_inf = 0._wp + + if (bubbles_euler) then + if (mpp_lim .and. (model_eqns == 2) .and. (num_fluids > 2)) then + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_fluids + rho = rho + alpha_rho(i) + gamma = gamma + alpha(i)*gammas(i) + pi_inf = pi_inf + alpha(i)*pi_infs(i) + end do + else if ((model_eqns == 2) .and. (num_fluids > 2)) then + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_fluids - 1 + rho = rho + alpha_rho(i) + gamma = gamma + alpha(i)*gammas(i) + pi_inf = pi_inf + alpha(i)*pi_infs(i) + end do + else + rho = alpha_rho(1) + gamma = gammas(1) + pi_inf = pi_infs(1) + end if + else + sum_alpha = 0._wp + if (mpp_lim) then + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_fluids + alpha_rho(i) = max(0._wp, alpha_rho(i)) + alpha(i) = min(max(0._wp, alpha(i)), 1._wp) + sum_alpha = sum_alpha + alpha(i) + end do + alpha = alpha/max(sum_alpha, sgm_eps) + end if + + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_fluids + rho = rho + alpha_rho(i) + gamma = gamma + alpha(i)*gammas(i) + pi_inf = pi_inf + alpha(i)*pi_infs(i) + end do + end if + + ! Compute dynamic pressure and update internal energies + dyn_pres = 0._wp + $:GPU_LOOP(parallelism='[seq]') + do i = momxb, momxe + dyn_pres = dyn_pres + 5.e-1_wp*q_cons_vf(i)%sf(j, k, l)* & + q_cons_vf(i)%sf(j, k, l)/max(rho, sgm_eps) + end do + + pres_relax = (q_cons_vf(E_idx)%sf(j, k, l) - dyn_pres - pi_inf)/gamma + + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_fluids + q_cons_vf(i + intxb - 1)%sf(j, k, l) = & + q_cons_vf(i + advxb - 1)%sf(j, k, l)*(gammas(i)*pres_relax + pi_infs(i)) + end do + + end subroutine s_correct_internal_energies + +end module m_pressure_relaxation diff --git a/src/simulation/m_re_visc.fpp b/src/simulation/m_re_visc.fpp new file mode 100644 index 0000000000..e741b563ec --- /dev/null +++ b/src/simulation/m_re_visc.fpp @@ -0,0 +1,346 @@ +!> +!! @file m_re_visc.f90 +!! @brief Contains module m_re_visc + +#:include 'macros.fpp' + +!> @brief The module contains routines that compute viscosity-related +!! quantities for both Newtonian and non-Newtonian fluids. +!! s_compute_re_visc returns Re_visc = 1/mu per phase. +!! s_compute_mixture_re computes mixture Re from per-phase values. +module m_re_visc + + use m_derived_types !< Definitions of the derived types + + use m_global_parameters !< Definitions of the global parameters + + use m_hb_function !< Herschel-Bulkley viscosity model + + implicit none + + private; public :: s_compute_re_visc, & + s_compute_mixture_re + +contains + + !> Computes velocity gradients at a single cell using finite differences. + !! Uses 2nd order central differences in interior, 1st order at boundaries. + !! @param q_prim_vf Primitive variables + !! @param j x index + !! @param k y index + !! @param l z index + !! @param D_xx Output: du/dx + !! @param D_yy Output: dv/dy + !! @param D_zz Output: dw/dz + !! @param D_xy Output: 0.5*(du/dy + dv/dx) + !! @param D_xz Output: 0.5*(du/dz + dw/dx) + !! @param D_yz Output: 0.5*(dv/dz + dw/dy) + pure subroutine s_compute_velocity_gradients_at_cell( & + q_prim_vf, j, k, l, D_xx, D_yy, D_zz, D_xy, D_xz, D_yz) + $:GPU_ROUTINE(parallelism='[seq]') + + type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf + integer, intent(in) :: j, k, l + real(wp), intent(out) :: D_xx, D_yy, D_zz, D_xy, D_xz, D_yz + + integer :: j_lo, j_hi, k_lo, k_hi, l_lo, l_hi + + j_lo = idwbuff(1)%beg + j_hi = idwbuff(1)%end + k_lo = idwbuff(2)%beg + k_hi = idwbuff(2)%end + l_lo = idwbuff(3)%beg + l_hi = idwbuff(3)%end + + ! Check bounds + if (.not. ((j >= j_lo) .and. (j <= j_hi) .and. & + (k >= k_lo) .and. (k <= k_hi) .and. & + (l >= l_lo) .and. (l <= l_hi))) then + D_xx = 0._wp; D_yy = 0._wp; D_zz = 0._wp + D_xy = 0._wp; D_xz = 0._wp; D_yz = 0._wp + return + end if + + ! D_xx = du/dx + if (j - 1 >= j_lo .and. j + 1 <= j_hi) then + D_xx = (q_prim_vf(momxb)%sf(j + 1, k, l) - & + q_prim_vf(momxb)%sf(j - 1, k, l))/ & + (x_cc(j + 1) - x_cc(j - 1)) + else if (j + 1 <= j_hi) then + D_xx = (q_prim_vf(momxb)%sf(j + 1, k, l) - & + q_prim_vf(momxb)%sf(j, k, l))/ & + (x_cc(j + 1) - x_cc(j)) + else if (j - 1 >= j_lo) then + D_xx = (q_prim_vf(momxb)%sf(j, k, l) - & + q_prim_vf(momxb)%sf(j - 1, k, l))/ & + (x_cc(j) - x_cc(j - 1)) + else + D_xx = 0._wp + end if + + ! D_yy = dv/dy (2D and 3D only) + if (n > 0) then + if (k - 1 >= k_lo .and. k + 1 <= k_hi) then + D_yy = (q_prim_vf(momxb + 1)%sf(j, k + 1, l) - & + q_prim_vf(momxb + 1)%sf(j, k - 1, l))/ & + (y_cc(k + 1) - y_cc(k - 1)) + else if (k + 1 <= k_hi) then + D_yy = (q_prim_vf(momxb + 1)%sf(j, k + 1, l) - & + q_prim_vf(momxb + 1)%sf(j, k, l))/ & + (y_cc(k + 1) - y_cc(k)) + else if (k - 1 >= k_lo) then + D_yy = (q_prim_vf(momxb + 1)%sf(j, k, l) - & + q_prim_vf(momxb + 1)%sf(j, k - 1, l))/ & + (y_cc(k) - y_cc(k - 1)) + else + D_yy = 0._wp + end if + else + D_yy = 0._wp + end if + + ! D_zz = dw/dz (3D only) + if (p > 0) then + if (l - 1 >= l_lo .and. l + 1 <= l_hi) then + D_zz = (q_prim_vf(momxb + 2)%sf(j, k, l + 1) - & + q_prim_vf(momxb + 2)%sf(j, k, l - 1))/ & + (z_cc(l + 1) - z_cc(l - 1)) + else if (l + 1 <= l_hi) then + D_zz = (q_prim_vf(momxb + 2)%sf(j, k, l + 1) - & + q_prim_vf(momxb + 2)%sf(j, k, l))/ & + (z_cc(l + 1) - z_cc(l)) + else if (l - 1 >= l_lo) then + D_zz = (q_prim_vf(momxb + 2)%sf(j, k, l) - & + q_prim_vf(momxb + 2)%sf(j, k, l - 1))/ & + (z_cc(l) - z_cc(l - 1)) + else + D_zz = 0._wp + end if + else + D_zz = 0._wp + end if + + ! D_xy = 0.5*(du/dy + dv/dx) (2D and 3D only) + if (n > 0) then + if (j - 1 >= j_lo .and. j + 1 <= j_hi .and. & + k - 1 >= k_lo .and. k + 1 <= k_hi) then + D_xy = 0.5_wp*( & + (q_prim_vf(momxb)%sf(j, k + 1, l) - & + q_prim_vf(momxb)%sf(j, k - 1, l))/ & + (y_cc(k + 1) - y_cc(k - 1)) + & + (q_prim_vf(momxb + 1)%sf(j + 1, k, l) - & + q_prim_vf(momxb + 1)%sf(j - 1, k, l))/ & + (x_cc(j + 1) - x_cc(j - 1))) + else + D_xy = 0._wp + if (k - 1 >= k_lo .and. k + 1 <= k_hi) then + D_xy = 0.5_wp*(q_prim_vf(momxb)%sf(j, k + 1, l) - & + q_prim_vf(momxb)%sf(j, k - 1, l))/ & + (y_cc(k + 1) - y_cc(k - 1)) + end if + if (j - 1 >= j_lo .and. j + 1 <= j_hi) then + D_xy = D_xy + 0.5_wp* & + (q_prim_vf(momxb + 1)%sf(j + 1, k, l) - & + q_prim_vf(momxb + 1)%sf(j - 1, k, l))/ & + (x_cc(j + 1) - x_cc(j - 1)) + end if + end if + else + D_xy = 0._wp + end if + + ! D_xz = 0.5*(du/dz + dw/dx) (3D only) + if (p > 0) then + if (j - 1 >= j_lo .and. j + 1 <= j_hi .and. & + l - 1 >= l_lo .and. l + 1 <= l_hi) then + D_xz = 0.5_wp*( & + (q_prim_vf(momxb)%sf(j, k, l + 1) - & + q_prim_vf(momxb)%sf(j, k, l - 1))/ & + (z_cc(l + 1) - z_cc(l - 1)) + & + (q_prim_vf(momxb + 2)%sf(j + 1, k, l) - & + q_prim_vf(momxb + 2)%sf(j - 1, k, l))/ & + (x_cc(j + 1) - x_cc(j - 1))) + else + D_xz = 0._wp + end if + else + D_xz = 0._wp + end if + + ! D_yz = 0.5*(dv/dz + dw/dy) (3D only) + if (p > 0 .and. n > 0) then + if (k - 1 >= k_lo .and. k + 1 <= k_hi .and. & + l - 1 >= l_lo .and. l + 1 <= l_hi) then + D_yz = 0.5_wp*( & + (q_prim_vf(momxb + 1)%sf(j, k, l + 1) - & + q_prim_vf(momxb + 1)%sf(j, k, l - 1))/ & + (z_cc(l + 1) - z_cc(l - 1)) + & + (q_prim_vf(momxb + 2)%sf(j, k + 1, l) - & + q_prim_vf(momxb + 2)%sf(j, k - 1, l))/ & + (y_cc(k + 1) - y_cc(k - 1))) + else + D_yz = 0._wp + end if + else + D_yz = 0._wp + end if + + end subroutine s_compute_velocity_gradients_at_cell + + !> Computes Re_visc per-phase for both Newtonian and non-Newtonian fluids. + !! Re_visc = 1/mu for each phase in each direction (shear and bulk). + !! @param q_prim_vf Primitive variables + !! @param alpha_visc Volume fractions + !! @param j x index + !! @param k y index + !! @param l z index + !! @param Re_visc_per_phase Output: 1/mu per fluid per direction + !! @param grad_x_vf Optional pre-computed x-direction gradients + !! @param grad_y_vf Optional pre-computed y-direction gradients + !! @param grad_z_vf Optional pre-computed z-direction gradients + pure subroutine s_compute_re_visc(q_prim_vf, alpha_visc, j, k, l, & + Re_visc_per_phase, grad_x_vf, grad_y_vf, grad_z_vf) + $:GPU_ROUTINE(parallelism='[seq]') + + type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf + #:if not MFC_CASE_OPTIMIZATION and USING_AMD + real(wp), dimension(3), intent(in) :: alpha_visc + #:else + real(wp), dimension(num_fluids), intent(in) :: alpha_visc + #:endif + integer, intent(in) :: j, k, l + #:if not MFC_CASE_OPTIMIZATION and USING_AMD + real(wp), dimension(3, 2), intent(out) :: Re_visc_per_phase + #:else + real(wp), dimension(num_fluids, 2), intent(out) :: Re_visc_per_phase + #:endif + type(scalar_field), dimension(:), intent(in), optional :: & + grad_x_vf, grad_y_vf, grad_z_vf + + real(wp) :: D_xx, D_yy, D_zz, D_xy, D_xz, D_yz + real(wp) :: shear_rate, mu_fluid + integer :: i, q, r + + ! Initialize all to default (inviscid) + $:GPU_LOOP(parallelism='[seq]') + do i = 1, 2 + $:GPU_LOOP(parallelism='[seq]') + do q = 1, num_fluids + Re_visc_per_phase(q, i) = dflt_real + end do + end do + + if (any_non_newtonian) then + ! Non-Newtonian path: compute velocity gradients and shear rate + if (present(grad_x_vf) .and. present(grad_y_vf) .and. & + present(grad_z_vf)) then + ! Use provided gradients + D_xx = grad_x_vf(1)%sf(j, k, l) + if (n > 0) then + D_yy = grad_y_vf(2)%sf(j, k, l) + D_xy = 0.5_wp*(grad_y_vf(1)%sf(j, k, l) + & + grad_x_vf(2)%sf(j, k, l)) + else + D_yy = 0._wp; D_xy = 0._wp + end if + if (p > 0) then + D_zz = grad_z_vf(3)%sf(j, k, l) + D_xz = 0.5_wp*(grad_z_vf(1)%sf(j, k, l) + & + grad_x_vf(3)%sf(j, k, l)) + D_yz = 0.5_wp*(grad_z_vf(2)%sf(j, k, l) + & + grad_y_vf(3)%sf(j, k, l)) + else + D_zz = 0._wp; D_xz = 0._wp; D_yz = 0._wp + end if + else + ! Compute gradients from primitive variables + call s_compute_velocity_gradients_at_cell( & + q_prim_vf, j, k, l, D_xx, D_yy, D_zz, D_xy, D_xz, D_yz) + end if + + ! Compute shear rate + shear_rate = f_compute_shear_rate_from_components( & + D_xx, D_yy, D_zz, D_xy, D_xz, D_yz) + + ! For each phase, compute Re_visc + $:GPU_LOOP(parallelism='[seq]') + do q = 1, num_fluids + if (fluid_pp(q)%non_newtonian) then + ! Non-Newtonian: compute shear mu from HB model + mu_fluid = f_compute_hb_viscosity( & + fluid_pp(q)%tau0, fluid_pp(q)%K, & + fluid_pp(q)%nn, fluid_pp(q)%mu_min, & + fluid_pp(q)%mu_max, shear_rate, & + fluid_pp(q)%hb_m) + Re_visc_per_phase(q, 1) = 1._wp/mu_fluid + ! Bulk viscosity + if (fluid_pp(q)%mu_bulk > 0._wp) then + Re_visc_per_phase(q, 2) = 1._wp/fluid_pp(q)%mu_bulk + else + Re_visc_per_phase(q, 2) = dflt_real + end if + else + ! Newtonian: return Re input values + $:GPU_LOOP(parallelism='[seq]') + do i = 1, 2 + if (Re_size(i) > 0) then + $:GPU_LOOP(parallelism='[seq]') + do r = 1, Re_size(i) + if (Re_idx(i, r) == q) then + Re_visc_per_phase(q, i) = fluid_pp(q)%Re(i) + exit + end if + end do + end if + end do + end if + end do + else + ! All Newtonian: return Re input values + $:GPU_LOOP(parallelism='[seq]') + do i = 1, 2 + $:GPU_LOOP(parallelism='[seq]') + do q = 1, Re_size(i) + Re_visc_per_phase(Re_idx(i, q), i) = & + fluid_pp(Re_idx(i, q))%Re(i) + end do + end do + end if + + end subroutine s_compute_re_visc + + !> Computes mixture Reynolds number from per-phase values and volume fractions. + !! Re_mix(i) = 1 / sum_q(alpha(q) / Re_per_phase(q, i)) + !! @param alpha Volume fractions + !! @param Re_per_phase Per-phase Re_visc = 1/mu + !! @param Re_mix Output: mixture Re (shear and bulk) + pure subroutine s_compute_mixture_re(alpha, Re_per_phase, Re_mix) + $:GPU_ROUTINE(parallelism='[seq]') + + #:if not MFC_CASE_OPTIMIZATION and USING_AMD + real(wp), dimension(3), intent(in) :: alpha + real(wp), dimension(3, 2), intent(in) :: Re_per_phase + #:else + real(wp), dimension(num_fluids), intent(in) :: alpha + real(wp), dimension(num_fluids, 2), intent(in) :: Re_per_phase + #:endif + real(wp), dimension(2), intent(out) :: Re_mix + + integer :: i, q + + $:GPU_LOOP(parallelism='[seq]') + do i = 1, 2 + Re_mix(i) = 0._wp + $:GPU_LOOP(parallelism='[seq]') + do q = 1, num_fluids + if (Re_per_phase(q, i) /= dflt_real & + .and. Re_per_phase(q, i) > sgm_eps) then + Re_mix(i) = Re_mix(i) + alpha(q)/Re_per_phase(q, i) + end if + end do + Re_mix(i) = 1._wp/max(Re_mix(i), sgm_eps) + end do + + end subroutine s_compute_mixture_re + +end module m_re_visc diff --git a/src/simulation/m_riemann_solvers.fpp b/src/simulation/m_riemann_solvers.fpp index 5a8d3a118a..93eade8a09 100644 --- a/src/simulation/m_riemann_solvers.fpp +++ b/src/simulation/m_riemann_solvers.fpp @@ -1,5257 +1,5272 @@ -!> -!! @file -!! @brief Contains module m_riemann_solvers - -!> @brief Approximate and exact Riemann solvers (HLL, HLLC, HLLD, exact) for the multicomponent Navier--Stokes equations - -#:include 'case.fpp' -#:include 'macros.fpp' -#:include 'inline_riemann.fpp' - -module m_riemann_solvers - - use m_derived_types !< Definitions of the derived types - - use m_global_parameters !< Definitions of the global parameters - - use m_mpi_proxy !< Message passing interface (MPI) module proxy - - use m_variables_conversion !< State variables type conversion procedures - - use m_bubbles !< To get the bubble wall pressure function - - use m_bubbles_EE - - use m_surface_tension !< To get the capillary fluxes - - use m_helper_basic !< Functions to compare floating point numbers - - use m_chemistry - - use m_thermochem, only: & - gas_constant, get_mixture_molecular_weight, & - get_mixture_specific_heat_cv_mass, get_mixture_energy_mass, & - get_species_specific_heats_r, get_species_enthalpies_rt, & - get_mixture_specific_heat_cp_mass - - #:if USING_AMD - use m_chemistry, only: molecular_weights_nonparameter - #:endif - - implicit none - - private; public :: s_initialize_riemann_solvers_module, & - s_riemann_solver, & - s_hll_riemann_solver, & - s_hllc_riemann_solver, & - s_hlld_riemann_solver, & - s_lf_riemann_solver, & - s_finalize_riemann_solvers_module - - !> The cell-boundary values of the fluxes (src - source) that are computed - !! through the chosen Riemann problem solver, and the direct evaluation of - !! source terms, by using the left and right states given in qK_prim_rs_vf, - !! dqK_prim_ds_vf where ds = dx, dy or dz. - !> @{ - - real(wp), allocatable, dimension(:, :, :, :) :: flux_rsx_vf, flux_src_rsx_vf - real(wp), allocatable, dimension(:, :, :, :) :: flux_rsy_vf, flux_src_rsy_vf - real(wp), allocatable, dimension(:, :, :, :) :: flux_rsz_vf, flux_src_rsz_vf - $:GPU_DECLARE(create='[flux_rsx_vf,flux_src_rsx_vf,flux_rsy_vf,flux_src_rsy_vf,flux_rsz_vf,flux_src_rsz_vf]') - !> @} - - !> The cell-boundary values of the geometrical source flux that are computed - !! through the chosen Riemann problem solver by using the left and right - !! states given in qK_prim_rs_vf. Currently 2D axisymmetric for inviscid only. - !> @{ - - real(wp), allocatable, dimension(:, :, :, :) :: flux_gsrc_rsx_vf !< - real(wp), allocatable, dimension(:, :, :, :) :: flux_gsrc_rsy_vf !< - real(wp), allocatable, dimension(:, :, :, :) :: flux_gsrc_rsz_vf !< - $:GPU_DECLARE(create='[flux_gsrc_rsx_vf,flux_gsrc_rsy_vf,flux_gsrc_rsz_vf]') - !> @} - - ! The cell-boundary values of the velocity. vel_src_rs_vf is determined as - ! part of Riemann problem solution and is used to evaluate the source flux. - - real(wp), allocatable, dimension(:, :, :, :) :: vel_src_rsx_vf - real(wp), allocatable, dimension(:, :, :, :) :: vel_src_rsy_vf - real(wp), allocatable, dimension(:, :, :, :) :: vel_src_rsz_vf - $:GPU_DECLARE(create='[vel_src_rsx_vf,vel_src_rsy_vf,vel_src_rsz_vf]') - - real(wp), allocatable, dimension(:, :, :, :) :: mom_sp_rsx_vf - real(wp), allocatable, dimension(:, :, :, :) :: mom_sp_rsy_vf - real(wp), allocatable, dimension(:, :, :, :) :: mom_sp_rsz_vf - $:GPU_DECLARE(create='[mom_sp_rsx_vf,mom_sp_rsy_vf,mom_sp_rsz_vf]') - - real(wp), allocatable, dimension(:, :, :, :) :: Re_avg_rsx_vf - real(wp), allocatable, dimension(:, :, :, :) :: Re_avg_rsy_vf - real(wp), allocatable, dimension(:, :, :, :) :: Re_avg_rsz_vf - $:GPU_DECLARE(create='[Re_avg_rsx_vf,Re_avg_rsy_vf,Re_avg_rsz_vf]') - - !> @name Indical bounds in the s1-, s2- and s3-directions - !> @{ - type(int_bounds_info) :: is1, is2, is3 - type(int_bounds_info) :: isx, isy, isz - !> @} - - $:GPU_DECLARE(create='[is1,is2,is3,isx,isy,isz]') - - real(wp), allocatable, dimension(:) :: Gs_rs - $:GPU_DECLARE(create='[Gs_rs]') - - real(wp), allocatable, dimension(:, :) :: Res_gs - $:GPU_DECLARE(create='[Res_gs]') - -contains - - !> Dispatch to the subroutines that are utilized to compute the - !! Riemann problem solution. For additional information please reference: - !! 1) s_hll_riemann_solver - !! 2) s_hllc_riemann_solver - !! 3) s_exact_riemann_solver - !! 4) s_hlld_riemann_solver - !! @param qL_prim_rsx_vf Left WENO-reconstructed cell-boundary values (x-dir) - !! @param qL_prim_rsy_vf Left WENO-reconstructed cell-boundary values (y-dir) - !! @param qL_prim_rsz_vf Left WENO-reconstructed cell-boundary values (z-dir) - !! @param dqL_prim_dx_vf The left WENO-reconstructed cell-boundary values of the - !! first-order x-dir spatial derivatives - !! @param dqL_prim_dy_vf The left WENO-reconstructed cell-boundary values of the - !! first-order y-dir spatial derivatives - !! @param dqL_prim_dz_vf The left WENO-reconstructed cell-boundary values of the - !! first-order z-dir spatial derivatives - !! @param qL_prim_vf The left WENO-reconstructed cell-boundary values of the - !! cell-average primitive variables - !! @param qR_prim_rsx_vf Right WENO-reconstructed cell-boundary values (x-dir) - !! @param qR_prim_rsy_vf Right WENO-reconstructed cell-boundary values (y-dir) - !! @param qR_prim_rsz_vf Right WENO-reconstructed cell-boundary values (z-dir) - !! @param dqR_prim_dx_vf The right WENO-reconstructed cell-boundary values of the - !! first-order x-dir spatial derivatives - !! @param dqR_prim_dy_vf The right WENO-reconstructed cell-boundary values of the - !! first-order y-dir spatial derivatives - !! @param dqR_prim_dz_vf The right WENO-reconstructed cell-boundary values of the - !! first-order z-dir spatial derivatives - !! @param qR_prim_vf The right WENO-reconstructed cell-boundary values of the - !! cell-average primitive variables - !! @param q_prim_vf Cell-averaged primitive variables - !! @param flux_vf Intra-cell fluxes - !! @param flux_src_vf Intra-cell fluxes sources - !! @param flux_gsrc_vf Intra-cell geometric fluxes sources - !! @param norm_dir Dir. splitting direction - !! @param ix Index bounds in the x-dir - !! @param iy Index bounds in the y-dir - !! @param iz Index bounds in the z-dir - subroutine s_riemann_solver(qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, dqL_prim_dx_vf, & - dqL_prim_dy_vf, & - dqL_prim_dz_vf, & - qL_prim_vf, & - qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf, dqR_prim_dx_vf, & - dqR_prim_dy_vf, & - dqR_prim_dz_vf, & - qR_prim_vf, & - q_prim_vf, & - flux_vf, flux_src_vf, & - flux_gsrc_vf, & - norm_dir, ix, iy, iz) - - real(wp), dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:), intent(INOUT) :: qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf - type(scalar_field), dimension(sys_size), intent(IN) :: q_prim_vf - - type(scalar_field), allocatable, dimension(:), intent(INOUT) :: qL_prim_vf, qR_prim_vf - - type(scalar_field), & - allocatable, dimension(:), & - intent(INOUT) :: dqL_prim_dx_vf, dqR_prim_dx_vf, & - dqL_prim_dy_vf, dqR_prim_dy_vf, & - dqL_prim_dz_vf, dqR_prim_dz_vf - - type(scalar_field), & - dimension(sys_size), & - intent(INOUT) :: flux_vf, flux_src_vf, flux_gsrc_vf - - integer, intent(IN) :: norm_dir - - type(int_bounds_info), intent(IN) :: ix, iy, iz - - #:for NAME, NUM in [('hll', 1), ('hllc', 2), ('hlld', 4), ('lf', 5)] - if (riemann_solver == ${NUM}$) then - call s_${NAME}$_riemann_solver(qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, dqL_prim_dx_vf, & - dqL_prim_dy_vf, & - dqL_prim_dz_vf, & - qL_prim_vf, & - qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf, dqR_prim_dx_vf, & - dqR_prim_dy_vf, & - dqR_prim_dz_vf, & - qR_prim_vf, & - q_prim_vf, & - flux_vf, flux_src_vf, & - flux_gsrc_vf, & - norm_dir, ix, iy, iz) - end if - #:endfor - - end subroutine s_riemann_solver - - !> Dispatch to the subroutines that are utilized to compute - !! the viscous source fluxes for either Cartesian or cylindrical geometries. - !! For more information please refer to: - !! 1) s_compute_cartesian_viscous_source_flux - !! 2) s_compute_cylindrical_viscous_source_flux - subroutine s_compute_viscous_source_flux(velL_vf, & - dvelL_dx_vf, & - dvelL_dy_vf, & - dvelL_dz_vf, & - velR_vf, & - dvelR_dx_vf, & - dvelR_dy_vf, & - dvelR_dz_vf, & - flux_src_vf, & - norm_dir, & - ix, iy, iz) - - type(scalar_field), & - dimension(num_vels), & - intent(IN) :: velL_vf, velR_vf, & - dvelL_dx_vf, dvelR_dx_vf, & - dvelL_dy_vf, dvelR_dy_vf, & - dvelL_dz_vf, dvelR_dz_vf - - type(scalar_field), & - dimension(sys_size), & - intent(INOUT) :: flux_src_vf - - integer, intent(IN) :: norm_dir - - type(int_bounds_info), intent(IN) :: ix, iy, iz - - if (grid_geometry == 3) then - call s_compute_cylindrical_viscous_source_flux(velL_vf, & - dvelL_dx_vf, & - dvelL_dy_vf, & - dvelL_dz_vf, & - velR_vf, & - dvelR_dx_vf, & - dvelR_dy_vf, & - dvelR_dz_vf, & - flux_src_vf, & - norm_dir, & - ix, iy, iz) - else - call s_compute_cartesian_viscous_source_flux(dvelL_dx_vf, & - dvelL_dy_vf, & - dvelL_dz_vf, & - dvelR_dx_vf, & - dvelR_dy_vf, & - dvelR_dz_vf, & - flux_src_vf, & - norm_dir) - end if - end subroutine s_compute_viscous_source_flux - - !> @brief Computes intercell fluxes using the Harten-Lax-van Leer (HLL) approximate Riemann solver. - subroutine s_hll_riemann_solver(qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, dqL_prim_dx_vf, & - dqL_prim_dy_vf, & - dqL_prim_dz_vf, & - qL_prim_vf, & - qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf, dqR_prim_dx_vf, & - dqR_prim_dy_vf, & - dqR_prim_dz_vf, & - qR_prim_vf, & - q_prim_vf, & - flux_vf, flux_src_vf, & - flux_gsrc_vf, & - norm_dir, ix, iy, iz) - - real(wp), dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:), intent(inout) :: qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf - type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf - - type(scalar_field), allocatable, dimension(:), intent(inout) :: qL_prim_vf, qR_prim_vf - - type(scalar_field), & - allocatable, dimension(:), & - intent(inout) :: dqL_prim_dx_vf, dqR_prim_dx_vf, & - dqL_prim_dy_vf, dqR_prim_dy_vf, & - dqL_prim_dz_vf, dqR_prim_dz_vf - - ! Intercell fluxes - type(scalar_field), & - dimension(sys_size), & - intent(inout) :: flux_vf, flux_src_vf, flux_gsrc_vf - real(wp) :: flux_tau_L, flux_tau_R - - integer, intent(in) :: norm_dir - type(int_bounds_info), intent(in) :: ix, iy, iz - #:if not MFC_CASE_OPTIMIZATION and USING_AMD - real(wp), dimension(3) :: alpha_rho_L, alpha_rho_R - real(wp), dimension(3) :: vel_L, vel_R - real(wp), dimension(3) :: alpha_L, alpha_R - real(wp), dimension(10) :: Ys_L, Ys_R - real(wp), dimension(10) :: Cp_iL, Cp_iR, Xs_L, Xs_R, Gamma_iL, Gamma_iR - real(wp), dimension(10) :: Yi_avg, Phi_avg, h_iL, h_iR, h_avg_2 - #:else - real(wp), dimension(num_fluids) :: alpha_rho_L, alpha_rho_R - real(wp), dimension(num_vels) :: vel_L, vel_R - real(wp), dimension(num_fluids) :: alpha_L, alpha_R - real(wp), dimension(num_species) :: Ys_L, Ys_R - real(wp), dimension(num_species) :: Cp_iL, Cp_iR, Xs_L, Xs_R, Gamma_iL, Gamma_iR - real(wp), dimension(num_species) :: Yi_avg, Phi_avg, h_iL, h_iR, h_avg_2 - #:endif - real(wp) :: rho_L, rho_R - real(wp) :: pres_L, pres_R - real(wp) :: E_L, E_R - real(wp) :: H_L, H_R - real(wp) :: Cp_avg, Cv_avg, T_avg, eps, c_sum_Yi_Phi - real(wp) :: T_L, T_R - real(wp) :: Y_L, Y_R - real(wp) :: MW_L, MW_R - real(wp) :: R_gas_L, R_gas_R - real(wp) :: Cp_L, Cp_R - real(wp) :: Cv_L, Cv_R - real(wp) :: Gamm_L, Gamm_R - real(wp) :: gamma_L, gamma_R - real(wp) :: pi_inf_L, pi_inf_R - real(wp) :: qv_L, qv_R - real(wp) :: c_L, c_R - real(wp), dimension(6) :: tau_e_L, tau_e_R - real(wp) :: G_L, G_R - real(wp), dimension(2) :: Re_L, Re_R - real(wp), dimension(3) :: xi_field_L, xi_field_R - - real(wp) :: rho_avg - real(wp) :: H_avg - real(wp) :: qv_avg - real(wp) :: gamma_avg - real(wp) :: c_avg - - real(wp) :: s_L, s_R, s_M, s_P, s_S - real(wp) :: xi_M, xi_P - - real(wp) :: ptilde_L, ptilde_R - real(wp) :: vel_L_rms, vel_R_rms, vel_avg_rms - real(wp) :: vel_L_tmp, vel_R_tmp - real(wp) :: Ms_L, Ms_R, pres_SL, pres_SR - real(wp) :: alpha_L_sum, alpha_R_sum - real(wp) :: zcoef, pcorr !< low Mach number correction - - type(riemann_states) :: c_fast, pres_mag - type(riemann_states_vec3) :: B - - type(riemann_states) :: Ga ! Gamma (Lorentz factor) - type(riemann_states) :: vdotB, B2 - type(riemann_states_vec3) :: b4 ! 4-magnetic field components (spatial: b4x, b4y, b4z) - type(riemann_states_vec3) :: cm ! Conservative momentum variables - - integer :: i, j, k, l, q !< Generic loop iterators - - ! Populating the buffers of the left and right Riemann problem - ! states variables, based on the choice of boundary conditions - call s_populate_riemann_states_variables_buffers( & - qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, dqL_prim_dx_vf, & - dqL_prim_dy_vf, & - dqL_prim_dz_vf, & - qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf, dqR_prim_dx_vf, & - dqR_prim_dy_vf, & - dqR_prim_dz_vf, & - norm_dir, ix, iy, iz) - - ! Reshaping inputted data based on dimensional splitting direction - call s_initialize_riemann_solver( & - flux_src_vf, & - norm_dir) - #:for NORM_DIR, XYZ in [(1, 'x'), (2, 'y'), (3, 'z')] - - if (norm_dir == ${NORM_DIR}$) then - $:GPU_PARALLEL_LOOP(collapse=3, private='[i,j,k,l,q,alpha_rho_L,alpha_rho_R,vel_L,vel_R,alpha_L,alpha_R,tau_e_L,tau_e_R,Re_L,Re_R,s_L,s_R,s_S,Ys_L,Ys_R,xi_field_L, xi_field_R, Cp_iL, Cp_iR, Xs_L, Xs_R, Gamma_iL, Gamma_iR, Yi_avg, Phi_avg, h_iL, h_iR, h_avg_2, c_fast, pres_mag, B, Ga, vdotB, B2, b4, cm, pcorr, zcoef, vel_L_tmp, vel_R_tmp, rho_L, rho_R, pres_L, pres_R, E_L, E_R, H_L, H_R, Cp_avg, Cv_avg, T_avg, eps, c_sum_Yi_Phi, T_L, T_R, Y_L, Y_R, MW_L, MW_R, R_gas_L, R_gas_R, Cp_L, Cp_R, Cv_L, Cv_R, Gamm_L, Gamm_R, gamma_L, gamma_R, pi_inf_L, pi_inf_R, qv_L, qv_R, qv_avg, c_L, c_R, G_L, G_R, rho_avg, H_avg, c_avg, gamma_avg, ptilde_L, ptilde_R, vel_L_rms, vel_R_rms, vel_avg_rms, Ms_L, Ms_R, pres_SL, pres_SR, alpha_L_sum, alpha_R_sum, flux_tau_L, flux_tau_R]', copyin='[norm_dir]') - do l = is3%beg, is3%end - do k = is2%beg, is2%end - do j = is1%beg, is1%end - $:GPU_LOOP(parallelism='[seq]') - do i = 1, contxe - alpha_rho_L(i) = qL_prim_rs${XYZ}$_vf(j, k, l, i) - alpha_rho_R(i) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, i) - end do - - vel_L_rms = 0._wp; vel_R_rms = 0._wp - - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_vels - vel_L(i) = qL_prim_rs${XYZ}$_vf(j, k, l, contxe + i) - vel_R(i) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, contxe + i) - vel_L_rms = vel_L_rms + vel_L(i)**2._wp - vel_R_rms = vel_R_rms + vel_R(i)**2._wp - end do - - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_fluids - alpha_L(i) = qL_prim_rs${XYZ}$_vf(j, k, l, E_idx + i) - alpha_R(i) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx + i) - end do - - pres_L = qL_prim_rs${XYZ}$_vf(j, k, l, E_idx) - pres_R = qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx) - - if (mhd) then - if (n == 0) then ! 1D: constant Bx; By, Bz as variables - B%L(1) = Bx0 - B%R(1) = Bx0 - B%L(2) = qL_prim_rs${XYZ}$_vf(j, k, l, B_idx%beg) - B%R(2) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, B_idx%beg) - B%L(3) = qL_prim_rs${XYZ}$_vf(j, k, l, B_idx%beg + 1) - B%R(3) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, B_idx%beg + 1) - else ! 2D/3D: Bx, By, Bz as variables - B%L(1) = qL_prim_rs${XYZ}$_vf(j, k, l, B_idx%beg) - B%R(1) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, B_idx%beg) - B%L(2) = qL_prim_rs${XYZ}$_vf(j, k, l, B_idx%beg + 1) - B%R(2) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, B_idx%beg + 1) - B%L(3) = qL_prim_rs${XYZ}$_vf(j, k, l, B_idx%beg + 2) - B%R(3) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, B_idx%beg + 2) - end if - end if - - rho_L = 0._wp - gamma_L = 0._wp - pi_inf_L = 0._wp - qv_L = 0._wp - - rho_R = 0._wp - gamma_R = 0._wp - pi_inf_R = 0._wp - qv_R = 0._wp - - alpha_L_sum = 0._wp - alpha_R_sum = 0._wp - - pres_mag%L = 0._wp - pres_mag%R = 0._wp - - if (mpp_lim) then - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_fluids - alpha_rho_L(i) = max(0._wp, alpha_rho_L(i)) - alpha_L(i) = min(max(0._wp, alpha_L(i)), 1._wp) - alpha_L_sum = alpha_L_sum + alpha_L(i) - alpha_rho_R(i) = max(0._wp, alpha_rho_R(i)) - alpha_R(i) = min(max(0._wp, alpha_R(i)), 1._wp) - alpha_R_sum = alpha_R_sum + alpha_R(i) - end do - - alpha_L = alpha_L/max(alpha_L_sum, sgm_eps) - alpha_R = alpha_R/max(alpha_R_sum, sgm_eps) - end if - - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_fluids - rho_L = rho_L + alpha_rho_L(i) - gamma_L = gamma_L + alpha_L(i)*gammas(i) - pi_inf_L = pi_inf_L + alpha_L(i)*pi_infs(i) - qv_L = qv_L + alpha_rho_L(i)*qvs(i) - - rho_R = rho_R + alpha_rho_R(i) - gamma_R = gamma_R + alpha_R(i)*gammas(i) - pi_inf_R = pi_inf_R + alpha_R(i)*pi_infs(i) - qv_R = qv_R + alpha_rho_R(i)*qvs(i) - end do - - if (viscous) then - $:GPU_LOOP(parallelism='[seq]') - do i = 1, 2 - Re_L(i) = dflt_real - Re_R(i) = dflt_real - - if (Re_size(i) > 0) Re_L(i) = 0._wp - if (Re_size(i) > 0) Re_R(i) = 0._wp - - $:GPU_LOOP(parallelism='[seq]') - do q = 1, Re_size(i) - Re_L(i) = alpha_L(Re_idx(i, q))/Res_gs(i, q) & - + Re_L(i) - Re_R(i) = alpha_R(Re_idx(i, q))/Res_gs(i, q) & - + Re_R(i) - end do - - Re_L(i) = 1._wp/max(Re_L(i), sgm_eps) - Re_R(i) = 1._wp/max(Re_R(i), sgm_eps) - end do - end if - - if (chemistry) then - $:GPU_LOOP(parallelism='[seq]') - do i = chemxb, chemxe - Ys_L(i - chemxb + 1) = qL_prim_rs${XYZ}$_vf(j, k, l, i) - Ys_R(i - chemxb + 1) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, i) - end do - - call get_mixture_molecular_weight(Ys_L, MW_L) - call get_mixture_molecular_weight(Ys_R, MW_R) - #:if USING_AMD - Xs_L(:) = Ys_L(:)*MW_L/molecular_weights_nonparameter(:) - Xs_R(:) = Ys_R(:)*MW_R/molecular_weights_nonparameter(:) - #:else - Xs_L(:) = Ys_L(:)*MW_L/molecular_weights(:) - Xs_R(:) = Ys_R(:)*MW_R/molecular_weights(:) - #:endif - - R_gas_L = gas_constant/MW_L - R_gas_R = gas_constant/MW_R - T_L = pres_L/rho_L/R_gas_L - T_R = pres_R/rho_R/R_gas_R - - call get_species_specific_heats_r(T_L, Cp_iL) - call get_species_specific_heats_r(T_R, Cp_iR) - - if (chem_params%gamma_method == 1) then - ! gamma_method = 1: Ref. Section 2.3.1 Formulation of doi:10.7907/ZKW8-ES97. - Gamma_iL = Cp_iL/(Cp_iL - 1.0_wp) - Gamma_iR = Cp_iR/(Cp_iR - 1.0_wp) - - gamma_L = sum(Xs_L(:)/(Gamma_iL(:) - 1.0_wp)) - gamma_R = sum(Xs_R(:)/(Gamma_iR(:) - 1.0_wp)) - else if (chem_params%gamma_method == 2) then - ! gamma_method = 2: c_p / c_v where c_p, c_v are specific heats. - call get_mixture_specific_heat_cp_mass(T_L, Ys_L, Cp_L) - call get_mixture_specific_heat_cp_mass(T_R, Ys_R, Cp_R) - call get_mixture_specific_heat_cv_mass(T_L, Ys_L, Cv_L) - call get_mixture_specific_heat_cv_mass(T_R, Ys_R, Cv_R) - - Gamm_L = Cp_L/Cv_L - gamma_L = 1.0_wp/(Gamm_L - 1.0_wp) - Gamm_R = Cp_R/Cv_R - gamma_R = 1.0_wp/(Gamm_R - 1.0_wp) - end if - - call get_mixture_energy_mass(T_L, Ys_L, E_L) - call get_mixture_energy_mass(T_R, Ys_R, E_R) - - E_L = rho_L*E_L + 5.e-1*rho_L*vel_L_rms - E_R = rho_R*E_R + 5.e-1*rho_R*vel_R_rms - H_L = (E_L + pres_L)/rho_L - H_R = (E_R + pres_R)/rho_R - elseif (mhd .and. relativity) then - Ga%L = 1._wp/sqrt(1._wp - vel_L_rms) - Ga%R = 1._wp/sqrt(1._wp - vel_R_rms) - #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 - vdotB%L = vel_L(1)*B%L(1) + vel_L(2)*B%L(2) + vel_L(3)*B%L(3) - vdotB%R = vel_R(1)*B%R(1) + vel_R(2)*B%R(2) + vel_R(3)*B%R(3) - - b4%L(1:3) = B%L(1:3)/Ga%L + Ga%L*vel_L(1:3)*vdotB%L - b4%R(1:3) = B%R(1:3)/Ga%R + Ga%R*vel_R(1:3)*vdotB%R - B2%L = B%L(1)**2._wp + B%L(2)**2._wp + B%L(3)**2._wp - B2%R = B%R(1)**2._wp + B%R(2)**2._wp + B%R(3)**2._wp - #:endif - - pres_mag%L = 0.5_wp*(B2%L/Ga%L**2._wp + vdotB%L**2._wp) - pres_mag%R = 0.5_wp*(B2%R/Ga%R**2._wp + vdotB%R**2._wp) - - ! Hard-coded EOS - H_L = 1._wp + (gamma_L + 1)*pres_L/rho_L - H_R = 1._wp + (gamma_R + 1)*pres_R/rho_R - #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 - cm%L(1:3) = (rho_L*H_L*Ga%L**2 + B2%L)*vel_L(1:3) - vdotB%L*B%L(1:3) - cm%R(1:3) = (rho_R*H_R*Ga%R**2 + B2%R)*vel_R(1:3) - vdotB%R*B%R(1:3) - #:endif - - E_L = rho_L*H_L*Ga%L**2 - pres_L + 0.5_wp*(B2%L + vel_L_rms*B2%L - vdotB%L**2._wp) - rho_L*Ga%L - E_R = rho_R*H_R*Ga%R**2 - pres_R + 0.5_wp*(B2%R + vel_R_rms*B2%R - vdotB%R**2._wp) - rho_R*Ga%R - elseif (mhd .and. .not. relativity) then - #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 - pres_mag%L = 0.5_wp*(B%L(1)**2._wp + B%L(2)**2._wp + B%L(3)**2._wp) - pres_mag%R = 0.5_wp*(B%R(1)**2._wp + B%R(2)**2._wp + B%R(3)**2._wp) - #:endif - E_L = gamma_L*pres_L + pi_inf_L + 0.5_wp*rho_L*vel_L_rms + qv_L + pres_mag%L - E_R = gamma_R*pres_R + pi_inf_R + 0.5_wp*rho_R*vel_R_rms + qv_R + pres_mag%R ! includes magnetic energy - H_L = (E_L + pres_L - pres_mag%L)/rho_L - H_R = (E_R + pres_R - pres_mag%R)/rho_R ! stagnation enthalpy here excludes magnetic energy (only used to find speed of sound) - else - E_L = gamma_L*pres_L + pi_inf_L + 5.e-1*rho_L*vel_L_rms + qv_L - E_R = gamma_R*pres_R + pi_inf_R + 5.e-1*rho_R*vel_R_rms + qv_R - H_L = (E_L + pres_L)/rho_L - H_R = (E_R + pres_R)/rho_R - end if - - ! elastic energy update - if (hypoelasticity) then - G_L = 0._wp; G_R = 0._wp - - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_fluids - G_L = G_L + alpha_L(i)*Gs_rs(i) - G_R = G_R + alpha_R(i)*Gs_rs(i) - end do - - if (cont_damage) then - G_L = G_L*max((1._wp - qL_prim_rs${XYZ}$_vf(j, k, l, damage_idx)), 0._wp) - G_R = G_R*max((1._wp - qR_prim_rs${XYZ}$_vf(j, k, l, damage_idx)), 0._wp) - end if - - $:GPU_LOOP(parallelism='[seq]') - do i = 1, strxe - strxb + 1 - tau_e_L(i) = qL_prim_rs${XYZ}$_vf(j, k, l, strxb - 1 + i) - tau_e_R(i) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, strxb - 1 + i) - ! Elastic contribution to energy if G large enough - !TODO take out if statement if stable without - if ((G_L > 1000) .and. (G_R > 1000)) then - E_L = E_L + (tau_e_L(i)*tau_e_L(i))/(4._wp*G_L) - E_R = E_R + (tau_e_R(i)*tau_e_R(i))/(4._wp*G_R) - ! Double for shear stresses - if (any(strxb - 1 + i == shear_indices)) then - E_L = E_L + (tau_e_L(i)*tau_e_L(i))/(4._wp*G_L) - E_R = E_R + (tau_e_R(i)*tau_e_R(i))/(4._wp*G_R) - end if - end if - end do - end if - - ! elastic energy update - !if ( hyperelasticity ) then - ! G_L = 0._wp - ! G_R = 0._wp - ! - ! $:GPU_LOOP(parallelism='[seq]') - ! do i = 1, num_fluids - ! G_L = G_L + alpha_L(i)*Gs_rs(i) - ! G_R = G_R + alpha_R(i)*Gs_rs(i) - ! end do - ! ! Elastic contribution to energy if G large enough - ! if ((G_L > 1.e-3_wp) .and. (G_R > 1.e-3_wp)) then - ! E_L = E_L + G_L*qL_prim_rs${XYZ}$_vf(j, k, l, xiend + 1) - ! E_R = E_R + G_R*qR_prim_rs${XYZ}$_vf(j + 1, k, l, xiend + 1) - ! $:GPU_LOOP(parallelism='[seq]') - ! do i = 1, b_size-1 - ! tau_e_L(i) = G_L*qL_prim_rs${XYZ}$_vf(j, k, l, strxb - 1 + i) - ! tau_e_R(i) = G_R*qR_prim_rs${XYZ}$_vf(j + 1, k, l, strxb - 1 + i) - ! end do - ! $:GPU_LOOP(parallelism='[seq]') - ! do i = 1, b_size-1 - ! tau_e_L(i) = 0._wp - ! tau_e_R(i) = 0._wp - ! end do - ! $:GPU_LOOP(parallelism='[seq]') - ! do i = 1, num_dims - ! xi_field_L(i) = qL_prim_rs${XYZ}$_vf(j, k, l, xibeg - 1 + i) - ! xi_field_R(i) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, xibeg - 1 + i) - ! end do - ! end if - !end if - - @:compute_average_state() - - call s_compute_speed_of_sound(pres_L, rho_L, gamma_L, pi_inf_L, H_L, alpha_L, & - vel_L_rms, 0._wp, c_L, qv_L) - - call s_compute_speed_of_sound(pres_R, rho_R, gamma_R, pi_inf_R, H_R, alpha_R, & - vel_R_rms, 0._wp, c_R, qv_R) - - !> The computation of c_avg does not require all the variables, and therefore the non '_avg' - ! variables are placeholders to call the subroutine. - - call s_compute_speed_of_sound(pres_R, rho_avg, gamma_avg, pi_inf_R, H_avg, alpha_R, & - vel_avg_rms, c_sum_Yi_Phi, c_avg, qv_avg) - - if (mhd) then - call s_compute_fast_magnetosonic_speed(rho_L, c_L, B%L, norm_dir, c_fast%L, H_L) - call s_compute_fast_magnetosonic_speed(rho_R, c_R, B%R, norm_dir, c_fast%R, H_R) - end if - - if (hyper_cleaning) then ! mhd - c_fast%L = min(c_fast%L, -hyper_cleaning_speed) - c_fast%R = max(c_fast%R, hyper_cleaning_speed) - end if - - if (viscous) then - if (chemistry) then - call compute_viscosity_and_inversion(T_L, Ys_L, T_R, Ys_R, Re_L(1), Re_R(1)) - end if - $:GPU_LOOP(parallelism='[seq]') - do i = 1, 2 - Re_avg_rs${XYZ}$_vf(j, k, l, i) = 2._wp/(1._wp/Re_L(i) + 1._wp/Re_R(i)) - end do - end if - - if (wave_speeds == 1) then - if (mhd) then - s_L = min(vel_L(dir_idx(1)) - c_fast%L, vel_R(dir_idx(1)) - c_fast%R) - s_R = max(vel_R(dir_idx(1)) + c_fast%R, vel_L(dir_idx(1)) + c_fast%L) - elseif (hypoelasticity) then - s_L = min(vel_L(dir_idx(1)) - sqrt(c_L*c_L + & - (((4._wp*G_L)/3._wp) + & - tau_e_L(dir_idx_tau(1)))/rho_L) & - , vel_R(dir_idx(1)) - sqrt(c_R*c_R + & - (((4._wp*G_R)/3._wp) + & - tau_e_R(dir_idx_tau(1)))/rho_R)) - s_R = max(vel_R(dir_idx(1)) + sqrt(c_R*c_R + & - (((4._wp*G_R)/3._wp) + & - tau_e_R(dir_idx_tau(1)))/rho_R) & - , vel_L(dir_idx(1)) + sqrt(c_L*c_L + & - (((4._wp*G_L)/3._wp) + & - tau_e_L(dir_idx_tau(1)))/rho_L)) - else if (hyperelasticity) then - s_L = min(vel_L(dir_idx(1)) - sqrt(c_L*c_L + (4._wp*G_L/3._wp)/rho_L) & - , vel_R(dir_idx(1)) - sqrt(c_R*c_R + (4._wp*G_R/3._wp)/rho_R)) - s_R = max(vel_R(dir_idx(1)) + sqrt(c_R*c_R + (4._wp*G_R/3._wp)/rho_R) & - , vel_L(dir_idx(1)) + sqrt(c_L*c_L + (4._wp*G_L/3._wp)/rho_L)) - else - s_L = min(vel_L(dir_idx(1)) - c_L, vel_R(dir_idx(1)) - c_R) - s_R = max(vel_R(dir_idx(1)) + c_R, vel_L(dir_idx(1)) + c_L) - end if - - s_S = (pres_R - pres_L + rho_L*vel_L(dir_idx(1))* & - (s_L - vel_L(dir_idx(1))) - & - rho_R*vel_R(dir_idx(1))* & - (s_R - vel_R(dir_idx(1)))) & - /(rho_L*(s_L - vel_L(dir_idx(1))) - & - rho_R*(s_R - vel_R(dir_idx(1)))) - elseif (wave_speeds == 2) then - pres_SL = 5.e-1_wp*(pres_L + pres_R + rho_avg*c_avg* & - (vel_L(dir_idx(1)) - & - vel_R(dir_idx(1)))) - - pres_SR = pres_SL - - Ms_L = max(1._wp, sqrt(1._wp + ((5.e-1_wp + gamma_L)/(1._wp + gamma_L))* & - (pres_SL/pres_L - 1._wp)*pres_L/ & - ((pres_L + pi_inf_L/(1._wp + gamma_L))))) - Ms_R = max(1._wp, sqrt(1._wp + ((5.e-1_wp + gamma_R)/(1._wp + gamma_R))* & - (pres_SR/pres_R - 1._wp)*pres_R/ & - ((pres_R + pi_inf_R/(1._wp + gamma_R))))) - - s_L = vel_L(dir_idx(1)) - c_L*Ms_L - s_R = vel_R(dir_idx(1)) + c_R*Ms_R - - s_S = 5.e-1_wp*((vel_L(dir_idx(1)) + vel_R(dir_idx(1))) + & - (pres_L - pres_R)/ & - (rho_avg*c_avg)) - end if - - s_M = min(0._wp, s_L); s_P = max(0._wp, s_R) - - xi_M = (5.e-1_wp + sign(5.e-1_wp, s_L)) & - + (5.e-1_wp - sign(5.e-1_wp, s_L)) & - *(5.e-1_wp + sign(5.e-1_wp, s_R)) - xi_P = (5.e-1_wp - sign(5.e-1_wp, s_R)) & - + (5.e-1_wp - sign(5.e-1_wp, s_L)) & - *(5.e-1_wp + sign(5.e-1_wp, s_R)) - - ! Low Mach correction - if (low_Mach == 1) then - @:compute_low_Mach_correction() - else - pcorr = 0._wp - end if - - ! Mass - if (.not. relativity) then - $:GPU_LOOP(parallelism='[seq]') - do i = 1, contxe - flux_rs${XYZ}$_vf(j, k, l, i) = & - (s_M*alpha_rho_R(i)*vel_R(norm_dir) & - - s_P*alpha_rho_L(i)*vel_L(norm_dir) & - + s_M*s_P*(alpha_rho_L(i) & - - alpha_rho_R(i))) & - /(s_M - s_P) - end do - elseif (relativity) then - $:GPU_LOOP(parallelism='[seq]') - do i = 1, contxe - flux_rs${XYZ}$_vf(j, k, l, i) = & - (s_M*Ga%R*alpha_rho_R(i)*vel_R(norm_dir) & - - s_P*Ga%L*alpha_rho_L(i)*vel_L(norm_dir) & - + s_M*s_P*(Ga%L*alpha_rho_L(i) & - - Ga%R*alpha_rho_R(i))) & - /(s_M - s_P) - end do - end if - - ! Momentum - if (mhd .and. (.not. relativity)) then - $:GPU_LOOP(parallelism='[seq]') - do i = 1, 3 - ! Flux of rho*v_i in the ${XYZ}$ direction - ! = rho * v_i * v_${XYZ}$ - B_i * B_${XYZ}$ + delta_(${XYZ}$,i) * p_tot - flux_rs${XYZ}$_vf(j, k, l, contxe + i) = & - (s_M*(rho_R*vel_R(i)*vel_R(norm_dir) & - - B%R(i)*B%R(norm_dir) & - + dir_flg(i)*(pres_R + pres_mag%R)) & - - s_P*(rho_L*vel_L(i)*vel_L(norm_dir) & - - B%L(i)*B%L(norm_dir) & - + dir_flg(i)*(pres_L + pres_mag%L)) & - + s_M*s_P*(rho_L*vel_L(i) - rho_R*vel_R(i))) & - /(s_M - s_P) - end do - elseif (mhd .and. relativity) then - $:GPU_LOOP(parallelism='[seq]') - do i = 1, 3 - ! Flux of m_i in the ${XYZ}$ direction - ! = m_i * v_${XYZ}$ - b_i/Gamma * B_${XYZ}$ + delta_(${XYZ}$,i) * p_tot - flux_rs${XYZ}$_vf(j, k, l, contxe + i) = & - (s_M*(cm%R(i)*vel_R(norm_dir) & - - b4%R(i)/Ga%R*B%R(norm_dir) & - + dir_flg(i)*(pres_R + pres_mag%R)) & - - s_P*(cm%L(i)*vel_L(norm_dir) & - - b4%L(i)/Ga%L*B%L(norm_dir) & - + dir_flg(i)*(pres_L + pres_mag%L)) & - + s_M*s_P*(cm%L(i) - cm%R(i))) & - /(s_M - s_P) - end do - elseif (bubbles_euler) then - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_vels - flux_rs${XYZ}$_vf(j, k, l, contxe + dir_idx(i)) = & - (s_M*(rho_R*vel_R(dir_idx(1)) & - *vel_R(dir_idx(i)) & - + dir_flg(dir_idx(i))*(pres_R - ptilde_R)) & - - s_P*(rho_L*vel_L(dir_idx(1)) & - *vel_L(dir_idx(i)) & - + dir_flg(dir_idx(i))*(pres_L - ptilde_L)) & - + s_M*s_P*(rho_L*vel_L(dir_idx(i)) & - - rho_R*vel_R(dir_idx(i)))) & - /(s_M - s_P) & - + (s_M/s_L)*(s_P/s_R)*pcorr*(vel_R(dir_idx(i)) - vel_L(dir_idx(i))) - end do - else if (hypoelasticity) then - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_vels - flux_rs${XYZ}$_vf(j, k, l, contxe + dir_idx(i)) = & - (s_M*(rho_R*vel_R(dir_idx(1)) & - *vel_R(dir_idx(i)) & - + dir_flg(dir_idx(i))*pres_R & - - tau_e_R(dir_idx_tau(i))) & - - s_P*(rho_L*vel_L(dir_idx(1)) & - *vel_L(dir_idx(i)) & - + dir_flg(dir_idx(i))*pres_L & - - tau_e_L(dir_idx_tau(i))) & - + s_M*s_P*(rho_L*vel_L(dir_idx(i)) & - - rho_R*vel_R(dir_idx(i)))) & - /(s_M - s_P) - end do - else - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_vels - flux_rs${XYZ}$_vf(j, k, l, contxe + dir_idx(i)) = & - (s_M*(rho_R*vel_R(dir_idx(1)) & - *vel_R(dir_idx(i)) & - + dir_flg(dir_idx(i))*pres_R) & - - s_P*(rho_L*vel_L(dir_idx(1)) & - *vel_L(dir_idx(i)) & - + dir_flg(dir_idx(i))*pres_L) & - + s_M*s_P*(rho_L*vel_L(dir_idx(i)) & - - rho_R*vel_R(dir_idx(i)))) & - /(s_M - s_P) & - + (s_M/s_L)*(s_P/s_R)*pcorr*(vel_R(dir_idx(i)) - vel_L(dir_idx(i))) - end do - end if - - ! Energy - if (mhd .and. (.not. relativity)) then - ! energy flux = (E + p + p_mag) * v_${XYZ}$ - B_${XYZ}$ * (v_x*B_x + v_y*B_y + v_z*B_z) - #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 - flux_rs${XYZ}$_vf(j, k, l, E_idx) = & - (s_M*(vel_R(norm_dir)*(E_R + pres_R + pres_mag%R) - B%R(norm_dir)*(vel_R(1)*B%R(1) + vel_R(2)*B%R(2) + vel_R(3)*B%R(3))) & - - s_P*(vel_L(norm_dir)*(E_L + pres_L + pres_mag%L) - B%L(norm_dir)*(vel_L(1)*B%L(1) + vel_L(2)*B%L(2) + vel_L(3)*B%L(3))) & - + s_M*s_P*(E_L - E_R)) & - /(s_M - s_P) - #:endif - elseif (mhd .and. relativity) then - ! energy flux = m_${XYZ}$ - mass flux - ! Hard-coded for single-component for now - flux_rs${XYZ}$_vf(j, k, l, E_idx) = & - (s_M*(cm%R(norm_dir) - Ga%R*alpha_rho_R(1)*vel_R(norm_dir)) & - - s_P*(cm%L(norm_dir) - Ga%L*alpha_rho_L(1)*vel_L(norm_dir)) & - + s_M*s_P*(E_L - E_R)) & - /(s_M - s_P) - else if (bubbles_euler) then - flux_rs${XYZ}$_vf(j, k, l, E_idx) = & - (s_M*vel_R(dir_idx(1))*(E_R + pres_R - ptilde_R) & - - s_P*vel_L(dir_idx(1))*(E_L + pres_L - ptilde_L) & - + s_M*s_P*(E_L - E_R)) & - /(s_M - s_P) & - + (s_M/s_L)*(s_P/s_R)*pcorr*(vel_R_rms - vel_L_rms)/2._wp - else if (hypoelasticity) then - flux_tau_L = 0._wp; flux_tau_R = 0._wp - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_dims - flux_tau_L = flux_tau_L + tau_e_L(dir_idx_tau(i))*vel_L(dir_idx(i)) - flux_tau_R = flux_tau_R + tau_e_R(dir_idx_tau(i))*vel_R(dir_idx(i)) - end do - flux_rs${XYZ}$_vf(j, k, l, E_idx) = & - (s_M*(vel_R(dir_idx(1))*(E_R + pres_R) - flux_tau_R) & - - s_P*(vel_L(dir_idx(1))*(E_L + pres_L) - flux_tau_L) & - + s_M*s_P*(E_L - E_R))/(s_M - s_P) - else - flux_rs${XYZ}$_vf(j, k, l, E_idx) = & - (s_M*vel_R(dir_idx(1))*(E_R + pres_R) & - - s_P*vel_L(dir_idx(1))*(E_L + pres_L) & - + s_M*s_P*(E_L - E_R)) & - /(s_M - s_P) & - + (s_M/s_L)*(s_P/s_R)*pcorr*(vel_R_rms - vel_L_rms)/2._wp - end if - - ! Elastic Stresses - if (hypoelasticity) then - do i = 1, strxe - strxb + 1 !TODO: this indexing may be slow - flux_rs${XYZ}$_vf(j, k, l, strxb - 1 + i) = & - (s_M*(rho_R*vel_R(dir_idx(1)) & - *tau_e_R(i)) & - - s_P*(rho_L*vel_L(dir_idx(1)) & - *tau_e_L(i)) & - + s_M*s_P*(rho_L*tau_e_L(i) & - - rho_R*tau_e_R(i))) & - /(s_M - s_P) - end do - end if - - ! Advection - $:GPU_LOOP(parallelism='[seq]') - do i = advxb, advxe - flux_rs${XYZ}$_vf(j, k, l, i) = & - (qL_prim_rs${XYZ}$_vf(j, k, l, i) & - - qR_prim_rs${XYZ}$_vf(j + 1, k, l, i)) & - *s_M*s_P/(s_M - s_P) - flux_src_rs${XYZ}$_vf(j, k, l, i) = & - (s_M*qR_prim_rs${XYZ}$_vf(j + 1, k, l, i) & - - s_P*qL_prim_rs${XYZ}$_vf(j, k, l, i)) & - /(s_M - s_P) - end do - - if (bubbles_euler) then - ! From HLLC: Kills mass transport @ bubble gas density - if (num_fluids > 1) then - flux_rs${XYZ}$_vf(j, k, l, contxe) = 0._wp - end if - end if - - if (chemistry) then - $:GPU_LOOP(parallelism='[seq]') - do i = chemxb, chemxe - Y_L = qL_prim_rs${XYZ}$_vf(j, k, l, i) - Y_R = qR_prim_rs${XYZ}$_vf(j + 1, k, l, i) - - flux_rs${XYZ}$_vf(j, k, l, i) = (s_M*Y_R*rho_R*vel_R(dir_idx(1)) & - - s_P*Y_L*rho_L*vel_L(dir_idx(1)) & - + s_M*s_P*(Y_L*rho_L - Y_R*rho_R)) & - /(s_M - s_P) - flux_src_rs${XYZ}$_vf(j, k, l, i) = 0._wp - end do - end if - - if (mhd) then - if (n == 0) then ! 1D: d/dx flux only & Bx = Bx0 = const. - ! B_y flux = v_x * B_y - v_y * Bx0 - ! B_z flux = v_x * B_z - v_z * Bx0 - $:GPU_LOOP(parallelism='[seq]') - do i = 0, 1 - flux_rsx_vf(j, k, l, B_idx%beg + i) = (s_M*(vel_R(1)*B%R(2 + i) - vel_R(2 + i)*Bx0) & - - s_P*(vel_L(1)*B%L(2 + i) - vel_L(2 + i)*Bx0) & - + s_M*s_P*(B%L(2 + i) - B%R(2 + i)))/(s_M - s_P) - end do - else ! 2D/3D: Bx, By, Bz /= const. but zero flux component in the same direction - ! B_x d/d${XYZ}$ flux = (1 - delta(x,${XYZ}$)) * (v_${XYZ}$ * B_x - v_x * B_${XYZ}$) - ! B_y d/d${XYZ}$ flux = (1 - delta(y,${XYZ}$)) * (v_${XYZ}$ * B_y - v_y * B_${XYZ}$) - ! B_z d/d${XYZ}$ flux = (1 - delta(z,${XYZ}$)) * (v_${XYZ}$ * B_z - v_z * B_${XYZ}$) - $:GPU_LOOP(parallelism='[seq]') - do i = 0, 2 - flux_rs${XYZ}$_vf(j, k, l, B_idx%beg + i) = (s_M*(vel_R(dir_idx(1))*B%R(i + 1) - vel_R(i + 1)*B%R(norm_dir)) - & - s_P*(vel_L(dir_idx(1))*B%L(i + 1) - vel_L(i + 1)*B%L(norm_dir)) + & - s_M*s_P*(B%L(i + 1) - B%R(i + 1)))/(s_M - s_P) - end do - - if (hyper_cleaning) then - ! propagate magnetic field divergence as a wave - flux_rs${XYZ}$_vf(j, k, l, B_idx%beg + norm_dir - 1) = flux_rs${XYZ}$_vf(j, k, l, B_idx%beg + norm_dir - 1) + & - (s_M*qR_prim_rs${XYZ}$_vf(j + 1, k, l, psi_idx) - s_P*qL_prim_rs${XYZ}$_vf(j, k, l, psi_idx))/(s_M - s_P) - - flux_rs${XYZ}$_vf(j, k, l, psi_idx) = (hyper_cleaning_speed**2*(s_M*B%R(norm_dir) - s_P*B%L(norm_dir)) + s_M*s_P*(qL_prim_rs${XYZ}$_vf(j, k, l, psi_idx) - qR_prim_rs${XYZ}$_vf(j + 1, k, l, psi_idx)))/(s_M - s_P) - else - flux_rs${XYZ}$_vf(j, k, l, B_idx%beg + norm_dir - 1) = 0._wp ! Without hyperbolic cleaning, make sure flux of B_normal is identically zero - end if - end if - flux_src_rs${XYZ}$_vf(j, k, l, advxb) = 0._wp - end if - - #:if (NORM_DIR == 2) - if (cyl_coord) then - !Substituting the advective flux into the inviscid geometrical source flux - $:GPU_LOOP(parallelism='[seq]') - do i = 1, E_idx - flux_gsrc_rs${XYZ}$_vf(j, k, l, i) = flux_rs${XYZ}$_vf(j, k, l, i) - end do - ! Recalculating the radial momentum geometric source flux - flux_gsrc_rs${XYZ}$_vf(j, k, l, contxe + 2) = & - flux_rs${XYZ}$_vf(j, k, l, contxe + 2) & - - (s_M*pres_R - s_P*pres_L)/(s_M - s_P) - ! Geometrical source of the void fraction(s) is zero - $:GPU_LOOP(parallelism='[seq]') - do i = advxb, advxe - flux_gsrc_rs${XYZ}$_vf(j, k, l, i) = flux_rs${XYZ}$_vf(j, k, l, i) - end do - end if - - if (cyl_coord .and. hypoelasticity) then - ! += tau_sigmasigma using HLL - flux_gsrc_rs${XYZ}$_vf(j, k, l, contxe + 2) = & - flux_gsrc_rs${XYZ}$_vf(j, k, l, contxe + 2) + & - (s_M*tau_e_R(4) - s_P*tau_e_L(4)) & - /(s_M - s_P) - - $:GPU_LOOP(parallelism='[seq]') - do i = strxb, strxe - flux_gsrc_rs${XYZ}$_vf(j, k, l, i) = flux_rs${XYZ}$_vf(j, k, l, i) - end do - end if - #:endif - - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - end if - - #:endfor - - if (viscous .or. dummy) then - if (weno_Re_flux) then - - call s_compute_viscous_source_flux( & - qL_prim_vf(momxb:momxe), & - dqL_prim_dx_vf(momxb:momxe), & - dqL_prim_dy_vf(momxb:momxe), & - dqL_prim_dz_vf(momxb:momxe), & - qR_prim_vf(momxb:momxe), & - dqR_prim_dx_vf(momxb:momxe), & - dqR_prim_dy_vf(momxb:momxe), & - dqR_prim_dz_vf(momxb:momxe), & - flux_src_vf, norm_dir, ix, iy, iz) - else - call s_compute_viscous_source_flux( & - q_prim_vf(momxb:momxe), & - dqL_prim_dx_vf(momxb:momxe), & - dqL_prim_dy_vf(momxb:momxe), & - dqL_prim_dz_vf(momxb:momxe), & - q_prim_vf(momxb:momxe), & - dqR_prim_dx_vf(momxb:momxe), & - dqR_prim_dy_vf(momxb:momxe), & - dqR_prim_dz_vf(momxb:momxe), & - flux_src_vf, norm_dir, ix, iy, iz) - end if - end if - - call s_finalize_riemann_solver(flux_vf, flux_src_vf, & - flux_gsrc_vf, & - norm_dir) - - end subroutine s_hll_riemann_solver - - !> @brief Computes intercell fluxes using the Lax-Friedrichs (LF) approximate Riemann solver. - subroutine s_lf_riemann_solver(qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, dqL_prim_dx_vf, & - dqL_prim_dy_vf, & - dqL_prim_dz_vf, & - qL_prim_vf, & - qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf, dqR_prim_dx_vf, & - dqR_prim_dy_vf, & - dqR_prim_dz_vf, & - qR_prim_vf, & - q_prim_vf, & - flux_vf, flux_src_vf, & - flux_gsrc_vf, & - norm_dir, ix, iy, iz) - - real(wp), dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:), intent(inout) :: qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf - type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf - - type(scalar_field), allocatable, dimension(:), intent(inout) :: qL_prim_vf, qR_prim_vf - - type(scalar_field), & - allocatable, dimension(:), & - intent(inout) :: dqL_prim_dx_vf, dqR_prim_dx_vf, & - dqL_prim_dy_vf, dqR_prim_dy_vf, & - dqL_prim_dz_vf, dqR_prim_dz_vf - - ! Intercell fluxes - type(scalar_field), & - dimension(sys_size), & - intent(inout) :: flux_vf, flux_src_vf, flux_gsrc_vf - real(wp) :: flux_tau_L, flux_tau_R - - integer, intent(in) :: norm_dir - type(int_bounds_info), intent(in) :: ix, iy, iz - #:if not MFC_CASE_OPTIMIZATION and USING_AMD - real(wp), dimension(3) :: alpha_rho_L, alpha_rho_R - real(wp), dimension(3) :: vel_L, vel_R - real(wp), dimension(3) :: alpha_L, alpha_R - real(wp), dimension(10) :: Ys_L, Ys_R - real(wp), dimension(10) :: Cp_iL, Cp_iR, Xs_L, Xs_R, Gamma_iL, Gamma_iR - real(wp), dimension(10) :: Yi_avg, Phi_avg, h_iL, h_iR, h_avg_2 - real(wp), dimension(3, 3) :: vel_grad_L, vel_grad_R !< Averaged velocity gradient tensor `d(vel_i)/d(coord_j)`. - #:else - real(wp), dimension(num_fluids) :: alpha_rho_L, alpha_rho_R - real(wp), dimension(num_vels) :: vel_L, vel_R - real(wp), dimension(num_fluids) :: alpha_L, alpha_R - real(wp), dimension(num_species) :: Ys_L, Ys_R - real(wp), dimension(num_species) :: Cp_iL, Cp_iR, Xs_L, Xs_R, Gamma_iL, Gamma_iR - real(wp), dimension(num_species) :: Yi_avg, Phi_avg, h_iL, h_iR, h_avg_2 - real(wp), dimension(num_dims, num_dims) :: vel_grad_L, vel_grad_R !< Averaged velocity gradient tensor `d(vel_i)/d(coord_j)`. - #:endif - real(wp) :: rho_L, rho_R - - real(wp) :: pres_L, pres_R - real(wp) :: E_L, E_R - real(wp) :: H_L, H_R - real(wp) :: Cp_avg, Cv_avg, T_avg, eps, c_sum_Yi_Phi - real(wp) :: T_L, T_R - real(wp) :: Y_L, Y_R - real(wp) :: MW_L, MW_R - real(wp) :: R_gas_L, R_gas_R - real(wp) :: Cp_L, Cp_R - real(wp) :: Cv_L, Cv_R - real(wp) :: Gamm_L, Gamm_R - real(wp) :: gamma_L, gamma_R - real(wp) :: pi_inf_L, pi_inf_R - real(wp) :: qv_L, qv_R - real(wp) :: c_L, c_R - real(wp), dimension(6) :: tau_e_L, tau_e_R - real(wp) :: G_L, G_R - real(wp), dimension(2) :: Re_L, Re_R - real(wp), dimension(3) :: xi_field_L, xi_field_R - - real(wp) :: rho_avg - real(wp) :: H_avg - real(wp) :: gamma_avg - real(wp) :: c_avg - - real(wp) :: s_L, s_R, s_M, s_P, s_S - real(wp) :: xi_M, xi_P - - real(wp) :: ptilde_L, ptilde_R - real(wp) :: vel_L_rms, vel_R_rms, vel_avg_rms - real(wp) :: vel_L_tmp, vel_R_tmp - real(wp) :: Ms_L, Ms_R, pres_SL, pres_SR - real(wp) :: alpha_L_sum, alpha_R_sum - real(wp) :: zcoef, pcorr !< low Mach number correction - - type(riemann_states) :: c_fast, pres_mag - type(riemann_states_vec3) :: B - - type(riemann_states) :: Ga ! Gamma (Lorentz factor) - type(riemann_states) :: vdotB, B2 - type(riemann_states_vec3) :: b4 ! 4-magnetic field components (spatial: b4x, b4y, b4z) - type(riemann_states_vec3) :: cm ! Conservative momentum variables - - integer :: i, j, k, l, q !< Generic loop iterators - integer, dimension(3) :: idx_right_phys !< Physical (j,k,l) indices for right state. - - ! Populating the buffers of the left and right Riemann problem - ! states variables, based on the choice of boundary conditions - call s_populate_riemann_states_variables_buffers( & - qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, dqL_prim_dx_vf, & - dqL_prim_dy_vf, & - dqL_prim_dz_vf, & - qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf, dqR_prim_dx_vf, & - dqR_prim_dy_vf, & - dqR_prim_dz_vf, & - norm_dir, ix, iy, iz) - - ! Reshaping inputted data based on dimensional splitting direction - call s_initialize_riemann_solver( & - flux_src_vf, & - norm_dir) - #:for NORM_DIR, XYZ in [(1, 'x'), (2, 'y'), (3, 'z')] - - if (norm_dir == ${NORM_DIR}$) then - $:GPU_PARALLEL_LOOP(collapse=3, private='[i,j,k,l, q, alpha_rho_L,alpha_rho_R,vel_L,vel_R,alpha_L,alpha_R,tau_e_L,tau_e_R,G_L,G_R,Re_L,Re_R,rho_avg,h_avg,gamma_avg,s_L,s_R,s_S,Ys_L,Ys_R,xi_field_L,xi_field_R,Cp_iL,Cp_iR,Xs_L,Xs_R,Gamma_iL,Gamma_iR,Yi_avg,Phi_avg,h_iL,h_iR,h_avg_2,c_fast,pres_mag,B,Ga,vdotB,B2,b4,cm,pcorr,zcoef,vel_grad_L,vel_grad_R,idx_right_phys,vel_L_rms,vel_R_rms,vel_avg_rms,vel_L_tmp,vel_R_tmp,Ms_L,Ms_R,pres_SL,pres_SR,alpha_L_sum,alpha_R_sum,c_avg,pres_L,pres_R,rho_L,rho_R,gamma_L,gamma_R,pi_inf_L,pi_inf_R,qv_L,qv_R,c_L,c_R,E_L,E_R,H_L,H_R,ptilde_L,ptilde_R,s_M,s_P,xi_M,xi_P,Cp_avg,Cv_avg,T_avg,eps,c_sum_Yi_Phi,Cp_L,Cp_R,Cv_L,Cv_R,R_gas_L,R_gas_R,MW_L,MW_R,T_L,T_R,Y_L,Y_R]') - do l = is3%beg, is3%end - do k = is2%beg, is2%end - do j = is1%beg, is1%end - $:GPU_LOOP(parallelism='[seq]') - do i = 1, contxe - alpha_rho_L(i) = qL_prim_rs${XYZ}$_vf(j, k, l, i) - alpha_rho_R(i) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, i) - end do - - vel_L_rms = 0._wp; vel_R_rms = 0._wp - - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_vels - vel_L(i) = qL_prim_rs${XYZ}$_vf(j, k, l, contxe + i) - vel_R(i) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, contxe + i) - vel_L_rms = vel_L_rms + vel_L(i)**2._wp - vel_R_rms = vel_R_rms + vel_R(i)**2._wp - end do - - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_fluids - alpha_L(i) = qL_prim_rs${XYZ}$_vf(j, k, l, E_idx + i) - alpha_R(i) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx + i) - end do - - pres_L = qL_prim_rs${XYZ}$_vf(j, k, l, E_idx) - pres_R = qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx) - - if (mhd) then - if (n == 0) then ! 1D: constant Bx; By, Bz as variables - B%L(1) = Bx0 - B%R(1) = Bx0 - B%L(2) = qL_prim_rs${XYZ}$_vf(j, k, l, B_idx%beg) - B%R(2) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, B_idx%beg) - B%L(3) = qL_prim_rs${XYZ}$_vf(j, k, l, B_idx%beg + 1) - B%R(3) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, B_idx%beg + 1) - else ! 2D/3D: Bx, By, Bz as variables - B%L(1) = qL_prim_rs${XYZ}$_vf(j, k, l, B_idx%beg) - B%R(1) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, B_idx%beg) - B%L(2) = qL_prim_rs${XYZ}$_vf(j, k, l, B_idx%beg + 1) - B%R(2) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, B_idx%beg + 1) - B%L(3) = qL_prim_rs${XYZ}$_vf(j, k, l, B_idx%beg + 2) - B%R(3) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, B_idx%beg + 2) - end if - end if - - rho_L = 0._wp - gamma_L = 0._wp - pi_inf_L = 0._wp - qv_L = 0._wp - - rho_R = 0._wp - gamma_R = 0._wp - pi_inf_R = 0._wp - qv_R = 0._wp - - alpha_L_sum = 0._wp - alpha_R_sum = 0._wp - - pres_mag%L = 0._wp - pres_mag%R = 0._wp - - if (mpp_lim) then - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_fluids - alpha_rho_L(i) = max(0._wp, alpha_rho_L(i)) - alpha_L(i) = min(max(0._wp, alpha_L(i)), 1._wp) - alpha_L_sum = alpha_L_sum + alpha_L(i) - alpha_rho_R(i) = max(0._wp, alpha_rho_R(i)) - alpha_R(i) = min(max(0._wp, alpha_R(i)), 1._wp) - alpha_R_sum = alpha_R_sum + alpha_R(i) - end do - - alpha_L = alpha_L/max(alpha_L_sum, sgm_eps) - alpha_R = alpha_R/max(alpha_R_sum, sgm_eps) - end if - - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_fluids - rho_L = rho_L + alpha_rho_L(i) - gamma_L = gamma_L + alpha_L(i)*gammas(i) - pi_inf_L = pi_inf_L + alpha_L(i)*pi_infs(i) - qv_L = qv_L + alpha_rho_L(i)*qvs(i) - - rho_R = rho_R + alpha_rho_R(i) - gamma_R = gamma_R + alpha_R(i)*gammas(i) - pi_inf_R = pi_inf_R + alpha_R(i)*pi_infs(i) - qv_R = qv_R + alpha_rho_R(i)*qvs(i) - end do - - if (viscous) then - $:GPU_LOOP(parallelism='[seq]') - do i = 1, 2 - Re_L(i) = dflt_real - Re_R(i) = dflt_real - - if (Re_size(i) > 0) Re_L(i) = 0._wp - if (Re_size(i) > 0) Re_R(i) = 0._wp - - $:GPU_LOOP(parallelism='[seq]') - do q = 1, Re_size(i) - Re_L(i) = alpha_L(Re_idx(i, q))/Res_gs(i, q) & - + Re_L(i) - Re_R(i) = alpha_R(Re_idx(i, q))/Res_gs(i, q) & - + Re_R(i) - end do - - Re_L(i) = 1._wp/max(Re_L(i), sgm_eps) - Re_R(i) = 1._wp/max(Re_R(i), sgm_eps) - end do - end if - - if (chemistry) then - $:GPU_LOOP(parallelism='[seq]') - do i = chemxb, chemxe - Ys_L(i - chemxb + 1) = qL_prim_rs${XYZ}$_vf(j, k, l, i) - Ys_R(i - chemxb + 1) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, i) - end do - - call get_mixture_molecular_weight(Ys_L, MW_L) - call get_mixture_molecular_weight(Ys_R, MW_R) - - #:if USING_AMD - Xs_L(:) = Ys_L(:)*MW_L/molecular_weights_nonparameter(:) - Xs_R(:) = Ys_R(:)*MW_R/molecular_weights_nonparameter(:) - #:else - Xs_L(:) = Ys_L(:)*MW_L/molecular_weights(:) - Xs_R(:) = Ys_R(:)*MW_R/molecular_weights(:) - #:endif - - R_gas_L = gas_constant/MW_L - R_gas_R = gas_constant/MW_R - T_L = pres_L/rho_L/R_gas_L - T_R = pres_R/rho_R/R_gas_R - - call get_species_specific_heats_r(T_L, Cp_iL) - call get_species_specific_heats_r(T_R, Cp_iR) - - if (chem_params%gamma_method == 1) then - ! gamma_method = 1: Ref. Section 2.3.1 Formulation of doi:10.7907/ZKW8-ES97. - Gamma_iL = Cp_iL/(Cp_iL - 1.0_wp) - Gamma_iR = Cp_iR/(Cp_iR - 1.0_wp) - - gamma_L = sum(Xs_L(:)/(Gamma_iL(:) - 1.0_wp)) - gamma_R = sum(Xs_R(:)/(Gamma_iR(:) - 1.0_wp)) - else if (chem_params%gamma_method == 2) then - ! gamma_method = 2: c_p / c_v where c_p, c_v are specific heats. - call get_mixture_specific_heat_cp_mass(T_L, Ys_L, Cp_L) - call get_mixture_specific_heat_cp_mass(T_R, Ys_R, Cp_R) - call get_mixture_specific_heat_cv_mass(T_L, Ys_L, Cv_L) - call get_mixture_specific_heat_cv_mass(T_R, Ys_R, Cv_R) - - Gamm_L = Cp_L/Cv_L - gamma_L = 1.0_wp/(Gamm_L - 1.0_wp) - Gamm_R = Cp_R/Cv_R - gamma_R = 1.0_wp/(Gamm_R - 1.0_wp) - end if - - call get_mixture_energy_mass(T_L, Ys_L, E_L) - call get_mixture_energy_mass(T_R, Ys_R, E_R) - - E_L = rho_L*E_L + 5.e-1*rho_L*vel_L_rms - E_R = rho_R*E_R + 5.e-1*rho_R*vel_R_rms - H_L = (E_L + pres_L)/rho_L - H_R = (E_R + pres_R)/rho_R - elseif (mhd .and. relativity) then - #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 - Ga%L = 1._wp/sqrt(1._wp - vel_L_rms) - Ga%R = 1._wp/sqrt(1._wp - vel_R_rms) - vdotB%L = vel_L(1)*B%L(1) + vel_L(2)*B%L(2) + vel_L(3)*B%L(3) - vdotB%R = vel_R(1)*B%R(1) + vel_R(2)*B%R(2) + vel_R(3)*B%R(3) - - b4%L(1:3) = B%L(1:3)/Ga%L + Ga%L*vel_L(1:3)*vdotB%L - b4%R(1:3) = B%R(1:3)/Ga%R + Ga%R*vel_R(1:3)*vdotB%R - B2%L = B%L(1)**2._wp + B%L(2)**2._wp + B%L(3)**2._wp - B2%R = B%R(1)**2._wp + B%R(2)**2._wp + B%R(3)**2._wp - - pres_mag%L = 0.5_wp*(B2%L/Ga%L**2._wp + vdotB%L**2._wp) - pres_mag%R = 0.5_wp*(B2%R/Ga%R**2._wp + vdotB%R**2._wp) - - ! Hard-coded EOS - H_L = 1._wp + (gamma_L + 1)*pres_L/rho_L - H_R = 1._wp + (gamma_R + 1)*pres_R/rho_R - - cm%L(1:3) = (rho_L*H_L*Ga%L**2 + B2%L)*vel_L(1:3) - vdotB%L*B%L(1:3) - cm%R(1:3) = (rho_R*H_R*Ga%R**2 + B2%R)*vel_R(1:3) - vdotB%R*B%R(1:3) - - E_L = rho_L*H_L*Ga%L**2 - pres_L + 0.5_wp*(B2%L + vel_L_rms*B2%L - vdotB%L**2._wp) - rho_L*Ga%L - E_R = rho_R*H_R*Ga%R**2 - pres_R + 0.5_wp*(B2%R + vel_R_rms*B2%R - vdotB%R**2._wp) - rho_R*Ga%R - #:endif - elseif (mhd .and. .not. relativity) then - pres_mag%L = 0.5_wp*(B%L(1)**2._wp + B%L(2)**2._wp + B%L(3)**2._wp) - pres_mag%R = 0.5_wp*(B%R(1)**2._wp + B%R(2)**2._wp + B%R(3)**2._wp) - E_L = gamma_L*pres_L + pi_inf_L + 0.5_wp*rho_L*vel_L_rms + qv_L + pres_mag%L - E_R = gamma_R*pres_R + pi_inf_R + 0.5_wp*rho_R*vel_R_rms + qv_R + pres_mag%R ! includes magnetic energy - H_L = (E_L + pres_L - pres_mag%L)/rho_L - H_R = (E_R + pres_R - pres_mag%R)/rho_R ! stagnation enthalpy here excludes magnetic energy (only used to find speed of sound) - else - E_L = gamma_L*pres_L + pi_inf_L + 5.e-1*rho_L*vel_L_rms + qv_L - E_R = gamma_R*pres_R + pi_inf_R + 5.e-1*rho_R*vel_R_rms + qv_R - H_L = (E_L + pres_L)/rho_L - H_R = (E_R + pres_R)/rho_R - end if - - ! elastic energy update - if (hypoelasticity) then - G_L = 0._wp; G_R = 0._wp - - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_fluids - G_L = G_L + alpha_L(i)*Gs_rs(i) - G_R = G_R + alpha_R(i)*Gs_rs(i) - end do - - if (cont_damage) then - G_L = G_L*max((1._wp - qL_prim_rs${XYZ}$_vf(j, k, l, damage_idx)), 0._wp) - G_R = G_R*max((1._wp - qR_prim_rs${XYZ}$_vf(j, k, l, damage_idx)), 0._wp) - end if - - do i = 1, strxe - strxb + 1 - tau_e_L(i) = qL_prim_rs${XYZ}$_vf(j, k, l, strxb - 1 + i) - tau_e_R(i) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, strxb - 1 + i) - ! Elastic contribution to energy if G large enough - !TODO take out if statement if stable without - if ((G_L > 1000) .and. (G_R > 1000)) then - E_L = E_L + (tau_e_L(i)*tau_e_L(i))/(4._wp*G_L) - E_R = E_R + (tau_e_R(i)*tau_e_R(i))/(4._wp*G_R) - ! Double for shear stresses - if (any(strxb - 1 + i == shear_indices)) then - E_L = E_L + (tau_e_L(i)*tau_e_L(i))/(4._wp*G_L) - E_R = E_R + (tau_e_R(i)*tau_e_R(i))/(4._wp*G_R) - end if - end if - end do - end if - - call s_compute_speed_of_sound(pres_L, rho_L, gamma_L, pi_inf_L, H_L, alpha_L, & - vel_L_rms, 0._wp, c_L, qv_L) - - call s_compute_speed_of_sound(pres_R, rho_R, gamma_R, pi_inf_R, H_R, alpha_R, & - vel_R_rms, 0._wp, c_R, qv_R) - - if (mhd) then - call s_compute_fast_magnetosonic_speed(rho_L, c_L, B%L, norm_dir, c_fast%L, H_L) - call s_compute_fast_magnetosonic_speed(rho_R, c_R, B%R, norm_dir, c_fast%R, H_R) - end if - - s_L = 0._wp; s_R = 0._wp - - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_dims - s_L = s_L + vel_L(i)**2._wp - s_R = s_R + vel_R(i)**2._wp - end do - - s_L = sqrt(s_L) - s_R = sqrt(s_R) - - s_P = max(s_L, s_R) + max(c_L, c_R) - s_M = -s_P - - s_L = s_M - s_R = s_P - - ! Low Mach correction - if (low_Mach == 1) then - @:compute_low_Mach_correction() - else - pcorr = 0._wp - end if - - ! Mass - if (.not. relativity) then - $:GPU_LOOP(parallelism='[seq]') - do i = 1, contxe - flux_rs${XYZ}$_vf(j, k, l, i) = & - (s_M*alpha_rho_R(i)*vel_R(norm_dir) & - - s_P*alpha_rho_L(i)*vel_L(norm_dir) & - + s_M*s_P*(alpha_rho_L(i) & - - alpha_rho_R(i))) & - /(s_M - s_P) - end do - elseif (relativity) then - $:GPU_LOOP(parallelism='[seq]') - do i = 1, contxe - flux_rs${XYZ}$_vf(j, k, l, i) = & - (s_M*Ga%R*alpha_rho_R(i)*vel_R(norm_dir) & - - s_P*Ga%L*alpha_rho_L(i)*vel_L(norm_dir) & - + s_M*s_P*(Ga%L*alpha_rho_L(i) & - - Ga%R*alpha_rho_R(i))) & - /(s_M - s_P) - end do - end if - - ! Momentum - if (mhd .and. (.not. relativity)) then - $:GPU_LOOP(parallelism='[seq]') - do i = 1, 3 - ! Flux of rho*v_i in the ${XYZ}$ direction - ! = rho * v_i * v_${XYZ}$ - B_i * B_${XYZ}$ + delta_(${XYZ}$,i) * p_tot - flux_rs${XYZ}$_vf(j, k, l, contxe + i) = & - (s_M*(rho_R*vel_R(i)*vel_R(norm_dir) & - - B%R(i)*B%R(norm_dir) & - + dir_flg(i)*(pres_R + pres_mag%R)) & - - s_P*(rho_L*vel_L(i)*vel_L(norm_dir) & - - B%L(i)*B%L(norm_dir) & - + dir_flg(i)*(pres_L + pres_mag%L)) & - + s_M*s_P*(rho_L*vel_L(i) - rho_R*vel_R(i))) & - /(s_M - s_P) - end do - elseif (mhd .and. relativity) then - $:GPU_LOOP(parallelism='[seq]') - do i = 1, 3 - ! Flux of m_i in the ${XYZ}$ direction - ! = m_i * v_${XYZ}$ - b_i/Gamma * B_${XYZ}$ + delta_(${XYZ}$,i) * p_tot - flux_rs${XYZ}$_vf(j, k, l, contxe + i) = & - (s_M*(cm%R(i)*vel_R(norm_dir) & - - b4%R(i)/Ga%R*B%R(norm_dir) & - + dir_flg(i)*(pres_R + pres_mag%R)) & - - s_P*(cm%L(i)*vel_L(norm_dir) & - - b4%L(i)/Ga%L*B%L(norm_dir) & - + dir_flg(i)*(pres_L + pres_mag%L)) & - + s_M*s_P*(cm%L(i) - cm%R(i))) & - /(s_M - s_P) - end do - elseif (bubbles_euler) then - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_vels - flux_rs${XYZ}$_vf(j, k, l, contxe + dir_idx(i)) = & - (s_M*(rho_R*vel_R(dir_idx(1)) & - *vel_R(dir_idx(i)) & - + dir_flg(dir_idx(i))*(pres_R - ptilde_R)) & - - s_P*(rho_L*vel_L(dir_idx(1)) & - *vel_L(dir_idx(i)) & - + dir_flg(dir_idx(i))*(pres_L - ptilde_L)) & - + s_M*s_P*(rho_L*vel_L(dir_idx(i)) & - - rho_R*vel_R(dir_idx(i)))) & - /(s_M - s_P) & - + (s_M/s_L)*(s_P/s_R)*pcorr*(vel_R(dir_idx(i)) - vel_L(dir_idx(i))) - end do - else if (hypoelasticity) then - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_vels - flux_rs${XYZ}$_vf(j, k, l, contxe + dir_idx(i)) = & - (s_M*(rho_R*vel_R(dir_idx(1)) & - *vel_R(dir_idx(i)) & - + dir_flg(dir_idx(i))*pres_R & - - tau_e_R(dir_idx_tau(i))) & - - s_P*(rho_L*vel_L(dir_idx(1)) & - *vel_L(dir_idx(i)) & - + dir_flg(dir_idx(i))*pres_L & - - tau_e_L(dir_idx_tau(i))) & - + s_M*s_P*(rho_L*vel_L(dir_idx(i)) & - - rho_R*vel_R(dir_idx(i)))) & - /(s_M - s_P) - end do - else - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_vels - flux_rs${XYZ}$_vf(j, k, l, contxe + dir_idx(i)) = & - (s_M*(rho_R*vel_R(dir_idx(1)) & - *vel_R(dir_idx(i)) & - + dir_flg(dir_idx(i))*pres_R) & - - s_P*(rho_L*vel_L(dir_idx(1)) & - *vel_L(dir_idx(i)) & - + dir_flg(dir_idx(i))*pres_L) & - + s_M*s_P*(rho_L*vel_L(dir_idx(i)) & - - rho_R*vel_R(dir_idx(i)))) & - /(s_M - s_P) & - + (s_M/s_L)*(s_P/s_R)*pcorr*(vel_R(dir_idx(i)) - vel_L(dir_idx(i))) - end do - end if - - ! Energy - if (mhd .and. (.not. relativity)) then - ! energy flux = (E + p + p_mag) * v_${XYZ}$ - B_${XYZ}$ * (v_x*B_x + v_y*B_y + v_z*B_z) - #:if not MFC_CASE_OPTIMIZATION or num_dims > 1 - flux_rs${XYZ}$_vf(j, k, l, E_idx) = & - (s_M*(vel_R(norm_dir)*(E_R + pres_R + pres_mag%R) - B%R(norm_dir)*(vel_R(1)*B%R(1) + vel_R(2)*B%R(2) + vel_R(3)*B%R(3))) & - - s_P*(vel_L(norm_dir)*(E_L + pres_L + pres_mag%L) - B%L(norm_dir)*(vel_L(1)*B%L(1) + vel_L(2)*B%L(2) + vel_L(3)*B%L(3))) & - + s_M*s_P*(E_L - E_R)) & - /(s_M - s_P) - #:endif - elseif (mhd .and. relativity) then - ! energy flux = m_${XYZ}$ - mass flux - ! Hard-coded for single-component for now - flux_rs${XYZ}$_vf(j, k, l, E_idx) = & - (s_M*(cm%R(norm_dir) - Ga%R*alpha_rho_R(1)*vel_R(norm_dir)) & - - s_P*(cm%L(norm_dir) - Ga%L*alpha_rho_L(1)*vel_L(norm_dir)) & - + s_M*s_P*(E_L - E_R)) & - /(s_M - s_P) - else if (bubbles_euler) then - flux_rs${XYZ}$_vf(j, k, l, E_idx) = & - (s_M*vel_R(dir_idx(1))*(E_R + pres_R - ptilde_R) & - - s_P*vel_L(dir_idx(1))*(E_L + pres_L - ptilde_L) & - + s_M*s_P*(E_L - E_R)) & - /(s_M - s_P) & - + (s_M/s_L)*(s_P/s_R)*pcorr*(vel_R_rms - vel_L_rms)/2._wp - else if (hypoelasticity) then - flux_tau_L = 0._wp; flux_tau_R = 0._wp - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_dims - flux_tau_L = flux_tau_L + tau_e_L(dir_idx_tau(i))*vel_L(dir_idx(i)) - flux_tau_R = flux_tau_R + tau_e_R(dir_idx_tau(i))*vel_R(dir_idx(i)) - end do - flux_rs${XYZ}$_vf(j, k, l, E_idx) = & - (s_M*(vel_R(dir_idx(1))*(E_R + pres_R) - flux_tau_R) & - - s_P*(vel_L(dir_idx(1))*(E_L + pres_L) - flux_tau_L) & - + s_M*s_P*(E_L - E_R))/(s_M - s_P) - else - flux_rs${XYZ}$_vf(j, k, l, E_idx) = & - (s_M*vel_R(dir_idx(1))*(E_R + pres_R) & - - s_P*vel_L(dir_idx(1))*(E_L + pres_L) & - + s_M*s_P*(E_L - E_R)) & - /(s_M - s_P) & - + (s_M/s_L)*(s_P/s_R)*pcorr*(vel_R_rms - vel_L_rms)/2._wp - end if - - ! Elastic Stresses - if (hypoelasticity) then - do i = 1, strxe - strxb + 1 !TODO: this indexing may be slow - flux_rs${XYZ}$_vf(j, k, l, strxb - 1 + i) = & - (s_M*(rho_R*vel_R(dir_idx(1)) & - *tau_e_R(i)) & - - s_P*(rho_L*vel_L(dir_idx(1)) & - *tau_e_L(i)) & - + s_M*s_P*(rho_L*tau_e_L(i) & - - rho_R*tau_e_R(i))) & - /(s_M - s_P) - end do - end if - - ! Advection - $:GPU_LOOP(parallelism='[seq]') - do i = advxb, advxe - flux_rs${XYZ}$_vf(j, k, l, i) = & - (qL_prim_rs${XYZ}$_vf(j, k, l, i) & - - qR_prim_rs${XYZ}$_vf(j + 1, k, l, i)) & - *s_M*s_P/(s_M - s_P) - flux_src_rs${XYZ}$_vf(j, k, l, i) = & - (s_M*qR_prim_rs${XYZ}$_vf(j + 1, k, l, i) & - - s_P*qL_prim_rs${XYZ}$_vf(j, k, l, i)) & - /(s_M - s_P) - end do - - if (bubbles_euler) then - ! From HLLC: Kills mass transport @ bubble gas density - if (num_fluids > 1) then - flux_rs${XYZ}$_vf(j, k, l, contxe) = 0._wp - end if - end if - - if (chemistry) then - $:GPU_LOOP(parallelism='[seq]') - do i = chemxb, chemxe - Y_L = qL_prim_rs${XYZ}$_vf(j, k, l, i) - Y_R = qR_prim_rs${XYZ}$_vf(j + 1, k, l, i) - - flux_rs${XYZ}$_vf(j, k, l, i) = (s_M*Y_R*rho_R*vel_R(dir_idx(1)) & - - s_P*Y_L*rho_L*vel_L(dir_idx(1)) & - + s_M*s_P*(Y_L*rho_L - Y_R*rho_R)) & - /(s_M - s_P) - flux_src_rs${XYZ}$_vf(j, k, l, i) = 0._wp - end do - end if - - if (mhd) then - if (n == 0) then ! 1D: d/dx flux only & Bx = Bx0 = const. - ! B_y flux = v_x * B_y - v_y * Bx0 - ! B_z flux = v_x * B_z - v_z * Bx0 - $:GPU_LOOP(parallelism='[seq]') - do i = 0, 1 - flux_rsx_vf(j, k, l, B_idx%beg + i) = (s_M*(vel_R(1)*B%R(2 + i) - vel_R(2 + i)*Bx0) & - - s_P*(vel_L(1)*B%L(2 + i) - vel_L(2 + i)*Bx0) & - + s_M*s_P*(B%L(2 + i) - B%R(2 + i)))/(s_M - s_P) - end do - else ! 2D/3D: Bx, By, Bz /= const. but zero flux component in the same direction - ! B_x d/d${XYZ}$ flux = (1 - delta(x,${XYZ}$)) * (v_${XYZ}$ * B_x - v_x * B_${XYZ}$) - ! B_y d/d${XYZ}$ flux = (1 - delta(y,${XYZ}$)) * (v_${XYZ}$ * B_y - v_y * B_${XYZ}$) - ! B_z d/d${XYZ}$ flux = (1 - delta(z,${XYZ}$)) * (v_${XYZ}$ * B_z - v_z * B_${XYZ}$) - $:GPU_LOOP(parallelism='[seq]') - do i = 0, 2 - flux_rs${XYZ}$_vf(j, k, l, B_idx%beg + i) = (1 - dir_flg(i + 1))*( & - s_M*(vel_R(dir_idx(1))*B%R(i + 1) - vel_R(i + 1)*B%R(norm_dir)) - & - s_P*(vel_L(dir_idx(1))*B%L(i + 1) - vel_L(i + 1)*B%L(norm_dir)) + & - s_M*s_P*(B%L(i + 1) - B%R(i + 1)))/(s_M - s_P) - end do - end if - flux_src_rs${XYZ}$_vf(j, k, l, advxb) = 0._wp - end if - - #:if (NORM_DIR == 2) - if (cyl_coord) then - !Substituting the advective flux into the inviscid geometrical source flux - $:GPU_LOOP(parallelism='[seq]') - do i = 1, E_idx - flux_gsrc_rs${XYZ}$_vf(j, k, l, i) = flux_rs${XYZ}$_vf(j, k, l, i) - end do - ! Recalculating the radial momentum geometric source flux - flux_gsrc_rs${XYZ}$_vf(j, k, l, contxe + 2) = & - flux_rs${XYZ}$_vf(j, k, l, contxe + 2) & - - (s_M*pres_R - s_P*pres_L)/(s_M - s_P) - ! Geometrical source of the void fraction(s) is zero - $:GPU_LOOP(parallelism='[seq]') - do i = advxb, advxe - flux_gsrc_rs${XYZ}$_vf(j, k, l, i) = flux_rs${XYZ}$_vf(j, k, l, i) - end do - end if - - if (cyl_coord .and. hypoelasticity) then - ! += tau_sigmasigma using HLL - flux_gsrc_rs${XYZ}$_vf(j, k, l, contxe + 2) = & - flux_gsrc_rs${XYZ}$_vf(j, k, l, contxe + 2) + & - (s_M*tau_e_R(4) - s_P*tau_e_L(4)) & - /(s_M - s_P) - - $:GPU_LOOP(parallelism='[seq]') - do i = strxb, strxe - flux_gsrc_rs${XYZ}$_vf(j, k, l, i) = flux_rs${XYZ}$_vf(j, k, l, i) - end do - end if - #:endif - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - end if - - #:endfor - - if (viscous .or. dummy) then - $:GPU_PARALLEL_LOOP(collapse=3, private='[i,j,k,l, idx_right_phys, vel_grad_L, vel_grad_R, alpha_L, alpha_R, vel_L, vel_R, Re_L, Re_R]', copyin='[norm_dir]') - do l = isz%beg, isz%end - do k = isy%beg, isy%end - do j = isx%beg, isx%end - idx_right_phys(1) = j - idx_right_phys(2) = k - idx_right_phys(3) = l - idx_right_phys(norm_dir) = idx_right_phys(norm_dir) + 1 - - if (norm_dir == 1) then - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_fluids - alpha_L(i) = qL_prim_rsx_vf(j, k, l, E_idx + i) - alpha_R(i) = qR_prim_rsx_vf(j + 1, k, l, E_idx + i) - end do - - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_dims - vel_L(i) = qL_prim_rsx_vf(j, k, l, momxb + i - 1) - vel_R(i) = qR_prim_rsx_vf(j + 1, k, l, momxb + i - 1) - end do - else if (norm_dir == 2) then - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_fluids - alpha_L(i) = qL_prim_rsy_vf(k, j, l, E_idx + i) - alpha_R(i) = qR_prim_rsy_vf(k + 1, j, l, E_idx + i) - end do - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_dims - vel_L(i) = qL_prim_rsy_vf(k, j, l, momxb + i - 1) - vel_R(i) = qR_prim_rsy_vf(k + 1, j, l, momxb + i - 1) - end do - else - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_fluids - alpha_L(i) = qL_prim_rsz_vf(l, k, j, E_idx + i) - alpha_R(i) = qR_prim_rsz_vf(l + 1, k, j, E_idx + i) - end do - - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_dims - vel_L(i) = qL_prim_rsz_vf(l, k, j, momxb + i - 1) - vel_R(i) = qR_prim_rsz_vf(l + 1, k, j, momxb + i - 1) - end do - end if - - $:GPU_LOOP(parallelism='[seq]') - do i = 1, 2 - Re_L(i) = dflt_real - Re_R(i) = dflt_real - - if (Re_size(i) > 0) Re_L(i) = 0._wp - if (Re_size(i) > 0) Re_R(i) = 0._wp - - $:GPU_LOOP(parallelism='[seq]') - do q = 1, Re_size(i) - Re_L(i) = alpha_L(Re_idx(i, q))/Res_gs(i, q) & - + Re_L(i) - Re_R(i) = alpha_R(Re_idx(i, q))/Res_gs(i, q) & - + Re_R(i) - end do - - Re_L(i) = 1._wp/max(Re_L(i), sgm_eps) - Re_R(i) = 1._wp/max(Re_R(i), sgm_eps) - end do - - if (shear_stress) then - - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_dims - vel_grad_L(i, 1) = (dqL_prim_dx_vf(momxb + i - 1)%sf(j, k, l)/Re_L(1)) - vel_grad_R(i, 1) = (dqR_prim_dx_vf(momxb + i - 1)%sf(idx_right_phys(1), idx_right_phys(2), idx_right_phys(3))/Re_R(1)) - #:if not MFC_CASE_OPTIMIZATION or num_dims > 1 - if (num_dims > 1) then - vel_grad_L(i, 2) = (dqL_prim_dy_vf(momxb + i - 1)%sf(j, k, l)/Re_L(1)) - vel_grad_R(i, 2) = (dqR_prim_dy_vf(momxb + i - 1)%sf(idx_right_phys(1), idx_right_phys(2), idx_right_phys(3))/Re_R(1)) - end if - #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 - if (num_dims > 2) then - vel_grad_L(i, 3) = (dqL_prim_dz_vf(momxb + i - 1)%sf(j, k, l)/Re_L(1)) - vel_grad_R(i, 3) = (dqR_prim_dz_vf(momxb + i - 1)%sf(idx_right_phys(1), idx_right_phys(2), idx_right_phys(3))/Re_R(1)) - end if - #:endif - #:endif - end do - - if (norm_dir == 1) then - flux_src_vf(momxb)%sf(j, k, l) = flux_src_vf(momxb)%sf(j, k, l) - (4._wp/3._wp)*0.5_wp*(vel_grad_L(1, 1) + vel_grad_R(1, 1)) - flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - (4._wp/3._wp)*0.5_wp*(vel_grad_L(1, 1)*vel_L(1) + vel_grad_R(1, 1)*vel_R(1)) - #:if not MFC_CASE_OPTIMIZATION or num_dims > 1 - if (num_dims > 1) then - flux_src_vf(momxb)%sf(j, k, l) = flux_src_vf(momxb)%sf(j, k, l) - (-2._wp/3._wp)*0.5_wp*(vel_grad_L(2, 2) + vel_grad_R(2, 2)) - flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - (-2._wp/3._wp)*0.5_wp*(vel_grad_L(2, 2)*vel_L(1) + vel_grad_R(2, 2)*vel_R(1)) - - flux_src_vf(momxb + 1)%sf(j, k, l) = flux_src_vf(momxb + 1)%sf(j, k, l) - 0.5_wp*(vel_grad_L(1, 2) + vel_grad_R(1, 2)) - 0.5_wp*(vel_grad_L(2, 1) + vel_grad_R(2, 1)) - flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - 0.5_wp*(vel_grad_L(1, 2)*vel_L(2) + vel_grad_R(1, 2)*vel_R(2)) - 0.5_wp*(vel_grad_L(2, 1)*vel_L(2) + vel_grad_R(2, 1)*vel_R(2)) - #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 - if (num_dims > 2) then - flux_src_vf(momxb)%sf(j, k, l) = flux_src_vf(momxb)%sf(j, k, l) - (-2._wp/3._wp)*0.5_wp*(vel_grad_L(3, 3) + vel_grad_R(3, 3)) - flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - (-2._wp/3._wp)*0.5_wp*(vel_grad_L(3, 3)*vel_L(1) + vel_grad_R(3, 3)*vel_R(1)) - - flux_src_vf(momxb + 2)%sf(j, k, l) = flux_src_vf(momxb + 2)%sf(j, k, l) - 0.5_wp*(vel_grad_L(1, 3) + vel_grad_R(1, 3)) - 0.5_wp*(vel_grad_L(3, 1) + vel_grad_R(3, 1)) - flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - 0.5_wp*(vel_grad_L(1, 3)*vel_L(3) + vel_grad_R(1, 3)*vel_R(3)) - 0.5_wp*(vel_grad_L(3, 1)*vel_L(3) + vel_grad_R(3, 1)*vel_R(3)) - end if - #:endif - end if - #:endif - - else if (norm_dir == 2) then - #:if not MFC_CASE_OPTIMIZATION or num_dims > 1 - flux_src_vf(momxb + 1)%sf(j, k, l) = flux_src_vf(momxb + 1)%sf(j, k, l) - (-2._wp/3._wp)*0.5_wp*(vel_grad_L(1, 1) + vel_grad_R(1, 1)) - flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - (-2._wp/3._wp)*0.5_wp*(vel_grad_L(1, 1)*vel_L(2) + vel_grad_R(1, 1)*vel_R(2)) - - flux_src_vf(momxb + 1)%sf(j, k, l) = flux_src_vf(momxb + 1)%sf(j, k, l) - (4._wp/3._wp)*0.5_wp*(vel_grad_L(2, 2) + vel_grad_R(2, 2)) - flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - (4._wp/3._wp)*0.5_wp*(vel_grad_L(2, 2)*vel_L(2) + vel_grad_R(2, 2)*vel_R(2)) - - flux_src_vf(momxb)%sf(j, k, l) = flux_src_vf(momxb)%sf(j, k, l) - 0.5_wp*(vel_grad_L(1, 2) + vel_grad_R(1, 2)) - 0.5_wp*(vel_grad_L(2, 1) + vel_grad_R(2, 1)) - flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - 0.5_wp*(vel_grad_L(1, 2)*vel_L(1) + vel_grad_R(1, 2)*vel_R(1)) - 0.5_wp*(vel_grad_L(2, 1)*vel_L(1) + vel_grad_R(2, 1)*vel_R(1)) - #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 - if (num_dims > 2) then - flux_src_vf(momxb + 1)%sf(j, k, l) = flux_src_vf(momxb + 1)%sf(j, k, l) - (-2._wp/3._wp)*0.5_wp*(vel_grad_L(3, 3) + vel_grad_R(3, 3)) - flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - (-2._wp/3._wp)*0.5_wp*(vel_grad_L(3, 3)*vel_L(2) + vel_grad_R(3, 3)*vel_R(2)) - - flux_src_vf(momxb + 2)%sf(j, k, l) = flux_src_vf(momxb + 2)%sf(j, k, l) - 0.5_wp*(vel_grad_L(2, 3) + vel_grad_R(2, 3)) - 0.5_wp*(vel_grad_L(3, 2) + vel_grad_R(3, 2)) - flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - 0.5_wp*(vel_grad_L(2, 3)*vel_L(3) + vel_grad_R(2, 3)*vel_R(3)) - 0.5_wp*(vel_grad_L(3, 2)*vel_L(3) + vel_grad_R(3, 2)*vel_R(3)) - end if - #:endif - #:endif - else - #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 - flux_src_vf(momxb + 2)%sf(j, k, l) = flux_src_vf(momxb + 2)%sf(j, k, l) - (-2._wp/3._wp)*0.5_wp*(vel_grad_L(1, 1) + vel_grad_R(1, 1)) - flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - (-2._wp/3._wp)*0.5_wp*(vel_grad_L(1, 1)*vel_L(3) + vel_grad_R(1, 1)*vel_R(3)) - - flux_src_vf(momxb + 2)%sf(j, k, l) = flux_src_vf(momxb + 2)%sf(j, k, l) - (-2._wp/3._wp)*0.5_wp*(vel_grad_L(2, 2) + vel_grad_R(2, 2)) - flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - (-2._wp/3._wp)*0.5_wp*(vel_grad_L(2, 2)*vel_L(3) + vel_grad_R(2, 2)*vel_R(3)) - - flux_src_vf(momxb)%sf(j, k, l) = flux_src_vf(momxb)%sf(j, k, l) - 0.5_wp*(vel_grad_L(1, 3) + vel_grad_R(1, 3)) - 0.5_wp*(vel_grad_L(3, 1) + vel_grad_R(3, 1)) - flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - 0.5_wp*(vel_grad_L(1, 3)*vel_L(1) + vel_grad_R(1, 3)*vel_R(1)) - 0.5_wp*(vel_grad_L(3, 1)*vel_L(1) + vel_grad_R(3, 1)*vel_R(1)) - - flux_src_vf(momxb + 2)%sf(j, k, l) = flux_src_vf(momxb + 2)%sf(j, k, l) - (4._wp/3._wp)*0.5_wp*(vel_grad_L(3, 3) + vel_grad_R(3, 3)) - flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - (4._wp/3._wp)*0.5_wp*(vel_grad_L(3, 3)*vel_L(3) + vel_grad_R(3, 3)*vel_R(3)) - - flux_src_vf(momxb + 1)%sf(j, k, l) = flux_src_vf(momxb + 1)%sf(j, k, l) - 0.5_wp*(vel_grad_L(2, 3) + vel_grad_R(2, 3)) - 0.5_wp*(vel_grad_L(3, 2) + vel_grad_R(3, 2)) - flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - 0.5_wp*(vel_grad_L(2, 3)*vel_L(2) + vel_grad_R(2, 3)*vel_R(2)) - 0.5_wp*(vel_grad_L(3, 2)*vel_L(2) + vel_grad_R(3, 2)*vel_R(2)) - #:endif - end if - end if - - if (bulk_stress) then - - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_dims - vel_grad_L(i, 1) = (dqL_prim_dx_vf(momxb + i - 1)%sf(j, k, l)/Re_L(2)) - vel_grad_R(i, 1) = (dqR_prim_dx_vf(momxb + i - 1)%sf(idx_right_phys(1), idx_right_phys(2), idx_right_phys(3))/Re_R(2)) - #:if not MFC_CASE_OPTIMIZATION or num_dims > 1 - if (num_dims > 1) then - vel_grad_L(i, 2) = (dqL_prim_dy_vf(momxb + i - 1)%sf(j, k, l)/Re_L(2)) - vel_grad_R(i, 2) = (dqR_prim_dy_vf(momxb + i - 1)%sf(idx_right_phys(1), idx_right_phys(2), idx_right_phys(3))/Re_R(2)) - end if - #:endif - #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 - if (num_dims > 2) then - vel_grad_L(i, 3) = (dqL_prim_dz_vf(momxb + i - 1)%sf(j, k, l)/Re_L(2)) - vel_grad_R(i, 3) = (dqR_prim_dz_vf(momxb + i - 1)%sf(idx_right_phys(1), idx_right_phys(2), idx_right_phys(3))/Re_R(2)) - end if - #:endif - end do - - if (norm_dir == 1) then - flux_src_vf(momxb)%sf(j, k, l) = flux_src_vf(momxb)%sf(j, k, l) - 0.5_wp*(vel_grad_L(1, 1) + vel_grad_R(1, 1)) - flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - 0.5_wp*(vel_grad_L(1, 1)*vel_L(1) + vel_grad_R(1, 1)*vel_R(1)) - #:if not MFC_CASE_OPTIMIZATION or num_dims > 1 - if (num_dims > 1) then - flux_src_vf(momxb)%sf(j, k, l) = flux_src_vf(momxb)%sf(j, k, l) - 0.5_wp*(vel_grad_L(2, 2) + vel_grad_R(2, 2)) - flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - 0.5_wp*(vel_grad_L(2, 2)*vel_L(1) + vel_grad_R(2, 2)*vel_R(1)) - - #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 - if (num_dims > 2) then - flux_src_vf(momxb)%sf(j, k, l) = flux_src_vf(momxb)%sf(j, k, l) - 0.5_wp*(vel_grad_L(3, 3) + vel_grad_R(3, 3)) - flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - 0.5_wp*(vel_grad_L(3, 3)*vel_L(1) + vel_grad_R(3, 3)*vel_R(1)) - end if - #:endif - end if - #:endif - - else if (norm_dir == 2) then - #:if not MFC_CASE_OPTIMIZATION or num_dims > 1 - flux_src_vf(momxb + 1)%sf(j, k, l) = flux_src_vf(momxb + 1)%sf(j, k, l) - 0.5_wp*(vel_grad_L(1, 1) + vel_grad_R(1, 1)) - flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - 0.5_wp*(vel_grad_L(1, 1)*vel_L(2) + vel_grad_R(1, 1)*vel_R(2)) - - flux_src_vf(momxb + 1)%sf(j, k, l) = flux_src_vf(momxb + 1)%sf(j, k, l) - 0.5_wp*(vel_grad_L(2, 2) + vel_grad_R(2, 2)) - flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - 0.5_wp*(vel_grad_L(2, 2)*vel_L(2) + vel_grad_R(2, 2)*vel_R(2)) - - #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 - if (num_dims > 2) then - flux_src_vf(momxb + 1)%sf(j, k, l) = flux_src_vf(momxb + 1)%sf(j, k, l) - 0.5_wp*(vel_grad_L(3, 3) + vel_grad_R(3, 3)) - flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - 0.5_wp*(vel_grad_L(3, 3)*vel_L(2) + vel_grad_R(3, 3)*vel_R(2)) - end if - #:endif - #:endif - else - #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 - flux_src_vf(momxb + 2)%sf(j, k, l) = flux_src_vf(momxb + 2)%sf(j, k, l) - 0.5_wp*(vel_grad_L(1, 1) + vel_grad_R(1, 1)) - flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - 0.5_wp*(vel_grad_L(1, 1)*vel_L(3) + vel_grad_R(1, 1)*vel_R(3)) - - flux_src_vf(momxb + 2)%sf(j, k, l) = flux_src_vf(momxb + 2)%sf(j, k, l) - 0.5_wp*(vel_grad_L(2, 2) + vel_grad_R(2, 2)) - flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - 0.5_wp*(vel_grad_L(2, 2)*vel_L(3) + vel_grad_R(2, 2)*vel_R(3)) - - flux_src_vf(momxb + 2)%sf(j, k, l) = flux_src_vf(momxb + 2)%sf(j, k, l) - 0.5_wp*(vel_grad_L(3, 3) + vel_grad_R(3, 3)) - flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - 0.5_wp*(vel_grad_L(3, 3)*vel_L(3) + vel_grad_R(3, 3)*vel_R(3)) - #:endif - end if - - end if - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - - end if - - call s_finalize_riemann_solver(flux_vf, flux_src_vf, & - flux_gsrc_vf, & - norm_dir) - - end subroutine s_lf_riemann_solver - - !> This procedure is the implementation of the Harten, Lax, - !! van Leer, and contact (HLLC) approximate Riemann solver, - !! see Toro (1999) and Johnsen (2007). The viscous and the - !! surface tension effects have been included by modifying - !! the exact Riemann solver of Perigaud and Saurel (2005). - !! @param qL_prim_rsx_vf Left WENO-reconstructed cell-boundary values (x-dir) - !! @param qL_prim_rsy_vf Left WENO-reconstructed cell-boundary values (y-dir) - !! @param qL_prim_rsz_vf Left WENO-reconstructed cell-boundary values (z-dir) - !! @param dqL_prim_dx_vf The left WENO-reconstructed cell-boundary values of the - !! first-order x-dir spatial derivatives - !! @param dqL_prim_dy_vf The left WENO-reconstructed cell-boundary values of the - !! first-order y-dir spatial derivatives - !! @param dqL_prim_dz_vf The left WENO-reconstructed cell-boundary values of the - !! first-order z-dir spatial derivatives - !! @param qL_prim_vf The left WENO-reconstructed cell-boundary values of the - !! cell-average primitive variables - !! @param qR_prim_rsx_vf Right WENO-reconstructed cell-boundary values (x-dir) - !! @param qR_prim_rsy_vf Right WENO-reconstructed cell-boundary values (y-dir) - !! @param qR_prim_rsz_vf Right WENO-reconstructed cell-boundary values (z-dir) - !! @param dqR_prim_dx_vf The right WENO-reconstructed cell-boundary values of the - !! first-order x-dir spatial derivatives - !! @param dqR_prim_dy_vf The right WENO-reconstructed cell-boundary values of the - !! first-order y-dir spatial derivatives - !! @param dqR_prim_dz_vf The right WENO-reconstructed cell-boundary values of the - !! first-order z-dir spatial derivatives - !! @param qR_prim_vf The right WENO-reconstructed cell-boundary values of the - !! cell-average primitive variables - !! @param q_prim_vf Cell-averaged primitive variables - !! @param flux_vf Intra-cell fluxes - !! @param flux_src_vf Intra-cell fluxes sources - !! @param flux_gsrc_vf Intra-cell geometric fluxes sources - !! @param norm_dir Dir. splitting direction - !! @param ix Index bounds in the x-dir - !! @param iy Index bounds in the y-dir - !! @param iz Index bounds in the z-dir - subroutine s_hllc_riemann_solver(qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, dqL_prim_dx_vf, & - dqL_prim_dy_vf, & - dqL_prim_dz_vf, & - qL_prim_vf, & - qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf, dqR_prim_dx_vf, & - dqR_prim_dy_vf, & - dqR_prim_dz_vf, & - qR_prim_vf, & - q_prim_vf, & - flux_vf, flux_src_vf, & - flux_gsrc_vf, & - norm_dir, ix, iy, iz) - - real(wp), dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:), intent(inout) :: qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf - type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf - type(scalar_field), allocatable, dimension(:), intent(inout) :: qL_prim_vf, qR_prim_vf - - type(scalar_field), & - allocatable, dimension(:), & - intent(inout) :: dqL_prim_dx_vf, dqR_prim_dx_vf, & - dqL_prim_dy_vf, dqR_prim_dy_vf, & - dqL_prim_dz_vf, dqR_prim_dz_vf - - ! Intercell fluxes - type(scalar_field), & - dimension(sys_size), & - intent(inout) :: flux_vf, flux_src_vf, flux_gsrc_vf - - integer, intent(in) :: norm_dir - type(int_bounds_info), intent(in) :: ix, iy, iz - - #:if not MFC_CASE_OPTIMIZATION and USING_AMD - real(wp), dimension(3) :: alpha_rho_L, alpha_rho_R - real(wp), dimension(3) :: alpha_L, alpha_R - real(wp), dimension(3) :: vel_L, vel_R - #:else - real(wp), dimension(num_fluids) :: alpha_rho_L, alpha_rho_R - real(wp), dimension(num_fluids) :: alpha_L, alpha_R - real(wp), dimension(num_dims) :: vel_L, vel_R - #:endif - - real(wp) :: rho_L, rho_R - real(wp) :: pres_L, pres_R - real(wp) :: E_L, E_R - real(wp) :: H_L, H_R - #:if not MFC_CASE_OPTIMIZATION and USING_AMD - real(wp), dimension(10) :: Ys_L, Ys_R, Xs_L, Xs_R, Gamma_iL, Gamma_iR, Cp_iL, Cp_iR - real(wp), dimension(10) :: Yi_avg, Phi_avg, h_iL, h_iR, h_avg_2 - #:else - real(wp), dimension(num_species) :: Ys_L, Ys_R, Xs_L, Xs_R, Gamma_iL, Gamma_iR, Cp_iL, Cp_iR - real(wp), dimension(num_species) :: Yi_avg, Phi_avg, h_iL, h_iR, h_avg_2 - #:endif - real(wp) :: Cp_avg, Cv_avg, T_avg, c_sum_Yi_Phi, eps - real(wp) :: T_L, T_R - real(wp) :: MW_L, MW_R - real(wp) :: R_gas_L, R_gas_R - real(wp) :: Cp_L, Cp_R - real(wp) :: Cv_L, Cv_R - real(wp) :: Gamm_L, Gamm_R - real(wp) :: Y_L, Y_R - real(wp) :: gamma_L, gamma_R - real(wp) :: pi_inf_L, pi_inf_R - real(wp) :: qv_L, qv_R - real(wp) :: c_L, c_R - real(wp), dimension(2) :: Re_L, Re_R - - real(wp) :: rho_avg - real(wp) :: H_avg - real(wp) :: gamma_avg - real(wp) :: qv_avg - real(wp) :: c_avg - - real(wp) :: s_L, s_R, s_M, s_P, s_S - real(wp) :: xi_L, xi_R !< Left and right wave speeds functions - real(wp) :: xi_M, xi_P - real(wp) :: xi_MP, xi_PP - #:if not MFC_CASE_OPTIMIZATION and USING_AMD - real(wp), dimension(3) :: R0_L, R0_R - real(wp), dimension(3) :: V0_L, V0_R - real(wp), dimension(3) :: P0_L, P0_R - real(wp), dimension(3) :: pbw_L, pbw_R - #:else - real(wp), dimension(nb) :: R0_L, R0_R - real(wp), dimension(nb) :: V0_L, V0_R - real(wp), dimension(nb) :: P0_L, P0_R - real(wp), dimension(nb) :: pbw_L, pbw_R - #:endif - - real(wp) :: alpha_L_sum, alpha_R_sum, nbub_L, nbub_R - real(wp) :: ptilde_L, ptilde_R - - real(wp) :: PbwR3Lbar, PbwR3Rbar - real(wp) :: R3Lbar, R3Rbar - real(wp) :: R3V2Lbar, R3V2Rbar - - real(wp), dimension(6) :: tau_e_L, tau_e_R - #:if not MFC_CASE_OPTIMIZATION and USING_AMD - real(wp), dimension(3) :: xi_field_L, xi_field_R - #:else - real(wp), dimension(num_dims) :: xi_field_L, xi_field_R - #:endif - real(wp) :: G_L, G_R - - real(wp) :: vel_L_rms, vel_R_rms, vel_avg_rms - real(wp) :: vel_L_tmp, vel_R_tmp - real(wp) :: rho_Star, E_Star, p_Star, p_K_Star, vel_K_star - real(wp) :: pres_SL, pres_SR, Ms_L, Ms_R - real(wp) :: flux_ene_e - real(wp) :: zcoef, pcorr !< low Mach number correction - - integer :: Re_max, i, j, k, l, q !< Generic loop iterators - - ! Populating the buffers of the left and right Riemann problem - ! states variables, based on the choice of boundary conditions - - call s_populate_riemann_states_variables_buffers( & - qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, dqL_prim_dx_vf, & - dqL_prim_dy_vf, & - dqL_prim_dz_vf, & - qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf, dqR_prim_dx_vf, & - dqR_prim_dy_vf, & - dqR_prim_dz_vf, & - norm_dir, ix, iy, iz) - - ! Reshaping inputted data based on dimensional splitting direction - - call s_initialize_riemann_solver( & - flux_src_vf, & - norm_dir) - - #:for NORM_DIR, XYZ in [(1, 'x'), (2, 'y'), (3, 'z')] - - if (norm_dir == ${NORM_DIR}$) then - - ! 6-EQUATION MODEL WITH HLLC - if (model_eqns == 3) then - !ME3 - $:GPU_PARALLEL_LOOP(collapse=3, private='[i,j,k,l, q, vel_L, vel_R, Re_L, Re_R, alpha_L, alpha_R, Ys_L, Ys_R, Xs_L, Xs_R, Gamma_iL, Gamma_iR, Cp_iL, Cp_iR, Yi_avg, Phi_avg, h_iL, h_iR, h_avg_2, tau_e_L, tau_e_R, flux_ene_e, xi_field_L, xi_field_R, pcorr, zcoef, rho_L, rho_R, pres_L, pres_R, E_L, E_R, H_L, H_R, Cp_avg, Cv_avg, T_avg, eps, c_sum_Yi_Phi, T_L, T_R, Y_L, Y_R, MW_L, MW_R, R_gas_L, R_gas_R, Cp_L, Cp_R, Cv_L, Cv_R, Gamm_L, Gamm_R, gamma_L, gamma_R, pi_inf_L, pi_inf_R, qv_L, qv_R, qv_avg, c_L, c_R, G_L, G_R, rho_avg, H_avg, c_avg, gamma_avg, ptilde_L, ptilde_R, vel_L_rms, vel_R_rms, vel_avg_rms, vel_L_tmp, vel_R_tmp, Ms_L, Ms_R, pres_SL, pres_SR, alpha_L_sum, alpha_R_sum, rho_Star, E_Star, p_Star, p_K_Star, vel_K_star, s_L, s_R, s_M, s_P, s_S, xi_M, xi_P, xi_L, xi_R, xi_MP, xi_PP]') - do l = is3%beg, is3%end - do k = is2%beg, is2%end - do j = is1%beg, is1%end - - vel_L_rms = 0._wp; vel_R_rms = 0._wp - rho_L = 0._wp; rho_R = 0._wp - gamma_L = 0._wp; gamma_R = 0._wp - pi_inf_L = 0._wp; pi_inf_R = 0._wp - qv_L = 0._wp; qv_R = 0._wp - alpha_L_sum = 0._wp; alpha_R_sum = 0._wp - - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_dims - vel_L(i) = qL_prim_rs${XYZ}$_vf(j, k, l, contxe + i) - vel_R(i) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, contxe + i) - vel_L_rms = vel_L_rms + vel_L(i)**2._wp - vel_R_rms = vel_R_rms + vel_R(i)**2._wp - end do - - pres_L = qL_prim_rs${XYZ}$_vf(j, k, l, E_idx) - pres_R = qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx) - - rho_L = 0._wp - gamma_L = 0._wp - pi_inf_L = 0._wp - qv_L = 0._wp - - rho_R = 0._wp - gamma_R = 0._wp - pi_inf_R = 0._wp - qv_R = 0._wp - - alpha_L_sum = 0._wp - alpha_R_sum = 0._wp - - if (mpp_lim) then - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_fluids - qL_prim_rs${XYZ}$_vf(j, k, l, i) = max(0._wp, qL_prim_rs${XYZ}$_vf(j, k, l, i)) - qL_prim_rs${XYZ}$_vf(j, k, l, E_idx + i) = min(max(0._wp, qL_prim_rs${XYZ}$_vf(j, k, l, E_idx + i)), 1._wp) - alpha_L_sum = alpha_L_sum + qL_prim_rs${XYZ}$_vf(j, k, l, E_idx + i) - end do - - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_fluids - qR_prim_rs${XYZ}$_vf(j + 1, k, l, i) = max(0._wp, qR_prim_rs${XYZ}$_vf(j + 1, k, l, i)) - qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx + i) = min(max(0._wp, qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx + i)), 1._wp) - alpha_R_sum = alpha_R_sum + qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx + i) - end do - - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_fluids - qL_prim_rs${XYZ}$_vf(j, k, l, E_idx + i) = qL_prim_rs${XYZ}$_vf(j, k, l, E_idx + i)/max(alpha_L_sum, sgm_eps) - qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx + i) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx + i)/max(alpha_R_sum, sgm_eps) - end do - end if - - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_fluids - rho_L = rho_L + qL_prim_rs${XYZ}$_vf(j, k, l, i) - gamma_L = gamma_L + qL_prim_rs${XYZ}$_vf(j, k, l, E_idx + i)*gammas(i) - pi_inf_L = pi_inf_L + qL_prim_rs${XYZ}$_vf(j, k, l, E_idx + i)*pi_infs(i) - qv_L = qv_L + qL_prim_rs${XYZ}$_vf(j, k, l, i)*qvs(i) - - rho_R = rho_R + qR_prim_rs${XYZ}$_vf(j + 1, k, l, i) - gamma_R = gamma_R + qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx + i)*gammas(i) - pi_inf_R = pi_inf_R + qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx + i)*pi_infs(i) - qv_R = qv_R + qR_prim_rs${XYZ}$_vf(j + 1, k, l, i)*qvs(i) - - alpha_L(i) = qL_prim_rs${XYZ}$_vf(j, k, l, advxb + i - 1) - alpha_R(i) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, advxb + i - 1) - end do - - if (viscous) then - $:GPU_LOOP(parallelism='[seq]') - do i = 1, 2 - Re_L(i) = dflt_real - Re_R(i) = dflt_real - if (Re_size(i) > 0) Re_L(i) = 0._wp - if (Re_size(i) > 0) Re_R(i) = 0._wp - $:GPU_LOOP(parallelism='[seq]') - do q = 1, Re_size(i) - Re_L(i) = qL_prim_rs${XYZ}$_vf(j, k, l, E_idx + Re_idx(i, q))/Res_gs(i, q) & - + Re_L(i) - Re_R(i) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx + Re_idx(i, q))/Res_gs(i, q) & - + Re_R(i) - end do - Re_L(i) = 1._wp/max(Re_L(i), sgm_eps) - Re_R(i) = 1._wp/max(Re_R(i), sgm_eps) - end do - end if - - E_L = gamma_L*pres_L + pi_inf_L + 5.e-1_wp*rho_L*vel_L_rms + qv_L - E_R = gamma_R*pres_R + pi_inf_R + 5.e-1_wp*rho_R*vel_R_rms + qv_R - - ! ENERGY ADJUSTMENTS FOR HYPOELASTIC ENERGY - if (hypoelasticity) then - $:GPU_LOOP(parallelism='[seq]') - do i = 1, strxe - strxb + 1 - tau_e_L(i) = qL_prim_rs${XYZ}$_vf(j, k, l, strxb - 1 + i) - tau_e_R(i) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, strxb - 1 + i) - end do - G_L = 0._wp; G_R = 0._wp - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_fluids - G_L = G_L + alpha_L(i)*Gs_rs(i) - G_R = G_R + alpha_R(i)*Gs_rs(i) - end do - $:GPU_LOOP(parallelism='[seq]') - do i = 1, strxe - strxb + 1 - ! Elastic contribution to energy if G large enough - if ((G_L > verysmall) .and. (G_R > verysmall)) then - E_L = E_L + (tau_e_L(i)*tau_e_L(i))/(4._wp*G_L) - E_R = E_R + (tau_e_R(i)*tau_e_R(i))/(4._wp*G_R) - ! Additional terms in 2D and 3D - if ((i == 2) .or. (i == 4) .or. (i == 5)) then - E_L = E_L + (tau_e_L(i)*tau_e_L(i))/(4._wp*G_L) - E_R = E_R + (tau_e_R(i)*tau_e_R(i))/(4._wp*G_R) - end if - end if - end do - end if - - ! ENERGY ADJUSTMENTS FOR HYPERELASTIC ENERGY - if (hyperelasticity) then - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_dims - xi_field_L(i) = qL_prim_rs${XYZ}$_vf(j, k, l, xibeg - 1 + i) - xi_field_R(i) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, xibeg - 1 + i) - end do - G_L = 0._wp; G_R = 0._wp; - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_fluids - ! Mixture left and right shear modulus - G_L = G_L + alpha_L(i)*Gs_rs(i) - G_R = G_R + alpha_R(i)*Gs_rs(i) - end do - ! Elastic contribution to energy if G large enough - if (G_L > verysmall .and. G_R > verysmall) then - E_L = E_L + G_L*qL_prim_rs${XYZ}$_vf(j, k, l, xiend + 1) - E_R = E_R + G_R*qR_prim_rs${XYZ}$_vf(j + 1, k, l, xiend + 1) - end if - $:GPU_LOOP(parallelism='[seq]') - do i = 1, b_size - 1 - tau_e_L(i) = qL_prim_rs${XYZ}$_vf(j, k, l, strxb - 1 + i) - tau_e_R(i) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, strxb - 1 + i) - end do - end if - - H_L = (E_L + pres_L)/rho_L - H_R = (E_R + pres_R)/rho_R - - @:compute_average_state() - - call s_compute_speed_of_sound(pres_L, rho_L, gamma_L, pi_inf_L, H_L, alpha_L, & - vel_L_rms, 0._wp, c_L, qv_L) - - call s_compute_speed_of_sound(pres_R, rho_R, gamma_R, pi_inf_R, H_R, alpha_R, & - vel_R_rms, 0._wp, c_R, qv_R) - - !> The computation of c_avg does not require all the variables, and therefore the non '_avg' - ! variables are placeholders to call the subroutine. - call s_compute_speed_of_sound(pres_R, rho_avg, gamma_avg, pi_inf_R, H_avg, alpha_R, & - vel_avg_rms, 0._wp, c_avg, qv_avg) - - if (viscous) then - $:GPU_LOOP(parallelism='[seq]') - do i = 1, 2 - Re_avg_rs${XYZ}$_vf(j, k, l, i) = 2._wp/(1._wp/Re_L(i) + 1._wp/Re_R(i)) - end do - end if - - ! Low Mach correction - if (low_Mach == 2) then - @:compute_low_Mach_correction() - end if - - ! COMPUTING THE DIRECT WAVE SPEEDS - if (wave_speeds == 1) then - if (elasticity) then - s_L = min(vel_L(dir_idx(1)) - sqrt(c_L*c_L + & - (((4._wp*G_L)/3._wp) + tau_e_L(dir_idx_tau(1)))/rho_L), vel_R(dir_idx(1)) - sqrt(c_R*c_R + & - (((4._wp*G_R)/3._wp) + tau_e_R(dir_idx_tau(1)))/rho_R)) - s_R = max(vel_R(dir_idx(1)) + sqrt(c_R*c_R + & - (((4._wp*G_R)/3._wp) + tau_e_R(dir_idx_tau(1)))/rho_R), vel_L(dir_idx(1)) + sqrt(c_L*c_L + & - (((4._wp*G_L)/3._wp) + tau_e_L(dir_idx_tau(1)))/rho_L)) - s_S = (pres_R - tau_e_R(dir_idx_tau(1)) - pres_L + & - tau_e_L(dir_idx_tau(1)) + rho_L*vel_L(dir_idx(1))*(s_L - vel_L(dir_idx(1))) - & - rho_R*vel_R(dir_idx(1))*(s_R - vel_R(dir_idx(1))))/(rho_L*(s_L - vel_L(dir_idx(1))) - & - rho_R*(s_R - vel_R(dir_idx(1)))) - else - s_L = min(vel_L(dir_idx(1)) - c_L, vel_R(dir_idx(1)) - c_R) - s_R = max(vel_R(dir_idx(1)) + c_R, vel_L(dir_idx(1)) + c_L) - s_S = (pres_R - pres_L + rho_L*vel_L(dir_idx(1))* & - (s_L - vel_L(dir_idx(1))) - rho_R*vel_R(dir_idx(1))*(s_R - vel_R(dir_idx(1)))) & - /(rho_L*(s_L - vel_L(dir_idx(1))) - rho_R*(s_R - vel_R(dir_idx(1)))) - - end if - elseif (wave_speeds == 2) then - pres_SL = 5.e-1_wp*(pres_L + pres_R + rho_avg*c_avg* & - (vel_L(dir_idx(1)) - & - vel_R(dir_idx(1)))) - - pres_SR = pres_SL - - Ms_L = max(1._wp, sqrt(1._wp + ((5.e-1_wp + gamma_L)/(1._wp + gamma_L))* & - (pres_SL/pres_L - 1._wp)*pres_L/ & - ((pres_L + pi_inf_L/(1._wp + gamma_L))))) - Ms_R = max(1._wp, sqrt(1._wp + ((5.e-1_wp + gamma_R)/(1._wp + gamma_R))* & - (pres_SR/pres_R - 1._wp)*pres_R/ & - ((pres_R + pi_inf_R/(1._wp + gamma_R))))) - - s_L = vel_L(dir_idx(1)) - c_L*Ms_L - s_R = vel_R(dir_idx(1)) + c_R*Ms_R - - s_S = 5.e-1_wp*((vel_L(dir_idx(1)) + vel_R(dir_idx(1))) + & - (pres_L - pres_R)/ & - (rho_avg*c_avg)) - end if - - ! follows Einfeldt et al. - ! s_M/P = min/max(0.,s_L/R) - s_M = min(0._wp, s_L); s_P = max(0._wp, s_R) - - ! goes with q_star_L/R = xi_L/R * (variable) - ! xi_L/R = ( ( s_L/R - u_L/R )/(s_L/R - s_star) ) - xi_L = (s_L - vel_L(dir_idx(1)))/(s_L - s_S) - xi_R = (s_R - vel_R(dir_idx(1)))/(s_R - s_S) - - ! goes with numerical star velocity in x/y/z directions - ! xi_P/M = 0.5 +/m sgn(0.5,s_star) - xi_M = (5.e-1_wp + sign(0.5_wp, s_S)) - xi_P = (5.e-1_wp - sign(0.5_wp, s_S)) - - ! goes with the numerical velocity in x/y/z directions - ! xi_P/M (pressure) = min/max(0. sgn(1,sL/sR)) - xi_MP = -min(0._wp, sign(1._wp, s_L)) - xi_PP = max(0._wp, sign(1._wp, s_R)) - - E_star = xi_M*(E_L + xi_MP*(xi_L*(E_L + (s_S - vel_L(dir_idx(1)))* & - (rho_L*s_S + pres_L/(s_L - vel_L(dir_idx(1))))) - E_L)) + & - xi_P*(E_R + xi_PP*(xi_R*(E_R + (s_S - vel_R(dir_idx(1)))* & - (rho_R*s_S + pres_R/(s_R - vel_R(dir_idx(1))))) - E_R)) - p_Star = xi_M*(pres_L + xi_MP*(rho_L*(s_L - vel_L(dir_idx(1)))*(s_S - vel_L(dir_idx(1))))) + & - xi_P*(pres_R + xi_PP*(rho_R*(s_R - vel_R(dir_idx(1)))*(s_S - vel_R(dir_idx(1))))) - - rho_Star = xi_M*(rho_L*(xi_MP*xi_L + 1._wp - xi_MP)) + & - xi_P*(rho_R*(xi_PP*xi_R + 1._wp - xi_PP)) - - vel_K_Star = vel_L(dir_idx(1))*(1._wp - xi_MP) + xi_MP*vel_R(dir_idx(1)) + & - xi_MP*xi_PP*(s_S - vel_R(dir_idx(1))) - - ! Low Mach correction - if (low_Mach == 1) then - @:compute_low_Mach_correction() - else - pcorr = 0._wp - end if - - ! COMPUTING FLUXES - ! MASS FLUX. - $:GPU_LOOP(parallelism='[seq]') - do i = 1, contxe - flux_rs${XYZ}$_vf(j, k, l, i) = & - xi_M*qL_prim_rs${XYZ}$_vf(j, k, l, i)*(vel_L(dir_idx(1)) + s_M*(xi_L - 1._wp)) + & - xi_P*qR_prim_rs${XYZ}$_vf(j + 1, k, l, i)*(vel_R(dir_idx(1)) + s_P*(xi_R - 1._wp)) - end do - - ! MOMENTUM FLUX. - ! f = \rho u u - \sigma, q = \rho u, q_star = \xi * \rho*(s_star, v, w) - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_dims - flux_rs${XYZ}$_vf(j, k, l, contxe + dir_idx(i)) = rho_Star*vel_K_Star* & - (dir_flg(dir_idx(i))*vel_K_Star + (1._wp - dir_flg(dir_idx(i)))*(xi_M*vel_L(dir_idx(i)) + xi_P*vel_R(dir_idx(i)))) + dir_flg(dir_idx(i))*p_Star & - + (s_M/s_L)*(s_P/s_R)*dir_flg(dir_idx(i))*pcorr - end do - - ! ENERGY FLUX. - ! f = u*(E-\sigma), q = E, q_star = \xi*E+(s-u)(\rho s_star - \sigma/(s-u)) - flux_rs${XYZ}$_vf(j, k, l, E_idx) = (E_star + p_Star)*vel_K_Star & - + (s_M/s_L)*(s_P/s_R)*pcorr*s_S - - ! ELASTICITY. Elastic shear stress additions for the momentum and energy flux - if (elasticity) then - flux_ene_e = 0._wp; - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_dims - ! MOMENTUM ELASTIC FLUX. - flux_rs${XYZ}$_vf(j, k, l, contxe + dir_idx(i)) = & - flux_rs${XYZ}$_vf(j, k, l, contxe + dir_idx(i)) & - - xi_M*tau_e_L(dir_idx_tau(i)) - xi_P*tau_e_R(dir_idx_tau(i)) - ! ENERGY ELASTIC FLUX. - flux_ene_e = flux_ene_e - & - xi_M*(vel_L(dir_idx(i))*tau_e_L(dir_idx_tau(i)) + & - s_M*(xi_L*((s_S - vel_L(i))*(tau_e_L(dir_idx_tau(i))/(s_L - vel_L(i)))))) - & - xi_P*(vel_R(dir_idx(i))*tau_e_R(dir_idx_tau(i)) + & - s_P*(xi_R*((s_S - vel_R(i))*(tau_e_R(dir_idx_tau(i))/(s_R - vel_R(i)))))) - end do - flux_rs${XYZ}$_vf(j, k, l, E_idx) = flux_rs${XYZ}$_vf(j, k, l, E_idx) + flux_ene_e - end if - - ! VOLUME FRACTION FLUX. - $:GPU_LOOP(parallelism='[seq]') - do i = advxb, advxe - flux_rs${XYZ}$_vf(j, k, l, i) = & - xi_M*qL_prim_rs${XYZ}$_vf(j, k, l, i)*s_S + & - xi_P*qR_prim_rs${XYZ}$_vf(j + 1, k, l, i)*s_S - end do - - ! SOURCE TERM FOR VOLUME FRACTION ADVECTION FLUX. - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_dims - vel_src_rs${XYZ}$_vf(j, k, l, dir_idx(i)) = & - xi_M*(vel_L(dir_idx(i)) + dir_flg(dir_idx(i))*(s_S*(xi_MP*(xi_L - 1) + 1) - vel_L(dir_idx(i)))) + & - xi_P*(vel_R(dir_idx(i)) + dir_flg(dir_idx(i))*(s_S*(xi_PP*(xi_R - 1) + 1) - vel_R(dir_idx(i)))) - end do - - ! INTERNAL ENERGIES ADVECTION FLUX. - ! K-th pressure and velocity in preparation for the internal energy flux - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_fluids - p_K_Star = xi_M*(xi_MP*((pres_L + pi_infs(i)/(1._wp + gammas(i)))* & - xi_L**(1._wp/gammas(i) + 1._wp) - pi_infs(i)/(1._wp + gammas(i)) - pres_L) + pres_L) + & - xi_P*(xi_PP*((pres_R + pi_infs(i)/(1._wp + gammas(i)))* & - xi_R**(1._wp/gammas(i) + 1._wp) - pi_infs(i)/(1._wp + gammas(i)) - pres_R) + pres_R) - - flux_rs${XYZ}$_vf(j, k, l, i + intxb - 1) = & - ((xi_M*qL_prim_rs${XYZ}$_vf(j, k, l, i + advxb - 1) + xi_P*qR_prim_rs${XYZ}$_vf(j + 1, k, l, i + advxb - 1))* & - (gammas(i)*p_K_Star + pi_infs(i)) + & - (xi_M*qL_prim_rs${XYZ}$_vf(j, k, l, i + contxb - 1) + xi_P*qR_prim_rs${XYZ}$_vf(j + 1, k, l, i + contxb - 1))* & - qvs(i))*vel_K_Star & - + (s_M/s_L)*(s_P/s_R)*pcorr*s_S*(xi_M*qL_prim_rs${XYZ}$_vf(j, k, l, i + advxb - 1) + xi_P*qR_prim_rs${XYZ}$_vf(j + 1, k, l, i + advxb - 1)) - end do - - flux_src_rs${XYZ}$_vf(j, k, l, advxb) = vel_src_rs${XYZ}$_vf(j, k, l, dir_idx(1)) - - ! HYPOELASTIC STRESS EVOLUTION FLUX. - if (hypoelasticity) then - $:GPU_LOOP(parallelism='[seq]') - do i = 1, strxe - strxb + 1 - flux_rs${XYZ}$_vf(j, k, l, strxb - 1 + i) = & - xi_M*(s_S/(s_L - s_S))*(s_L*rho_L*tau_e_L(i) - rho_L*vel_L(dir_idx(1))*tau_e_L(i)) + & - xi_P*(s_S/(s_R - s_S))*(s_R*rho_R*tau_e_R(i) - rho_R*vel_R(dir_idx(1))*tau_e_R(i)) - end do - end if - - ! REFERENCE MAP FLUX. - if (hyperelasticity) then - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_dims - flux_rs${XYZ}$_vf(j, k, l, xibeg - 1 + i) = & - xi_M*(s_S/(s_L - s_S))*(s_L*rho_L*xi_field_L(i) & - - rho_L*vel_L(dir_idx(1))*xi_field_L(i)) + & - xi_P*(s_S/(s_R - s_S))*(s_R*rho_R*xi_field_R(i) & - - rho_R*vel_R(dir_idx(1))*xi_field_R(i)) - end do - end if - - ! COLOR FUNCTION FLUX - if (surface_tension) then - flux_rs${XYZ}$_vf(j, k, l, c_idx) = & - (xi_M*qL_prim_rs${XYZ}$_vf(j, k, l, c_idx) + & - xi_P*qR_prim_rs${XYZ}$_vf(j + 1, k, l, c_idx))*s_S - end if - - ! Geometrical source flux for cylindrical coordinates - #:if (NORM_DIR == 2) - if (cyl_coord) then - !Substituting the advective flux into the inviscid geometrical source flux - $:GPU_LOOP(parallelism='[seq]') - do i = 1, E_idx - flux_gsrc_rs${XYZ}$_vf(j, k, l, i) = flux_rs${XYZ}$_vf(j, k, l, i) - end do - $:GPU_LOOP(parallelism='[seq]') - do i = intxb, intxe - flux_gsrc_rs${XYZ}$_vf(j, k, l, i) = flux_rs${XYZ}$_vf(j, k, l, i) - end do - ! Recalculating the radial momentum geometric source flux - flux_gsrc_rs${XYZ}$_vf(j, k, l, momxb - 1 + dir_idx(1)) = & - flux_gsrc_rs${XYZ}$_vf(j, k, l, momxb - 1 + dir_idx(1)) - p_Star - ! Geometrical source of the void fraction(s) is zero - $:GPU_LOOP(parallelism='[seq]') - do i = advxb, advxe - flux_gsrc_rs${XYZ}$_vf(j, k, l, i) = 0._wp - end do - end if - #:endif - #:if (NORM_DIR == 3) - if (grid_geometry == 3) then - $:GPU_LOOP(parallelism='[seq]') - do i = 1, sys_size - flux_gsrc_rs${XYZ}$_vf(j, k, l, i) = 0._wp - end do - flux_gsrc_rs${XYZ}$_vf(j, k, l, momxb - 1 + dir_idx(1)) = & - flux_gsrc_rs${XYZ}$_vf(j, k, l, momxb - 1 + dir_idx(1)) - p_Star - - flux_gsrc_rs${XYZ}$_vf(j, k, l, momxe) = flux_rs${XYZ}$_vf(j, k, l, momxb + 1) - end if - #:endif - - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - - elseif (model_eqns == 4) then - !ME4 - $:GPU_PARALLEL_LOOP(collapse=3, private='[i, q, alpha_rho_L, alpha_rho_R, vel_L, vel_R, alpha_L, alpha_R, nbub_L, nbub_R, rho_L, rho_R, pres_L, pres_R, E_L, E_R, H_L, H_R, Cp_avg, Cv_avg, T_avg, eps, c_sum_Yi_Phi, T_L, T_R, Y_L, Y_R, MW_L, MW_R, R_gas_L, R_gas_R, Cp_L, Cp_R, Gamm_L, Gamm_R, gamma_L, gamma_R, pi_inf_L, pi_inf_R, qv_L, qv_R, qv_avg,c_L, c_R, G_L, G_R, rho_avg, H_avg, c_avg, gamma_avg, ptilde_L, ptilde_R, vel_L_rms, vel_R_rms, vel_avg_rms, vel_L_tmp, vel_R_tmp, Ms_L, Ms_R, pres_SL, pres_SR, alpha_L_sum, alpha_R_sum, rho_Star, E_Star, p_Star, p_K_Star, vel_K_star, s_L, s_R, s_M, s_P, s_S, xi_M, xi_P, xi_L, xi_R, xi_MP, xi_PP]') - do l = is3%beg, is3%end - do k = is2%beg, is2%end - do j = is1%beg, is1%end - - vel_L_rms = 0._wp; vel_R_rms = 0._wp - rho_L = 0._wp; rho_R = 0._wp - gamma_L = 0._wp; gamma_R = 0._wp - pi_inf_L = 0._wp; pi_inf_R = 0._wp - qv_L = 0._wp; qv_R = 0._wp - - $:GPU_LOOP(parallelism='[seq]') - do i = 1, contxe - alpha_rho_L(i) = qL_prim_rs${XYZ}$_vf(j, k, l, i) - alpha_rho_R(i) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, i) - end do - - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_dims - vel_L(i) = qL_prim_rs${XYZ}$_vf(j, k, l, contxe + i) - vel_R(i) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, contxe + i) - vel_L_rms = vel_L_rms + vel_L(i)**2._wp - vel_R_rms = vel_R_rms + vel_R(i)**2._wp - end do - - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_fluids - alpha_L(i) = qL_prim_rs${XYZ}$_vf(j, k, l, E_idx + i) - alpha_R(i) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx + i) - end do - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_fluids - alpha_L(i) = qL_prim_rs${XYZ}$_vf(j, k, l, E_idx + i) - alpha_R(i) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx + i) - end do - - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_fluids - rho_L = rho_L + alpha_rho_L(i) - gamma_L = gamma_L + alpha_L(i)*gammas(i) - pi_inf_L = pi_inf_L + alpha_L(i)*pi_infs(i) - qv_L = qv_L + alpha_rho_L(i)*qvs(i) - - rho_R = rho_R + alpha_rho_R(i) - gamma_R = gamma_R + alpha_R(i)*gammas(i) - pi_inf_R = pi_inf_R + alpha_R(i)*pi_infs(i) - qv_R = qv_R + alpha_rho_R(i)*qvs(i) - end do - - pres_L = qL_prim_rs${XYZ}$_vf(j, k, l, E_idx) - pres_R = qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx) - - E_L = gamma_L*pres_L + pi_inf_L + 5.e-1_wp*rho_L*vel_L_rms + qv_L - E_R = gamma_R*pres_R + pi_inf_R + 5.e-1_wp*rho_R*vel_R_rms + qv_R - - H_L = (E_L + pres_L)/rho_L - H_R = (E_R + pres_R)/rho_R - - @:compute_average_state() - - call s_compute_speed_of_sound(pres_L, rho_L, gamma_L, pi_inf_L, H_L, alpha_L, & - vel_L_rms, 0._wp, c_L, qv_L) - - call s_compute_speed_of_sound(pres_R, rho_R, gamma_R, pi_inf_R, H_R, alpha_R, & - vel_R_rms, 0._wp, c_R, qv_R) - - !> The computation of c_avg does not require all the variables, and therefore the non '_avg' - ! variables are placeholders to call the subroutine. - - call s_compute_speed_of_sound(pres_R, rho_avg, gamma_avg, pi_inf_R, H_avg, alpha_R, & - vel_avg_rms, 0._wp, c_avg, qv_avg) - - if (wave_speeds == 1) then - s_L = min(vel_L(dir_idx(1)) - c_L, vel_R(dir_idx(1)) - c_R) - s_R = max(vel_R(dir_idx(1)) + c_R, vel_L(dir_idx(1)) + c_L) - - s_S = (pres_R - pres_L + rho_L*vel_L(dir_idx(1))* & - (s_L - vel_L(dir_idx(1))) - & - rho_R*vel_R(dir_idx(1))* & - (s_R - vel_R(dir_idx(1)))) & - /(rho_L*(s_L - vel_L(dir_idx(1))) - & - rho_R*(s_R - vel_R(dir_idx(1)))) - elseif (wave_speeds == 2) then - pres_SL = 5.e-1_wp*(pres_L + pres_R + rho_avg*c_avg* & - (vel_L(dir_idx(1)) - & - vel_R(dir_idx(1)))) - - pres_SR = pres_SL - - Ms_L = max(1._wp, sqrt(1._wp + ((5.e-1_wp + gamma_L)/(1._wp + gamma_L))* & - (pres_SL/pres_L - 1._wp)*pres_L/ & - ((pres_L + pi_inf_L/(1._wp + gamma_L))))) - Ms_R = max(1._wp, sqrt(1._wp + ((5.e-1_wp + gamma_R)/(1._wp + gamma_R))* & - (pres_SR/pres_R - 1._wp)*pres_R/ & - ((pres_R + pi_inf_R/(1._wp + gamma_R))))) - - s_L = vel_L(dir_idx(1)) - c_L*Ms_L - s_R = vel_R(dir_idx(1)) + c_R*Ms_R - - s_S = 5.e-1_wp*((vel_L(dir_idx(1)) + vel_R(dir_idx(1))) + & - (pres_L - pres_R)/ & - (rho_avg*c_avg)) - end if - - ! follows Einfeldt et al. - ! s_M/P = min/max(0.,s_L/R) - s_M = min(0._wp, s_L); s_P = max(0._wp, s_R) - - ! goes with q_star_L/R = xi_L/R * (variable) - ! xi_L/R = ( ( s_L/R - u_L/R )/(s_L/R - s_star) ) - xi_L = (s_L - vel_L(dir_idx(1)))/(s_L - s_S) - xi_R = (s_R - vel_R(dir_idx(1)))/(s_R - s_S) - - ! goes with numerical velocity in x/y/z directions - ! xi_P/M = 0.5 +/m sgn(0.5,s_star) - xi_M = (5.e-1_wp + sign(5.e-1_wp, s_S)) - xi_P = (5.e-1_wp - sign(5.e-1_wp, s_S)) - - $:GPU_LOOP(parallelism='[seq]') - do i = 1, contxe - flux_rs${XYZ}$_vf(j, k, l, i) = & - xi_M*alpha_rho_L(i) & - *(vel_L(dir_idx(1)) + s_M*(xi_L - 1._wp)) & - + xi_P*alpha_rho_R(i) & - *(vel_R(dir_idx(1)) + s_P*(xi_R - 1._wp)) - end do - - ! Momentum flux. - ! f = \rho u u + p I, q = \rho u, q_star = \xi * \rho*(s_star, v, w) - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_dims - flux_rs${XYZ}$_vf(j, k, l, contxe + dir_idx(i)) = & - xi_M*(rho_L*(vel_L(dir_idx(1))* & - vel_L(dir_idx(i)) + & - s_M*(xi_L*(dir_flg(dir_idx(i))*s_S + & - (1._wp - dir_flg(dir_idx(i)))* & - vel_L(dir_idx(i))) - vel_L(dir_idx(i)))) + & - dir_flg(dir_idx(i))*pres_L) & - + xi_P*(rho_R*(vel_R(dir_idx(1))* & - vel_R(dir_idx(i)) + & - s_P*(xi_R*(dir_flg(dir_idx(i))*s_S + & - (1._wp - dir_flg(dir_idx(i)))* & - vel_R(dir_idx(i))) - vel_R(dir_idx(i)))) + & - dir_flg(dir_idx(i))*pres_R) - end do - - if (bubbles_euler) then - ! Put p_tilde in - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_dims - flux_rs${XYZ}$_vf(j, k, l, contxe + dir_idx(i)) = & - flux_rs${XYZ}$_vf(j, k, l, contxe + dir_idx(i)) + & - xi_M*(dir_flg(dir_idx(i))*(-1._wp*ptilde_L)) & - + xi_P*(dir_flg(dir_idx(i))*(-1._wp*ptilde_R)) - end do - end if - - flux_rs${XYZ}$_vf(j, k, l, E_idx) = 0._wp - - $:GPU_LOOP(parallelism='[seq]') - do i = alf_idx, alf_idx !only advect the void fraction - flux_rs${XYZ}$_vf(j, k, l, i) = & - xi_M*qL_prim_rs${XYZ}$_vf(j, k, l, i) & - *(vel_L(dir_idx(1)) + s_M*(xi_L - 1._wp)) & - + xi_P*qR_prim_rs${XYZ}$_vf(j + 1, k, l, i) & - *(vel_R(dir_idx(1)) + s_P*(xi_R - 1._wp)) - end do - - ! Source for volume fraction advection equation - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_dims - - vel_src_rs${XYZ}$_vf(j, k, l, dir_idx(i)) = 0._wp - !IF ( (model_eqns == 4) .or. (num_fluids==1) ) vel_src_rs_vf(dir_idx(i))%sf(j,k,l) = 0._wp - end do - - flux_src_rs${XYZ}$_vf(j, k, l, advxb) = vel_src_rs${XYZ}$_vf(j, k, l, dir_idx(1)) - - ! Add advection flux for bubble variables - if (bubbles_euler) then - $:GPU_LOOP(parallelism='[seq]') - do i = bubxb, bubxe - flux_rs${XYZ}$_vf(j, k, l, i) = & - xi_M*nbub_L*qL_prim_rs${XYZ}$_vf(j, k, l, i) & - *(vel_L(dir_idx(1)) + s_M*(xi_L - 1._wp)) & - + xi_P*nbub_R*qR_prim_rs${XYZ}$_vf(j + 1, k, l, i) & - *(vel_R(dir_idx(1)) + s_P*(xi_R - 1._wp)) - end do - end if - - ! Geometrical source flux for cylindrical coordinates - - #:if (NORM_DIR == 2) - if (cyl_coord) then - ! Substituting the advective flux into the inviscid geometrical source flux - $:GPU_LOOP(parallelism='[seq]') - do i = 1, E_idx - flux_gsrc_rs${XYZ}$_vf(j, k, l, i) = flux_rs${XYZ}$_vf(j, k, l, i) - end do - ! Recalculating the radial momentum geometric source flux - flux_gsrc_rs${XYZ}$_vf(j, k, l, contxe + dir_idx(1)) = & - xi_M*(rho_L*(vel_L(dir_idx(1))* & - vel_L(dir_idx(1)) + & - s_M*(xi_L*(dir_flg(dir_idx(1))*s_S + & - (1._wp - dir_flg(dir_idx(1)))* & - vel_L(dir_idx(1))) - vel_L(dir_idx(1))))) & - + xi_P*(rho_R*(vel_R(dir_idx(1))* & - vel_R(dir_idx(1)) + & - s_P*(xi_R*(dir_flg(dir_idx(1))*s_S + & - (1._wp - dir_flg(dir_idx(1)))* & - vel_R(dir_idx(1))) - vel_R(dir_idx(1))))) - ! Geometrical source of the void fraction(s) is zero - $:GPU_LOOP(parallelism='[seq]') - do i = advxb, advxe - flux_gsrc_rs${XYZ}$_vf(j, k, l, i) = 0._wp - end do - end if - #:endif - #:if (NORM_DIR == 3) - if (grid_geometry == 3) then - $:GPU_LOOP(parallelism='[seq]') - do i = 1, sys_size - flux_gsrc_rs${XYZ}$_vf(j, k, l, i) = 0._wp - end do - flux_gsrc_rs${XYZ}$_vf(j, k, l, momxb + 1) = & - -xi_M*(rho_L*(vel_L(dir_idx(1))* & - vel_L(dir_idx(1)) + & - s_M*(xi_L*(dir_flg(dir_idx(1))*s_S + & - (1._wp - dir_flg(dir_idx(1)))* & - vel_L(dir_idx(1))) - vel_L(dir_idx(1))))) & - - xi_P*(rho_R*(vel_R(dir_idx(1))* & - vel_R(dir_idx(1)) + & - s_P*(xi_R*(dir_flg(dir_idx(1))*s_S + & - (1._wp - dir_flg(dir_idx(1)))* & - vel_R(dir_idx(1))) - vel_R(dir_idx(1))))) - flux_gsrc_rs${XYZ}$_vf(j, k, l, momxe) = flux_rs${XYZ}$_vf(j, k, l, momxb + 1) - end if - #:endif - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - - elseif (model_eqns == 2 .and. bubbles_euler) then - $:GPU_PARALLEL_LOOP(collapse=3, private='[i, q, R0_L, R0_R, V0_L, V0_R, P0_L, P0_R, pbw_L, pbw_R, vel_L, vel_R, rho_avg, alpha_L, alpha_R, h_avg, gamma_avg, Re_L, Re_R, pcorr, zcoef, rho_L, rho_R, pres_L, pres_R, E_L, E_R, H_L, H_R, gamma_L, gamma_R, pi_inf_L, pi_inf_R, qv_L, qv_R, qv_avg, c_L, c_R, c_avg, vel_L_rms, vel_R_rms, vel_avg_rms, vel_L_tmp, vel_R_tmp, Ms_L, Ms_R, pres_SL, pres_SR, alpha_L_sum, alpha_R_sum, s_L, s_R, s_M, s_P, s_S, xi_M, xi_P, xi_L, xi_R, xi_MP, xi_PP, nbub_L, nbub_R, PbwR3Lbar, PbwR3Rbar, R3Lbar, R3Rbar, R3V2Lbar, R3V2Rbar]') - do l = is3%beg, is3%end - do k = is2%beg, is2%end - do j = is1%beg, is1%end - - vel_L_rms = 0._wp; vel_R_rms = 0._wp - rho_L = 0._wp; rho_R = 0._wp - gamma_L = 0._wp; gamma_R = 0._wp - pi_inf_L = 0._wp; pi_inf_R = 0._wp - qv_L = 0._wp; qv_R = 0._wp - - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_fluids - alpha_L(i) = qL_prim_rs${XYZ}$_vf(j, k, l, E_idx + i) - alpha_R(i) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx + i) - end do - - vel_L_rms = 0._wp; vel_R_rms = 0._wp - - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_dims - vel_L(i) = qL_prim_rs${XYZ}$_vf(j, k, l, contxe + i) - vel_R(i) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, contxe + i) - vel_L_rms = vel_L_rms + vel_L(i)**2._wp - vel_R_rms = vel_R_rms + vel_R(i)**2._wp - end do - - ! Retain this in the refactor - if (mpp_lim .and. (num_fluids > 2)) then - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_fluids - rho_L = rho_L + qL_prim_rs${XYZ}$_vf(j, k, l, i) - gamma_L = gamma_L + qL_prim_rs${XYZ}$_vf(j, k, l, E_idx + i)*gammas(i) - pi_inf_L = pi_inf_L + qL_prim_rs${XYZ}$_vf(j, k, l, E_idx + i)*pi_infs(i) - qv_L = qv_L + qL_prim_rs${XYZ}$_vf(j, k, l, i)*qvs(i) - rho_R = rho_R + qR_prim_rs${XYZ}$_vf(j + 1, k, l, i) - gamma_R = gamma_R + qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx + i)*gammas(i) - pi_inf_R = pi_inf_R + qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx + i)*pi_infs(i) - qv_R = qv_R + qR_prim_rs${XYZ}$_vf(j + 1, k, l, i)*qvs(i) - end do - else if (num_fluids > 2) then - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_fluids - 1 - rho_L = rho_L + qL_prim_rs${XYZ}$_vf(j, k, l, i) - gamma_L = gamma_L + qL_prim_rs${XYZ}$_vf(j, k, l, E_idx + i)*gammas(i) - pi_inf_L = pi_inf_L + qL_prim_rs${XYZ}$_vf(j, k, l, E_idx + i)*pi_infs(i) - qv_L = qv_L + qL_prim_rs${XYZ}$_vf(j, k, l, i)*qvs(i) - rho_R = rho_R + qR_prim_rs${XYZ}$_vf(j + 1, k, l, i) - gamma_R = gamma_R + qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx + i)*gammas(i) - pi_inf_R = pi_inf_R + qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx + i)*pi_infs(i) - qv_R = qv_R + qR_prim_rs${XYZ}$_vf(j + 1, k, l, i)*qvs(i) - end do - else - rho_L = qL_prim_rs${XYZ}$_vf(j, k, l, 1) - gamma_L = gammas(1) - pi_inf_L = pi_infs(1) - qv_L = qvs(1) - rho_R = qR_prim_rs${XYZ}$_vf(j + 1, k, l, 1) - gamma_R = gammas(1) - pi_inf_R = pi_infs(1) - qv_R = qvs(1) - end if - - if (viscous) then - if (num_fluids == 1) then ! Need to consider case with num_fluids >= 2 - $:GPU_LOOP(parallelism='[seq]') - do i = 1, 2 - Re_L(i) = dflt_real - Re_R(i) = dflt_real - - if (Re_size(i) > 0) Re_L(i) = 0._wp - if (Re_size(i) > 0) Re_R(i) = 0._wp - - $:GPU_LOOP(parallelism='[seq]') - do q = 1, Re_size(i) - Re_L(i) = (1._wp - qL_prim_rs${XYZ}$_vf(j, k, l, E_idx + Re_idx(i, q)))/Res_gs(i, q) & - + Re_L(i) - Re_R(i) = (1._wp - qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx + Re_idx(i, q)))/Res_gs(i, q) & - + Re_R(i) - end do - - Re_L(i) = 1._wp/max(Re_L(i), sgm_eps) - Re_R(i) = 1._wp/max(Re_R(i), sgm_eps) - - end do - end if - end if - - pres_L = qL_prim_rs${XYZ}$_vf(j, k, l, E_idx) - pres_R = qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx) - - E_L = gamma_L*pres_L + pi_inf_L + 5.e-1_wp*rho_L*vel_L_rms - E_R = gamma_R*pres_R + pi_inf_R + 5.e-1_wp*rho_R*vel_R_rms - - H_L = (E_L + pres_L)/rho_L - H_R = (E_R + pres_R)/rho_R - - if (avg_state == 2) then - $:GPU_LOOP(parallelism='[seq]') - do i = 1, nb - R0_L(i) = qL_prim_rs${XYZ}$_vf(j, k, l, rs(i)) - R0_R(i) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, rs(i)) - - V0_L(i) = qL_prim_rs${XYZ}$_vf(j, k, l, vs(i)) - V0_R(i) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, vs(i)) - if (.not. polytropic .and. .not. qbmm) then - P0_L(i) = qL_prim_rs${XYZ}$_vf(j, k, l, ps(i)) - P0_R(i) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, ps(i)) - end if - end do - - if (.not. qbmm) then - if (adv_n) then - nbub_L = qL_prim_rs${XYZ}$_vf(j, k, l, n_idx) - nbub_R = qR_prim_rs${XYZ}$_vf(j + 1, k, l, n_idx) - else - nbub_L = 0._wp - nbub_R = 0._wp - $:GPU_LOOP(parallelism='[seq]') - do i = 1, nb - nbub_L = nbub_L + (R0_L(i)**3._wp)*weight(i) - nbub_R = nbub_R + (R0_R(i)**3._wp)*weight(i) - end do - - nbub_L = (3._wp/(4._wp*pi))*qL_prim_rs${XYZ}$_vf(j, k, l, E_idx + num_fluids)/nbub_L - nbub_R = (3._wp/(4._wp*pi))*qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx + num_fluids)/nbub_R - end if - else - !nb stored in 0th moment of first R0 bin in variable conversion module - nbub_L = qL_prim_rs${XYZ}$_vf(j, k, l, bubxb) - nbub_R = qR_prim_rs${XYZ}$_vf(j + 1, k, l, bubxb) - end if - - $:GPU_LOOP(parallelism='[seq]') - do i = 1, nb - if (.not. qbmm) then - pbw_L(i) = f_cpbw_KM(R0(i), R0_L(i), V0_L(i), P0_L(i)) - pbw_R(i) = f_cpbw_KM(R0(i), R0_R(i), V0_R(i), P0_R(i)) - end if - end do - - if (qbmm) then - PbwR3Lbar = mom_sp_rs${XYZ}$_vf(j, k, l, 4) - PbwR3Rbar = mom_sp_rs${XYZ}$_vf(j + 1, k, l, 4) - - R3Lbar = mom_sp_rs${XYZ}$_vf(j, k, l, 1) - R3Rbar = mom_sp_rs${XYZ}$_vf(j + 1, k, l, 1) - - R3V2Lbar = mom_sp_rs${XYZ}$_vf(j, k, l, 3) - R3V2Rbar = mom_sp_rs${XYZ}$_vf(j + 1, k, l, 3) - else - - PbwR3Lbar = 0._wp - PbwR3Rbar = 0._wp - - R3Lbar = 0._wp - R3Rbar = 0._wp - - R3V2Lbar = 0._wp - R3V2Rbar = 0._wp - - $:GPU_LOOP(parallelism='[seq]') - do i = 1, nb - PbwR3Lbar = PbwR3Lbar + pbw_L(i)*(R0_L(i)**3._wp)*weight(i) - PbwR3Rbar = PbwR3Rbar + pbw_R(i)*(R0_R(i)**3._wp)*weight(i) - - R3Lbar = R3Lbar + (R0_L(i)**3._wp)*weight(i) - R3Rbar = R3Rbar + (R0_R(i)**3._wp)*weight(i) - - R3V2Lbar = R3V2Lbar + (R0_L(i)**3._wp)*(V0_L(i)**2._wp)*weight(i) - R3V2Rbar = R3V2Rbar + (R0_R(i)**3._wp)*(V0_R(i)**2._wp)*weight(i) - end do - end if - - rho_avg = 5.e-1_wp*(rho_L + rho_R) - H_avg = 5.e-1_wp*(H_L + H_R) - gamma_avg = 5.e-1_wp*(gamma_L + gamma_R) - qv_avg = 5.e-1_wp*(qv_L + qv_R) - vel_avg_rms = 0._wp - - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_dims - vel_avg_rms = vel_avg_rms + (5.e-1_wp*(vel_L(i) + vel_R(i)))**2._wp - end do - - end if - - call s_compute_speed_of_sound(pres_L, rho_L, gamma_L, pi_inf_L, H_L, alpha_L, & - vel_L_rms, 0._wp, c_L, qv_L) - - call s_compute_speed_of_sound(pres_R, rho_R, gamma_R, pi_inf_R, H_R, alpha_R, & - vel_R_rms, 0._wp, c_R, qv_R) - - !> The computation of c_avg does not require all the variables, and therefore the non '_avg' - ! variables are placeholders to call the subroutine. - call s_compute_speed_of_sound(pres_R, rho_avg, gamma_avg, pi_inf_R, H_avg, alpha_R, & - vel_avg_rms, 0._wp, c_avg, qv_avg) - - if (viscous) then - $:GPU_LOOP(parallelism='[seq]') - do i = 1, 2 - Re_avg_rs${XYZ}$_vf(j, k, l, i) = 2._wp/(1._wp/Re_L(i) + 1._wp/Re_R(i)) - end do - end if - - ! Low Mach correction - if (low_Mach == 2) then - @:compute_low_Mach_correction() - end if - - if (wave_speeds == 1) then - s_L = min(vel_L(dir_idx(1)) - c_L, vel_R(dir_idx(1)) - c_R) - s_R = max(vel_R(dir_idx(1)) + c_R, vel_L(dir_idx(1)) + c_L) - - s_S = (pres_R - pres_L + rho_L*vel_L(dir_idx(1))* & - (s_L - vel_L(dir_idx(1))) - & - rho_R*vel_R(dir_idx(1))* & - (s_R - vel_R(dir_idx(1)))) & - /(rho_L*(s_L - vel_L(dir_idx(1))) - & - rho_R*(s_R - vel_R(dir_idx(1)))) - elseif (wave_speeds == 2) then - pres_SL = 5.e-1_wp*(pres_L + pres_R + rho_avg*c_avg* & - (vel_L(dir_idx(1)) - & - vel_R(dir_idx(1)))) - - pres_SR = pres_SL - - Ms_L = max(1._wp, sqrt(1._wp + ((5.e-1_wp + gamma_L)/(1._wp + gamma_L))* & - (pres_SL/pres_L - 1._wp)*pres_L/ & - ((pres_L + pi_inf_L/(1._wp + gamma_L))))) - Ms_R = max(1._wp, sqrt(1._wp + ((5.e-1_wp + gamma_R)/(1._wp + gamma_R))* & - (pres_SR/pres_R - 1._wp)*pres_R/ & - ((pres_R + pi_inf_R/(1._wp + gamma_R))))) - - s_L = vel_L(dir_idx(1)) - c_L*Ms_L - s_R = vel_R(dir_idx(1)) + c_R*Ms_R - - s_S = 5.e-1_wp*((vel_L(dir_idx(1)) + vel_R(dir_idx(1))) + & - (pres_L - pres_R)/ & - (rho_avg*c_avg)) - end if - - ! follows Einfeldt et al. - ! s_M/P = min/max(0.,s_L/R) - s_M = min(0._wp, s_L); s_P = max(0._wp, s_R) - - ! goes with q_star_L/R = xi_L/R * (variable) - ! xi_L/R = ( ( s_L/R - u_L/R )/(s_L/R - s_star) ) - xi_L = (s_L - vel_L(dir_idx(1)))/(s_L - s_S) - xi_R = (s_R - vel_R(dir_idx(1)))/(s_R - s_S) - - ! goes with numerical velocity in x/y/z directions - ! xi_P/M = 0.5 +/m sgn(0.5,s_star) - xi_M = (5.e-1_wp + sign(5.e-1_wp, s_S)) - xi_P = (5.e-1_wp - sign(5.e-1_wp, s_S)) - - ! Low Mach correction - if (low_Mach == 1) then - @:compute_low_Mach_correction() - else - pcorr = 0._wp - end if - - $:GPU_LOOP(parallelism='[seq]') - do i = 1, contxe - flux_rs${XYZ}$_vf(j, k, l, i) = & - xi_M*qL_prim_rs${XYZ}$_vf(j, k, l, i) & - *(vel_L(dir_idx(1)) + s_M*(xi_L - 1._wp)) & - + xi_P*qR_prim_rs${XYZ}$_vf(j + 1, k, l, i) & - *(vel_R(dir_idx(1)) + s_P*(xi_R - 1._wp)) - end do - - if (bubbles_euler .and. (num_fluids > 1)) then - ! Kill mass transport @ gas density - flux_rs${XYZ}$_vf(j, k, l, contxe) = 0._wp - end if - - ! Momentum flux. - ! f = \rho u u + p I, q = \rho u, q_star = \xi * \rho*(s_star, v, w) - - ! Include p_tilde - - if (avg_state == 2) then - if (alpha_L(num_fluids) < small_alf .or. R3Lbar < small_alf) then - pres_L = pres_L - alpha_L(num_fluids)*pres_L - else - pres_L = pres_L - alpha_L(num_fluids)*(pres_L - PbwR3Lbar/R3Lbar - & - rho_L*R3V2Lbar/R3Lbar) - end if - - if (alpha_R(num_fluids) < small_alf .or. R3Rbar < small_alf) then - pres_R = pres_R - alpha_R(num_fluids)*pres_R - else - pres_R = pres_R - alpha_R(num_fluids)*(pres_R - PbwR3Rbar/R3Rbar - & - rho_R*R3V2Rbar/R3Rbar) - end if - end if - - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_dims - flux_rs${XYZ}$_vf(j, k, l, contxe + dir_idx(i)) = & - xi_M*(rho_L*(vel_L(dir_idx(1))* & - vel_L(dir_idx(i)) + & - s_M*(xi_L*(dir_flg(dir_idx(i))*s_S + & - (1._wp - dir_flg(dir_idx(i)))* & - vel_L(dir_idx(i))) - vel_L(dir_idx(i)))) + & - dir_flg(dir_idx(i))*(pres_L)) & - + xi_P*(rho_R*(vel_R(dir_idx(1))* & - vel_R(dir_idx(i)) + & - s_P*(xi_R*(dir_flg(dir_idx(i))*s_S + & - (1._wp - dir_flg(dir_idx(i)))* & - vel_R(dir_idx(i))) - vel_R(dir_idx(i)))) + & - dir_flg(dir_idx(i))*(pres_R)) & - + (s_M/s_L)*(s_P/s_R)*dir_flg(dir_idx(i))*pcorr - end do - - ! Energy flux. - ! f = u*(E+p), q = E, q_star = \xi*E+(s-u)(\rho s_star + p/(s-u)) - flux_rs${XYZ}$_vf(j, k, l, E_idx) = & - xi_M*(vel_L(dir_idx(1))*(E_L + pres_L) + & - s_M*(xi_L*(E_L + (s_S - vel_L(dir_idx(1)))* & - (rho_L*s_S + (pres_L)/ & - (s_L - vel_L(dir_idx(1))))) - E_L)) & - + xi_P*(vel_R(dir_idx(1))*(E_R + pres_R) + & - s_P*(xi_R*(E_R + (s_S - vel_R(dir_idx(1)))* & - (rho_R*s_S + (pres_R)/ & - (s_R - vel_R(dir_idx(1))))) - E_R)) & - + (s_M/s_L)*(s_P/s_R)*pcorr*s_S - - ! Volume fraction flux - $:GPU_LOOP(parallelism='[seq]') - do i = advxb, advxe - flux_rs${XYZ}$_vf(j, k, l, i) = & - xi_M*qL_prim_rs${XYZ}$_vf(j, k, l, i) & - *(vel_L(dir_idx(1)) + s_M*(xi_L - 1._wp)) & - + xi_P*qR_prim_rs${XYZ}$_vf(j + 1, k, l, i) & - *(vel_R(dir_idx(1)) + s_P*(xi_R - 1._wp)) - end do - - ! Source for volume fraction advection equation - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_dims - vel_src_rs${XYZ}$_vf(j, k, l, dir_idx(i)) = & - xi_M*(vel_L(dir_idx(i)) + & - dir_flg(dir_idx(i))* & - s_M*(xi_L - 1._wp)) & - + xi_P*(vel_R(dir_idx(i)) + & - dir_flg(dir_idx(i))* & - s_P*(xi_R - 1._wp)) - - !IF ( (model_eqns == 4) .or. (num_fluids==1) ) vel_src_rs_vf(dir_idx(i))%sf(j,k,l) = 0._wp - end do - - flux_src_rs${XYZ}$_vf(j, k, l, advxb) = vel_src_rs${XYZ}$_vf(j, k, l, dir_idx(1)) - - ! Add advection flux for bubble variables - $:GPU_LOOP(parallelism='[seq]') - do i = bubxb, bubxe - flux_rs${XYZ}$_vf(j, k, l, i) = & - xi_M*nbub_L*qL_prim_rs${XYZ}$_vf(j, k, l, i) & - *(vel_L(dir_idx(1)) + s_M*(xi_L - 1._wp)) & - + xi_P*nbub_R*qR_prim_rs${XYZ}$_vf(j + 1, k, l, i) & - *(vel_R(dir_idx(1)) + s_P*(xi_R - 1._wp)) - end do - - if (qbmm) then - flux_rs${XYZ}$_vf(j, k, l, bubxb) = & - xi_M*nbub_L & - *(vel_L(dir_idx(1)) + s_M*(xi_L - 1._wp)) & - + xi_P*nbub_R & - *(vel_R(dir_idx(1)) + s_P*(xi_R - 1._wp)) - end if - - if (adv_n) then - flux_rs${XYZ}$_vf(j, k, l, n_idx) = & - xi_M*nbub_L & - *(vel_L(dir_idx(1)) + s_M*(xi_L - 1._wp)) & - + xi_P*nbub_R & - *(vel_R(dir_idx(1)) + s_P*(xi_R - 1._wp)) - end if - - ! Geometrical source flux for cylindrical coordinates - #:if (NORM_DIR == 2) - if (cyl_coord) then - ! Substituting the advective flux into the inviscid geometrical source flux - $:GPU_LOOP(parallelism='[seq]') - do i = 1, E_idx - flux_gsrc_rs${XYZ}$_vf(j, k, l, i) = flux_rs${XYZ}$_vf(j, k, l, i) - end do - ! Recalculating the radial momentum geometric source flux - flux_gsrc_rs${XYZ}$_vf(j, k, l, contxe + dir_idx(1)) = & - xi_M*(rho_L*(vel_L(dir_idx(1))* & - vel_L(dir_idx(1)) + & - s_M*(xi_L*(dir_flg(dir_idx(1))*s_S + & - (1._wp - dir_flg(dir_idx(1)))* & - vel_L(dir_idx(1))) - vel_L(dir_idx(1))))) & - + xi_P*(rho_R*(vel_R(dir_idx(1))* & - vel_R(dir_idx(1)) + & - s_P*(xi_R*(dir_flg(dir_idx(1))*s_S + & - (1._wp - dir_flg(dir_idx(1)))* & - vel_R(dir_idx(1))) - vel_R(dir_idx(1))))) - ! Geometrical source of the void fraction(s) is zero - $:GPU_LOOP(parallelism='[seq]') - do i = advxb, advxe - flux_gsrc_rs${XYZ}$_vf(j, k, l, i) = 0._wp - end do - end if - #:endif - #:if (NORM_DIR == 3) - if (grid_geometry == 3) then - $:GPU_LOOP(parallelism='[seq]') - do i = 1, sys_size - flux_gsrc_rs${XYZ}$_vf(j, k, l, i) = 0._wp - end do - - flux_gsrc_rs${XYZ}$_vf(j, k, l, momxb + 1) = & - -xi_M*(rho_L*(vel_L(dir_idx(1))* & - vel_L(dir_idx(1)) + & - s_M*(xi_L*(dir_flg(dir_idx(1))*s_S + & - (1._wp - dir_flg(dir_idx(1)))* & - vel_L(dir_idx(1))) - vel_L(dir_idx(1))))) & - - xi_P*(rho_R*(vel_R(dir_idx(1))* & - vel_R(dir_idx(1)) + & - s_P*(xi_R*(dir_flg(dir_idx(1))*s_S + & - (1._wp - dir_flg(dir_idx(1)))* & - vel_R(dir_idx(1))) - vel_R(dir_idx(1))))) - flux_gsrc_rs${XYZ}$_vf(j, k, l, momxe) = flux_rs${XYZ}$_vf(j, k, l, momxb + 1) - - end if - #:endif - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - else - ! 5-EQUATION MODEL WITH HLLC - $:GPU_PARALLEL_LOOP(collapse=3, private='[Re_max, i, q, T_L, T_R, vel_L_rms, vel_R_rms, pres_L, pres_R, rho_L, gamma_L, pi_inf_L, qv_L, rho_R, gamma_R, pi_inf_R, qv_R, alpha_L_sum, alpha_R_sum, E_L, E_R, MW_L, MW_R, R_gas_L, R_gas_R, Cp_L, Cp_R, Cv_L, Cv_R, Gamm_L, Gamm_R, Y_L, Y_R, H_L, H_R, qv_avg, rho_avg, gamma_avg, H_avg, c_L, c_R, c_avg, s_P, s_M, xi_P, xi_M, xi_L, xi_R, Ms_L, Ms_R, pres_SL, pres_SR, vel_L, vel_R, Re_L, Re_R, alpha_L, alpha_R, s_L, s_R, s_S, vel_avg_rms, pcorr, zcoef, vel_L_tmp, vel_R_tmp, Ys_L, Ys_R, Xs_L, Xs_R, Gamma_iL, Gamma_iR, Cp_iL, Cp_iR, tau_e_L, tau_e_R, xi_field_L, xi_field_R, Yi_avg,Phi_avg, h_iL, h_iR, h_avg_2, G_L, G_R]', copyin='[is1, is2, is3]') - do l = is3%beg, is3%end - do k = is2%beg, is2%end - do j = is1%beg, is1%end - - vel_L_rms = 0._wp; vel_R_rms = 0._wp - rho_L = 0._wp; rho_R = 0._wp - gamma_L = 0._wp; gamma_R = 0._wp - pi_inf_L = 0._wp; pi_inf_R = 0._wp - qv_L = 0._wp; qv_R = 0._wp - alpha_L_sum = 0._wp; alpha_R_sum = 0._wp - - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_fluids - alpha_L(i) = qL_prim_rs${XYZ}$_vf(j, k, l, E_idx + i) - alpha_R(i) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx + i) - end do - - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_dims - vel_L(i) = qL_prim_rs${XYZ}$_vf(j, k, l, contxe + i) - vel_R(i) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, contxe + i) - vel_L_rms = vel_L_rms + vel_L(i)**2._wp - vel_R_rms = vel_R_rms + vel_R(i)**2._wp - end do - - pres_L = qL_prim_rs${XYZ}$_vf(j, k, l, E_idx) - pres_R = qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx) - - ! Change this by splitting it into the cases - ! present in the bubbles_euler - if (mpp_lim) then - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_fluids - qL_prim_rs${XYZ}$_vf(j, k, l, i) = max(0._wp, qL_prim_rs${XYZ}$_vf(j, k, l, i)) - qL_prim_rs${XYZ}$_vf(j, k, l, E_idx + i) = min(max(0._wp, qL_prim_rs${XYZ}$_vf(j, k, l, E_idx + i)), 1._wp) - qR_prim_rs${XYZ}$_vf(j + 1, k, l, i) = max(0._wp, qR_prim_rs${XYZ}$_vf(j + 1, k, l, i)) - qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx + i) = min(max(0._wp, qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx + i)), 1._wp) - alpha_L_sum = alpha_L_sum + qL_prim_rs${XYZ}$_vf(j, k, l, E_idx + i) - alpha_R_sum = alpha_R_sum + qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx + i) - end do - - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_fluids - qL_prim_rs${XYZ}$_vf(j, k, l, E_idx + i) = qL_prim_rs${XYZ}$_vf(j, k, l, E_idx + i)/max(alpha_L_sum, sgm_eps) - qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx + i) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx + i)/max(alpha_R_sum, sgm_eps) - end do - end if - - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_fluids - rho_L = rho_L + qL_prim_rs${XYZ}$_vf(j, k, l, i) - gamma_L = gamma_L + qL_prim_rs${XYZ}$_vf(j, k, l, E_idx + i)*gammas(i) - pi_inf_L = pi_inf_L + qL_prim_rs${XYZ}$_vf(j, k, l, E_idx + i)*pi_infs(i) - qv_L = qv_L + qL_prim_rs${XYZ}$_vf(j, k, l, i)*qvs(i) - - rho_R = rho_R + qR_prim_rs${XYZ}$_vf(j + 1, k, l, i) - gamma_R = gamma_R + qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx + i)*gammas(i) - pi_inf_R = pi_inf_R + qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx + i)*pi_infs(i) - qv_R = qv_R + qR_prim_rs${XYZ}$_vf(j + 1, k, l, i)*qvs(i) - end do - - Re_max = 0 - if (Re_size(1) > 0) Re_max = 1 - if (Re_size(2) > 0) Re_max = 2 - - if (viscous) then - $:GPU_LOOP(parallelism='[seq]') - do i = 1, Re_max - Re_L(i) = 0._wp - Re_R(i) = 0._wp - - $:GPU_LOOP(parallelism='[seq]') - do q = 1, Re_size(i) - Re_L(i) = alpha_L(Re_idx(i, q))/Res_gs(i, q) & - + Re_L(i) - Re_R(i) = alpha_R(Re_idx(i, q))/Res_gs(i, q) & - + Re_R(i) - end do - - Re_L(i) = 1._wp/max(Re_L(i), sgm_eps) - Re_R(i) = 1._wp/max(Re_R(i), sgm_eps) - end do - end if - - if (chemistry) then - c_sum_Yi_Phi = 0.0_wp - $:GPU_LOOP(parallelism='[seq]') - do i = chemxb, chemxe - Ys_L(i - chemxb + 1) = qL_prim_rs${XYZ}$_vf(j, k, l, i) - Ys_R(i - chemxb + 1) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, i) - end do - - call get_mixture_molecular_weight(Ys_L, MW_L) - call get_mixture_molecular_weight(Ys_R, MW_R) - - #:if USING_AMD - Xs_L(:) = Ys_L(:)*MW_L/molecular_weights_nonparameter(:) - Xs_R(:) = Ys_R(:)*MW_R/molecular_weights_nonparameter(:) - #:else - Xs_L(:) = Ys_L(:)*MW_L/molecular_weights(:) - Xs_R(:) = Ys_R(:)*MW_R/molecular_weights(:) - #:endif - - R_gas_L = gas_constant/MW_L - R_gas_R = gas_constant/MW_R - - T_L = pres_L/rho_L/R_gas_L - T_R = pres_R/rho_R/R_gas_R - - call get_species_specific_heats_r(T_L, Cp_iL) - call get_species_specific_heats_r(T_R, Cp_iR) - - if (chem_params%gamma_method == 1) then - !> gamma_method = 1: Ref. Section 2.3.1 Formulation of doi:10.7907/ZKW8-ES97. - Gamma_iL = Cp_iL/(Cp_iL - 1.0_wp) - Gamma_iR = Cp_iR/(Cp_iR - 1.0_wp) - - gamma_L = sum(Xs_L(:)/(Gamma_iL(:) - 1.0_wp)) - gamma_R = sum(Xs_R(:)/(Gamma_iR(:) - 1.0_wp)) - else if (chem_params%gamma_method == 2) then - !> gamma_method = 2: c_p / c_v where c_p, c_v are specific heats. - call get_mixture_specific_heat_cp_mass(T_L, Ys_L, Cp_L) - call get_mixture_specific_heat_cp_mass(T_R, Ys_R, Cp_R) - call get_mixture_specific_heat_cv_mass(T_L, Ys_L, Cv_L) - call get_mixture_specific_heat_cv_mass(T_R, Ys_R, Cv_R) - - Gamm_L = Cp_L/Cv_L; Gamm_R = Cp_R/Cv_R - gamma_L = 1.0_wp/(Gamm_L - 1.0_wp); gamma_R = 1.0_wp/(Gamm_R - 1.0_wp) - end if - - call get_mixture_energy_mass(T_L, Ys_L, E_L) - call get_mixture_energy_mass(T_R, Ys_R, E_R) - - E_L = rho_L*E_L + 5.e-1*rho_L*vel_L_rms - E_R = rho_R*E_R + 5.e-1*rho_R*vel_R_rms - H_L = (E_L + pres_L)/rho_L - H_R = (E_R + pres_R)/rho_R - else - E_L = gamma_L*pres_L + pi_inf_L + 5.e-1*rho_L*vel_L_rms + qv_L - E_R = gamma_R*pres_R + pi_inf_R + 5.e-1*rho_R*vel_R_rms + qv_R - - H_L = (E_L + pres_L)/rho_L - H_R = (E_R + pres_R)/rho_R - end if - - ! ENERGY ADJUSTMENTS FOR HYPOELASTIC ENERGY - if (hypoelasticity) then - $:GPU_LOOP(parallelism='[seq]') - do i = 1, strxe - strxb + 1 - tau_e_L(i) = qL_prim_rs${XYZ}$_vf(j, k, l, strxb - 1 + i) - tau_e_R(i) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, strxb - 1 + i) - end do - G_L = 0._wp - G_R = 0._wp - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_fluids - G_L = G_L + alpha_L(i)*Gs_rs(i) - G_R = G_R + alpha_R(i)*Gs_rs(i) - end do - $:GPU_LOOP(parallelism='[seq]') - do i = 1, strxe - strxb + 1 - ! Elastic contribution to energy if G large enough - if ((G_L > verysmall) .and. (G_R > verysmall)) then - E_L = E_L + (tau_e_L(i)*tau_e_L(i))/(4._wp*G_L) - E_R = E_R + (tau_e_R(i)*tau_e_R(i))/(4._wp*G_R) - ! Additional terms in 2D and 3D - if ((i == 2) .or. (i == 4) .or. (i == 5)) then - E_L = E_L + (tau_e_L(i)*tau_e_L(i))/(4._wp*G_L) - E_R = E_R + (tau_e_R(i)*tau_e_R(i))/(4._wp*G_R) - end if - end if - end do - end if - - ! ENERGY ADJUSTMENTS FOR HYPERELASTIC ENERGY - if (hyperelasticity) then - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_dims - xi_field_L(i) = qL_prim_rs${XYZ}$_vf(j, k, l, xibeg - 1 + i) - xi_field_R(i) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, xibeg - 1 + i) - end do - G_L = 0._wp - G_R = 0._wp - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_fluids - ! Mixture left and right shear modulus - G_L = G_L + alpha_L(i)*Gs_rs(i) - G_R = G_R + alpha_R(i)*Gs_rs(i) - end do - ! Elastic contribution to energy if G large enough - if (G_L > verysmall .and. G_R > verysmall) then - E_L = E_L + G_L*qL_prim_rs${XYZ}$_vf(j, k, l, xiend + 1) - E_R = E_R + G_R*qR_prim_rs${XYZ}$_vf(j + 1, k, l, xiend + 1) - end if - $:GPU_LOOP(parallelism='[seq]') - do i = 1, b_size - 1 - tau_e_L(i) = qL_prim_rs${XYZ}$_vf(j, k, l, strxb - 1 + i) - tau_e_R(i) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, strxb - 1 + i) - end do - end if - - H_L = (E_L + pres_L)/rho_L - H_R = (E_R + pres_R)/rho_R - - @:compute_average_state() - - call s_compute_speed_of_sound(pres_L, rho_L, gamma_L, pi_inf_L, H_L, alpha_L, & - vel_L_rms, 0._wp, c_L, qv_L) - - call s_compute_speed_of_sound(pres_R, rho_R, gamma_R, pi_inf_R, H_R, alpha_R, & - vel_R_rms, 0._wp, c_R, qv_R) - - !> The computation of c_avg does not require all the variables, and therefore the non '_avg' - ! variables are placeholders to call the subroutine. - call s_compute_speed_of_sound(pres_R, rho_avg, gamma_avg, pi_inf_R, H_avg, alpha_R, & - vel_avg_rms, c_sum_Yi_Phi, c_avg, qv_avg) - - if (viscous) then - if (chemistry) then - call compute_viscosity_and_inversion(T_L, Ys_L, T_R, Ys_R, Re_L(1), Re_R(1)) - end if - $:GPU_LOOP(parallelism='[seq]') - do i = 1, 2 - Re_avg_rs${XYZ}$_vf(j, k, l, i) = 2._wp/(1._wp/Re_L(i) + 1._wp/Re_R(i)) - end do - end if - - ! Low Mach correction - if (low_Mach == 2) then - @:compute_low_Mach_correction() - end if - - if (wave_speeds == 1) then - if (elasticity) then - s_L = min(vel_L(dir_idx(1)) - sqrt(c_L*c_L + & - (((4._wp*G_L)/3._wp) + tau_e_L(dir_idx_tau(1)))/rho_L), vel_R(dir_idx(1)) - sqrt(c_R*c_R + & - (((4._wp*G_R)/3._wp) + tau_e_R(dir_idx_tau(1)))/rho_R)) - s_R = max(vel_R(dir_idx(1)) + sqrt(c_R*c_R + & - (((4._wp*G_R)/3._wp) + tau_e_R(dir_idx_tau(1)))/rho_R), vel_L(dir_idx(1)) + sqrt(c_L*c_L + & - (((4._wp*G_L)/3._wp) + tau_e_L(dir_idx_tau(1)))/rho_L)) - s_S = (pres_R - tau_e_R(dir_idx_tau(1)) - pres_L + & - tau_e_L(dir_idx_tau(1)) + rho_L*vel_L(dir_idx(1))*(s_L - vel_L(dir_idx(1))) - & - rho_R*vel_R(dir_idx(1))*(s_R - vel_R(dir_idx(1))))/(rho_L*(s_L - vel_L(dir_idx(1))) - & - rho_R*(s_R - vel_R(dir_idx(1)))) - else - s_L = min(vel_L(dir_idx(1)) - c_L, vel_R(dir_idx(1)) - c_R) - s_R = max(vel_R(dir_idx(1)) + c_R, vel_L(dir_idx(1)) + c_L) - s_S = (pres_R - pres_L + rho_L*vel_L(dir_idx(1))* & - (s_L - vel_L(dir_idx(1))) - rho_R*vel_R(dir_idx(1))*(s_R - vel_R(dir_idx(1)))) & - /(rho_L*(s_L - vel_L(dir_idx(1))) - rho_R*(s_R - vel_R(dir_idx(1)))) - - end if - elseif (wave_speeds == 2) then - pres_SL = 5.e-1_wp*(pres_L + pres_R + rho_avg*c_avg* & - (vel_L(dir_idx(1)) - & - vel_R(dir_idx(1)))) - - pres_SR = pres_SL - - Ms_L = max(1._wp, sqrt(1._wp + ((5.e-1_wp + gamma_L)/(1._wp + gamma_L))* & - (pres_SL/pres_L - 1._wp)*pres_L/ & - ((pres_L + pi_inf_L/(1._wp + gamma_L))))) - Ms_R = max(1._wp, sqrt(1._wp + ((5.e-1_wp + gamma_R)/(1._wp + gamma_R))* & - (pres_SR/pres_R - 1._wp)*pres_R/ & - ((pres_R + pi_inf_R/(1._wp + gamma_R))))) - - s_L = vel_L(dir_idx(1)) - c_L*Ms_L - s_R = vel_R(dir_idx(1)) + c_R*Ms_R - - s_S = 5.e-1_wp*((vel_L(dir_idx(1)) + vel_R(dir_idx(1))) + & - (pres_L - pres_R)/ & - (rho_avg*c_avg)) - end if - - ! follows Einfeldt et al. - ! s_M/P = min/max(0.,s_L/R) - s_M = min(0._wp, s_L); s_P = max(0._wp, s_R) - - ! goes with q_star_L/R = xi_L/R * (variable) - ! xi_L/R = ( ( s_L/R - u_L/R )/(s_L/R - s_star) ) - xi_L = (s_L - vel_L(dir_idx(1)))/(s_L - s_S) - xi_R = (s_R - vel_R(dir_idx(1)))/(s_R - s_S) - - ! goes with numerical velocity in x/y/z directions - ! xi_P/M = 0.5 +/m sgn(0.5,s_star) - xi_M = (5.e-1_wp + sign(5.e-1_wp, s_S)) - xi_P = (5.e-1_wp - sign(5.e-1_wp, s_S)) - - ! Low Mach correction - if (low_Mach == 1) then - @:compute_low_Mach_correction() - else - pcorr = 0._wp - end if - - ! COMPUTING THE HLLC FLUXES - ! MASS FLUX. - $:GPU_LOOP(parallelism='[seq]') - do i = 1, contxe - flux_rs${XYZ}$_vf(j, k, l, i) = & - xi_M*qL_prim_rs${XYZ}$_vf(j, k, l, i) & - *(vel_L(dir_idx(1)) + s_M*(xi_L - 1._wp)) & - + xi_P*qR_prim_rs${XYZ}$_vf(j + 1, k, l, i) & - *(vel_R(dir_idx(1)) + s_P*(xi_R - 1._wp)) - end do - - ! MOMENTUM FLUX. - ! f = \rho u u - \sigma, q = \rho u, q_star = \xi * \rho*(s_star, v, w) - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_dims - flux_rs${XYZ}$_vf(j, k, l, contxe + dir_idx(i)) = & - xi_M*(rho_L*(vel_L(dir_idx(1))* & - vel_L(dir_idx(i)) + & - s_M*(xi_L*(dir_flg(dir_idx(i))*s_S + & - (1._wp - dir_flg(dir_idx(i)))* & - vel_L(dir_idx(i))) - vel_L(dir_idx(i)))) + & - dir_flg(dir_idx(i))*(pres_L)) & - + xi_P*(rho_R*(vel_R(dir_idx(1))* & - vel_R(dir_idx(i)) + & - s_P*(xi_R*(dir_flg(dir_idx(i))*s_S + & - (1._wp - dir_flg(dir_idx(i)))* & - vel_R(dir_idx(i))) - vel_R(dir_idx(i)))) + & - dir_flg(dir_idx(i))*(pres_R)) & - + (s_M/s_L)*(s_P/s_R)*dir_flg(dir_idx(i))*pcorr - end do - - ! ENERGY FLUX. - ! f = u*(E-\sigma), q = E, q_star = \xi*E+(s-u)(\rho s_star - \sigma/(s-u)) - flux_rs${XYZ}$_vf(j, k, l, E_idx) = & - xi_M*(vel_L(dir_idx(1))*(E_L + pres_L) + & - s_M*(xi_L*(E_L + (s_S - vel_L(dir_idx(1)))* & - (rho_L*s_S + pres_L/ & - (s_L - vel_L(dir_idx(1))))) - E_L)) & - + xi_P*(vel_R(dir_idx(1))*(E_R + pres_R) + & - s_P*(xi_R*(E_R + (s_S - vel_R(dir_idx(1)))* & - (rho_R*s_S + pres_R/ & - (s_R - vel_R(dir_idx(1))))) - E_R)) & - + (s_M/s_L)*(s_P/s_R)*pcorr*s_S - - ! ELASTICITY. Elastic shear stress additions for the momentum and energy flux - if (elasticity) then - flux_ene_e = 0._wp - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_dims - ! MOMENTUM ELASTIC FLUX. - flux_rs${XYZ}$_vf(j, k, l, contxe + dir_idx(i)) = & - flux_rs${XYZ}$_vf(j, k, l, contxe + dir_idx(i)) & - - xi_M*tau_e_L(dir_idx_tau(i)) - xi_P*tau_e_R(dir_idx_tau(i)) - ! ENERGY ELASTIC FLUX. - flux_ene_e = flux_ene_e - & - xi_M*(vel_L(dir_idx(i))*tau_e_L(dir_idx_tau(i)) + & - s_M*(xi_L*((s_S - vel_L(i))*(tau_e_L(dir_idx_tau(i))/(s_L - vel_L(i)))))) - & - xi_P*(vel_R(dir_idx(i))*tau_e_R(dir_idx_tau(i)) + & - s_P*(xi_R*((s_S - vel_R(i))*(tau_e_R(dir_idx_tau(i))/(s_R - vel_R(i)))))) - end do - flux_rs${XYZ}$_vf(j, k, l, E_idx) = flux_rs${XYZ}$_vf(j, k, l, E_idx) + flux_ene_e - end if - - ! HYPOELASTIC STRESS EVOLUTION FLUX. - if (hypoelasticity) then - $:GPU_LOOP(parallelism='[seq]') - do i = 1, strxe - strxb + 1 - flux_rs${XYZ}$_vf(j, k, l, strxb - 1 + i) = & - xi_M*(s_S/(s_L - s_S))*(s_L*rho_L*tau_e_L(i) - rho_L*vel_L(dir_idx(1))*tau_e_L(i)) + & - xi_P*(s_S/(s_R - s_S))*(s_R*rho_R*tau_e_R(i) - rho_R*vel_R(dir_idx(1))*tau_e_R(i)) - end do - end if - - ! VOLUME FRACTION FLUX. - $:GPU_LOOP(parallelism='[seq]') - do i = advxb, advxe - flux_rs${XYZ}$_vf(j, k, l, i) = & - xi_M*qL_prim_rs${XYZ}$_vf(j, k, l, i) & - *(vel_L(dir_idx(1)) + s_M*(xi_L - 1._wp)) & - + xi_P*qR_prim_rs${XYZ}$_vf(j + 1, k, l, i) & - *(vel_R(dir_idx(1)) + s_P*(xi_R - 1._wp)) - end do - - ! VOLUME FRACTION SOURCE FLUX. - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_dims - vel_src_rs${XYZ}$_vf(j, k, l, dir_idx(i)) = & - xi_M*(vel_L(dir_idx(i)) + & - dir_flg(dir_idx(i))* & - s_M*(xi_L - 1._wp)) & - + xi_P*(vel_R(dir_idx(i)) + & - dir_flg(dir_idx(i))* & - s_P*(xi_R - 1._wp)) - end do - - ! COLOR FUNCTION FLUX - if (surface_tension) then - flux_rs${XYZ}$_vf(j, k, l, c_idx) = & - xi_M*qL_prim_rs${XYZ}$_vf(j, k, l, c_idx) & - *(vel_L(dir_idx(1)) + s_M*(xi_L - 1._wp)) & - + xi_P*qR_prim_rs${XYZ}$_vf(j + 1, k, l, c_idx) & - *(vel_R(dir_idx(1)) + s_P*(xi_R - 1._wp)) - end if - - ! REFERENCE MAP FLUX. - if (hyperelasticity) then - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_dims - flux_rs${XYZ}$_vf(j, k, l, xibeg - 1 + i) = & - xi_M*(s_S/(s_L - s_S))*(s_L*rho_L*xi_field_L(i) & - - rho_L*vel_L(dir_idx(1))*xi_field_L(i)) + & - xi_P*(s_S/(s_R - s_S))*(s_R*rho_R*xi_field_R(i) & - - rho_R*vel_R(dir_idx(1))*xi_field_R(i)) - end do - end if - - flux_src_rs${XYZ}$_vf(j, k, l, advxb) = vel_src_rs${XYZ}$_vf(j, k, l, dir_idx(1)) - - if (chemistry) then - $:GPU_LOOP(parallelism='[seq]') - do i = chemxb, chemxe - Y_L = qL_prim_rs${XYZ}$_vf(j, k, l, i) - Y_R = qR_prim_rs${XYZ}$_vf(j + 1, k, l, i) - - flux_rs${XYZ}$_vf(j, k, l, i) = xi_M*rho_L*Y_L*(vel_L(dir_idx(1)) + s_M*(xi_L - 1._wp)) & - + xi_P*rho_R*Y_R*(vel_R(dir_idx(1)) + s_P*(xi_R - 1._wp)) - flux_src_rs${XYZ}$_vf(j, k, l, i) = 0.0_wp - end do - end if - - ! Geometrical source flux for cylindrical coordinates - #:if (NORM_DIR == 2) - if (cyl_coord) then - !Substituting the advective flux into the inviscid geometrical source flux - $:GPU_LOOP(parallelism='[seq]') - do i = 1, E_idx - flux_gsrc_rs${XYZ}$_vf(j, k, l, i) = flux_rs${XYZ}$_vf(j, k, l, i) - end do - ! Recalculating the radial momentum geometric source flux - flux_gsrc_rs${XYZ}$_vf(j, k, l, contxe + dir_idx(1)) = & - xi_M*(rho_L*(vel_L(dir_idx(1))* & - vel_L(dir_idx(1)) + & - s_M*(xi_L*(dir_flg(dir_idx(1))*s_S + & - (1._wp - dir_flg(dir_idx(1)))* & - vel_L(dir_idx(1))) - vel_L(dir_idx(1))))) & - + xi_P*(rho_R*(vel_R(dir_idx(1))* & - vel_R(dir_idx(1)) + & - s_P*(xi_R*(dir_flg(dir_idx(1))*s_S + & - (1._wp - dir_flg(dir_idx(1)))* & - vel_R(dir_idx(1))) - vel_R(dir_idx(1))))) - ! Geometrical source of the void fraction(s) is zero - $:GPU_LOOP(parallelism='[seq]') - do i = advxb, advxe - flux_gsrc_rs${XYZ}$_vf(j, k, l, i) = 0._wp - end do - end if - #:endif - #:if (NORM_DIR == 3) - if (grid_geometry == 3) then - $:GPU_LOOP(parallelism='[seq]') - do i = 1, sys_size - flux_gsrc_rs${XYZ}$_vf(j, k, l, i) = 0._wp - end do - - flux_gsrc_rs${XYZ}$_vf(j, k, l, momxb + 1) = & - -xi_M*(rho_L*(vel_L(dir_idx(1))* & - vel_L(dir_idx(1)) + & - s_M*(xi_L*(dir_flg(dir_idx(1))*s_S + & - (1._wp - dir_flg(dir_idx(1)))* & - vel_L(dir_idx(1))) - vel_L(dir_idx(1))))) & - - xi_P*(rho_R*(vel_R(dir_idx(1))* & - vel_R(dir_idx(1)) + & - s_P*(xi_R*(dir_flg(dir_idx(1))*s_S + & - (1._wp - dir_flg(dir_idx(1)))* & - vel_R(dir_idx(1))) - vel_R(dir_idx(1))))) - flux_gsrc_rs${XYZ}$_vf(j, k, l, momxe) = flux_rs${XYZ}$_vf(j, k, l, momxb + 1) - - end if - #:endif - - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - end if - end if - #:endfor - ! Computing HLLC flux and source flux for Euler system of equations - - if (viscous .or. dummy) then - if (weno_Re_flux) then - call s_compute_viscous_source_flux( & - qL_prim_vf(momxb:momxe), & - dqL_prim_dx_vf(momxb:momxe), & - dqL_prim_dy_vf(momxb:momxe), & - dqL_prim_dz_vf(momxb:momxe), & - qR_prim_vf(momxb:momxe), & - dqR_prim_dx_vf(momxb:momxe), & - dqR_prim_dy_vf(momxb:momxe), & - dqR_prim_dz_vf(momxb:momxe), & - flux_src_vf, norm_dir, ix, iy, iz) - else - call s_compute_viscous_source_flux( & - q_prim_vf(momxb:momxe), & - dqL_prim_dx_vf(momxb:momxe), & - dqL_prim_dy_vf(momxb:momxe), & - dqL_prim_dz_vf(momxb:momxe), & - q_prim_vf(momxb:momxe), & - dqR_prim_dx_vf(momxb:momxe), & - dqR_prim_dy_vf(momxb:momxe), & - dqR_prim_dz_vf(momxb:momxe), & - flux_src_vf, norm_dir, ix, iy, iz) - end if - end if - - if (surface_tension) then - call s_compute_capillary_source_flux( & - vel_src_rsx_vf, & - vel_src_rsy_vf, & - vel_src_rsz_vf, & - flux_src_vf, & - norm_dir, isx, isy, isz) - end if - - call s_finalize_riemann_solver(flux_vf, flux_src_vf, & - flux_gsrc_vf, & - norm_dir) - - end subroutine s_hllc_riemann_solver - - !> HLLD Riemann solver resolves 5 of the 7 waves of MHD equations: - !! 1 entropy wave, 2 Alfvén waves, 2 fast magnetosonic waves. - subroutine s_hlld_riemann_solver(qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, & - dqL_prim_dx_vf, dqL_prim_dy_vf, dqL_prim_dz_vf, & - qL_prim_vf, & - qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf, & - dqR_prim_dx_vf, dqR_prim_dy_vf, dqR_prim_dz_vf, & - qR_prim_vf, & - q_prim_vf, & - flux_vf, flux_src_vf, flux_gsrc_vf, & - norm_dir, ix, iy, iz) - - real(wp), dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:), intent(inout) :: qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, & - qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf - - type(scalar_field), allocatable, dimension(:), intent(inout) :: dqL_prim_dx_vf, dqR_prim_dx_vf, & - dqL_prim_dy_vf, dqR_prim_dy_vf, & - dqL_prim_dz_vf, dqR_prim_dz_vf - - type(scalar_field), allocatable, dimension(:), intent(inout) :: qL_prim_vf, qR_prim_vf - - type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf - type(scalar_field), dimension(sys_size), intent(inout) :: flux_vf, flux_src_vf, flux_gsrc_vf - - integer, intent(in) :: norm_dir - type(int_bounds_info), intent(in) :: ix, iy, iz - - ! Local variables: - #:if not MFC_CASE_OPTIMIZATION and USING_AMD - real(wp), dimension(3) :: alpha_L, alpha_R, alpha_rho_L, alpha_rho_R - #:else - real(wp), dimension(num_fluids) :: alpha_L, alpha_R, alpha_rho_L, alpha_rho_R - #:endif - type(riemann_states_vec3) :: vel - type(riemann_states) :: rho, pres, E, H_no_mag - type(riemann_states) :: gamma, pi_inf, qv - type(riemann_states) :: vel_rms - - type(riemann_states_vec3) :: B - type(riemann_states) :: c, c_fast, pres_mag - - ! HLLD speeds and intermediate state variables: - real(wp) :: s_L, s_R, s_M, s_starL, s_starR - real(wp) :: pTot_L, pTot_R, p_star, rhoL_star, rhoR_star, E_starL, E_starR - - real(wp), dimension(7) :: U_L, U_R, U_starL, U_starR, U_doubleL, U_doubleR - real(wp), dimension(7) :: F_L, F_R, F_starL, F_starR, F_hlld - - ! Indices for U and F: (rho, rho*vel(1), rho*vel(2), rho*vel(3), By, Bz, E) - ! Note: vel and B are permutated, so vel(1) is the normal velocity, and x is the normal direction - ! Note: Bx is omitted as the magnetic flux is always zero in the normal direction - - real(wp) :: sqrt_rhoL_star, sqrt_rhoR_star, denom_ds, sign_Bx - real(wp) :: vL_star, vR_star, wL_star, wR_star - real(wp) :: v_double, w_double, By_double, Bz_double, E_doubleL, E_doubleR, E_double - - integer :: i, j, k, l - - call s_populate_riemann_states_variables_buffers( & - qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, dqL_prim_dx_vf, & - dqL_prim_dy_vf, dqL_prim_dz_vf, & - qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf, dqR_prim_dx_vf, & - dqR_prim_dy_vf, dqR_prim_dz_vf, & - norm_dir, ix, iy, iz) - - call s_initialize_riemann_solver( & - flux_src_vf, norm_dir) - - #:for NORM_DIR, XYZ in [(1, 'x'), (2, 'y'), (3, 'z')] - if (norm_dir == ${NORM_DIR}$) then - $:GPU_PARALLEL_LOOP(collapse=3, private='[alpha_rho_L, alpha_rho_R, vel, alpha_L, alpha_R, rho, pres,E, H_no_mag, gamma, pi_inf, qv, vel_rms, B, c, c_fast, pres_mag, U_L, U_R, U_starL, U_starR, U_doubleL, U_doubleR, F_L, F_R, F_starL, F_starR, F_hlld, s_L, s_R, s_M, s_starL, s_starR, pTot_L, pTot_R, p_star, rhoL_star, rhoR_star, E_starL, E_starR, sqrt_rhoL_star, sqrt_rhoR_star, denom_ds, sign_Bx, vL_star, vR_star, wL_star, wR_star, v_double, w_double, By_double, Bz_double, E_doubleL, E_doubleR, E_double]', copyin='[norm_dir]') - do l = is3%beg, is3%end - do k = is2%beg, is2%end - do j = is1%beg, is1%end - - ! (1) Extract the left/right primitive states - do i = 1, contxe - alpha_rho_L(i) = qL_prim_rs${XYZ}$_vf(j, k, l, i) - alpha_rho_R(i) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, i) - end do - - ! NOTE: unlike HLL & HLLC, vel_L here is permutated by dir_idx for simpler logic - do i = 1, num_vels - vel%L(i) = qL_prim_rs${XYZ}$_vf(j, k, l, contxe + dir_idx(i)) - vel%R(i) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, contxe + dir_idx(i)) - end do - - vel_rms%L = sum(vel%L**2._wp) - vel_rms%R = sum(vel%R**2._wp) - - do i = 1, num_fluids - alpha_L(i) = qL_prim_rs${XYZ}$_vf(j, k, l, E_idx + i) - alpha_R(i) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx + i) - end do - - pres%L = qL_prim_rs${XYZ}$_vf(j, k, l, E_idx) - pres%R = qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx) - - ! NOTE: unlike HLL, Bx, By, Bz are permutated by dir_idx for simpler logic - if (mhd) then - if (n == 0) then ! 1D: constant Bx; By, Bz as variables; only in x so not permutated - B%L = [Bx0, qL_prim_rs${XYZ}$_vf(j, k, l, B_idx%beg), qL_prim_rs${XYZ}$_vf(j, k, l, B_idx%beg + 1)] - B%R = [Bx0, qR_prim_rs${XYZ}$_vf(j + 1, k, l, B_idx%beg), qR_prim_rs${XYZ}$_vf(j + 1, k, l, B_idx%beg + 1)] - else ! 2D/3D: Bx, By, Bz as variables - B%L = [qL_prim_rs${XYZ}$_vf(j, k, l, B_idx%beg + dir_idx(1) - 1), & - qL_prim_rs${XYZ}$_vf(j, k, l, B_idx%beg + dir_idx(2) - 1), & - qL_prim_rs${XYZ}$_vf(j, k, l, B_idx%beg + dir_idx(3) - 1)] - B%R = [qR_prim_rs${XYZ}$_vf(j + 1, k, l, B_idx%beg + dir_idx(1) - 1), & - qR_prim_rs${XYZ}$_vf(j + 1, k, l, B_idx%beg + dir_idx(2) - 1), & - qR_prim_rs${XYZ}$_vf(j + 1, k, l, B_idx%beg + dir_idx(3) - 1)] - end if - end if - - ! Sum properties of all fluid components - rho%L = 0._wp; gamma%L = 0._wp; pi_inf%L = 0._wp; qv%L = 0._wp - rho%R = 0._wp; gamma%R = 0._wp; pi_inf%R = 0._wp; qv%R = 0._wp - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_fluids - rho%L = rho%L + alpha_rho_L(i) - gamma%L = gamma%L + alpha_L(i)*gammas(i) - pi_inf%L = pi_inf%L + alpha_L(i)*pi_infs(i) - qv%L = qv%L + alpha_rho_L(i)*qvs(i) - - rho%R = rho%R + alpha_rho_R(i) - gamma%R = gamma%R + alpha_R(i)*gammas(i) - pi_inf%R = pi_inf%R + alpha_R(i)*pi_infs(i) - qv%R = qv%R + alpha_rho_R(i)*qvs(i) - end do - - pres_mag%L = 0.5_wp*sum(B%L**2._wp) - pres_mag%R = 0.5_wp*sum(B%R**2._wp) - E%L = gamma%L*pres%L + pi_inf%L + 0.5_wp*rho%L*vel_rms%L + qv%L + pres_mag%L - E%R = gamma%R*pres%R + pi_inf%R + 0.5_wp*rho%R*vel_rms%R + qv%R + pres_mag%R ! includes magnetic energy - H_no_mag%L = (E%L + pres%L - pres_mag%L)/rho%L - H_no_mag%R = (E%R + pres%R - pres_mag%R)/rho%R ! stagnation enthalpy here excludes magnetic energy (only used to find speed of sound) - - ! (2) Compute fast wave speeds - call s_compute_speed_of_sound(pres%L, rho%L, gamma%L, pi_inf%L, H_no_mag%L, alpha_L, vel_rms%L, 0._wp, c%L, qv%L) - call s_compute_speed_of_sound(pres%R, rho%R, gamma%R, pi_inf%R, H_no_mag%R, alpha_R, vel_rms%R, 0._wp, c%R, qv%R) - call s_compute_fast_magnetosonic_speed(rho%L, c%L, B%L, norm_dir, c_fast%L, H_no_mag%L) - call s_compute_fast_magnetosonic_speed(rho%R, c%R, B%R, norm_dir, c_fast%R, H_no_mag%R) - - ! (3) Compute contact speed s_M [Miyoshi Equ. (38)] - s_L = min(vel%L(1) - c_fast%L, vel%R(1) - c_fast%R) - s_R = max(vel%R(1) + c_fast%R, vel%L(1) + c_fast%L) - - pTot_L = pres%L + pres_mag%L - pTot_R = pres%R + pres_mag%R - - s_M = (((s_R - vel%R(1))*rho%R*vel%R(1) - & - (s_L - vel%L(1))*rho%L*vel%L(1) - pTot_R + pTot_L)/ & - ((s_R - vel%R(1))*rho%R - (s_L - vel%L(1))*rho%L)) - - ! (4) Compute star state variables - rhoL_star = rho%L*(s_L - vel%L(1))/(s_L - s_M) - rhoR_star = rho%R*(s_R - vel%R(1))/(s_R - s_M) - p_star = pTot_L + rho%L*(s_L - vel%L(1))*(s_M - vel%L(1))/(s_L - s_M) - E_starL = ((s_L - vel%L(1))*E%L - pTot_L*vel%L(1) + p_star*s_M)/(s_L - s_M) - E_starR = ((s_R - vel%R(1))*E%R - pTot_R*vel%R(1) + p_star*s_M)/(s_R - s_M) - - ! (5) Compute left/right state vectors and fluxes - U_L = [rho%L, rho%L*vel%L(1:3), B%L(2:3), E%L] - U_starL = [rhoL_star, rhoL_star*s_M, rhoL_star*vel%L(2:3), B%L(2:3), E_starL] - U_R = [rho%R, rho%R*vel%R(1:3), B%R(2:3), E%R] - U_starR = [rhoR_star, rhoR_star*s_M, rhoR_star*vel%R(2:3), B%R(2:3), E_starR] - - ! Compute the left/right fluxes - F_L(1) = U_L(2) - F_L(2) = U_L(2)*vel%L(1) - B%L(1)*B%L(1) + pTot_L - F_L(3:4) = U_L(2)*vel%L(2:3) - B%L(1)*B%L(2:3) - F_L(5:6) = vel%L(1)*B%L(2:3) - vel%L(2:3)*B%L(1) - F_L(7) = (E%L + pTot_L)*vel%L(1) - B%L(1)*(vel%L(1)*B%L(1) + vel%L(2)*B%L(2) + vel%L(3)*B%L(3)) - - F_R(1) = U_R(2) - F_R(2) = U_R(2)*vel%R(1) - B%R(1)*B%R(1) + pTot_R - F_R(3:4) = U_R(2)*vel%R(2:3) - B%R(1)*B%R(2:3) - F_R(5:6) = vel%R(1)*B%R(2:3) - vel%R(2:3)*B%R(1) - F_R(7) = (E%R + pTot_R)*vel%R(1) - B%R(1)*(vel%R(1)*B%R(1) + vel%R(2)*B%R(2) + vel%R(3)*B%R(3)) - ! Compute the star flux using HLL relation - F_starL = F_L + s_L*(U_starL - U_L) - F_starR = F_R + s_R*(U_starR - U_R) - ! Compute the rotational (Alfvén) speeds - s_starL = s_M - abs(B%L(1))/sqrt(rhoL_star) - s_starR = s_M + abs(B%L(1))/sqrt(rhoR_star) - ! Compute the double–star states [Miyoshi Eqns. (59)-(62)] - sqrt_rhoL_star = sqrt(rhoL_star); sqrt_rhoR_star = sqrt(rhoR_star) - vL_star = vel%L(2); wL_star = vel%L(3) - vR_star = vel%R(2); wR_star = vel%R(3) - - ! (6) Compute the double–star states [Miyoshi Eqns. (59)-(62)] - denom_ds = sqrt_rhoL_star + sqrt_rhoR_star - sign_Bx = sign(1._wp, B%L(1)) - v_double = (sqrt_rhoL_star*vL_star + sqrt_rhoR_star*vR_star + (B%R(2) - B%L(2))*sign_Bx)/denom_ds - w_double = (sqrt_rhoL_star*wL_star + sqrt_rhoR_star*wR_star + (B%R(3) - B%L(3))*sign_Bx)/denom_ds - By_double = (sqrt_rhoL_star*B%R(2) + sqrt_rhoR_star*B%L(2) + sqrt_rhoL_star*sqrt_rhoR_star*(vR_star - vL_star)*sign_Bx)/denom_ds - Bz_double = (sqrt_rhoL_star*B%R(3) + sqrt_rhoR_star*B%L(3) + sqrt_rhoL_star*sqrt_rhoR_star*(wR_star - wL_star)*sign_Bx)/denom_ds - - E_doubleL = E_starL - sqrt_rhoL_star*((vL_star*B%L(2) + wL_star*B%L(3)) - (v_double*By_double + w_double*Bz_double))*sign_Bx - E_doubleR = E_starR + sqrt_rhoR_star*((vR_star*B%R(2) + wR_star*B%R(3)) - (v_double*By_double + w_double*Bz_double))*sign_Bx - E_double = 0.5_wp*(E_doubleL + E_doubleR) - - U_doubleL = [rhoL_star, rhoL_star*s_M, rhoL_star*v_double, rhoL_star*w_double, By_double, Bz_double, E_double] - U_doubleR = [rhoR_star, rhoR_star*s_M, rhoR_star*v_double, rhoR_star*w_double, By_double, Bz_double, E_double] - - ! (11) Choose HLLD flux based on wave-speed regions - if (0.0_wp <= s_L) then - F_hlld = F_L - else if (0.0_wp <= s_starL) then - F_hlld = F_L + s_L*(U_starL - U_L) - else if (0.0_wp <= s_M) then - F_hlld = F_starL + s_starL*(U_doubleL - U_starL) - else if (0.0_wp <= s_starR) then - F_hlld = F_starR + s_starR*(U_doubleR - U_starR) - else if (0.0_wp <= s_R) then - F_hlld = F_R + s_R*(U_starR - U_R) - else - F_hlld = F_R - end if - - ! (12) Reorder and write temporary variables to the flux array - ! Mass - flux_rs${XYZ}$_vf(j, k, l, 1) = F_hlld(1) ! TODO multi-component - ! Momentum - flux_rs${XYZ}$_vf(j, k, l, contxe + dir_idx(1)) = F_hlld(2) - flux_rs${XYZ}$_vf(j, k, l, contxe + dir_idx(2)) = F_hlld(3) - flux_rs${XYZ}$_vf(j, k, l, contxe + dir_idx(3)) = F_hlld(4) - ! Magnetic field - if (n == 0) then - flux_rs${XYZ}$_vf(j, k, l, B_idx%beg) = F_hlld(5) - flux_rs${XYZ}$_vf(j, k, l, B_idx%beg + 1) = F_hlld(6) - else - flux_rs${XYZ}$_vf(j, k, l, B_idx%beg + dir_idx(2) - 1) = F_hlld(5) - flux_rs${XYZ}$_vf(j, k, l, B_idx%beg + dir_idx(3) - 1) = F_hlld(6) - end if - ! Energy - flux_rs${XYZ}$_vf(j, k, l, E_idx) = F_hlld(7) - ! Partial fraction - $:GPU_LOOP(parallelism='[seq]') - do i = advxb, advxe - flux_rs${XYZ}$_vf(j, k, l, i) = 0._wp ! TODO multi-component (zero for now) - end do - - flux_src_rs${XYZ}$_vf(j, k, l, advxb) = 0._wp - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - end if - #:endfor - - call s_finalize_riemann_solver(flux_vf, flux_src_vf, flux_gsrc_vf, & - norm_dir) - end subroutine s_hlld_riemann_solver - - !> The computation of parameters, the allocation of memory, - !! the association of pointers and/or the execution of any - !! other procedures that are necessary to setup the module. - impure subroutine s_initialize_riemann_solvers_module - - ! Allocating the variables that will be utilized to formulate the - ! left, right, and average states of the Riemann problem, as well - ! the Riemann problem solution - integer :: i, j - - @:ALLOCATE(Gs_rs(1:num_fluids)) - - do i = 1, num_fluids - Gs_rs(i) = fluid_pp(i)%G - end do - $:GPU_UPDATE(device='[Gs_rs]') - - if (viscous) then - @:ALLOCATE(Res_gs(1:2, 1:Re_size_max)) - end if - - if (viscous) then - do i = 1, 2 - do j = 1, Re_size(i) - Res_gs(i, j) = fluid_pp(Re_idx(i, j))%Re(i) - end do - end do - $:GPU_UPDATE(device='[Res_gs,Re_idx,Re_size]') - end if - - $:GPU_ENTER_DATA(copyin='[is1,is2,is3,isx,isy,isz]') - - is1%beg = -1; is2%beg = 0; is3%beg = 0 - is1%end = m; is2%end = n; is3%end = p - - @:ALLOCATE(flux_rsx_vf(is1%beg:is1%end, & - is2%beg:is2%end, & - is3%beg:is3%end, 1:sys_size)) - @:ALLOCATE(flux_gsrc_rsx_vf(is1%beg:is1%end, & - is2%beg:is2%end, & - is3%beg:is3%end, 1:sys_size)) - @:ALLOCATE(flux_src_rsx_vf(is1%beg:is1%end, & - is2%beg:is2%end, & - is3%beg:is3%end, advxb:sys_size)) - @:ALLOCATE(vel_src_rsx_vf(is1%beg:is1%end, & - is2%beg:is2%end, & - is3%beg:is3%end, 1:num_vels)) - if (qbmm) then - @:ALLOCATE(mom_sp_rsx_vf(is1%beg:is1%end + 1, is2%beg:is2%end, is3%beg:is3%end, 1:4)) - end if - - if (viscous) then - @:ALLOCATE(Re_avg_rsx_vf(is1%beg:is1%end, & - is2%beg:is2%end, & - is3%beg:is3%end, 1:2)) - end if - - if (n == 0) return - - is1%beg = -1; is2%beg = 0; is3%beg = 0 - is1%end = n; is2%end = m; is3%end = p - - @:ALLOCATE(flux_rsy_vf(is1%beg:is1%end, & - is2%beg:is2%end, & - is3%beg:is3%end, 1:sys_size)) - @:ALLOCATE(flux_gsrc_rsy_vf(is1%beg:is1%end, & - is2%beg:is2%end, & - is3%beg:is3%end, 1:sys_size)) - @:ALLOCATE(flux_src_rsy_vf(is1%beg:is1%end, & - is2%beg:is2%end, & - is3%beg:is3%end, advxb:sys_size)) - @:ALLOCATE(vel_src_rsy_vf(is1%beg:is1%end, & - is2%beg:is2%end, & - is3%beg:is3%end, 1:num_vels)) - - if (qbmm) then - @:ALLOCATE(mom_sp_rsy_vf(is1%beg:is1%end + 1, is2%beg:is2%end, is3%beg:is3%end, 1:4)) - end if - - if (viscous) then - @:ALLOCATE(Re_avg_rsy_vf(is1%beg:is1%end, & - is2%beg:is2%end, & - is3%beg:is3%end, 1:2)) - end if - - if (p == 0) return - - is1%beg = -1; is2%beg = 0; is3%beg = 0 - is1%end = p; is2%end = n; is3%end = m - - @:ALLOCATE(flux_rsz_vf(is1%beg:is1%end, & - is2%beg:is2%end, & - is3%beg:is3%end, 1:sys_size)) - @:ALLOCATE(flux_gsrc_rsz_vf(is1%beg:is1%end, & - is2%beg:is2%end, & - is3%beg:is3%end, 1:sys_size)) - @:ALLOCATE(flux_src_rsz_vf(is1%beg:is1%end, & - is2%beg:is2%end, & - is3%beg:is3%end, advxb:sys_size)) - @:ALLOCATE(vel_src_rsz_vf(is1%beg:is1%end, & - is2%beg:is2%end, & - is3%beg:is3%end, 1:num_vels)) - - if (qbmm) then - @:ALLOCATE(mom_sp_rsz_vf(is1%beg:is1%end + 1, is2%beg:is2%end, is3%beg:is3%end, 1:4)) - end if - - if (viscous) then - @:ALLOCATE(Re_avg_rsz_vf(is1%beg:is1%end, & - is2%beg:is2%end, & - is3%beg:is3%end, 1:2)) - end if - - end subroutine s_initialize_riemann_solvers_module - - !> The purpose of this subroutine is to populate the buffers - !! of the left and right Riemann states variables, depending - !! on the boundary conditions. - !! @param qL_prim_rsx_vf Left WENO-reconstructed cell-boundary values (x-dir) - !! @param qL_prim_rsy_vf Left WENO-reconstructed cell-boundary values (y-dir) - !! @param qL_prim_rsz_vf Left WENO-reconstructed cell-boundary values (z-dir) - !! @param dqL_prim_dx_vf The left WENO-reconstructed cell-boundary values of the - !! first-order x-dir spatial derivatives - !! @param dqL_prim_dy_vf The left WENO-reconstructed cell-boundary values of the - !! first-order y-dir spatial derivatives - !! @param dqL_prim_dz_vf The left WENO-reconstructed cell-boundary values of the - !! first-order z-dir spatial derivatives - !! @param qR_prim_rsx_vf Right WENO-reconstructed cell-boundary values (x-dir) - !! @param qR_prim_rsy_vf Right WENO-reconstructed cell-boundary values (y-dir) - !! @param qR_prim_rsz_vf Right WENO-reconstructed cell-boundary values (z-dir) - !! @param dqR_prim_dx_vf The right WENO-reconstructed cell-boundary values of the - !! first-order x-dir spatial derivatives - !! @param dqR_prim_dy_vf The right WENO-reconstructed cell-boundary values of the - !! first-order y-dir spatial derivatives - !! @param dqR_prim_dz_vf The right WENO-reconstructed cell-boundary values of the - !! first-order z-dir spatial derivatives - !! @param norm_dir Dir. splitting direction - !! @param ix Index bounds in the x-dir - !! @param iy Index bounds in the y-dir - !! @param iz Index bounds in the z-dir - subroutine s_populate_riemann_states_variables_buffers( & - qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, dqL_prim_dx_vf, & - dqL_prim_dy_vf, & - dqL_prim_dz_vf, & - qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf, dqR_prim_dx_vf, & - dqR_prim_dy_vf, & - dqR_prim_dz_vf, & - norm_dir, ix, iy, iz) - - real(wp), dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:), intent(inout) :: qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf - - type(scalar_field), & - allocatable, dimension(:), & - intent(inout) :: dqL_prim_dx_vf, dqR_prim_dx_vf, & - dqL_prim_dy_vf, dqR_prim_dy_vf, & - dqL_prim_dz_vf, dqR_prim_dz_vf - - integer, intent(in) :: norm_dir - type(int_bounds_info), intent(in) :: ix, iy, iz - - integer :: i, j, k, l !< Generic loop iterator - - if (norm_dir == 1) then - is1 = ix; is2 = iy; is3 = iz - dir_idx = (/1, 2, 3/); dir_flg = (/1._wp, 0._wp, 0._wp/) - elseif (norm_dir == 2) then - is1 = iy; is2 = ix; is3 = iz - dir_idx = (/2, 1, 3/); dir_flg = (/0._wp, 1._wp, 0._wp/) - else - is1 = iz; is2 = iy; is3 = ix - dir_idx = (/3, 1, 2/); dir_flg = (/0._wp, 0._wp, 1._wp/) - end if - - $:GPU_UPDATE(device='[is1,is2,is3]') - - if (elasticity) then - if (norm_dir == 1) then - dir_idx_tau = (/1, 2, 4/) - else if (norm_dir == 2) then - dir_idx_tau = (/3, 2, 5/) - else - dir_idx_tau = (/6, 4, 5/) - end if - end if - - isx = ix; isy = iy; isz = iz - ! for stuff in the same module - $:GPU_UPDATE(device='[isx,isy,isz]') - ! for stuff in different modules - $:GPU_UPDATE(device='[dir_idx,dir_flg,dir_idx_tau]') - - ! Population of Buffers in x-direction - if (norm_dir == 1) then - - if (bc_x%beg == BC_RIEMANN_EXTRAP) then ! Riemann state extrap. BC at beginning - $:GPU_PARALLEL_LOOP(collapse=3) - do i = 1, sys_size - do l = is3%beg, is3%end - do k = is2%beg, is2%end - qL_prim_rsx_vf(-1, k, l, i) = & - qR_prim_rsx_vf(0, k, l, i) - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - - if (viscous .or. dummy) then - $:GPU_PARALLEL_LOOP(collapse=3) - do i = momxb, momxe - do l = isz%beg, isz%end - do k = isy%beg, isy%end - - dqL_prim_dx_vf(i)%sf(-1, k, l) = & - dqR_prim_dx_vf(i)%sf(0, k, l) - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - - if (n > 0) then - $:GPU_PARALLEL_LOOP(collapse=3) - do i = momxb, momxe - do l = isz%beg, isz%end - do k = isy%beg, isy%end - - dqL_prim_dy_vf(i)%sf(-1, k, l) = & - dqR_prim_dy_vf(i)%sf(0, k, l) - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - - if (p > 0) then - $:GPU_PARALLEL_LOOP(collapse=3) - do i = momxb, momxe - do l = isz%beg, isz%end - do k = isy%beg, isy%end - - dqL_prim_dz_vf(i)%sf(-1, k, l) = & - dqR_prim_dz_vf(i)%sf(0, k, l) - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - end if - - end if - - end if - - end if - - if (bc_x%end == BC_RIEMANN_EXTRAP) then ! Riemann state extrap. BC at end - - $:GPU_PARALLEL_LOOP(collapse=3) - do i = 1, sys_size - do l = is3%beg, is3%end - do k = is2%beg, is2%end - qR_prim_rsx_vf(m + 1, k, l, i) = & - qL_prim_rsx_vf(m, k, l, i) - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - - if (viscous .or. dummy) then - - $:GPU_PARALLEL_LOOP(collapse=3) - do i = momxb, momxe - do l = isz%beg, isz%end - do k = isy%beg, isy%end - - dqR_prim_dx_vf(i)%sf(m + 1, k, l) = & - dqL_prim_dx_vf(i)%sf(m, k, l) - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - - if (n > 0) then - $:GPU_PARALLEL_LOOP(collapse=3) - do i = momxb, momxe - do l = isz%beg, isz%end - do k = isy%beg, isy%end - - dqR_prim_dy_vf(i)%sf(m + 1, k, l) = & - dqL_prim_dy_vf(i)%sf(m, k, l) - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - - if (p > 0) then - $:GPU_PARALLEL_LOOP(collapse=3) - do i = momxb, momxe - do l = isz%beg, isz%end - do k = isy%beg, isy%end - - dqR_prim_dz_vf(i)%sf(m + 1, k, l) = & - dqL_prim_dz_vf(i)%sf(m, k, l) - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - end if - - end if - - end if - - end if - ! END: Population of Buffers in x-direction - - ! Population of Buffers in y-direction - elseif (norm_dir == 2) then - - if (bc_y%beg == BC_RIEMANN_EXTRAP) then ! Riemann state extrap. BC at beginning - $:GPU_PARALLEL_LOOP(collapse=3) - do i = 1, sys_size - do l = is3%beg, is3%end - do k = is2%beg, is2%end - qL_prim_rsy_vf(-1, k, l, i) = & - qR_prim_rsy_vf(0, k, l, i) - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - - if (viscous .or. dummy) then - - $:GPU_PARALLEL_LOOP(collapse=3) - do i = momxb, momxe - do l = isz%beg, isz%end - do j = isx%beg, isx%end - dqL_prim_dx_vf(i)%sf(j, -1, l) = & - dqR_prim_dx_vf(i)%sf(j, 0, l) - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - - $:GPU_PARALLEL_LOOP(collapse=3) - do i = momxb, momxe - do l = isz%beg, isz%end - do j = isx%beg, isx%end - dqL_prim_dy_vf(i)%sf(j, -1, l) = & - dqR_prim_dy_vf(i)%sf(j, 0, l) - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - - if (p > 0) then - $:GPU_PARALLEL_LOOP(collapse=3) - do i = momxb, momxe - do l = isz%beg, isz%end - do j = isx%beg, isx%end - dqL_prim_dz_vf(i)%sf(j, -1, l) = & - dqR_prim_dz_vf(i)%sf(j, 0, l) - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - end if - - end if - - end if - - if (bc_y%end == BC_RIEMANN_EXTRAP) then ! Riemann state extrap. BC at end - - $:GPU_PARALLEL_LOOP(collapse=3) - do i = 1, sys_size - do l = is3%beg, is3%end - do k = is2%beg, is2%end - qR_prim_rsy_vf(n + 1, k, l, i) = & - qL_prim_rsy_vf(n, k, l, i) - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - - if (viscous .or. dummy) then - - $:GPU_PARALLEL_LOOP(collapse=3) - do i = momxb, momxe - do l = isz%beg, isz%end - do j = isx%beg, isx%end - dqR_prim_dx_vf(i)%sf(j, n + 1, l) = & - dqL_prim_dx_vf(i)%sf(j, n, l) - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - - $:GPU_PARALLEL_LOOP(collapse=3) - do i = momxb, momxe - do l = isz%beg, isz%end - do j = isx%beg, isx%end - dqR_prim_dy_vf(i)%sf(j, n + 1, l) = & - dqL_prim_dy_vf(i)%sf(j, n, l) - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - - if (p > 0) then - $:GPU_PARALLEL_LOOP(collapse=3) - do i = momxb, momxe - do l = isz%beg, isz%end - do j = isx%beg, isx%end - dqR_prim_dz_vf(i)%sf(j, n + 1, l) = & - dqL_prim_dz_vf(i)%sf(j, n, l) - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - end if - - end if - - end if - ! END: Population of Buffers in y-direction - - ! Population of Buffers in z-direction - else - - if (bc_z%beg == BC_RIEMANN_EXTRAP) then ! Riemann state extrap. BC at beginning - $:GPU_PARALLEL_LOOP(collapse=3) - do i = 1, sys_size - do l = is3%beg, is3%end - do k = is2%beg, is2%end - qL_prim_rsz_vf(-1, k, l, i) = & - qR_prim_rsz_vf(0, k, l, i) - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - - if (viscous .or. dummy) then - $:GPU_PARALLEL_LOOP(collapse=3) - do i = momxb, momxe - do k = isy%beg, isy%end - do j = isx%beg, isx%end - dqL_prim_dx_vf(i)%sf(j, k, -1) = & - dqR_prim_dx_vf(i)%sf(j, k, 0) - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - $:GPU_PARALLEL_LOOP(collapse=3) - do i = momxb, momxe - do k = isy%beg, isy%end - do j = isx%beg, isx%end - dqL_prim_dy_vf(i)%sf(j, k, -1) = & - dqR_prim_dy_vf(i)%sf(j, k, 0) - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - $:GPU_PARALLEL_LOOP(collapse=3) - do i = momxb, momxe - do k = isy%beg, isy%end - do j = isx%beg, isx%end - dqL_prim_dz_vf(i)%sf(j, k, -1) = & - dqR_prim_dz_vf(i)%sf(j, k, 0) - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - end if - - end if - - if (bc_z%end == BC_RIEMANN_EXTRAP) then ! Riemann state extrap. BC at end - - $:GPU_PARALLEL_LOOP(collapse=3) - do i = 1, sys_size - do l = is3%beg, is3%end - do k = is2%beg, is2%end - qR_prim_rsz_vf(p + 1, k, l, i) = & - qL_prim_rsz_vf(p, k, l, i) - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - - if (viscous .or. dummy) then - $:GPU_PARALLEL_LOOP(collapse=3) - do i = momxb, momxe - do k = isy%beg, isy%end - do j = isx%beg, isx%end - dqR_prim_dx_vf(i)%sf(j, k, p + 1) = & - dqL_prim_dx_vf(i)%sf(j, k, p) - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - - $:GPU_PARALLEL_LOOP(collapse=3) - do i = momxb, momxe - do k = isy%beg, isy%end - do j = isx%beg, isx%end - dqR_prim_dy_vf(i)%sf(j, k, p + 1) = & - dqL_prim_dy_vf(i)%sf(j, k, p) - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - - $:GPU_PARALLEL_LOOP(collapse=3) - do i = momxb, momxe - do k = isy%beg, isy%end - do j = isx%beg, isx%end - dqR_prim_dz_vf(i)%sf(j, k, p + 1) = & - dqL_prim_dz_vf(i)%sf(j, k, p) - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - end if - - end if - - end if - ! END: Population of Buffers in z-direction - - end subroutine s_populate_riemann_states_variables_buffers - - !> The computation of parameters, the allocation of memory, - !! the association of pointers and/or the execution of any - !! other procedures needed to configure the chosen Riemann - !! solver algorithm. - !! @param flux_src_vf Intra-cell fluxes sources - !! @param norm_dir Dir. splitting direction - subroutine s_initialize_riemann_solver( & - flux_src_vf, & - norm_dir) - - type(scalar_field), & - dimension(sys_size), & - intent(inout) :: flux_src_vf - - integer, intent(in) :: norm_dir - - integer :: i, j, k, l ! Generic loop iterators - - ! Reshaping Inputted Data in x-direction - - if (norm_dir == 1) then - - if (viscous .or. (surface_tension) .or. dummy) then - - $:GPU_PARALLEL_LOOP(collapse=4) - do i = momxb, E_idx - do l = is3%beg, is3%end - do k = is2%beg, is2%end - do j = is1%beg, is1%end - flux_src_vf(i)%sf(j, k, l) = 0._wp - end do - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - end if - - if (chem_params%diffusion) then - $:GPU_PARALLEL_LOOP(collapse=4) - do i = E_idx, chemxe - do l = is3%beg, is3%end - do k = is2%beg, is2%end - do j = is1%beg, is1%end - if (i == E_idx .or. i >= chemxb) then - flux_src_vf(i)%sf(j, k, l) = 0._wp - end if - end do - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - end if - - if (qbmm) then - $:GPU_PARALLEL_LOOP(collapse=4) - do i = 1, 4 - do l = is3%beg, is3%end - do k = is2%beg, is2%end - do j = is1%beg, is1%end + 1 - mom_sp_rsx_vf(j, k, l, i) = mom_sp(i)%sf(j, k, l) - end do - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - end if - - ! Reshaping Inputted Data in y-direction - elseif (norm_dir == 2) then - - if (viscous .or. (surface_tension) .or. dummy) then - $:GPU_PARALLEL_LOOP(collapse=4) - do i = momxb, E_idx - do l = is3%beg, is3%end - do j = is1%beg, is1%end - do k = is2%beg, is2%end - flux_src_vf(i)%sf(k, j, l) = 0._wp - end do - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - end if - - if (chem_params%diffusion) then - $:GPU_PARALLEL_LOOP(collapse=4) - do i = E_idx, chemxe - do l = is3%beg, is3%end - do j = is1%beg, is1%end - do k = is2%beg, is2%end - if (i == E_idx .or. i >= chemxb) then - flux_src_vf(i)%sf(k, j, l) = 0._wp - end if - end do - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - end if - - if (qbmm) then - $:GPU_PARALLEL_LOOP(collapse=4) - do i = 1, 4 - do l = is3%beg, is3%end - do k = is2%beg, is2%end - do j = is1%beg, is1%end + 1 - mom_sp_rsy_vf(j, k, l, i) = mom_sp(i)%sf(k, j, l) - end do - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - end if - - ! Reshaping Inputted Data in z-direction - else - - if (viscous .or. (surface_tension) .or. dummy) then - $:GPU_PARALLEL_LOOP(collapse=4) - do i = momxb, E_idx - do j = is1%beg, is1%end - do k = is2%beg, is2%end - do l = is3%beg, is3%end - flux_src_vf(i)%sf(l, k, j) = 0._wp - end do - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - end if - - if (chem_params%diffusion) then - $:GPU_PARALLEL_LOOP(collapse=4) - do i = E_idx, chemxe - do j = is1%beg, is1%end - do k = is2%beg, is2%end - do l = is3%beg, is3%end - if (i == E_idx .or. i >= chemxb) then - flux_src_vf(i)%sf(l, k, j) = 0._wp - end if - end do - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - end if - - if (qbmm) then - $:GPU_PARALLEL_LOOP(collapse=4) - do i = 1, 4 - do l = is3%beg, is3%end - do k = is2%beg, is2%end - do j = is1%beg, is1%end + 1 - mom_sp_rsz_vf(j, k, l, i) = mom_sp(i)%sf(l, k, j) - end do - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - end if - - end if - - end subroutine s_initialize_riemann_solver - - !> @brief Computes cylindrical viscous source flux contributions for momentum and energy. - !! Calculates Cartesian components of the stress tensor using averaged velocity derivatives - !! and cylindrical geometric factors, then updates `flux_src_vf`. - !! Assumes x-dir is axial (z_cyl), y-dir is radial (r_cyl), z-dir is azimuthal (theta_cyl for derivatives). - !! @param[in] velL_vf Left boundary velocity (\f$v_x, v_y, v_z\f$) (num_dims scalar_field). - !! @param[in] dvelL_dx_vf Left boundary \f$\partial v_i/\partial x\f$ (num_dims scalar_field). - !! @param[in] dvelL_dy_vf Left boundary \f$\partial v_i/\partial y\f$ (num_dims scalar_field). - !! @param[in] dvelL_dz_vf Left boundary \f$\partial v_i/\partial z\f$ (num_dims scalar_field). - !! @param[in] velR_vf Right boundary velocity (\f$v_x, v_y, v_z\f$) (num_dims scalar_field). - !! @param[in] dvelR_dx_vf Right boundary \f$\partial v_i/\partial x\f$ (num_dims scalar_field). - !! @param[in] dvelR_dy_vf Right boundary \f$\partial v_i/\partial y\f$ (num_dims scalar_field). - !! @param[in] dvelR_dz_vf Right boundary \f$\partial v_i/\partial z\f$ (num_dims scalar_field). - !! @param[inout] flux_src_vf Intercell source flux array to update (sys_size scalar_field). - !! @param[in] norm_dir Interface normal direction (1=x-face, 2=y-face, 3=z-face). - !! @param[in] ix Global X-direction loop bounds (int_bounds_info). - !! @param[in] iy Global Y-direction loop bounds (int_bounds_info). - !! @param[in] iz Global Z-direction loop bounds (int_bounds_info). - subroutine s_compute_cylindrical_viscous_source_flux(velL_vf, & - dvelL_dx_vf, dvelL_dy_vf, dvelL_dz_vf, & - velR_vf, & - dvelR_dx_vf, dvelR_dy_vf, dvelR_dz_vf, & - flux_src_vf, norm_dir, ix, iy, iz) - - type(scalar_field), dimension(num_dims), intent(in) :: velL_vf, velR_vf - type(scalar_field), dimension(num_dims), intent(in) :: dvelL_dx_vf, dvelR_dx_vf - type(scalar_field), dimension(num_dims), intent(in) :: dvelL_dy_vf, dvelR_dy_vf - type(scalar_field), dimension(num_dims), intent(in) :: dvelL_dz_vf, dvelR_dz_vf - type(scalar_field), dimension(sys_size), intent(inout) :: flux_src_vf - integer, intent(in) :: norm_dir - type(int_bounds_info), intent(in) :: ix, iy, iz - - ! Local variables - #:if not MFC_CASE_OPTIMIZATION and USING_AMD - real(wp), dimension(3) :: avg_v_int !!< Averaged interface velocity (\f$v_x, v_y, v_z\f$) (grid directions). - real(wp), dimension(3) :: avg_dvdx_int !!< Averaged interface \f$\partial v_i/\partial x\f$ (grid dir 1). - real(wp), dimension(3) :: avg_dvdy_int !!< Averaged interface \f$\partial v_i/\partial y\f$ (grid dir 2). - real(wp), dimension(3) :: avg_dvdz_int !!< Averaged interface \f$\partial v_i/\partial z\f$ (grid dir 3). - real(wp), dimension(3) :: vel_src_int !!< Interface velocity (\f$v_1,v_2,v_3\f$) (grid directions) for viscous work. - real(wp), dimension(3) :: stress_vector_shear !!< Shear stress vector (\f$\sigma_{N1}, \sigma_{N2}, \sigma_{N3}\f$) on N-face (grid directions). - #:else - real(wp), dimension(num_dims) :: avg_v_int !!< Averaged interface velocity (\f$v_x, v_y, v_z\f$) (grid directions). - real(wp), dimension(num_dims) :: avg_dvdx_int !!< Averaged interface \f$\partial v_i/\partial x\f$ (grid dir 1). - real(wp), dimension(num_dims) :: avg_dvdy_int !!< Averaged interface \f$\partial v_i/\partial y\f$ (grid dir 2). - real(wp), dimension(num_dims) :: avg_dvdz_int !!< Averaged interface \f$\partial v_i/\partial z\f$ (grid dir 3). - real(wp), dimension(num_dims) :: vel_src_int !!< Interface velocity (\f$v_1,v_2,v_3\f$) (grid directions) for viscous work. - real(wp), dimension(num_dims) :: stress_vector_shear !!< Shear stress vector (\f$\sigma_{N1}, \sigma_{N2}, \sigma_{N3}\f$) on N-face (grid directions). - #:endif - real(wp) :: stress_normal_bulk !!< Normal bulk stress component \f$\sigma_{NN}\f$ on N-face. - - real(wp) :: Re_s, Re_b !!< Effective interface shear and bulk Reynolds numbers. - real(wp) :: r_eff !!< Effective radius at interface for cylindrical terms. - real(wp) :: div_v_term_const !!< Common term \f$-(2/3)(\nabla \cdot \mathbf{v}) / \text{Re}_s\f$ for shear stress diagonal. - real(wp) :: divergence_cyl !!< Full divergence \f$\nabla \cdot \mathbf{v}\f$ in cylindrical coordinates. - - integer :: j, k, l !!< Loop iterators for \f$x, y, z\f$ grid directions. - integer :: i_vel !!< Loop iterator for velocity components. - integer :: idx_rp(3) !!< Indices \f$(j,k,l)\f$ of 'right' point for averaging. - - $:GPU_PARALLEL_LOOP(collapse=3, private='[idx_rp, avg_v_int, avg_dvdx_int, avg_dvdy_int, avg_dvdz_int, Re_s, Re_b, vel_src_int, r_eff, divergence_cyl, stress_vector_shear, stress_normal_bulk, div_v_term_const]') - do l = iz%beg, iz%end - do k = iy%beg, iy%end - do j = ix%beg, ix%end - - ! Determine indices for the 'right' state for averaging across the interface - idx_rp = [j, k, l] - idx_rp(norm_dir) = idx_rp(norm_dir) + 1 - - ! Average velocities and their derivatives at the interface - ! For cylindrical: x-dir ~ axial (z_cyl), y-dir ~ radial (r_cyl), z-dir ~ azimuthal (theta_cyl) - $:GPU_LOOP(parallelism='[seq]') - do i_vel = 1, num_dims - avg_v_int(i_vel) = 0.5_wp*(velL_vf(i_vel)%sf(j, k, l) + velR_vf(i_vel)%sf(idx_rp(1), idx_rp(2), idx_rp(3))) - - avg_dvdx_int(i_vel) = 0.5_wp*(dvelL_dx_vf(i_vel)%sf(j, k, l) + & - dvelR_dx_vf(i_vel)%sf(idx_rp(1), idx_rp(2), idx_rp(3))) - if (num_dims > 1) then - avg_dvdy_int(i_vel) = 0.5_wp*(dvelL_dy_vf(i_vel)%sf(j, k, l) + & - dvelR_dy_vf(i_vel)%sf(idx_rp(1), idx_rp(2), idx_rp(3))) - else - avg_dvdy_int(i_vel) = 0.0_wp - end if - if (num_dims > 2) then - avg_dvdz_int(i_vel) = 0.5_wp*(dvelL_dz_vf(i_vel)%sf(j, k, l) + & - dvelR_dz_vf(i_vel)%sf(idx_rp(1), idx_rp(2), idx_rp(3))) - else - avg_dvdz_int(i_vel) = 0.0_wp - end if - end do - - ! Get Re numbers and interface velocity for viscous work - select case (norm_dir) - case (1) ! x-face (axial face in z_cyl direction) - Re_s = Re_avg_rsx_vf(j, k, l, 1) - Re_b = Re_avg_rsx_vf(j, k, l, 2) - vel_src_int = vel_src_rsx_vf(j, k, l, 1:num_dims) - r_eff = y_cc(k) - case (2) ! y-face (radial face in r_cyl direction) - Re_s = Re_avg_rsy_vf(k, j, l, 1) - Re_b = Re_avg_rsy_vf(k, j, l, 2) - vel_src_int = vel_src_rsy_vf(k, j, l, 1:num_dims) - r_eff = y_cb(k) - case (3) ! z-face (azimuthal face in theta_cyl direction) - Re_s = Re_avg_rsz_vf(l, k, j, 1) - Re_b = Re_avg_rsz_vf(l, k, j, 2) - vel_src_int = vel_src_rsz_vf(l, k, j, 1:num_dims) - r_eff = y_cc(k) - end select - - ! Divergence in cylindrical coordinates (vx=vz_cyl, vy=vr_cyl, vz=vtheta_cyl) - #:if not MFC_CASE_OPTIMIZATION or num_dims > 1 - divergence_cyl = avg_dvdx_int(1) + avg_dvdy_int(2) + avg_v_int(2)/r_eff - if (num_dims > 2) then - #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 - divergence_cyl = divergence_cyl + avg_dvdz_int(3)/r_eff - #:endif - end if - #:endif - - stress_vector_shear = 0.0_wp - stress_normal_bulk = 0.0_wp - - if (shear_stress) then - div_v_term_const = -(2.0_wp/3.0_wp)*divergence_cyl/Re_s - - select case (norm_dir) - case (1) ! X-face (axial normal, z_cyl) - stress_vector_shear(1) = (2.0_wp*avg_dvdx_int(1))/Re_s + div_v_term_const - if (num_dims > 1) then - #:if not MFC_CASE_OPTIMIZATION or num_dims > 1 - stress_vector_shear(2) = (avg_dvdy_int(1) + avg_dvdx_int(2))/Re_s - #:endif - end if - if (num_dims > 2) then - #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 - stress_vector_shear(3) = (avg_dvdz_int(1)/r_eff + avg_dvdx_int(3))/Re_s - #:endif - end if - case (2) ! Y-face (radial normal, r_cyl) - if (num_dims > 1) then - #:if not MFC_CASE_OPTIMIZATION or num_dims > 1 - stress_vector_shear(1) = (avg_dvdy_int(1) + avg_dvdx_int(2))/Re_s - stress_vector_shear(2) = (2.0_wp*avg_dvdy_int(2))/Re_s + div_v_term_const - if (num_dims > 2) then - #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 - stress_vector_shear(3) = (avg_dvdz_int(2)/r_eff - avg_v_int(3)/r_eff + avg_dvdy_int(3))/Re_s - #:endif - end if - #:endif - else - stress_vector_shear(1) = (2.0_wp*avg_dvdx_int(1))/Re_s + div_v_term_const - end if - case (3) ! Z-face (azimuthal normal, theta_cyl) - if (num_dims > 2) then - #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 - stress_vector_shear(1) = (avg_dvdz_int(1)/r_eff + avg_dvdx_int(3))/Re_s - stress_vector_shear(2) = (avg_dvdz_int(2)/r_eff - avg_v_int(3)/r_eff + avg_dvdy_int(3))/Re_s - stress_vector_shear(3) = (2.0_wp*(avg_dvdz_int(3)/r_eff + avg_v_int(2)/r_eff))/Re_s + div_v_term_const - #:endif - end if - end select - - $:GPU_LOOP(parallelism='[seq]') - do i_vel = 1, num_dims - flux_src_vf(momxb + i_vel - 1)%sf(j, k, l) = flux_src_vf(momxb + i_vel - 1)%sf(j, k, l) - stress_vector_shear(i_vel) - flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - vel_src_int(i_vel)*stress_vector_shear(i_vel) - end do - end if - - if (bulk_stress) then - stress_normal_bulk = divergence_cyl/Re_b - - flux_src_vf(momxb + norm_dir - 1)%sf(j, k, l) = flux_src_vf(momxb + norm_dir - 1)%sf(j, k, l) - stress_normal_bulk - flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - vel_src_int(norm_dir)*stress_normal_bulk - end if - - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - - end subroutine s_compute_cylindrical_viscous_source_flux - - !> @brief Computes Cartesian viscous source flux contributions for momentum and energy. - !! Calculates averaged velocity gradients, gets Re and interface velocities, - !! calls helpers for shear/bulk stress, then updates `flux_src_vf`. - !! @param[in] dvelL_dx_vf Left boundary d(vel)/dx (num_dims scalar_field). - !! @param[in] dvelL_dy_vf Left boundary d(vel)/dy (num_dims scalar_field). - !! @param[in] dvelL_dz_vf Left boundary d(vel)/dz (num_dims scalar_field). - !! @param[in] dvelR_dx_vf Right boundary d(vel)/dx (num_dims scalar_field). - !! @param[in] dvelR_dy_vf Right boundary d(vel)/dy (num_dims scalar_field). - !! @param[in] dvelR_dz_vf Right boundary d(vel)/dz (num_dims scalar_field). - !! @param[inout] flux_src_vf Intercell source flux array to update (sys_size scalar_field). - !! @param[in] norm_dir Interface normal direction (1=x, 2=y, 3=z). - subroutine s_compute_cartesian_viscous_source_flux(dvelL_dx_vf, & - dvelL_dy_vf, & - dvelL_dz_vf, & - dvelR_dx_vf, & - dvelR_dy_vf, & - dvelR_dz_vf, & - flux_src_vf, & - norm_dir) - - ! Arguments - type(scalar_field), dimension(num_dims), intent(in) :: dvelL_dx_vf, dvelR_dx_vf - type(scalar_field), dimension(num_dims), intent(in) :: dvelL_dy_vf, dvelR_dy_vf - type(scalar_field), dimension(num_dims), intent(in) :: dvelL_dz_vf, dvelR_dz_vf - type(scalar_field), dimension(sys_size), intent(inout) :: flux_src_vf - integer, intent(in) :: norm_dir - - ! Local variables - #:if not MFC_CASE_OPTIMIZATION and USING_AMD - real(wp), dimension(3, 3) :: vel_grad_avg !< Averaged velocity gradient tensor `d(vel_i)/d(coord_j)`. - real(wp), dimension(3, 3) :: current_tau_shear !< Current shear stress tensor. - real(wp), dimension(3, 3) :: current_tau_bulk !< Current bulk stress tensor. - real(wp), dimension(3) :: vel_src_at_interface !< Interface velocities (u,v,w) for viscous work. - #:else - real(wp), dimension(num_dims, num_dims) :: vel_grad_avg !< Averaged velocity gradient tensor `d(vel_i)/d(coord_j)`. - real(wp), dimension(num_dims, num_dims) :: current_tau_shear !< Current shear stress tensor. - real(wp), dimension(num_dims, num_dims) :: current_tau_bulk !< Current bulk stress tensor. - real(wp), dimension(num_dims) :: vel_src_at_interface !< Interface velocities (u,v,w) for viscous work. - #:endif - integer, dimension(3) :: idx_right_phys !< Physical (j,k,l) indices for right state. - - real(wp) :: Re_shear !< Interface shear Reynolds number. - real(wp) :: Re_bulk !< Interface bulk Reynolds number. - - integer :: j_loop !< Physical x-index loop iterator. - integer :: k_loop !< Physical y-index loop iterator. - integer :: l_loop !< Physical z-index loop iterator. - integer :: i_dim !< Generic dimension/component iterator. - integer :: vel_comp_idx !< Velocity component iterator (1=u, 2=v, 3=w). - - real(wp) :: divergence_v !< Velocity divergence at interface. - - $:GPU_PARALLEL_LOOP(collapse=3, private='[idx_right_phys, vel_grad_avg, current_tau_shear, current_tau_bulk, vel_src_at_interface, Re_shear, Re_bulk, divergence_v, i_dim, vel_comp_idx]') - do l_loop = isz%beg, isz%end - do k_loop = isy%beg, isy%end - do j_loop = isx%beg, isx%end - - idx_right_phys(1) = j_loop - idx_right_phys(2) = k_loop - idx_right_phys(3) = l_loop - idx_right_phys(norm_dir) = idx_right_phys(norm_dir) + 1 - - vel_grad_avg = 0.0_wp - do vel_comp_idx = 1, num_dims - vel_grad_avg(vel_comp_idx, 1) = 0.5_wp*(dvelL_dx_vf(vel_comp_idx)%sf(j_loop, k_loop, l_loop) + & - dvelR_dx_vf(vel_comp_idx)%sf(idx_right_phys(1), idx_right_phys(2), idx_right_phys(3))) - if (num_dims > 1) then - #:if not MFC_CASE_OPTIMIZATION or num_dims > 1 - vel_grad_avg(vel_comp_idx, 2) = 0.5_wp*(dvelL_dy_vf(vel_comp_idx)%sf(j_loop, k_loop, l_loop) + & - dvelR_dy_vf(vel_comp_idx)%sf(idx_right_phys(1), idx_right_phys(2), idx_right_phys(3))) - #:endif - end if - if (num_dims > 2) then - #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 - vel_grad_avg(vel_comp_idx, 3) = 0.5_wp*(dvelL_dz_vf(vel_comp_idx)%sf(j_loop, k_loop, l_loop) + & - dvelR_dz_vf(vel_comp_idx)%sf(idx_right_phys(1), idx_right_phys(2), idx_right_phys(3))) - #:endif - end if - end do - - divergence_v = 0.0_wp - do i_dim = 1, num_dims - divergence_v = divergence_v + vel_grad_avg(i_dim, i_dim) - end do - - vel_src_at_interface = 0.0_wp - if (norm_dir == 1) then - Re_shear = Re_avg_rsx_vf(j_loop, k_loop, l_loop, 1) - Re_bulk = Re_avg_rsx_vf(j_loop, k_loop, l_loop, 2) - do i_dim = 1, num_dims - vel_src_at_interface(i_dim) = vel_src_rsx_vf(j_loop, k_loop, l_loop, i_dim) - end do - else if (norm_dir == 2) then - Re_shear = Re_avg_rsy_vf(k_loop, j_loop, l_loop, 1) - Re_bulk = Re_avg_rsy_vf(k_loop, j_loop, l_loop, 2) - do i_dim = 1, num_dims - vel_src_at_interface(i_dim) = vel_src_rsy_vf(k_loop, j_loop, l_loop, i_dim) - end do - else - Re_shear = Re_avg_rsz_vf(l_loop, k_loop, j_loop, 1) - Re_bulk = Re_avg_rsz_vf(l_loop, k_loop, j_loop, 2) - do i_dim = 1, num_dims - vel_src_at_interface(i_dim) = vel_src_rsz_vf(l_loop, k_loop, j_loop, i_dim) - end do - end if - - if (shear_stress) then - ! current_tau_shear = 0.0_wp - call s_calculate_shear_stress_tensor(vel_grad_avg, Re_shear, divergence_v, current_tau_shear) - - do i_dim = 1, num_dims - flux_src_vf(momxb + i_dim - 1)%sf(j_loop, k_loop, l_loop) = & - flux_src_vf(momxb + i_dim - 1)%sf(j_loop, k_loop, l_loop) - current_tau_shear(norm_dir, i_dim) - - flux_src_vf(E_idx)%sf(j_loop, k_loop, l_loop) = & - flux_src_vf(E_idx)%sf(j_loop, k_loop, l_loop) - & - vel_src_at_interface(i_dim)*current_tau_shear(norm_dir, i_dim) - end do - end if - - if (bulk_stress) then - ! current_tau_bulk = 0.0_wp - call s_calculate_bulk_stress_tensor(Re_bulk, divergence_v, current_tau_bulk) - - do i_dim = 1, num_dims - flux_src_vf(momxb + i_dim - 1)%sf(j_loop, k_loop, l_loop) = & - flux_src_vf(momxb + i_dim - 1)%sf(j_loop, k_loop, l_loop) - current_tau_bulk(norm_dir, i_dim) - - flux_src_vf(E_idx)%sf(j_loop, k_loop, l_loop) = & - flux_src_vf(E_idx)%sf(j_loop, k_loop, l_loop) - & - vel_src_at_interface(i_dim)*current_tau_bulk(norm_dir, i_dim) - end do - end if - - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - - end subroutine s_compute_cartesian_viscous_source_flux - - !> @brief Calculates shear stress tensor components. - !! tau_ij_shear = ( (dui/dxj + duj/dxi) - (2/3)*(div_v)*delta_ij ) / Re_shear - !! @param[in] vel_grad_avg Averaged velocity gradient tensor (d(vel_i)/d(coord_j)). - !! @param[in] Re_shear Shear Reynolds number. - !! @param[in] divergence_v Velocity divergence (du/dx + dv/dy + dw/dz). - !! @param[out] tau_shear_out Calculated shear stress tensor (stress on i-face, j-direction). - subroutine s_calculate_shear_stress_tensor(vel_grad_avg, Re_shear, divergence_v, tau_shear_out) - $:GPU_ROUTINE(parallelism='[seq]') - - ! Arguments - #:if not MFC_CASE_OPTIMIZATION and USING_AMD - real(wp), dimension(3, 3), intent(in) :: vel_grad_avg - real(wp), dimension(3, 3), intent(out) :: tau_shear_out - #:else - real(wp), dimension(num_dims, num_dims), intent(in) :: vel_grad_avg - real(wp), dimension(num_dims, num_dims), intent(out) :: tau_shear_out - #:endif - real(wp), intent(in) :: Re_shear - real(wp), intent(in) :: divergence_v - - ! Local variables - integer :: i_dim !< Loop iterator for face normal. - integer :: j_dim !< Loop iterator for force component direction. - - tau_shear_out = 0.0_wp - - do i_dim = 1, num_dims - do j_dim = 1, num_dims - tau_shear_out(i_dim, j_dim) = (vel_grad_avg(j_dim, i_dim) + vel_grad_avg(i_dim, j_dim))/Re_shear - if (i_dim == j_dim) then - tau_shear_out(i_dim, j_dim) = tau_shear_out(i_dim, j_dim) - & - (2.0_wp/3.0_wp)*divergence_v/Re_shear - end if - end do - end do - - end subroutine s_calculate_shear_stress_tensor - - !> @brief Calculates bulk stress tensor components (diagonal only). - !! tau_ii_bulk = (div_v) / Re_bulk. Off-diagonals are zero. - !! @param[in] Re_bulk Bulk Reynolds number. - !! @param[in] divergence_v Velocity divergence (du/dx + dv/dy + dw/dz). - !! @param[out] tau_bulk_out Calculated bulk stress tensor (stress on i-face, i-direction). - subroutine s_calculate_bulk_stress_tensor(Re_bulk, divergence_v, tau_bulk_out) - $:GPU_ROUTINE(parallelism='[seq]') - - ! Arguments - real(wp), intent(in) :: Re_bulk - real(wp), intent(in) :: divergence_v - #:if not MFC_CASE_OPTIMIZATION and USING_AMD - real(wp), dimension(3, 3), intent(out) :: tau_bulk_out - #:else - real(wp), dimension(num_dims, num_dims), intent(out) :: tau_bulk_out - #:endif - - ! Local variables - integer :: i_dim !< Loop iterator for diagonal components. - - tau_bulk_out = 0.0_wp - - do i_dim = 1, num_dims - tau_bulk_out(i_dim, i_dim) = divergence_v/Re_bulk - end do - - end subroutine s_calculate_bulk_stress_tensor - - !> Deallocation and/or disassociation procedures that are - !! needed to finalize the selected Riemann problem solver - !! @param flux_vf Intercell fluxes - !! @param flux_src_vf Intercell source fluxes - !! @param flux_gsrc_vf Intercell geometric source fluxes - !! @param norm_dir Dimensional splitting coordinate direction - subroutine s_finalize_riemann_solver(flux_vf, flux_src_vf, & - flux_gsrc_vf, & - norm_dir) - - type(scalar_field), & - dimension(sys_size), & - intent(inout) :: flux_vf, flux_src_vf, flux_gsrc_vf - - integer, intent(in) :: norm_dir - - integer :: i, j, k, l !< Generic loop iterators - - ! Reshaping Outputted Data in y-direction - if (norm_dir == 2) then - $:GPU_PARALLEL_LOOP(collapse=4) - do i = 1, sys_size - do l = is3%beg, is3%end - do j = is1%beg, is1%end - do k = is2%beg, is2%end - flux_vf(i)%sf(k, j, l) = & - flux_rsy_vf(j, k, l, i) - end do - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - - if (cyl_coord) then - $:GPU_PARALLEL_LOOP(collapse=4) - do i = 1, sys_size - do l = is3%beg, is3%end - do j = is1%beg, is1%end - do k = is2%beg, is2%end - flux_gsrc_vf(i)%sf(k, j, l) = & - flux_gsrc_rsy_vf(j, k, l, i) - end do - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - end if - - $:GPU_PARALLEL_LOOP(collapse=3) - do l = is3%beg, is3%end - do j = is1%beg, is1%end - do k = is2%beg, is2%end - flux_src_vf(advxb)%sf(k, j, l) = & - flux_src_rsy_vf(j, k, l, advxb) - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - - if (riemann_solver == 1 .or. riemann_solver == 4) then - $:GPU_PARALLEL_LOOP(collapse=4) - do i = advxb + 1, advxe - do l = is3%beg, is3%end - do j = is1%beg, is1%end - do k = is2%beg, is2%end - flux_src_vf(i)%sf(k, j, l) = & - flux_src_rsy_vf(j, k, l, i) - end do - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - - end if - ! Reshaping Outputted Data in z-direction - elseif (norm_dir == 3) then - $:GPU_PARALLEL_LOOP(collapse=4) - do i = 1, sys_size - do j = is1%beg, is1%end - do k = is2%beg, is2%end - do l = is3%beg, is3%end - - flux_vf(i)%sf(l, k, j) = & - flux_rsz_vf(j, k, l, i) - end do - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - if (grid_geometry == 3) then - $:GPU_PARALLEL_LOOP(collapse=4) - do i = 1, sys_size - do j = is1%beg, is1%end - do k = is2%beg, is2%end - do l = is3%beg, is3%end - - flux_gsrc_vf(i)%sf(l, k, j) = & - flux_gsrc_rsz_vf(j, k, l, i) - end do - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - end if - - $:GPU_PARALLEL_LOOP(collapse=3) - do j = is1%beg, is1%end - do k = is2%beg, is2%end - do l = is3%beg, is3%end - flux_src_vf(advxb)%sf(l, k, j) = & - flux_src_rsz_vf(j, k, l, advxb) - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - - if (riemann_solver == 1 .or. riemann_solver == 4) then - $:GPU_PARALLEL_LOOP(collapse=4) - do i = advxb + 1, advxe - do j = is1%beg, is1%end - do k = is2%beg, is2%end - do l = is3%beg, is3%end - flux_src_vf(i)%sf(l, k, j) = & - flux_src_rsz_vf(j, k, l, i) - end do - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - - end if - elseif (norm_dir == 1) then - $:GPU_PARALLEL_LOOP(collapse=4) - do i = 1, sys_size - do l = is3%beg, is3%end - do k = is2%beg, is2%end - do j = is1%beg, is1%end - flux_vf(i)%sf(j, k, l) = & - flux_rsx_vf(j, k, l, i) - end do - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - - $:GPU_PARALLEL_LOOP(collapse=3) - do l = is3%beg, is3%end - do k = is2%beg, is2%end - do j = is1%beg, is1%end - flux_src_vf(advxb)%sf(j, k, l) = & - flux_src_rsx_vf(j, k, l, advxb) - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - - if (riemann_solver == 1 .or. riemann_solver == 4) then - $:GPU_PARALLEL_LOOP(collapse=4) - do i = advxb + 1, advxe - do l = is3%beg, is3%end - do k = is2%beg, is2%end - do j = is1%beg, is1%end - flux_src_vf(i)%sf(j, k, l) = & - flux_src_rsx_vf(j, k, l, i) - end do - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - end if - end if - - end subroutine s_finalize_riemann_solver - - !> Module deallocation and/or disassociation procedures - impure subroutine s_finalize_riemann_solvers_module - - if (viscous) then - @:DEALLOCATE(Re_avg_rsx_vf) - end if - @:DEALLOCATE(vel_src_rsx_vf) - @:DEALLOCATE(flux_rsx_vf) - @:DEALLOCATE(flux_src_rsx_vf) - @:DEALLOCATE(flux_gsrc_rsx_vf) - if (qbmm) then - @:DEALLOCATE(mom_sp_rsx_vf) - end if - - if (n == 0) return - - if (viscous) then - @:DEALLOCATE(Re_avg_rsy_vf) - end if - @:DEALLOCATE(vel_src_rsy_vf) - @:DEALLOCATE(flux_rsy_vf) - @:DEALLOCATE(flux_src_rsy_vf) - @:DEALLOCATE(flux_gsrc_rsy_vf) - if (qbmm) then - @:DEALLOCATE(mom_sp_rsy_vf) - end if - - if (p == 0) return - - if (viscous) then - @:DEALLOCATE(Re_avg_rsz_vf) - end if - @:DEALLOCATE(vel_src_rsz_vf) - @:DEALLOCATE(flux_rsz_vf) - @:DEALLOCATE(flux_src_rsz_vf) - @:DEALLOCATE(flux_gsrc_rsz_vf) - if (qbmm) then - @:DEALLOCATE(mom_sp_rsz_vf) - end if - - end subroutine s_finalize_riemann_solvers_module - -end module m_riemann_solvers +!> +!! @file +!! @brief Contains module m_riemann_solvers + +!> @brief Approximate and exact Riemann solvers (HLL, HLLC, HLLD, exact) for the multicomponent Navier--Stokes equations + +#:include 'case.fpp' +#:include 'macros.fpp' +#:include 'inline_riemann.fpp' + +module m_riemann_solvers + + use m_derived_types !< Definitions of the derived types + + use m_global_parameters !< Definitions of the global parameters + + use m_mpi_proxy !< Message passing interface (MPI) module proxy + + use m_variables_conversion !< State variables type conversion procedures + + use m_bubbles !< To get the bubble wall pressure function + + use m_bubbles_EE + + use m_surface_tension !< To get the capillary fluxes + + use m_helper_basic !< Functions to compare floating point numbers + + use m_chemistry + + use m_re_visc !< Dynamic Re_visc (Newtonian/non-Newtonian) + + use m_thermochem, only: & + gas_constant, get_mixture_molecular_weight, & + get_mixture_specific_heat_cv_mass, get_mixture_energy_mass, & + get_species_specific_heats_r, get_species_enthalpies_rt, & + get_mixture_specific_heat_cp_mass + + #:if USING_AMD + use m_chemistry, only: molecular_weights_nonparameter + #:endif + + implicit none + + private; public :: s_initialize_riemann_solvers_module, & + s_riemann_solver, & + s_hll_riemann_solver, & + s_hllc_riemann_solver, & + s_hlld_riemann_solver, & + s_lf_riemann_solver, & + s_finalize_riemann_solvers_module + + !> The cell-boundary values of the fluxes (src - source) that are computed + !! through the chosen Riemann problem solver, and the direct evaluation of + !! source terms, by using the left and right states given in qK_prim_rs_vf, + !! dqK_prim_ds_vf where ds = dx, dy or dz. + !> @{ + + real(wp), allocatable, dimension(:, :, :, :) :: flux_rsx_vf, flux_src_rsx_vf + real(wp), allocatable, dimension(:, :, :, :) :: flux_rsy_vf, flux_src_rsy_vf + real(wp), allocatable, dimension(:, :, :, :) :: flux_rsz_vf, flux_src_rsz_vf + $:GPU_DECLARE(create='[flux_rsx_vf,flux_src_rsx_vf,flux_rsy_vf,flux_src_rsy_vf,flux_rsz_vf,flux_src_rsz_vf]') + !> @} + + !> The cell-boundary values of the geometrical source flux that are computed + !! through the chosen Riemann problem solver by using the left and right + !! states given in qK_prim_rs_vf. Currently 2D axisymmetric for inviscid only. + !> @{ + + real(wp), allocatable, dimension(:, :, :, :) :: flux_gsrc_rsx_vf !< + real(wp), allocatable, dimension(:, :, :, :) :: flux_gsrc_rsy_vf !< + real(wp), allocatable, dimension(:, :, :, :) :: flux_gsrc_rsz_vf !< + $:GPU_DECLARE(create='[flux_gsrc_rsx_vf,flux_gsrc_rsy_vf,flux_gsrc_rsz_vf]') + !> @} + + ! The cell-boundary values of the velocity. vel_src_rs_vf is determined as + ! part of Riemann problem solution and is used to evaluate the source flux. + + real(wp), allocatable, dimension(:, :, :, :) :: vel_src_rsx_vf + real(wp), allocatable, dimension(:, :, :, :) :: vel_src_rsy_vf + real(wp), allocatable, dimension(:, :, :, :) :: vel_src_rsz_vf + $:GPU_DECLARE(create='[vel_src_rsx_vf,vel_src_rsy_vf,vel_src_rsz_vf]') + + real(wp), allocatable, dimension(:, :, :, :) :: mom_sp_rsx_vf + real(wp), allocatable, dimension(:, :, :, :) :: mom_sp_rsy_vf + real(wp), allocatable, dimension(:, :, :, :) :: mom_sp_rsz_vf + $:GPU_DECLARE(create='[mom_sp_rsx_vf,mom_sp_rsy_vf,mom_sp_rsz_vf]') + + real(wp), allocatable, dimension(:, :, :, :) :: Re_avg_rsx_vf + real(wp), allocatable, dimension(:, :, :, :) :: Re_avg_rsy_vf + real(wp), allocatable, dimension(:, :, :, :) :: Re_avg_rsz_vf + $:GPU_DECLARE(create='[Re_avg_rsx_vf,Re_avg_rsy_vf,Re_avg_rsz_vf]') + + !> @name Indical bounds in the s1-, s2- and s3-directions + !> @{ + type(int_bounds_info) :: is1, is2, is3 + type(int_bounds_info) :: isx, isy, isz + !> @} + + $:GPU_DECLARE(create='[is1,is2,is3,isx,isy,isz]') + + real(wp), allocatable, dimension(:) :: Gs_rs + $:GPU_DECLARE(create='[Gs_rs]') + + ! Note: Static Res_gs array removed - s_compute_re_visc handles + ! both Newtonian and non-Newtonian cases dynamically + +contains + + !> Dispatch to the subroutines that are utilized to compute the + !! Riemann problem solution. For additional information please reference: + !! 1) s_hll_riemann_solver + !! 2) s_hllc_riemann_solver + !! 3) s_exact_riemann_solver + !! 4) s_hlld_riemann_solver + !! @param qL_prim_rsx_vf Left WENO-reconstructed cell-boundary values (x-dir) + !! @param qL_prim_rsy_vf Left WENO-reconstructed cell-boundary values (y-dir) + !! @param qL_prim_rsz_vf Left WENO-reconstructed cell-boundary values (z-dir) + !! @param dqL_prim_dx_vf The left WENO-reconstructed cell-boundary values of the + !! first-order x-dir spatial derivatives + !! @param dqL_prim_dy_vf The left WENO-reconstructed cell-boundary values of the + !! first-order y-dir spatial derivatives + !! @param dqL_prim_dz_vf The left WENO-reconstructed cell-boundary values of the + !! first-order z-dir spatial derivatives + !! @param qL_prim_vf The left WENO-reconstructed cell-boundary values of the + !! cell-average primitive variables + !! @param qR_prim_rsx_vf Right WENO-reconstructed cell-boundary values (x-dir) + !! @param qR_prim_rsy_vf Right WENO-reconstructed cell-boundary values (y-dir) + !! @param qR_prim_rsz_vf Right WENO-reconstructed cell-boundary values (z-dir) + !! @param dqR_prim_dx_vf The right WENO-reconstructed cell-boundary values of the + !! first-order x-dir spatial derivatives + !! @param dqR_prim_dy_vf The right WENO-reconstructed cell-boundary values of the + !! first-order y-dir spatial derivatives + !! @param dqR_prim_dz_vf The right WENO-reconstructed cell-boundary values of the + !! first-order z-dir spatial derivatives + !! @param qR_prim_vf The right WENO-reconstructed cell-boundary values of the + !! cell-average primitive variables + !! @param q_prim_vf Cell-averaged primitive variables + !! @param flux_vf Intra-cell fluxes + !! @param flux_src_vf Intra-cell fluxes sources + !! @param flux_gsrc_vf Intra-cell geometric fluxes sources + !! @param norm_dir Dir. splitting direction + !! @param ix Index bounds in the x-dir + !! @param iy Index bounds in the y-dir + !! @param iz Index bounds in the z-dir + subroutine s_riemann_solver(qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, dqL_prim_dx_vf, & + dqL_prim_dy_vf, & + dqL_prim_dz_vf, & + qL_prim_vf, & + qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf, dqR_prim_dx_vf, & + dqR_prim_dy_vf, & + dqR_prim_dz_vf, & + qR_prim_vf, & + q_prim_vf, & + flux_vf, flux_src_vf, & + flux_gsrc_vf, & + norm_dir, ix, iy, iz) + + real(wp), dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:), intent(INOUT) :: qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf + type(scalar_field), dimension(sys_size), intent(IN) :: q_prim_vf + + type(scalar_field), allocatable, dimension(:), intent(INOUT) :: qL_prim_vf, qR_prim_vf + + type(scalar_field), & + allocatable, dimension(:), & + intent(INOUT) :: dqL_prim_dx_vf, dqR_prim_dx_vf, & + dqL_prim_dy_vf, dqR_prim_dy_vf, & + dqL_prim_dz_vf, dqR_prim_dz_vf + + type(scalar_field), & + dimension(sys_size), & + intent(INOUT) :: flux_vf, flux_src_vf, flux_gsrc_vf + + integer, intent(IN) :: norm_dir + + type(int_bounds_info), intent(IN) :: ix, iy, iz + + #:for NAME, NUM in [('hll', 1), ('hllc', 2), ('hlld', 4), ('lf', 5)] + if (riemann_solver == ${NUM}$) then + call s_${NAME}$_riemann_solver(qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, dqL_prim_dx_vf, & + dqL_prim_dy_vf, & + dqL_prim_dz_vf, & + qL_prim_vf, & + qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf, dqR_prim_dx_vf, & + dqR_prim_dy_vf, & + dqR_prim_dz_vf, & + qR_prim_vf, & + q_prim_vf, & + flux_vf, flux_src_vf, & + flux_gsrc_vf, & + norm_dir, ix, iy, iz) + end if + #:endfor + + end subroutine s_riemann_solver + + !> Dispatch to the subroutines that are utilized to compute + !! the viscous source fluxes for either Cartesian or cylindrical geometries. + !! For more information please refer to: + !! 1) s_compute_cartesian_viscous_source_flux + !! 2) s_compute_cylindrical_viscous_source_flux + subroutine s_compute_viscous_source_flux(velL_vf, & + dvelL_dx_vf, & + dvelL_dy_vf, & + dvelL_dz_vf, & + velR_vf, & + dvelR_dx_vf, & + dvelR_dy_vf, & + dvelR_dz_vf, & + flux_src_vf, & + norm_dir, & + ix, iy, iz) + + type(scalar_field), & + dimension(num_vels), & + intent(IN) :: velL_vf, velR_vf, & + dvelL_dx_vf, dvelR_dx_vf, & + dvelL_dy_vf, dvelR_dy_vf, & + dvelL_dz_vf, dvelR_dz_vf + + type(scalar_field), & + dimension(sys_size), & + intent(INOUT) :: flux_src_vf + + integer, intent(IN) :: norm_dir + + type(int_bounds_info), intent(IN) :: ix, iy, iz + + if (grid_geometry == 3) then + call s_compute_cylindrical_viscous_source_flux(velL_vf, & + dvelL_dx_vf, & + dvelL_dy_vf, & + dvelL_dz_vf, & + velR_vf, & + dvelR_dx_vf, & + dvelR_dy_vf, & + dvelR_dz_vf, & + flux_src_vf, & + norm_dir, & + ix, iy, iz) + else + call s_compute_cartesian_viscous_source_flux(dvelL_dx_vf, & + dvelL_dy_vf, & + dvelL_dz_vf, & + dvelR_dx_vf, & + dvelR_dy_vf, & + dvelR_dz_vf, & + flux_src_vf, & + norm_dir) + end if + end subroutine s_compute_viscous_source_flux + + !> @brief Computes intercell fluxes using the Harten-Lax-van Leer (HLL) approximate Riemann solver. + subroutine s_hll_riemann_solver(qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, dqL_prim_dx_vf, & + dqL_prim_dy_vf, & + dqL_prim_dz_vf, & + qL_prim_vf, & + qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf, dqR_prim_dx_vf, & + dqR_prim_dy_vf, & + dqR_prim_dz_vf, & + qR_prim_vf, & + q_prim_vf, & + flux_vf, flux_src_vf, & + flux_gsrc_vf, & + norm_dir, ix, iy, iz) + + real(wp), dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:), intent(inout) :: qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf + type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf + + type(scalar_field), allocatable, dimension(:), intent(inout) :: qL_prim_vf, qR_prim_vf + + type(scalar_field), & + allocatable, dimension(:), & + intent(inout) :: dqL_prim_dx_vf, dqR_prim_dx_vf, & + dqL_prim_dy_vf, dqR_prim_dy_vf, & + dqL_prim_dz_vf, dqR_prim_dz_vf + + ! Intercell fluxes + type(scalar_field), & + dimension(sys_size), & + intent(inout) :: flux_vf, flux_src_vf, flux_gsrc_vf + real(wp) :: flux_tau_L, flux_tau_R + + integer, intent(in) :: norm_dir + type(int_bounds_info), intent(in) :: ix, iy, iz + #:if not MFC_CASE_OPTIMIZATION and USING_AMD + real(wp), dimension(3) :: alpha_rho_L, alpha_rho_R + real(wp), dimension(3) :: vel_L, vel_R + real(wp), dimension(3) :: alpha_L, alpha_R + real(wp), dimension(10) :: Ys_L, Ys_R + real(wp), dimension(10) :: Cp_iL, Cp_iR, Xs_L, Xs_R, Gamma_iL, Gamma_iR + real(wp), dimension(10) :: Yi_avg, Phi_avg, h_iL, h_iR, h_avg_2 + #:else + real(wp), dimension(num_fluids) :: alpha_rho_L, alpha_rho_R + real(wp), dimension(num_vels) :: vel_L, vel_R + real(wp), dimension(num_fluids) :: alpha_L, alpha_R + real(wp), dimension(num_species) :: Ys_L, Ys_R + real(wp), dimension(num_species) :: Cp_iL, Cp_iR, Xs_L, Xs_R, Gamma_iL, Gamma_iR + real(wp), dimension(num_species) :: Yi_avg, Phi_avg, h_iL, h_iR, h_avg_2 + #:endif + real(wp) :: rho_L, rho_R + real(wp) :: pres_L, pres_R + real(wp) :: E_L, E_R + real(wp) :: H_L, H_R + real(wp) :: Cp_avg, Cv_avg, T_avg, eps, c_sum_Yi_Phi + real(wp) :: T_L, T_R + real(wp) :: Y_L, Y_R + real(wp) :: MW_L, MW_R + real(wp) :: R_gas_L, R_gas_R + real(wp) :: Cp_L, Cp_R + real(wp) :: Cv_L, Cv_R + real(wp) :: Gamm_L, Gamm_R + real(wp) :: gamma_L, gamma_R + real(wp) :: pi_inf_L, pi_inf_R + real(wp) :: qv_L, qv_R + real(wp) :: c_L, c_R + real(wp), dimension(6) :: tau_e_L, tau_e_R + real(wp) :: G_L, G_R + real(wp), dimension(2) :: Re_L, Re_R + real(wp), dimension(3) :: xi_field_L, xi_field_R + ! Non-Newtonian per-phase Re arrays + #:if not MFC_CASE_OPTIMIZATION and USING_AMD + real(wp), dimension(3, 2) :: Re_visc_per_phase_L, Re_visc_per_phase_R + #:else + real(wp), dimension(num_fluids, 2) :: Re_visc_per_phase_L, Re_visc_per_phase_R + #:endif + + real(wp) :: rho_avg + real(wp) :: H_avg + real(wp) :: qv_avg + real(wp) :: gamma_avg + real(wp) :: c_avg + + real(wp) :: s_L, s_R, s_M, s_P, s_S + real(wp) :: xi_M, xi_P + + real(wp) :: ptilde_L, ptilde_R + real(wp) :: vel_L_rms, vel_R_rms, vel_avg_rms + real(wp) :: vel_L_tmp, vel_R_tmp + real(wp) :: Ms_L, Ms_R, pres_SL, pres_SR + real(wp) :: alpha_L_sum, alpha_R_sum + real(wp) :: zcoef, pcorr !< low Mach number correction + + type(riemann_states) :: c_fast, pres_mag + type(riemann_states_vec3) :: B + + type(riemann_states) :: Ga ! Gamma (Lorentz factor) + type(riemann_states) :: vdotB, B2 + type(riemann_states_vec3) :: b4 ! 4-magnetic field components (spatial: b4x, b4y, b4z) + type(riemann_states_vec3) :: cm ! Conservative momentum variables + + integer :: i, j, k, l, q !< Generic loop iterators + + ! Populating the buffers of the left and right Riemann problem + ! states variables, based on the choice of boundary conditions + call s_populate_riemann_states_variables_buffers( & + qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, dqL_prim_dx_vf, & + dqL_prim_dy_vf, & + dqL_prim_dz_vf, & + qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf, dqR_prim_dx_vf, & + dqR_prim_dy_vf, & + dqR_prim_dz_vf, & + norm_dir, ix, iy, iz) + + ! Reshaping inputted data based on dimensional splitting direction + call s_initialize_riemann_solver( & + flux_src_vf, & + norm_dir) + #:for NORM_DIR, XYZ in [(1, 'x'), (2, 'y'), (3, 'z')] + + if (norm_dir == ${NORM_DIR}$) then + $:GPU_PARALLEL_LOOP(collapse=3, private='[i,j,k,l,q,alpha_rho_L,alpha_rho_R,vel_L,vel_R,alpha_L,alpha_R,tau_e_L,tau_e_R,Re_L,Re_R,s_L,s_R,s_S,Ys_L,Ys_R,xi_field_L, xi_field_R, Cp_iL, Cp_iR, Xs_L, Xs_R, Gamma_iL, Gamma_iR, Yi_avg, Phi_avg, h_iL, h_iR, h_avg_2, c_fast, pres_mag, B, Ga, vdotB, B2, b4, cm, pcorr, zcoef, vel_L_tmp, vel_R_tmp, rho_L, rho_R, pres_L, pres_R, E_L, E_R, H_L, H_R, Cp_avg, Cv_avg, T_avg, eps, c_sum_Yi_Phi, T_L, T_R, Y_L, Y_R, MW_L, MW_R, R_gas_L, R_gas_R, Cp_L, Cp_R, Cv_L, Cv_R, Gamm_L, Gamm_R, gamma_L, gamma_R, pi_inf_L, pi_inf_R, qv_L, qv_R, qv_avg, c_L, c_R, G_L, G_R, rho_avg, H_avg, c_avg, gamma_avg, ptilde_L, ptilde_R, vel_L_rms, vel_R_rms, vel_avg_rms, Ms_L, Ms_R, pres_SL, pres_SR, alpha_L_sum, alpha_R_sum, flux_tau_L, flux_tau_R, Re_visc_per_phase_L, Re_visc_per_phase_R]', copyin='[norm_dir]') + do l = is3%beg, is3%end + do k = is2%beg, is2%end + do j = is1%beg, is1%end + $:GPU_LOOP(parallelism='[seq]') + do i = 1, contxe + alpha_rho_L(i) = qL_prim_rs${XYZ}$_vf(j, k, l, i) + alpha_rho_R(i) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, i) + end do + + vel_L_rms = 0._wp; vel_R_rms = 0._wp + + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_vels + vel_L(i) = qL_prim_rs${XYZ}$_vf(j, k, l, contxe + i) + vel_R(i) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, contxe + i) + vel_L_rms = vel_L_rms + vel_L(i)**2._wp + vel_R_rms = vel_R_rms + vel_R(i)**2._wp + end do + + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_fluids + alpha_L(i) = qL_prim_rs${XYZ}$_vf(j, k, l, E_idx + i) + alpha_R(i) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx + i) + end do + + pres_L = qL_prim_rs${XYZ}$_vf(j, k, l, E_idx) + pres_R = qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx) + + if (mhd) then + if (n == 0) then ! 1D: constant Bx; By, Bz as variables + B%L(1) = Bx0 + B%R(1) = Bx0 + B%L(2) = qL_prim_rs${XYZ}$_vf(j, k, l, B_idx%beg) + B%R(2) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, B_idx%beg) + B%L(3) = qL_prim_rs${XYZ}$_vf(j, k, l, B_idx%beg + 1) + B%R(3) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, B_idx%beg + 1) + else ! 2D/3D: Bx, By, Bz as variables + B%L(1) = qL_prim_rs${XYZ}$_vf(j, k, l, B_idx%beg) + B%R(1) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, B_idx%beg) + B%L(2) = qL_prim_rs${XYZ}$_vf(j, k, l, B_idx%beg + 1) + B%R(2) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, B_idx%beg + 1) + B%L(3) = qL_prim_rs${XYZ}$_vf(j, k, l, B_idx%beg + 2) + B%R(3) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, B_idx%beg + 2) + end if + end if + + rho_L = 0._wp + gamma_L = 0._wp + pi_inf_L = 0._wp + qv_L = 0._wp + + rho_R = 0._wp + gamma_R = 0._wp + pi_inf_R = 0._wp + qv_R = 0._wp + + alpha_L_sum = 0._wp + alpha_R_sum = 0._wp + + pres_mag%L = 0._wp + pres_mag%R = 0._wp + + if (mpp_lim) then + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_fluids + alpha_rho_L(i) = max(0._wp, alpha_rho_L(i)) + alpha_L(i) = min(max(0._wp, alpha_L(i)), 1._wp) + alpha_L_sum = alpha_L_sum + alpha_L(i) + alpha_rho_R(i) = max(0._wp, alpha_rho_R(i)) + alpha_R(i) = min(max(0._wp, alpha_R(i)), 1._wp) + alpha_R_sum = alpha_R_sum + alpha_R(i) + end do + + alpha_L = alpha_L/max(alpha_L_sum, sgm_eps) + alpha_R = alpha_R/max(alpha_R_sum, sgm_eps) + end if + + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_fluids + rho_L = rho_L + alpha_rho_L(i) + gamma_L = gamma_L + alpha_L(i)*gammas(i) + pi_inf_L = pi_inf_L + alpha_L(i)*pi_infs(i) + qv_L = qv_L + alpha_rho_L(i)*qvs(i) + + rho_R = rho_R + alpha_rho_R(i) + gamma_R = gamma_R + alpha_R(i)*gammas(i) + pi_inf_R = pi_inf_R + alpha_R(i)*pi_infs(i) + qv_R = qv_R + alpha_rho_R(i)*qvs(i) + end do + + if (viscous) then + ! Map rotated (j,k,l) to physical (x,y,z) indices + #:if NORM_DIR == 1 + call s_compute_re_visc(q_prim_vf, & + alpha_L, j, k, l, Re_visc_per_phase_L) + call s_compute_re_visc(q_prim_vf, & + alpha_R, j + 1, k, l, Re_visc_per_phase_R) + #:elif NORM_DIR == 2 + call s_compute_re_visc(q_prim_vf, & + alpha_L, k, j, l, Re_visc_per_phase_L) + call s_compute_re_visc(q_prim_vf, & + alpha_R, k, j + 1, l, Re_visc_per_phase_R) + #:else + call s_compute_re_visc(q_prim_vf, & + alpha_L, l, k, j, Re_visc_per_phase_L) + call s_compute_re_visc(q_prim_vf, & + alpha_R, l, k, j + 1, Re_visc_per_phase_R) + #:endif + call s_compute_mixture_re( & + alpha_L, Re_visc_per_phase_L, Re_L) + call s_compute_mixture_re( & + alpha_R, Re_visc_per_phase_R, Re_R) + end if + + if (chemistry) then + $:GPU_LOOP(parallelism='[seq]') + do i = chemxb, chemxe + Ys_L(i - chemxb + 1) = qL_prim_rs${XYZ}$_vf(j, k, l, i) + Ys_R(i - chemxb + 1) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, i) + end do + + call get_mixture_molecular_weight(Ys_L, MW_L) + call get_mixture_molecular_weight(Ys_R, MW_R) + #:if USING_AMD + Xs_L(:) = Ys_L(:)*MW_L/molecular_weights_nonparameter(:) + Xs_R(:) = Ys_R(:)*MW_R/molecular_weights_nonparameter(:) + #:else + Xs_L(:) = Ys_L(:)*MW_L/molecular_weights(:) + Xs_R(:) = Ys_R(:)*MW_R/molecular_weights(:) + #:endif + + R_gas_L = gas_constant/MW_L + R_gas_R = gas_constant/MW_R + T_L = pres_L/rho_L/R_gas_L + T_R = pres_R/rho_R/R_gas_R + + call get_species_specific_heats_r(T_L, Cp_iL) + call get_species_specific_heats_r(T_R, Cp_iR) + + if (chem_params%gamma_method == 1) then + ! gamma_method = 1: Ref. Section 2.3.1 Formulation of doi:10.7907/ZKW8-ES97. + Gamma_iL = Cp_iL/(Cp_iL - 1.0_wp) + Gamma_iR = Cp_iR/(Cp_iR - 1.0_wp) + + gamma_L = sum(Xs_L(:)/(Gamma_iL(:) - 1.0_wp)) + gamma_R = sum(Xs_R(:)/(Gamma_iR(:) - 1.0_wp)) + else if (chem_params%gamma_method == 2) then + ! gamma_method = 2: c_p / c_v where c_p, c_v are specific heats. + call get_mixture_specific_heat_cp_mass(T_L, Ys_L, Cp_L) + call get_mixture_specific_heat_cp_mass(T_R, Ys_R, Cp_R) + call get_mixture_specific_heat_cv_mass(T_L, Ys_L, Cv_L) + call get_mixture_specific_heat_cv_mass(T_R, Ys_R, Cv_R) + + Gamm_L = Cp_L/Cv_L + gamma_L = 1.0_wp/(Gamm_L - 1.0_wp) + Gamm_R = Cp_R/Cv_R + gamma_R = 1.0_wp/(Gamm_R - 1.0_wp) + end if + + call get_mixture_energy_mass(T_L, Ys_L, E_L) + call get_mixture_energy_mass(T_R, Ys_R, E_R) + + E_L = rho_L*E_L + 5.e-1*rho_L*vel_L_rms + E_R = rho_R*E_R + 5.e-1*rho_R*vel_R_rms + H_L = (E_L + pres_L)/rho_L + H_R = (E_R + pres_R)/rho_R + elseif (mhd .and. relativity) then + Ga%L = 1._wp/sqrt(1._wp - vel_L_rms) + Ga%R = 1._wp/sqrt(1._wp - vel_R_rms) + #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 + vdotB%L = vel_L(1)*B%L(1) + vel_L(2)*B%L(2) + vel_L(3)*B%L(3) + vdotB%R = vel_R(1)*B%R(1) + vel_R(2)*B%R(2) + vel_R(3)*B%R(3) + + b4%L(1:3) = B%L(1:3)/Ga%L + Ga%L*vel_L(1:3)*vdotB%L + b4%R(1:3) = B%R(1:3)/Ga%R + Ga%R*vel_R(1:3)*vdotB%R + B2%L = B%L(1)**2._wp + B%L(2)**2._wp + B%L(3)**2._wp + B2%R = B%R(1)**2._wp + B%R(2)**2._wp + B%R(3)**2._wp + #:endif + + pres_mag%L = 0.5_wp*(B2%L/Ga%L**2._wp + vdotB%L**2._wp) + pres_mag%R = 0.5_wp*(B2%R/Ga%R**2._wp + vdotB%R**2._wp) + + ! Hard-coded EOS + H_L = 1._wp + (gamma_L + 1)*pres_L/rho_L + H_R = 1._wp + (gamma_R + 1)*pres_R/rho_R + #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 + cm%L(1:3) = (rho_L*H_L*Ga%L**2 + B2%L)*vel_L(1:3) - vdotB%L*B%L(1:3) + cm%R(1:3) = (rho_R*H_R*Ga%R**2 + B2%R)*vel_R(1:3) - vdotB%R*B%R(1:3) + #:endif + + E_L = rho_L*H_L*Ga%L**2 - pres_L + 0.5_wp*(B2%L + vel_L_rms*B2%L - vdotB%L**2._wp) - rho_L*Ga%L + E_R = rho_R*H_R*Ga%R**2 - pres_R + 0.5_wp*(B2%R + vel_R_rms*B2%R - vdotB%R**2._wp) - rho_R*Ga%R + elseif (mhd .and. .not. relativity) then + #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 + pres_mag%L = 0.5_wp*(B%L(1)**2._wp + B%L(2)**2._wp + B%L(3)**2._wp) + pres_mag%R = 0.5_wp*(B%R(1)**2._wp + B%R(2)**2._wp + B%R(3)**2._wp) + #:endif + E_L = gamma_L*pres_L + pi_inf_L + 0.5_wp*rho_L*vel_L_rms + qv_L + pres_mag%L + E_R = gamma_R*pres_R + pi_inf_R + 0.5_wp*rho_R*vel_R_rms + qv_R + pres_mag%R ! includes magnetic energy + H_L = (E_L + pres_L - pres_mag%L)/rho_L + H_R = (E_R + pres_R - pres_mag%R)/rho_R ! stagnation enthalpy here excludes magnetic energy (only used to find speed of sound) + else + E_L = gamma_L*pres_L + pi_inf_L + 5.e-1*rho_L*vel_L_rms + qv_L + E_R = gamma_R*pres_R + pi_inf_R + 5.e-1*rho_R*vel_R_rms + qv_R + H_L = (E_L + pres_L)/rho_L + H_R = (E_R + pres_R)/rho_R + end if + + ! elastic energy update + if (hypoelasticity) then + G_L = 0._wp; G_R = 0._wp + + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_fluids + G_L = G_L + alpha_L(i)*Gs_rs(i) + G_R = G_R + alpha_R(i)*Gs_rs(i) + end do + + if (cont_damage) then + G_L = G_L*max((1._wp - qL_prim_rs${XYZ}$_vf(j, k, l, damage_idx)), 0._wp) + G_R = G_R*max((1._wp - qR_prim_rs${XYZ}$_vf(j, k, l, damage_idx)), 0._wp) + end if + + $:GPU_LOOP(parallelism='[seq]') + do i = 1, strxe - strxb + 1 + tau_e_L(i) = qL_prim_rs${XYZ}$_vf(j, k, l, strxb - 1 + i) + tau_e_R(i) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, strxb - 1 + i) + ! Elastic contribution to energy if G large enough + !TODO take out if statement if stable without + if ((G_L > 1000) .and. (G_R > 1000)) then + E_L = E_L + (tau_e_L(i)*tau_e_L(i))/(4._wp*G_L) + E_R = E_R + (tau_e_R(i)*tau_e_R(i))/(4._wp*G_R) + ! Double for shear stresses + if (any(strxb - 1 + i == shear_indices)) then + E_L = E_L + (tau_e_L(i)*tau_e_L(i))/(4._wp*G_L) + E_R = E_R + (tau_e_R(i)*tau_e_R(i))/(4._wp*G_R) + end if + end if + end do + end if + + ! elastic energy update + !if ( hyperelasticity ) then + ! G_L = 0._wp + ! G_R = 0._wp + ! + ! $:GPU_LOOP(parallelism='[seq]') + ! do i = 1, num_fluids + ! G_L = G_L + alpha_L(i)*Gs_rs(i) + ! G_R = G_R + alpha_R(i)*Gs_rs(i) + ! end do + ! ! Elastic contribution to energy if G large enough + ! if ((G_L > 1.e-3_wp) .and. (G_R > 1.e-3_wp)) then + ! E_L = E_L + G_L*qL_prim_rs${XYZ}$_vf(j, k, l, xiend + 1) + ! E_R = E_R + G_R*qR_prim_rs${XYZ}$_vf(j + 1, k, l, xiend + 1) + ! $:GPU_LOOP(parallelism='[seq]') + ! do i = 1, b_size-1 + ! tau_e_L(i) = G_L*qL_prim_rs${XYZ}$_vf(j, k, l, strxb - 1 + i) + ! tau_e_R(i) = G_R*qR_prim_rs${XYZ}$_vf(j + 1, k, l, strxb - 1 + i) + ! end do + ! $:GPU_LOOP(parallelism='[seq]') + ! do i = 1, b_size-1 + ! tau_e_L(i) = 0._wp + ! tau_e_R(i) = 0._wp + ! end do + ! $:GPU_LOOP(parallelism='[seq]') + ! do i = 1, num_dims + ! xi_field_L(i) = qL_prim_rs${XYZ}$_vf(j, k, l, xibeg - 1 + i) + ! xi_field_R(i) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, xibeg - 1 + i) + ! end do + ! end if + !end if + + @:compute_average_state() + + call s_compute_speed_of_sound(pres_L, rho_L, gamma_L, pi_inf_L, H_L, alpha_L, & + vel_L_rms, 0._wp, c_L, qv_L) + + call s_compute_speed_of_sound(pres_R, rho_R, gamma_R, pi_inf_R, H_R, alpha_R, & + vel_R_rms, 0._wp, c_R, qv_R) + + !> The computation of c_avg does not require all the variables, and therefore the non '_avg' + ! variables are placeholders to call the subroutine. + + call s_compute_speed_of_sound(pres_R, rho_avg, gamma_avg, pi_inf_R, H_avg, alpha_R, & + vel_avg_rms, c_sum_Yi_Phi, c_avg, qv_avg) + + if (mhd) then + call s_compute_fast_magnetosonic_speed(rho_L, c_L, B%L, norm_dir, c_fast%L, H_L) + call s_compute_fast_magnetosonic_speed(rho_R, c_R, B%R, norm_dir, c_fast%R, H_R) + end if + + if (hyper_cleaning) then ! mhd + c_fast%L = min(c_fast%L, -hyper_cleaning_speed) + c_fast%R = max(c_fast%R, hyper_cleaning_speed) + end if + + if (viscous) then + if (chemistry) then + call compute_viscosity_and_inversion(T_L, Ys_L, T_R, Ys_R, Re_L(1), Re_R(1)) + end if + $:GPU_LOOP(parallelism='[seq]') + do i = 1, 2 + Re_avg_rs${XYZ}$_vf(j, k, l, i) = 2._wp/(1._wp/Re_L(i) + 1._wp/Re_R(i)) + end do + end if + + if (wave_speeds == 1) then + if (mhd) then + s_L = min(vel_L(dir_idx(1)) - c_fast%L, vel_R(dir_idx(1)) - c_fast%R) + s_R = max(vel_R(dir_idx(1)) + c_fast%R, vel_L(dir_idx(1)) + c_fast%L) + elseif (hypoelasticity) then + s_L = min(vel_L(dir_idx(1)) - sqrt(c_L*c_L + & + (((4._wp*G_L)/3._wp) + & + tau_e_L(dir_idx_tau(1)))/rho_L) & + , vel_R(dir_idx(1)) - sqrt(c_R*c_R + & + (((4._wp*G_R)/3._wp) + & + tau_e_R(dir_idx_tau(1)))/rho_R)) + s_R = max(vel_R(dir_idx(1)) + sqrt(c_R*c_R + & + (((4._wp*G_R)/3._wp) + & + tau_e_R(dir_idx_tau(1)))/rho_R) & + , vel_L(dir_idx(1)) + sqrt(c_L*c_L + & + (((4._wp*G_L)/3._wp) + & + tau_e_L(dir_idx_tau(1)))/rho_L)) + else if (hyperelasticity) then + s_L = min(vel_L(dir_idx(1)) - sqrt(c_L*c_L + (4._wp*G_L/3._wp)/rho_L) & + , vel_R(dir_idx(1)) - sqrt(c_R*c_R + (4._wp*G_R/3._wp)/rho_R)) + s_R = max(vel_R(dir_idx(1)) + sqrt(c_R*c_R + (4._wp*G_R/3._wp)/rho_R) & + , vel_L(dir_idx(1)) + sqrt(c_L*c_L + (4._wp*G_L/3._wp)/rho_L)) + else + s_L = min(vel_L(dir_idx(1)) - c_L, vel_R(dir_idx(1)) - c_R) + s_R = max(vel_R(dir_idx(1)) + c_R, vel_L(dir_idx(1)) + c_L) + end if + + s_S = (pres_R - pres_L + rho_L*vel_L(dir_idx(1))* & + (s_L - vel_L(dir_idx(1))) - & + rho_R*vel_R(dir_idx(1))* & + (s_R - vel_R(dir_idx(1)))) & + /(rho_L*(s_L - vel_L(dir_idx(1))) - & + rho_R*(s_R - vel_R(dir_idx(1)))) + elseif (wave_speeds == 2) then + pres_SL = 5.e-1_wp*(pres_L + pres_R + rho_avg*c_avg* & + (vel_L(dir_idx(1)) - & + vel_R(dir_idx(1)))) + + pres_SR = pres_SL + + Ms_L = max(1._wp, sqrt(1._wp + ((5.e-1_wp + gamma_L)/(1._wp + gamma_L))* & + (pres_SL/pres_L - 1._wp)*pres_L/ & + ((pres_L + pi_inf_L/(1._wp + gamma_L))))) + Ms_R = max(1._wp, sqrt(1._wp + ((5.e-1_wp + gamma_R)/(1._wp + gamma_R))* & + (pres_SR/pres_R - 1._wp)*pres_R/ & + ((pres_R + pi_inf_R/(1._wp + gamma_R))))) + + s_L = vel_L(dir_idx(1)) - c_L*Ms_L + s_R = vel_R(dir_idx(1)) + c_R*Ms_R + + s_S = 5.e-1_wp*((vel_L(dir_idx(1)) + vel_R(dir_idx(1))) + & + (pres_L - pres_R)/ & + (rho_avg*c_avg)) + end if + + s_M = min(0._wp, s_L); s_P = max(0._wp, s_R) + + xi_M = (5.e-1_wp + sign(5.e-1_wp, s_L)) & + + (5.e-1_wp - sign(5.e-1_wp, s_L)) & + *(5.e-1_wp + sign(5.e-1_wp, s_R)) + xi_P = (5.e-1_wp - sign(5.e-1_wp, s_R)) & + + (5.e-1_wp - sign(5.e-1_wp, s_L)) & + *(5.e-1_wp + sign(5.e-1_wp, s_R)) + + ! Low Mach correction + if (low_Mach == 1) then + @:compute_low_Mach_correction() + else + pcorr = 0._wp + end if + + ! Mass + if (.not. relativity) then + $:GPU_LOOP(parallelism='[seq]') + do i = 1, contxe + flux_rs${XYZ}$_vf(j, k, l, i) = & + (s_M*alpha_rho_R(i)*vel_R(norm_dir) & + - s_P*alpha_rho_L(i)*vel_L(norm_dir) & + + s_M*s_P*(alpha_rho_L(i) & + - alpha_rho_R(i))) & + /(s_M - s_P) + end do + elseif (relativity) then + $:GPU_LOOP(parallelism='[seq]') + do i = 1, contxe + flux_rs${XYZ}$_vf(j, k, l, i) = & + (s_M*Ga%R*alpha_rho_R(i)*vel_R(norm_dir) & + - s_P*Ga%L*alpha_rho_L(i)*vel_L(norm_dir) & + + s_M*s_P*(Ga%L*alpha_rho_L(i) & + - Ga%R*alpha_rho_R(i))) & + /(s_M - s_P) + end do + end if + + ! Momentum + if (mhd .and. (.not. relativity)) then + $:GPU_LOOP(parallelism='[seq]') + do i = 1, 3 + ! Flux of rho*v_i in the ${XYZ}$ direction + ! = rho * v_i * v_${XYZ}$ - B_i * B_${XYZ}$ + delta_(${XYZ}$,i) * p_tot + flux_rs${XYZ}$_vf(j, k, l, contxe + i) = & + (s_M*(rho_R*vel_R(i)*vel_R(norm_dir) & + - B%R(i)*B%R(norm_dir) & + + dir_flg(i)*(pres_R + pres_mag%R)) & + - s_P*(rho_L*vel_L(i)*vel_L(norm_dir) & + - B%L(i)*B%L(norm_dir) & + + dir_flg(i)*(pres_L + pres_mag%L)) & + + s_M*s_P*(rho_L*vel_L(i) - rho_R*vel_R(i))) & + /(s_M - s_P) + end do + elseif (mhd .and. relativity) then + $:GPU_LOOP(parallelism='[seq]') + do i = 1, 3 + ! Flux of m_i in the ${XYZ}$ direction + ! = m_i * v_${XYZ}$ - b_i/Gamma * B_${XYZ}$ + delta_(${XYZ}$,i) * p_tot + flux_rs${XYZ}$_vf(j, k, l, contxe + i) = & + (s_M*(cm%R(i)*vel_R(norm_dir) & + - b4%R(i)/Ga%R*B%R(norm_dir) & + + dir_flg(i)*(pres_R + pres_mag%R)) & + - s_P*(cm%L(i)*vel_L(norm_dir) & + - b4%L(i)/Ga%L*B%L(norm_dir) & + + dir_flg(i)*(pres_L + pres_mag%L)) & + + s_M*s_P*(cm%L(i) - cm%R(i))) & + /(s_M - s_P) + end do + elseif (bubbles_euler) then + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_vels + flux_rs${XYZ}$_vf(j, k, l, contxe + dir_idx(i)) = & + (s_M*(rho_R*vel_R(dir_idx(1)) & + *vel_R(dir_idx(i)) & + + dir_flg(dir_idx(i))*(pres_R - ptilde_R)) & + - s_P*(rho_L*vel_L(dir_idx(1)) & + *vel_L(dir_idx(i)) & + + dir_flg(dir_idx(i))*(pres_L - ptilde_L)) & + + s_M*s_P*(rho_L*vel_L(dir_idx(i)) & + - rho_R*vel_R(dir_idx(i)))) & + /(s_M - s_P) & + + (s_M/s_L)*(s_P/s_R)*pcorr*(vel_R(dir_idx(i)) - vel_L(dir_idx(i))) + end do + else if (hypoelasticity) then + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_vels + flux_rs${XYZ}$_vf(j, k, l, contxe + dir_idx(i)) = & + (s_M*(rho_R*vel_R(dir_idx(1)) & + *vel_R(dir_idx(i)) & + + dir_flg(dir_idx(i))*pres_R & + - tau_e_R(dir_idx_tau(i))) & + - s_P*(rho_L*vel_L(dir_idx(1)) & + *vel_L(dir_idx(i)) & + + dir_flg(dir_idx(i))*pres_L & + - tau_e_L(dir_idx_tau(i))) & + + s_M*s_P*(rho_L*vel_L(dir_idx(i)) & + - rho_R*vel_R(dir_idx(i)))) & + /(s_M - s_P) + end do + else + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_vels + flux_rs${XYZ}$_vf(j, k, l, contxe + dir_idx(i)) = & + (s_M*(rho_R*vel_R(dir_idx(1)) & + *vel_R(dir_idx(i)) & + + dir_flg(dir_idx(i))*pres_R) & + - s_P*(rho_L*vel_L(dir_idx(1)) & + *vel_L(dir_idx(i)) & + + dir_flg(dir_idx(i))*pres_L) & + + s_M*s_P*(rho_L*vel_L(dir_idx(i)) & + - rho_R*vel_R(dir_idx(i)))) & + /(s_M - s_P) & + + (s_M/s_L)*(s_P/s_R)*pcorr*(vel_R(dir_idx(i)) - vel_L(dir_idx(i))) + end do + end if + + ! Energy + if (mhd .and. (.not. relativity)) then + ! energy flux = (E + p + p_mag) * v_${XYZ}$ - B_${XYZ}$ * (v_x*B_x + v_y*B_y + v_z*B_z) + #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 + flux_rs${XYZ}$_vf(j, k, l, E_idx) = & + (s_M*(vel_R(norm_dir)*(E_R + pres_R + pres_mag%R) - B%R(norm_dir)*(vel_R(1)*B%R(1) + vel_R(2)*B%R(2) + vel_R(3)*B%R(3))) & + - s_P*(vel_L(norm_dir)*(E_L + pres_L + pres_mag%L) - B%L(norm_dir)*(vel_L(1)*B%L(1) + vel_L(2)*B%L(2) + vel_L(3)*B%L(3))) & + + s_M*s_P*(E_L - E_R)) & + /(s_M - s_P) + #:endif + elseif (mhd .and. relativity) then + ! energy flux = m_${XYZ}$ - mass flux + ! Hard-coded for single-component for now + flux_rs${XYZ}$_vf(j, k, l, E_idx) = & + (s_M*(cm%R(norm_dir) - Ga%R*alpha_rho_R(1)*vel_R(norm_dir)) & + - s_P*(cm%L(norm_dir) - Ga%L*alpha_rho_L(1)*vel_L(norm_dir)) & + + s_M*s_P*(E_L - E_R)) & + /(s_M - s_P) + else if (bubbles_euler) then + flux_rs${XYZ}$_vf(j, k, l, E_idx) = & + (s_M*vel_R(dir_idx(1))*(E_R + pres_R - ptilde_R) & + - s_P*vel_L(dir_idx(1))*(E_L + pres_L - ptilde_L) & + + s_M*s_P*(E_L - E_R)) & + /(s_M - s_P) & + + (s_M/s_L)*(s_P/s_R)*pcorr*(vel_R_rms - vel_L_rms)/2._wp + else if (hypoelasticity) then + flux_tau_L = 0._wp; flux_tau_R = 0._wp + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_dims + flux_tau_L = flux_tau_L + tau_e_L(dir_idx_tau(i))*vel_L(dir_idx(i)) + flux_tau_R = flux_tau_R + tau_e_R(dir_idx_tau(i))*vel_R(dir_idx(i)) + end do + flux_rs${XYZ}$_vf(j, k, l, E_idx) = & + (s_M*(vel_R(dir_idx(1))*(E_R + pres_R) - flux_tau_R) & + - s_P*(vel_L(dir_idx(1))*(E_L + pres_L) - flux_tau_L) & + + s_M*s_P*(E_L - E_R))/(s_M - s_P) + else + flux_rs${XYZ}$_vf(j, k, l, E_idx) = & + (s_M*vel_R(dir_idx(1))*(E_R + pres_R) & + - s_P*vel_L(dir_idx(1))*(E_L + pres_L) & + + s_M*s_P*(E_L - E_R)) & + /(s_M - s_P) & + + (s_M/s_L)*(s_P/s_R)*pcorr*(vel_R_rms - vel_L_rms)/2._wp + end if + + ! Elastic Stresses + if (hypoelasticity) then + do i = 1, strxe - strxb + 1 !TODO: this indexing may be slow + flux_rs${XYZ}$_vf(j, k, l, strxb - 1 + i) = & + (s_M*(rho_R*vel_R(dir_idx(1)) & + *tau_e_R(i)) & + - s_P*(rho_L*vel_L(dir_idx(1)) & + *tau_e_L(i)) & + + s_M*s_P*(rho_L*tau_e_L(i) & + - rho_R*tau_e_R(i))) & + /(s_M - s_P) + end do + end if + + ! Advection + $:GPU_LOOP(parallelism='[seq]') + do i = advxb, advxe + flux_rs${XYZ}$_vf(j, k, l, i) = & + (qL_prim_rs${XYZ}$_vf(j, k, l, i) & + - qR_prim_rs${XYZ}$_vf(j + 1, k, l, i)) & + *s_M*s_P/(s_M - s_P) + flux_src_rs${XYZ}$_vf(j, k, l, i) = & + (s_M*qR_prim_rs${XYZ}$_vf(j + 1, k, l, i) & + - s_P*qL_prim_rs${XYZ}$_vf(j, k, l, i)) & + /(s_M - s_P) + end do + + if (bubbles_euler) then + ! From HLLC: Kills mass transport @ bubble gas density + if (num_fluids > 1) then + flux_rs${XYZ}$_vf(j, k, l, contxe) = 0._wp + end if + end if + + if (chemistry) then + $:GPU_LOOP(parallelism='[seq]') + do i = chemxb, chemxe + Y_L = qL_prim_rs${XYZ}$_vf(j, k, l, i) + Y_R = qR_prim_rs${XYZ}$_vf(j + 1, k, l, i) + + flux_rs${XYZ}$_vf(j, k, l, i) = (s_M*Y_R*rho_R*vel_R(dir_idx(1)) & + - s_P*Y_L*rho_L*vel_L(dir_idx(1)) & + + s_M*s_P*(Y_L*rho_L - Y_R*rho_R)) & + /(s_M - s_P) + flux_src_rs${XYZ}$_vf(j, k, l, i) = 0._wp + end do + end if + + if (mhd) then + if (n == 0) then ! 1D: d/dx flux only & Bx = Bx0 = const. + ! B_y flux = v_x * B_y - v_y * Bx0 + ! B_z flux = v_x * B_z - v_z * Bx0 + $:GPU_LOOP(parallelism='[seq]') + do i = 0, 1 + flux_rsx_vf(j, k, l, B_idx%beg + i) = (s_M*(vel_R(1)*B%R(2 + i) - vel_R(2 + i)*Bx0) & + - s_P*(vel_L(1)*B%L(2 + i) - vel_L(2 + i)*Bx0) & + + s_M*s_P*(B%L(2 + i) - B%R(2 + i)))/(s_M - s_P) + end do + else ! 2D/3D: Bx, By, Bz /= const. but zero flux component in the same direction + ! B_x d/d${XYZ}$ flux = (1 - delta(x,${XYZ}$)) * (v_${XYZ}$ * B_x - v_x * B_${XYZ}$) + ! B_y d/d${XYZ}$ flux = (1 - delta(y,${XYZ}$)) * (v_${XYZ}$ * B_y - v_y * B_${XYZ}$) + ! B_z d/d${XYZ}$ flux = (1 - delta(z,${XYZ}$)) * (v_${XYZ}$ * B_z - v_z * B_${XYZ}$) + $:GPU_LOOP(parallelism='[seq]') + do i = 0, 2 + flux_rs${XYZ}$_vf(j, k, l, B_idx%beg + i) = (s_M*(vel_R(dir_idx(1))*B%R(i + 1) - vel_R(i + 1)*B%R(norm_dir)) - & + s_P*(vel_L(dir_idx(1))*B%L(i + 1) - vel_L(i + 1)*B%L(norm_dir)) + & + s_M*s_P*(B%L(i + 1) - B%R(i + 1)))/(s_M - s_P) + end do + + if (hyper_cleaning) then + ! propagate magnetic field divergence as a wave + flux_rs${XYZ}$_vf(j, k, l, B_idx%beg + norm_dir - 1) = flux_rs${XYZ}$_vf(j, k, l, B_idx%beg + norm_dir - 1) + & + (s_M*qR_prim_rs${XYZ}$_vf(j + 1, k, l, psi_idx) - s_P*qL_prim_rs${XYZ}$_vf(j, k, l, psi_idx))/(s_M - s_P) + + flux_rs${XYZ}$_vf(j, k, l, psi_idx) = (hyper_cleaning_speed**2*(s_M*B%R(norm_dir) - s_P*B%L(norm_dir)) + s_M*s_P*(qL_prim_rs${XYZ}$_vf(j, k, l, psi_idx) - qR_prim_rs${XYZ}$_vf(j + 1, k, l, psi_idx)))/(s_M - s_P) + else + flux_rs${XYZ}$_vf(j, k, l, B_idx%beg + norm_dir - 1) = 0._wp ! Without hyperbolic cleaning, make sure flux of B_normal is identically zero + end if + end if + flux_src_rs${XYZ}$_vf(j, k, l, advxb) = 0._wp + end if + + #:if (NORM_DIR == 2) + if (cyl_coord) then + !Substituting the advective flux into the inviscid geometrical source flux + $:GPU_LOOP(parallelism='[seq]') + do i = 1, E_idx + flux_gsrc_rs${XYZ}$_vf(j, k, l, i) = flux_rs${XYZ}$_vf(j, k, l, i) + end do + ! Recalculating the radial momentum geometric source flux + flux_gsrc_rs${XYZ}$_vf(j, k, l, contxe + 2) = & + flux_rs${XYZ}$_vf(j, k, l, contxe + 2) & + - (s_M*pres_R - s_P*pres_L)/(s_M - s_P) + ! Geometrical source of the void fraction(s) is zero + $:GPU_LOOP(parallelism='[seq]') + do i = advxb, advxe + flux_gsrc_rs${XYZ}$_vf(j, k, l, i) = flux_rs${XYZ}$_vf(j, k, l, i) + end do + end if + + if (cyl_coord .and. hypoelasticity) then + ! += tau_sigmasigma using HLL + flux_gsrc_rs${XYZ}$_vf(j, k, l, contxe + 2) = & + flux_gsrc_rs${XYZ}$_vf(j, k, l, contxe + 2) + & + (s_M*tau_e_R(4) - s_P*tau_e_L(4)) & + /(s_M - s_P) + + $:GPU_LOOP(parallelism='[seq]') + do i = strxb, strxe + flux_gsrc_rs${XYZ}$_vf(j, k, l, i) = flux_rs${XYZ}$_vf(j, k, l, i) + end do + end if + #:endif + + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + end if + + #:endfor + + if (viscous .or. dummy) then + if (weno_Re_flux) then + + call s_compute_viscous_source_flux( & + qL_prim_vf(momxb:momxe), & + dqL_prim_dx_vf(momxb:momxe), & + dqL_prim_dy_vf(momxb:momxe), & + dqL_prim_dz_vf(momxb:momxe), & + qR_prim_vf(momxb:momxe), & + dqR_prim_dx_vf(momxb:momxe), & + dqR_prim_dy_vf(momxb:momxe), & + dqR_prim_dz_vf(momxb:momxe), & + flux_src_vf, norm_dir, ix, iy, iz) + else + call s_compute_viscous_source_flux( & + q_prim_vf(momxb:momxe), & + dqL_prim_dx_vf(momxb:momxe), & + dqL_prim_dy_vf(momxb:momxe), & + dqL_prim_dz_vf(momxb:momxe), & + q_prim_vf(momxb:momxe), & + dqR_prim_dx_vf(momxb:momxe), & + dqR_prim_dy_vf(momxb:momxe), & + dqR_prim_dz_vf(momxb:momxe), & + flux_src_vf, norm_dir, ix, iy, iz) + end if + end if + + call s_finalize_riemann_solver(flux_vf, flux_src_vf, & + flux_gsrc_vf, & + norm_dir) + + end subroutine s_hll_riemann_solver + + !> @brief Computes intercell fluxes using the Lax-Friedrichs (LF) approximate Riemann solver. + subroutine s_lf_riemann_solver(qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, dqL_prim_dx_vf, & + dqL_prim_dy_vf, & + dqL_prim_dz_vf, & + qL_prim_vf, & + qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf, dqR_prim_dx_vf, & + dqR_prim_dy_vf, & + dqR_prim_dz_vf, & + qR_prim_vf, & + q_prim_vf, & + flux_vf, flux_src_vf, & + flux_gsrc_vf, & + norm_dir, ix, iy, iz) + + real(wp), dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:), intent(inout) :: qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf + type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf + + type(scalar_field), allocatable, dimension(:), intent(inout) :: qL_prim_vf, qR_prim_vf + + type(scalar_field), & + allocatable, dimension(:), & + intent(inout) :: dqL_prim_dx_vf, dqR_prim_dx_vf, & + dqL_prim_dy_vf, dqR_prim_dy_vf, & + dqL_prim_dz_vf, dqR_prim_dz_vf + + ! Intercell fluxes + type(scalar_field), & + dimension(sys_size), & + intent(inout) :: flux_vf, flux_src_vf, flux_gsrc_vf + real(wp) :: flux_tau_L, flux_tau_R + + integer, intent(in) :: norm_dir + type(int_bounds_info), intent(in) :: ix, iy, iz + #:if not MFC_CASE_OPTIMIZATION and USING_AMD + real(wp), dimension(3) :: alpha_rho_L, alpha_rho_R + real(wp), dimension(3) :: vel_L, vel_R + real(wp), dimension(3) :: alpha_L, alpha_R + real(wp), dimension(10) :: Ys_L, Ys_R + real(wp), dimension(10) :: Cp_iL, Cp_iR, Xs_L, Xs_R, Gamma_iL, Gamma_iR + real(wp), dimension(10) :: Yi_avg, Phi_avg, h_iL, h_iR, h_avg_2 + real(wp), dimension(3, 3) :: vel_grad_L, vel_grad_R !< Averaged velocity gradient tensor `d(vel_i)/d(coord_j)`. + #:else + real(wp), dimension(num_fluids) :: alpha_rho_L, alpha_rho_R + real(wp), dimension(num_vels) :: vel_L, vel_R + real(wp), dimension(num_fluids) :: alpha_L, alpha_R + real(wp), dimension(num_species) :: Ys_L, Ys_R + real(wp), dimension(num_species) :: Cp_iL, Cp_iR, Xs_L, Xs_R, Gamma_iL, Gamma_iR + real(wp), dimension(num_species) :: Yi_avg, Phi_avg, h_iL, h_iR, h_avg_2 + real(wp), dimension(num_dims, num_dims) :: vel_grad_L, vel_grad_R !< Averaged velocity gradient tensor `d(vel_i)/d(coord_j)`. + #:endif + real(wp) :: rho_L, rho_R + + real(wp) :: pres_L, pres_R + real(wp) :: E_L, E_R + real(wp) :: H_L, H_R + real(wp) :: Cp_avg, Cv_avg, T_avg, eps, c_sum_Yi_Phi + real(wp) :: T_L, T_R + real(wp) :: Y_L, Y_R + real(wp) :: MW_L, MW_R + real(wp) :: R_gas_L, R_gas_R + real(wp) :: Cp_L, Cp_R + real(wp) :: Cv_L, Cv_R + real(wp) :: Gamm_L, Gamm_R + real(wp) :: gamma_L, gamma_R + real(wp) :: pi_inf_L, pi_inf_R + real(wp) :: qv_L, qv_R + real(wp) :: c_L, c_R + real(wp), dimension(6) :: tau_e_L, tau_e_R + real(wp) :: G_L, G_R + real(wp), dimension(2) :: Re_L, Re_R + real(wp), dimension(3) :: xi_field_L, xi_field_R + ! Non-Newtonian per-phase Re arrays + #:if not MFC_CASE_OPTIMIZATION and USING_AMD + real(wp), dimension(3, 2) :: Re_visc_per_phase_L, Re_visc_per_phase_R + #:else + real(wp), dimension(num_fluids, 2) :: Re_visc_per_phase_L, Re_visc_per_phase_R + #:endif + + real(wp) :: rho_avg + real(wp) :: H_avg + real(wp) :: gamma_avg + real(wp) :: c_avg + + real(wp) :: s_L, s_R, s_M, s_P, s_S + real(wp) :: xi_M, xi_P + + real(wp) :: ptilde_L, ptilde_R + real(wp) :: vel_L_rms, vel_R_rms, vel_avg_rms + real(wp) :: vel_L_tmp, vel_R_tmp + real(wp) :: Ms_L, Ms_R, pres_SL, pres_SR + real(wp) :: alpha_L_sum, alpha_R_sum + real(wp) :: zcoef, pcorr !< low Mach number correction + + type(riemann_states) :: c_fast, pres_mag + type(riemann_states_vec3) :: B + + type(riemann_states) :: Ga ! Gamma (Lorentz factor) + type(riemann_states) :: vdotB, B2 + type(riemann_states_vec3) :: b4 ! 4-magnetic field components (spatial: b4x, b4y, b4z) + type(riemann_states_vec3) :: cm ! Conservative momentum variables + + integer :: i, j, k, l, q !< Generic loop iterators + integer, dimension(3) :: idx_right_phys !< Physical (j,k,l) indices for right state. + + ! Populating the buffers of the left and right Riemann problem + ! states variables, based on the choice of boundary conditions + call s_populate_riemann_states_variables_buffers( & + qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, dqL_prim_dx_vf, & + dqL_prim_dy_vf, & + dqL_prim_dz_vf, & + qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf, dqR_prim_dx_vf, & + dqR_prim_dy_vf, & + dqR_prim_dz_vf, & + norm_dir, ix, iy, iz) + + ! Reshaping inputted data based on dimensional splitting direction + call s_initialize_riemann_solver( & + flux_src_vf, & + norm_dir) + #:for NORM_DIR, XYZ in [(1, 'x'), (2, 'y'), (3, 'z')] + + if (norm_dir == ${NORM_DIR}$) then + $:GPU_PARALLEL_LOOP(collapse=3, private='[i,j,k,l, q, alpha_rho_L,alpha_rho_R,vel_L,vel_R,alpha_L,alpha_R,tau_e_L,tau_e_R,G_L,G_R,Re_L,Re_R,rho_avg,h_avg,gamma_avg,s_L,s_R,s_S,Ys_L,Ys_R,xi_field_L,xi_field_R,Cp_iL,Cp_iR,Xs_L,Xs_R,Gamma_iL,Gamma_iR,Yi_avg,Phi_avg,h_iL,h_iR,h_avg_2,c_fast,pres_mag,B,Ga,vdotB,B2,b4,cm,pcorr,zcoef,vel_grad_L,vel_grad_R,idx_right_phys,vel_L_rms,vel_R_rms,vel_avg_rms,vel_L_tmp,vel_R_tmp,Ms_L,Ms_R,pres_SL,pres_SR,alpha_L_sum,alpha_R_sum,c_avg,pres_L,pres_R,rho_L,rho_R,gamma_L,gamma_R,pi_inf_L,pi_inf_R,qv_L,qv_R,c_L,c_R,E_L,E_R,H_L,H_R,ptilde_L,ptilde_R,s_M,s_P,xi_M,xi_P,Cp_avg,Cv_avg,T_avg,eps,c_sum_Yi_Phi,Cp_L,Cp_R,Cv_L,Cv_R,R_gas_L,R_gas_R,MW_L,MW_R,T_L,T_R,Y_L,Y_R, Re_visc_per_phase_L, Re_visc_per_phase_R]') + do l = is3%beg, is3%end + do k = is2%beg, is2%end + do j = is1%beg, is1%end + $:GPU_LOOP(parallelism='[seq]') + do i = 1, contxe + alpha_rho_L(i) = qL_prim_rs${XYZ}$_vf(j, k, l, i) + alpha_rho_R(i) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, i) + end do + + vel_L_rms = 0._wp; vel_R_rms = 0._wp + + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_vels + vel_L(i) = qL_prim_rs${XYZ}$_vf(j, k, l, contxe + i) + vel_R(i) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, contxe + i) + vel_L_rms = vel_L_rms + vel_L(i)**2._wp + vel_R_rms = vel_R_rms + vel_R(i)**2._wp + end do + + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_fluids + alpha_L(i) = qL_prim_rs${XYZ}$_vf(j, k, l, E_idx + i) + alpha_R(i) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx + i) + end do + + pres_L = qL_prim_rs${XYZ}$_vf(j, k, l, E_idx) + pres_R = qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx) + + if (mhd) then + if (n == 0) then ! 1D: constant Bx; By, Bz as variables + B%L(1) = Bx0 + B%R(1) = Bx0 + B%L(2) = qL_prim_rs${XYZ}$_vf(j, k, l, B_idx%beg) + B%R(2) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, B_idx%beg) + B%L(3) = qL_prim_rs${XYZ}$_vf(j, k, l, B_idx%beg + 1) + B%R(3) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, B_idx%beg + 1) + else ! 2D/3D: Bx, By, Bz as variables + B%L(1) = qL_prim_rs${XYZ}$_vf(j, k, l, B_idx%beg) + B%R(1) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, B_idx%beg) + B%L(2) = qL_prim_rs${XYZ}$_vf(j, k, l, B_idx%beg + 1) + B%R(2) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, B_idx%beg + 1) + B%L(3) = qL_prim_rs${XYZ}$_vf(j, k, l, B_idx%beg + 2) + B%R(3) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, B_idx%beg + 2) + end if + end if + + rho_L = 0._wp + gamma_L = 0._wp + pi_inf_L = 0._wp + qv_L = 0._wp + + rho_R = 0._wp + gamma_R = 0._wp + pi_inf_R = 0._wp + qv_R = 0._wp + + alpha_L_sum = 0._wp + alpha_R_sum = 0._wp + + pres_mag%L = 0._wp + pres_mag%R = 0._wp + + if (mpp_lim) then + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_fluids + alpha_rho_L(i) = max(0._wp, alpha_rho_L(i)) + alpha_L(i) = min(max(0._wp, alpha_L(i)), 1._wp) + alpha_L_sum = alpha_L_sum + alpha_L(i) + alpha_rho_R(i) = max(0._wp, alpha_rho_R(i)) + alpha_R(i) = min(max(0._wp, alpha_R(i)), 1._wp) + alpha_R_sum = alpha_R_sum + alpha_R(i) + end do + + alpha_L = alpha_L/max(alpha_L_sum, sgm_eps) + alpha_R = alpha_R/max(alpha_R_sum, sgm_eps) + end if + + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_fluids + rho_L = rho_L + alpha_rho_L(i) + gamma_L = gamma_L + alpha_L(i)*gammas(i) + pi_inf_L = pi_inf_L + alpha_L(i)*pi_infs(i) + qv_L = qv_L + alpha_rho_L(i)*qvs(i) + + rho_R = rho_R + alpha_rho_R(i) + gamma_R = gamma_R + alpha_R(i)*gammas(i) + pi_inf_R = pi_inf_R + alpha_R(i)*pi_infs(i) + qv_R = qv_R + alpha_rho_R(i)*qvs(i) + end do + + if (viscous) then + ! Map rotated (j,k,l) to physical (x,y,z) indices + #:if NORM_DIR == 1 + call s_compute_re_visc(q_prim_vf, & + alpha_L, j, k, l, Re_visc_per_phase_L) + call s_compute_re_visc(q_prim_vf, & + alpha_R, j + 1, k, l, Re_visc_per_phase_R) + #:elif NORM_DIR == 2 + call s_compute_re_visc(q_prim_vf, & + alpha_L, k, j, l, Re_visc_per_phase_L) + call s_compute_re_visc(q_prim_vf, & + alpha_R, k, j + 1, l, Re_visc_per_phase_R) + #:else + call s_compute_re_visc(q_prim_vf, & + alpha_L, l, k, j, Re_visc_per_phase_L) + call s_compute_re_visc(q_prim_vf, & + alpha_R, l, k, j + 1, Re_visc_per_phase_R) + #:endif + call s_compute_mixture_re( & + alpha_L, Re_visc_per_phase_L, Re_L) + call s_compute_mixture_re( & + alpha_R, Re_visc_per_phase_R, Re_R) + end if + + if (chemistry) then + $:GPU_LOOP(parallelism='[seq]') + do i = chemxb, chemxe + Ys_L(i - chemxb + 1) = qL_prim_rs${XYZ}$_vf(j, k, l, i) + Ys_R(i - chemxb + 1) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, i) + end do + + call get_mixture_molecular_weight(Ys_L, MW_L) + call get_mixture_molecular_weight(Ys_R, MW_R) + + #:if USING_AMD + Xs_L(:) = Ys_L(:)*MW_L/molecular_weights_nonparameter(:) + Xs_R(:) = Ys_R(:)*MW_R/molecular_weights_nonparameter(:) + #:else + Xs_L(:) = Ys_L(:)*MW_L/molecular_weights(:) + Xs_R(:) = Ys_R(:)*MW_R/molecular_weights(:) + #:endif + + R_gas_L = gas_constant/MW_L + R_gas_R = gas_constant/MW_R + T_L = pres_L/rho_L/R_gas_L + T_R = pres_R/rho_R/R_gas_R + + call get_species_specific_heats_r(T_L, Cp_iL) + call get_species_specific_heats_r(T_R, Cp_iR) + + if (chem_params%gamma_method == 1) then + ! gamma_method = 1: Ref. Section 2.3.1 Formulation of doi:10.7907/ZKW8-ES97. + Gamma_iL = Cp_iL/(Cp_iL - 1.0_wp) + Gamma_iR = Cp_iR/(Cp_iR - 1.0_wp) + + gamma_L = sum(Xs_L(:)/(Gamma_iL(:) - 1.0_wp)) + gamma_R = sum(Xs_R(:)/(Gamma_iR(:) - 1.0_wp)) + else if (chem_params%gamma_method == 2) then + ! gamma_method = 2: c_p / c_v where c_p, c_v are specific heats. + call get_mixture_specific_heat_cp_mass(T_L, Ys_L, Cp_L) + call get_mixture_specific_heat_cp_mass(T_R, Ys_R, Cp_R) + call get_mixture_specific_heat_cv_mass(T_L, Ys_L, Cv_L) + call get_mixture_specific_heat_cv_mass(T_R, Ys_R, Cv_R) + + Gamm_L = Cp_L/Cv_L + gamma_L = 1.0_wp/(Gamm_L - 1.0_wp) + Gamm_R = Cp_R/Cv_R + gamma_R = 1.0_wp/(Gamm_R - 1.0_wp) + end if + + call get_mixture_energy_mass(T_L, Ys_L, E_L) + call get_mixture_energy_mass(T_R, Ys_R, E_R) + + E_L = rho_L*E_L + 5.e-1*rho_L*vel_L_rms + E_R = rho_R*E_R + 5.e-1*rho_R*vel_R_rms + H_L = (E_L + pres_L)/rho_L + H_R = (E_R + pres_R)/rho_R + elseif (mhd .and. relativity) then + #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 + Ga%L = 1._wp/sqrt(1._wp - vel_L_rms) + Ga%R = 1._wp/sqrt(1._wp - vel_R_rms) + vdotB%L = vel_L(1)*B%L(1) + vel_L(2)*B%L(2) + vel_L(3)*B%L(3) + vdotB%R = vel_R(1)*B%R(1) + vel_R(2)*B%R(2) + vel_R(3)*B%R(3) + + b4%L(1:3) = B%L(1:3)/Ga%L + Ga%L*vel_L(1:3)*vdotB%L + b4%R(1:3) = B%R(1:3)/Ga%R + Ga%R*vel_R(1:3)*vdotB%R + B2%L = B%L(1)**2._wp + B%L(2)**2._wp + B%L(3)**2._wp + B2%R = B%R(1)**2._wp + B%R(2)**2._wp + B%R(3)**2._wp + + pres_mag%L = 0.5_wp*(B2%L/Ga%L**2._wp + vdotB%L**2._wp) + pres_mag%R = 0.5_wp*(B2%R/Ga%R**2._wp + vdotB%R**2._wp) + + ! Hard-coded EOS + H_L = 1._wp + (gamma_L + 1)*pres_L/rho_L + H_R = 1._wp + (gamma_R + 1)*pres_R/rho_R + + cm%L(1:3) = (rho_L*H_L*Ga%L**2 + B2%L)*vel_L(1:3) - vdotB%L*B%L(1:3) + cm%R(1:3) = (rho_R*H_R*Ga%R**2 + B2%R)*vel_R(1:3) - vdotB%R*B%R(1:3) + + E_L = rho_L*H_L*Ga%L**2 - pres_L + 0.5_wp*(B2%L + vel_L_rms*B2%L - vdotB%L**2._wp) - rho_L*Ga%L + E_R = rho_R*H_R*Ga%R**2 - pres_R + 0.5_wp*(B2%R + vel_R_rms*B2%R - vdotB%R**2._wp) - rho_R*Ga%R + #:endif + elseif (mhd .and. .not. relativity) then + pres_mag%L = 0.5_wp*(B%L(1)**2._wp + B%L(2)**2._wp + B%L(3)**2._wp) + pres_mag%R = 0.5_wp*(B%R(1)**2._wp + B%R(2)**2._wp + B%R(3)**2._wp) + E_L = gamma_L*pres_L + pi_inf_L + 0.5_wp*rho_L*vel_L_rms + qv_L + pres_mag%L + E_R = gamma_R*pres_R + pi_inf_R + 0.5_wp*rho_R*vel_R_rms + qv_R + pres_mag%R ! includes magnetic energy + H_L = (E_L + pres_L - pres_mag%L)/rho_L + H_R = (E_R + pres_R - pres_mag%R)/rho_R ! stagnation enthalpy here excludes magnetic energy (only used to find speed of sound) + else + E_L = gamma_L*pres_L + pi_inf_L + 5.e-1*rho_L*vel_L_rms + qv_L + E_R = gamma_R*pres_R + pi_inf_R + 5.e-1*rho_R*vel_R_rms + qv_R + H_L = (E_L + pres_L)/rho_L + H_R = (E_R + pres_R)/rho_R + end if + + ! elastic energy update + if (hypoelasticity) then + G_L = 0._wp; G_R = 0._wp + + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_fluids + G_L = G_L + alpha_L(i)*Gs_rs(i) + G_R = G_R + alpha_R(i)*Gs_rs(i) + end do + + if (cont_damage) then + G_L = G_L*max((1._wp - qL_prim_rs${XYZ}$_vf(j, k, l, damage_idx)), 0._wp) + G_R = G_R*max((1._wp - qR_prim_rs${XYZ}$_vf(j, k, l, damage_idx)), 0._wp) + end if + + do i = 1, strxe - strxb + 1 + tau_e_L(i) = qL_prim_rs${XYZ}$_vf(j, k, l, strxb - 1 + i) + tau_e_R(i) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, strxb - 1 + i) + ! Elastic contribution to energy if G large enough + !TODO take out if statement if stable without + if ((G_L > 1000) .and. (G_R > 1000)) then + E_L = E_L + (tau_e_L(i)*tau_e_L(i))/(4._wp*G_L) + E_R = E_R + (tau_e_R(i)*tau_e_R(i))/(4._wp*G_R) + ! Double for shear stresses + if (any(strxb - 1 + i == shear_indices)) then + E_L = E_L + (tau_e_L(i)*tau_e_L(i))/(4._wp*G_L) + E_R = E_R + (tau_e_R(i)*tau_e_R(i))/(4._wp*G_R) + end if + end if + end do + end if + + call s_compute_speed_of_sound(pres_L, rho_L, gamma_L, pi_inf_L, H_L, alpha_L, & + vel_L_rms, 0._wp, c_L, qv_L) + + call s_compute_speed_of_sound(pres_R, rho_R, gamma_R, pi_inf_R, H_R, alpha_R, & + vel_R_rms, 0._wp, c_R, qv_R) + + if (mhd) then + call s_compute_fast_magnetosonic_speed(rho_L, c_L, B%L, norm_dir, c_fast%L, H_L) + call s_compute_fast_magnetosonic_speed(rho_R, c_R, B%R, norm_dir, c_fast%R, H_R) + end if + + s_L = 0._wp; s_R = 0._wp + + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_dims + s_L = s_L + vel_L(i)**2._wp + s_R = s_R + vel_R(i)**2._wp + end do + + s_L = sqrt(s_L) + s_R = sqrt(s_R) + + s_P = max(s_L, s_R) + max(c_L, c_R) + s_M = -s_P + + s_L = s_M + s_R = s_P + + ! Low Mach correction + if (low_Mach == 1) then + @:compute_low_Mach_correction() + else + pcorr = 0._wp + end if + + ! Mass + if (.not. relativity) then + $:GPU_LOOP(parallelism='[seq]') + do i = 1, contxe + flux_rs${XYZ}$_vf(j, k, l, i) = & + (s_M*alpha_rho_R(i)*vel_R(norm_dir) & + - s_P*alpha_rho_L(i)*vel_L(norm_dir) & + + s_M*s_P*(alpha_rho_L(i) & + - alpha_rho_R(i))) & + /(s_M - s_P) + end do + elseif (relativity) then + $:GPU_LOOP(parallelism='[seq]') + do i = 1, contxe + flux_rs${XYZ}$_vf(j, k, l, i) = & + (s_M*Ga%R*alpha_rho_R(i)*vel_R(norm_dir) & + - s_P*Ga%L*alpha_rho_L(i)*vel_L(norm_dir) & + + s_M*s_P*(Ga%L*alpha_rho_L(i) & + - Ga%R*alpha_rho_R(i))) & + /(s_M - s_P) + end do + end if + + ! Momentum + if (mhd .and. (.not. relativity)) then + $:GPU_LOOP(parallelism='[seq]') + do i = 1, 3 + ! Flux of rho*v_i in the ${XYZ}$ direction + ! = rho * v_i * v_${XYZ}$ - B_i * B_${XYZ}$ + delta_(${XYZ}$,i) * p_tot + flux_rs${XYZ}$_vf(j, k, l, contxe + i) = & + (s_M*(rho_R*vel_R(i)*vel_R(norm_dir) & + - B%R(i)*B%R(norm_dir) & + + dir_flg(i)*(pres_R + pres_mag%R)) & + - s_P*(rho_L*vel_L(i)*vel_L(norm_dir) & + - B%L(i)*B%L(norm_dir) & + + dir_flg(i)*(pres_L + pres_mag%L)) & + + s_M*s_P*(rho_L*vel_L(i) - rho_R*vel_R(i))) & + /(s_M - s_P) + end do + elseif (mhd .and. relativity) then + $:GPU_LOOP(parallelism='[seq]') + do i = 1, 3 + ! Flux of m_i in the ${XYZ}$ direction + ! = m_i * v_${XYZ}$ - b_i/Gamma * B_${XYZ}$ + delta_(${XYZ}$,i) * p_tot + flux_rs${XYZ}$_vf(j, k, l, contxe + i) = & + (s_M*(cm%R(i)*vel_R(norm_dir) & + - b4%R(i)/Ga%R*B%R(norm_dir) & + + dir_flg(i)*(pres_R + pres_mag%R)) & + - s_P*(cm%L(i)*vel_L(norm_dir) & + - b4%L(i)/Ga%L*B%L(norm_dir) & + + dir_flg(i)*(pres_L + pres_mag%L)) & + + s_M*s_P*(cm%L(i) - cm%R(i))) & + /(s_M - s_P) + end do + elseif (bubbles_euler) then + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_vels + flux_rs${XYZ}$_vf(j, k, l, contxe + dir_idx(i)) = & + (s_M*(rho_R*vel_R(dir_idx(1)) & + *vel_R(dir_idx(i)) & + + dir_flg(dir_idx(i))*(pres_R - ptilde_R)) & + - s_P*(rho_L*vel_L(dir_idx(1)) & + *vel_L(dir_idx(i)) & + + dir_flg(dir_idx(i))*(pres_L - ptilde_L)) & + + s_M*s_P*(rho_L*vel_L(dir_idx(i)) & + - rho_R*vel_R(dir_idx(i)))) & + /(s_M - s_P) & + + (s_M/s_L)*(s_P/s_R)*pcorr*(vel_R(dir_idx(i)) - vel_L(dir_idx(i))) + end do + else if (hypoelasticity) then + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_vels + flux_rs${XYZ}$_vf(j, k, l, contxe + dir_idx(i)) = & + (s_M*(rho_R*vel_R(dir_idx(1)) & + *vel_R(dir_idx(i)) & + + dir_flg(dir_idx(i))*pres_R & + - tau_e_R(dir_idx_tau(i))) & + - s_P*(rho_L*vel_L(dir_idx(1)) & + *vel_L(dir_idx(i)) & + + dir_flg(dir_idx(i))*pres_L & + - tau_e_L(dir_idx_tau(i))) & + + s_M*s_P*(rho_L*vel_L(dir_idx(i)) & + - rho_R*vel_R(dir_idx(i)))) & + /(s_M - s_P) + end do + else + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_vels + flux_rs${XYZ}$_vf(j, k, l, contxe + dir_idx(i)) = & + (s_M*(rho_R*vel_R(dir_idx(1)) & + *vel_R(dir_idx(i)) & + + dir_flg(dir_idx(i))*pres_R) & + - s_P*(rho_L*vel_L(dir_idx(1)) & + *vel_L(dir_idx(i)) & + + dir_flg(dir_idx(i))*pres_L) & + + s_M*s_P*(rho_L*vel_L(dir_idx(i)) & + - rho_R*vel_R(dir_idx(i)))) & + /(s_M - s_P) & + + (s_M/s_L)*(s_P/s_R)*pcorr*(vel_R(dir_idx(i)) - vel_L(dir_idx(i))) + end do + end if + + ! Energy + if (mhd .and. (.not. relativity)) then + ! energy flux = (E + p + p_mag) * v_${XYZ}$ - B_${XYZ}$ * (v_x*B_x + v_y*B_y + v_z*B_z) + #:if not MFC_CASE_OPTIMIZATION or num_dims > 1 + flux_rs${XYZ}$_vf(j, k, l, E_idx) = & + (s_M*(vel_R(norm_dir)*(E_R + pres_R + pres_mag%R) - B%R(norm_dir)*(vel_R(1)*B%R(1) + vel_R(2)*B%R(2) + vel_R(3)*B%R(3))) & + - s_P*(vel_L(norm_dir)*(E_L + pres_L + pres_mag%L) - B%L(norm_dir)*(vel_L(1)*B%L(1) + vel_L(2)*B%L(2) + vel_L(3)*B%L(3))) & + + s_M*s_P*(E_L - E_R)) & + /(s_M - s_P) + #:endif + elseif (mhd .and. relativity) then + ! energy flux = m_${XYZ}$ - mass flux + ! Hard-coded for single-component for now + flux_rs${XYZ}$_vf(j, k, l, E_idx) = & + (s_M*(cm%R(norm_dir) - Ga%R*alpha_rho_R(1)*vel_R(norm_dir)) & + - s_P*(cm%L(norm_dir) - Ga%L*alpha_rho_L(1)*vel_L(norm_dir)) & + + s_M*s_P*(E_L - E_R)) & + /(s_M - s_P) + else if (bubbles_euler) then + flux_rs${XYZ}$_vf(j, k, l, E_idx) = & + (s_M*vel_R(dir_idx(1))*(E_R + pres_R - ptilde_R) & + - s_P*vel_L(dir_idx(1))*(E_L + pres_L - ptilde_L) & + + s_M*s_P*(E_L - E_R)) & + /(s_M - s_P) & + + (s_M/s_L)*(s_P/s_R)*pcorr*(vel_R_rms - vel_L_rms)/2._wp + else if (hypoelasticity) then + flux_tau_L = 0._wp; flux_tau_R = 0._wp + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_dims + flux_tau_L = flux_tau_L + tau_e_L(dir_idx_tau(i))*vel_L(dir_idx(i)) + flux_tau_R = flux_tau_R + tau_e_R(dir_idx_tau(i))*vel_R(dir_idx(i)) + end do + flux_rs${XYZ}$_vf(j, k, l, E_idx) = & + (s_M*(vel_R(dir_idx(1))*(E_R + pres_R) - flux_tau_R) & + - s_P*(vel_L(dir_idx(1))*(E_L + pres_L) - flux_tau_L) & + + s_M*s_P*(E_L - E_R))/(s_M - s_P) + else + flux_rs${XYZ}$_vf(j, k, l, E_idx) = & + (s_M*vel_R(dir_idx(1))*(E_R + pres_R) & + - s_P*vel_L(dir_idx(1))*(E_L + pres_L) & + + s_M*s_P*(E_L - E_R)) & + /(s_M - s_P) & + + (s_M/s_L)*(s_P/s_R)*pcorr*(vel_R_rms - vel_L_rms)/2._wp + end if + + ! Elastic Stresses + if (hypoelasticity) then + do i = 1, strxe - strxb + 1 !TODO: this indexing may be slow + flux_rs${XYZ}$_vf(j, k, l, strxb - 1 + i) = & + (s_M*(rho_R*vel_R(dir_idx(1)) & + *tau_e_R(i)) & + - s_P*(rho_L*vel_L(dir_idx(1)) & + *tau_e_L(i)) & + + s_M*s_P*(rho_L*tau_e_L(i) & + - rho_R*tau_e_R(i))) & + /(s_M - s_P) + end do + end if + + ! Advection + $:GPU_LOOP(parallelism='[seq]') + do i = advxb, advxe + flux_rs${XYZ}$_vf(j, k, l, i) = & + (qL_prim_rs${XYZ}$_vf(j, k, l, i) & + - qR_prim_rs${XYZ}$_vf(j + 1, k, l, i)) & + *s_M*s_P/(s_M - s_P) + flux_src_rs${XYZ}$_vf(j, k, l, i) = & + (s_M*qR_prim_rs${XYZ}$_vf(j + 1, k, l, i) & + - s_P*qL_prim_rs${XYZ}$_vf(j, k, l, i)) & + /(s_M - s_P) + end do + + if (bubbles_euler) then + ! From HLLC: Kills mass transport @ bubble gas density + if (num_fluids > 1) then + flux_rs${XYZ}$_vf(j, k, l, contxe) = 0._wp + end if + end if + + if (chemistry) then + $:GPU_LOOP(parallelism='[seq]') + do i = chemxb, chemxe + Y_L = qL_prim_rs${XYZ}$_vf(j, k, l, i) + Y_R = qR_prim_rs${XYZ}$_vf(j + 1, k, l, i) + + flux_rs${XYZ}$_vf(j, k, l, i) = (s_M*Y_R*rho_R*vel_R(dir_idx(1)) & + - s_P*Y_L*rho_L*vel_L(dir_idx(1)) & + + s_M*s_P*(Y_L*rho_L - Y_R*rho_R)) & + /(s_M - s_P) + flux_src_rs${XYZ}$_vf(j, k, l, i) = 0._wp + end do + end if + + if (mhd) then + if (n == 0) then ! 1D: d/dx flux only & Bx = Bx0 = const. + ! B_y flux = v_x * B_y - v_y * Bx0 + ! B_z flux = v_x * B_z - v_z * Bx0 + $:GPU_LOOP(parallelism='[seq]') + do i = 0, 1 + flux_rsx_vf(j, k, l, B_idx%beg + i) = (s_M*(vel_R(1)*B%R(2 + i) - vel_R(2 + i)*Bx0) & + - s_P*(vel_L(1)*B%L(2 + i) - vel_L(2 + i)*Bx0) & + + s_M*s_P*(B%L(2 + i) - B%R(2 + i)))/(s_M - s_P) + end do + else ! 2D/3D: Bx, By, Bz /= const. but zero flux component in the same direction + ! B_x d/d${XYZ}$ flux = (1 - delta(x,${XYZ}$)) * (v_${XYZ}$ * B_x - v_x * B_${XYZ}$) + ! B_y d/d${XYZ}$ flux = (1 - delta(y,${XYZ}$)) * (v_${XYZ}$ * B_y - v_y * B_${XYZ}$) + ! B_z d/d${XYZ}$ flux = (1 - delta(z,${XYZ}$)) * (v_${XYZ}$ * B_z - v_z * B_${XYZ}$) + $:GPU_LOOP(parallelism='[seq]') + do i = 0, 2 + flux_rs${XYZ}$_vf(j, k, l, B_idx%beg + i) = (1 - dir_flg(i + 1))*( & + s_M*(vel_R(dir_idx(1))*B%R(i + 1) - vel_R(i + 1)*B%R(norm_dir)) - & + s_P*(vel_L(dir_idx(1))*B%L(i + 1) - vel_L(i + 1)*B%L(norm_dir)) + & + s_M*s_P*(B%L(i + 1) - B%R(i + 1)))/(s_M - s_P) + end do + end if + flux_src_rs${XYZ}$_vf(j, k, l, advxb) = 0._wp + end if + + #:if (NORM_DIR == 2) + if (cyl_coord) then + !Substituting the advective flux into the inviscid geometrical source flux + $:GPU_LOOP(parallelism='[seq]') + do i = 1, E_idx + flux_gsrc_rs${XYZ}$_vf(j, k, l, i) = flux_rs${XYZ}$_vf(j, k, l, i) + end do + ! Recalculating the radial momentum geometric source flux + flux_gsrc_rs${XYZ}$_vf(j, k, l, contxe + 2) = & + flux_rs${XYZ}$_vf(j, k, l, contxe + 2) & + - (s_M*pres_R - s_P*pres_L)/(s_M - s_P) + ! Geometrical source of the void fraction(s) is zero + $:GPU_LOOP(parallelism='[seq]') + do i = advxb, advxe + flux_gsrc_rs${XYZ}$_vf(j, k, l, i) = flux_rs${XYZ}$_vf(j, k, l, i) + end do + end if + + if (cyl_coord .and. hypoelasticity) then + ! += tau_sigmasigma using HLL + flux_gsrc_rs${XYZ}$_vf(j, k, l, contxe + 2) = & + flux_gsrc_rs${XYZ}$_vf(j, k, l, contxe + 2) + & + (s_M*tau_e_R(4) - s_P*tau_e_L(4)) & + /(s_M - s_P) + + $:GPU_LOOP(parallelism='[seq]') + do i = strxb, strxe + flux_gsrc_rs${XYZ}$_vf(j, k, l, i) = flux_rs${XYZ}$_vf(j, k, l, i) + end do + end if + #:endif + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + end if + + #:endfor + + if (viscous .or. dummy) then + $:GPU_PARALLEL_LOOP(collapse=3, private='[i,j,k,l, idx_right_phys, vel_grad_L, vel_grad_R, alpha_L, alpha_R, vel_L, vel_R, Re_L, Re_R, Re_visc_per_phase_L, Re_visc_per_phase_R]', copyin='[norm_dir]') + do l = isz%beg, isz%end + do k = isy%beg, isy%end + do j = isx%beg, isx%end + idx_right_phys(1) = j + idx_right_phys(2) = k + idx_right_phys(3) = l + idx_right_phys(norm_dir) = idx_right_phys(norm_dir) + 1 + + if (norm_dir == 1) then + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_fluids + alpha_L(i) = qL_prim_rsx_vf(j, k, l, E_idx + i) + alpha_R(i) = qR_prim_rsx_vf(j + 1, k, l, E_idx + i) + end do + + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_dims + vel_L(i) = qL_prim_rsx_vf(j, k, l, momxb + i - 1) + vel_R(i) = qR_prim_rsx_vf(j + 1, k, l, momxb + i - 1) + end do + else if (norm_dir == 2) then + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_fluids + alpha_L(i) = qL_prim_rsy_vf(k, j, l, E_idx + i) + alpha_R(i) = qR_prim_rsy_vf(k + 1, j, l, E_idx + i) + end do + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_dims + vel_L(i) = qL_prim_rsy_vf(k, j, l, momxb + i - 1) + vel_R(i) = qR_prim_rsy_vf(k + 1, j, l, momxb + i - 1) + end do + else + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_fluids + alpha_L(i) = qL_prim_rsz_vf(l, k, j, E_idx + i) + alpha_R(i) = qR_prim_rsz_vf(l + 1, k, j, E_idx + i) + end do + + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_dims + vel_L(i) = qL_prim_rsz_vf(l, k, j, momxb + i - 1) + vel_R(i) = qR_prim_rsz_vf(l + 1, k, j, momxb + i - 1) + end do + end if + + call s_compute_re_visc(q_prim_vf, & + alpha_L, j, k, l, Re_visc_per_phase_L) + call s_compute_re_visc(q_prim_vf, & + alpha_R, idx_right_phys(1), idx_right_phys(2), idx_right_phys(3), Re_visc_per_phase_R) + call s_compute_mixture_re( & + alpha_L, Re_visc_per_phase_L, Re_L) + call s_compute_mixture_re( & + alpha_R, Re_visc_per_phase_R, Re_R) + + if (shear_stress) then + + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_dims + vel_grad_L(i, 1) = (dqL_prim_dx_vf(momxb + i - 1)%sf(j, k, l)/Re_L(1)) + vel_grad_R(i, 1) = (dqR_prim_dx_vf(momxb + i - 1)%sf(idx_right_phys(1), idx_right_phys(2), idx_right_phys(3))/Re_R(1)) + #:if not MFC_CASE_OPTIMIZATION or num_dims > 1 + if (num_dims > 1) then + vel_grad_L(i, 2) = (dqL_prim_dy_vf(momxb + i - 1)%sf(j, k, l)/Re_L(1)) + vel_grad_R(i, 2) = (dqR_prim_dy_vf(momxb + i - 1)%sf(idx_right_phys(1), idx_right_phys(2), idx_right_phys(3))/Re_R(1)) + end if + #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 + if (num_dims > 2) then + vel_grad_L(i, 3) = (dqL_prim_dz_vf(momxb + i - 1)%sf(j, k, l)/Re_L(1)) + vel_grad_R(i, 3) = (dqR_prim_dz_vf(momxb + i - 1)%sf(idx_right_phys(1), idx_right_phys(2), idx_right_phys(3))/Re_R(1)) + end if + #:endif + #:endif + end do + + if (norm_dir == 1) then + flux_src_vf(momxb)%sf(j, k, l) = flux_src_vf(momxb)%sf(j, k, l) - (4._wp/3._wp)*0.5_wp*(vel_grad_L(1, 1) + vel_grad_R(1, 1)) + flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - (4._wp/3._wp)*0.5_wp*(vel_grad_L(1, 1)*vel_L(1) + vel_grad_R(1, 1)*vel_R(1)) + #:if not MFC_CASE_OPTIMIZATION or num_dims > 1 + if (num_dims > 1) then + flux_src_vf(momxb)%sf(j, k, l) = flux_src_vf(momxb)%sf(j, k, l) - (-2._wp/3._wp)*0.5_wp*(vel_grad_L(2, 2) + vel_grad_R(2, 2)) + flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - (-2._wp/3._wp)*0.5_wp*(vel_grad_L(2, 2)*vel_L(1) + vel_grad_R(2, 2)*vel_R(1)) + + flux_src_vf(momxb + 1)%sf(j, k, l) = flux_src_vf(momxb + 1)%sf(j, k, l) - 0.5_wp*(vel_grad_L(1, 2) + vel_grad_R(1, 2)) - 0.5_wp*(vel_grad_L(2, 1) + vel_grad_R(2, 1)) + flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - 0.5_wp*(vel_grad_L(1, 2)*vel_L(2) + vel_grad_R(1, 2)*vel_R(2)) - 0.5_wp*(vel_grad_L(2, 1)*vel_L(2) + vel_grad_R(2, 1)*vel_R(2)) + #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 + if (num_dims > 2) then + flux_src_vf(momxb)%sf(j, k, l) = flux_src_vf(momxb)%sf(j, k, l) - (-2._wp/3._wp)*0.5_wp*(vel_grad_L(3, 3) + vel_grad_R(3, 3)) + flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - (-2._wp/3._wp)*0.5_wp*(vel_grad_L(3, 3)*vel_L(1) + vel_grad_R(3, 3)*vel_R(1)) + + flux_src_vf(momxb + 2)%sf(j, k, l) = flux_src_vf(momxb + 2)%sf(j, k, l) - 0.5_wp*(vel_grad_L(1, 3) + vel_grad_R(1, 3)) - 0.5_wp*(vel_grad_L(3, 1) + vel_grad_R(3, 1)) + flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - 0.5_wp*(vel_grad_L(1, 3)*vel_L(3) + vel_grad_R(1, 3)*vel_R(3)) - 0.5_wp*(vel_grad_L(3, 1)*vel_L(3) + vel_grad_R(3, 1)*vel_R(3)) + end if + #:endif + end if + #:endif + + else if (norm_dir == 2) then + #:if not MFC_CASE_OPTIMIZATION or num_dims > 1 + flux_src_vf(momxb + 1)%sf(j, k, l) = flux_src_vf(momxb + 1)%sf(j, k, l) - (-2._wp/3._wp)*0.5_wp*(vel_grad_L(1, 1) + vel_grad_R(1, 1)) + flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - (-2._wp/3._wp)*0.5_wp*(vel_grad_L(1, 1)*vel_L(2) + vel_grad_R(1, 1)*vel_R(2)) + + flux_src_vf(momxb + 1)%sf(j, k, l) = flux_src_vf(momxb + 1)%sf(j, k, l) - (4._wp/3._wp)*0.5_wp*(vel_grad_L(2, 2) + vel_grad_R(2, 2)) + flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - (4._wp/3._wp)*0.5_wp*(vel_grad_L(2, 2)*vel_L(2) + vel_grad_R(2, 2)*vel_R(2)) + + flux_src_vf(momxb)%sf(j, k, l) = flux_src_vf(momxb)%sf(j, k, l) - 0.5_wp*(vel_grad_L(1, 2) + vel_grad_R(1, 2)) - 0.5_wp*(vel_grad_L(2, 1) + vel_grad_R(2, 1)) + flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - 0.5_wp*(vel_grad_L(1, 2)*vel_L(1) + vel_grad_R(1, 2)*vel_R(1)) - 0.5_wp*(vel_grad_L(2, 1)*vel_L(1) + vel_grad_R(2, 1)*vel_R(1)) + #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 + if (num_dims > 2) then + flux_src_vf(momxb + 1)%sf(j, k, l) = flux_src_vf(momxb + 1)%sf(j, k, l) - (-2._wp/3._wp)*0.5_wp*(vel_grad_L(3, 3) + vel_grad_R(3, 3)) + flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - (-2._wp/3._wp)*0.5_wp*(vel_grad_L(3, 3)*vel_L(2) + vel_grad_R(3, 3)*vel_R(2)) + + flux_src_vf(momxb + 2)%sf(j, k, l) = flux_src_vf(momxb + 2)%sf(j, k, l) - 0.5_wp*(vel_grad_L(2, 3) + vel_grad_R(2, 3)) - 0.5_wp*(vel_grad_L(3, 2) + vel_grad_R(3, 2)) + flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - 0.5_wp*(vel_grad_L(2, 3)*vel_L(3) + vel_grad_R(2, 3)*vel_R(3)) - 0.5_wp*(vel_grad_L(3, 2)*vel_L(3) + vel_grad_R(3, 2)*vel_R(3)) + end if + #:endif + #:endif + else + #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 + flux_src_vf(momxb + 2)%sf(j, k, l) = flux_src_vf(momxb + 2)%sf(j, k, l) - (-2._wp/3._wp)*0.5_wp*(vel_grad_L(1, 1) + vel_grad_R(1, 1)) + flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - (-2._wp/3._wp)*0.5_wp*(vel_grad_L(1, 1)*vel_L(3) + vel_grad_R(1, 1)*vel_R(3)) + + flux_src_vf(momxb + 2)%sf(j, k, l) = flux_src_vf(momxb + 2)%sf(j, k, l) - (-2._wp/3._wp)*0.5_wp*(vel_grad_L(2, 2) + vel_grad_R(2, 2)) + flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - (-2._wp/3._wp)*0.5_wp*(vel_grad_L(2, 2)*vel_L(3) + vel_grad_R(2, 2)*vel_R(3)) + + flux_src_vf(momxb)%sf(j, k, l) = flux_src_vf(momxb)%sf(j, k, l) - 0.5_wp*(vel_grad_L(1, 3) + vel_grad_R(1, 3)) - 0.5_wp*(vel_grad_L(3, 1) + vel_grad_R(3, 1)) + flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - 0.5_wp*(vel_grad_L(1, 3)*vel_L(1) + vel_grad_R(1, 3)*vel_R(1)) - 0.5_wp*(vel_grad_L(3, 1)*vel_L(1) + vel_grad_R(3, 1)*vel_R(1)) + + flux_src_vf(momxb + 2)%sf(j, k, l) = flux_src_vf(momxb + 2)%sf(j, k, l) - (4._wp/3._wp)*0.5_wp*(vel_grad_L(3, 3) + vel_grad_R(3, 3)) + flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - (4._wp/3._wp)*0.5_wp*(vel_grad_L(3, 3)*vel_L(3) + vel_grad_R(3, 3)*vel_R(3)) + + flux_src_vf(momxb + 1)%sf(j, k, l) = flux_src_vf(momxb + 1)%sf(j, k, l) - 0.5_wp*(vel_grad_L(2, 3) + vel_grad_R(2, 3)) - 0.5_wp*(vel_grad_L(3, 2) + vel_grad_R(3, 2)) + flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - 0.5_wp*(vel_grad_L(2, 3)*vel_L(2) + vel_grad_R(2, 3)*vel_R(2)) - 0.5_wp*(vel_grad_L(3, 2)*vel_L(2) + vel_grad_R(3, 2)*vel_R(2)) + #:endif + end if + end if + + if (bulk_stress) then + + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_dims + vel_grad_L(i, 1) = (dqL_prim_dx_vf(momxb + i - 1)%sf(j, k, l)/Re_L(2)) + vel_grad_R(i, 1) = (dqR_prim_dx_vf(momxb + i - 1)%sf(idx_right_phys(1), idx_right_phys(2), idx_right_phys(3))/Re_R(2)) + #:if not MFC_CASE_OPTIMIZATION or num_dims > 1 + if (num_dims > 1) then + vel_grad_L(i, 2) = (dqL_prim_dy_vf(momxb + i - 1)%sf(j, k, l)/Re_L(2)) + vel_grad_R(i, 2) = (dqR_prim_dy_vf(momxb + i - 1)%sf(idx_right_phys(1), idx_right_phys(2), idx_right_phys(3))/Re_R(2)) + end if + #:endif + #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 + if (num_dims > 2) then + vel_grad_L(i, 3) = (dqL_prim_dz_vf(momxb + i - 1)%sf(j, k, l)/Re_L(2)) + vel_grad_R(i, 3) = (dqR_prim_dz_vf(momxb + i - 1)%sf(idx_right_phys(1), idx_right_phys(2), idx_right_phys(3))/Re_R(2)) + end if + #:endif + end do + + if (norm_dir == 1) then + flux_src_vf(momxb)%sf(j, k, l) = flux_src_vf(momxb)%sf(j, k, l) - 0.5_wp*(vel_grad_L(1, 1) + vel_grad_R(1, 1)) + flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - 0.5_wp*(vel_grad_L(1, 1)*vel_L(1) + vel_grad_R(1, 1)*vel_R(1)) + #:if not MFC_CASE_OPTIMIZATION or num_dims > 1 + if (num_dims > 1) then + flux_src_vf(momxb)%sf(j, k, l) = flux_src_vf(momxb)%sf(j, k, l) - 0.5_wp*(vel_grad_L(2, 2) + vel_grad_R(2, 2)) + flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - 0.5_wp*(vel_grad_L(2, 2)*vel_L(1) + vel_grad_R(2, 2)*vel_R(1)) + + #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 + if (num_dims > 2) then + flux_src_vf(momxb)%sf(j, k, l) = flux_src_vf(momxb)%sf(j, k, l) - 0.5_wp*(vel_grad_L(3, 3) + vel_grad_R(3, 3)) + flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - 0.5_wp*(vel_grad_L(3, 3)*vel_L(1) + vel_grad_R(3, 3)*vel_R(1)) + end if + #:endif + end if + #:endif + + else if (norm_dir == 2) then + #:if not MFC_CASE_OPTIMIZATION or num_dims > 1 + flux_src_vf(momxb + 1)%sf(j, k, l) = flux_src_vf(momxb + 1)%sf(j, k, l) - 0.5_wp*(vel_grad_L(1, 1) + vel_grad_R(1, 1)) + flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - 0.5_wp*(vel_grad_L(1, 1)*vel_L(2) + vel_grad_R(1, 1)*vel_R(2)) + + flux_src_vf(momxb + 1)%sf(j, k, l) = flux_src_vf(momxb + 1)%sf(j, k, l) - 0.5_wp*(vel_grad_L(2, 2) + vel_grad_R(2, 2)) + flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - 0.5_wp*(vel_grad_L(2, 2)*vel_L(2) + vel_grad_R(2, 2)*vel_R(2)) + + #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 + if (num_dims > 2) then + flux_src_vf(momxb + 1)%sf(j, k, l) = flux_src_vf(momxb + 1)%sf(j, k, l) - 0.5_wp*(vel_grad_L(3, 3) + vel_grad_R(3, 3)) + flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - 0.5_wp*(vel_grad_L(3, 3)*vel_L(2) + vel_grad_R(3, 3)*vel_R(2)) + end if + #:endif + #:endif + else + #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 + flux_src_vf(momxb + 2)%sf(j, k, l) = flux_src_vf(momxb + 2)%sf(j, k, l) - 0.5_wp*(vel_grad_L(1, 1) + vel_grad_R(1, 1)) + flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - 0.5_wp*(vel_grad_L(1, 1)*vel_L(3) + vel_grad_R(1, 1)*vel_R(3)) + + flux_src_vf(momxb + 2)%sf(j, k, l) = flux_src_vf(momxb + 2)%sf(j, k, l) - 0.5_wp*(vel_grad_L(2, 2) + vel_grad_R(2, 2)) + flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - 0.5_wp*(vel_grad_L(2, 2)*vel_L(3) + vel_grad_R(2, 2)*vel_R(3)) + + flux_src_vf(momxb + 2)%sf(j, k, l) = flux_src_vf(momxb + 2)%sf(j, k, l) - 0.5_wp*(vel_grad_L(3, 3) + vel_grad_R(3, 3)) + flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - 0.5_wp*(vel_grad_L(3, 3)*vel_L(3) + vel_grad_R(3, 3)*vel_R(3)) + #:endif + end if + + end if + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + + end if + + call s_finalize_riemann_solver(flux_vf, flux_src_vf, & + flux_gsrc_vf, & + norm_dir) + + end subroutine s_lf_riemann_solver + + !> This procedure is the implementation of the Harten, Lax, + !! van Leer, and contact (HLLC) approximate Riemann solver, + !! see Toro (1999) and Johnsen (2007). The viscous and the + !! surface tension effects have been included by modifying + !! the exact Riemann solver of Perigaud and Saurel (2005). + !! @param qL_prim_rsx_vf Left WENO-reconstructed cell-boundary values (x-dir) + !! @param qL_prim_rsy_vf Left WENO-reconstructed cell-boundary values (y-dir) + !! @param qL_prim_rsz_vf Left WENO-reconstructed cell-boundary values (z-dir) + !! @param dqL_prim_dx_vf The left WENO-reconstructed cell-boundary values of the + !! first-order x-dir spatial derivatives + !! @param dqL_prim_dy_vf The left WENO-reconstructed cell-boundary values of the + !! first-order y-dir spatial derivatives + !! @param dqL_prim_dz_vf The left WENO-reconstructed cell-boundary values of the + !! first-order z-dir spatial derivatives + !! @param qL_prim_vf The left WENO-reconstructed cell-boundary values of the + !! cell-average primitive variables + !! @param qR_prim_rsx_vf Right WENO-reconstructed cell-boundary values (x-dir) + !! @param qR_prim_rsy_vf Right WENO-reconstructed cell-boundary values (y-dir) + !! @param qR_prim_rsz_vf Right WENO-reconstructed cell-boundary values (z-dir) + !! @param dqR_prim_dx_vf The right WENO-reconstructed cell-boundary values of the + !! first-order x-dir spatial derivatives + !! @param dqR_prim_dy_vf The right WENO-reconstructed cell-boundary values of the + !! first-order y-dir spatial derivatives + !! @param dqR_prim_dz_vf The right WENO-reconstructed cell-boundary values of the + !! first-order z-dir spatial derivatives + !! @param qR_prim_vf The right WENO-reconstructed cell-boundary values of the + !! cell-average primitive variables + !! @param q_prim_vf Cell-averaged primitive variables + !! @param flux_vf Intra-cell fluxes + !! @param flux_src_vf Intra-cell fluxes sources + !! @param flux_gsrc_vf Intra-cell geometric fluxes sources + !! @param norm_dir Dir. splitting direction + !! @param ix Index bounds in the x-dir + !! @param iy Index bounds in the y-dir + !! @param iz Index bounds in the z-dir + subroutine s_hllc_riemann_solver(qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, dqL_prim_dx_vf, & + dqL_prim_dy_vf, & + dqL_prim_dz_vf, & + qL_prim_vf, & + qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf, dqR_prim_dx_vf, & + dqR_prim_dy_vf, & + dqR_prim_dz_vf, & + qR_prim_vf, & + q_prim_vf, & + flux_vf, flux_src_vf, & + flux_gsrc_vf, & + norm_dir, ix, iy, iz) + + real(wp), dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:), intent(inout) :: qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf + type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf + type(scalar_field), allocatable, dimension(:), intent(inout) :: qL_prim_vf, qR_prim_vf + + type(scalar_field), & + allocatable, dimension(:), & + intent(inout) :: dqL_prim_dx_vf, dqR_prim_dx_vf, & + dqL_prim_dy_vf, dqR_prim_dy_vf, & + dqL_prim_dz_vf, dqR_prim_dz_vf + + ! Intercell fluxes + type(scalar_field), & + dimension(sys_size), & + intent(inout) :: flux_vf, flux_src_vf, flux_gsrc_vf + + integer, intent(in) :: norm_dir + type(int_bounds_info), intent(in) :: ix, iy, iz + + #:if not MFC_CASE_OPTIMIZATION and USING_AMD + real(wp), dimension(3) :: alpha_rho_L, alpha_rho_R + real(wp), dimension(3) :: alpha_L, alpha_R + real(wp), dimension(3) :: vel_L, vel_R + #:else + real(wp), dimension(num_fluids) :: alpha_rho_L, alpha_rho_R + real(wp), dimension(num_fluids) :: alpha_L, alpha_R + real(wp), dimension(num_dims) :: vel_L, vel_R + #:endif + + real(wp) :: rho_L, rho_R + real(wp) :: pres_L, pres_R + real(wp) :: E_L, E_R + real(wp) :: H_L, H_R + #:if not MFC_CASE_OPTIMIZATION and USING_AMD + real(wp), dimension(10) :: Ys_L, Ys_R, Xs_L, Xs_R, Gamma_iL, Gamma_iR, Cp_iL, Cp_iR + real(wp), dimension(10) :: Yi_avg, Phi_avg, h_iL, h_iR, h_avg_2 + #:else + real(wp), dimension(num_species) :: Ys_L, Ys_R, Xs_L, Xs_R, Gamma_iL, Gamma_iR, Cp_iL, Cp_iR + real(wp), dimension(num_species) :: Yi_avg, Phi_avg, h_iL, h_iR, h_avg_2 + #:endif + real(wp) :: Cp_avg, Cv_avg, T_avg, c_sum_Yi_Phi, eps + real(wp) :: T_L, T_R + real(wp) :: MW_L, MW_R + real(wp) :: R_gas_L, R_gas_R + real(wp) :: Cp_L, Cp_R + real(wp) :: Cv_L, Cv_R + real(wp) :: Gamm_L, Gamm_R + real(wp) :: Y_L, Y_R + real(wp) :: gamma_L, gamma_R + real(wp) :: pi_inf_L, pi_inf_R + real(wp) :: qv_L, qv_R + real(wp) :: c_L, c_R + real(wp), dimension(2) :: Re_L, Re_R + ! Non-Newtonian per-phase Re arrays + #:if not MFC_CASE_OPTIMIZATION and USING_AMD + real(wp), dimension(3, 2) :: Re_visc_per_phase_L, Re_visc_per_phase_R + #:else + real(wp), dimension(num_fluids, 2) :: Re_visc_per_phase_L, Re_visc_per_phase_R + #:endif + + real(wp) :: rho_avg + real(wp) :: H_avg + real(wp) :: gamma_avg + real(wp) :: qv_avg + real(wp) :: c_avg + + real(wp) :: s_L, s_R, s_M, s_P, s_S + real(wp) :: xi_L, xi_R !< Left and right wave speeds functions + real(wp) :: xi_M, xi_P + real(wp) :: xi_MP, xi_PP + #:if not MFC_CASE_OPTIMIZATION and USING_AMD + real(wp), dimension(3) :: R0_L, R0_R + real(wp), dimension(3) :: V0_L, V0_R + real(wp), dimension(3) :: P0_L, P0_R + real(wp), dimension(3) :: pbw_L, pbw_R + #:else + real(wp), dimension(nb) :: R0_L, R0_R + real(wp), dimension(nb) :: V0_L, V0_R + real(wp), dimension(nb) :: P0_L, P0_R + real(wp), dimension(nb) :: pbw_L, pbw_R + #:endif + + real(wp) :: alpha_L_sum, alpha_R_sum, nbub_L, nbub_R + real(wp) :: ptilde_L, ptilde_R + + real(wp) :: PbwR3Lbar, PbwR3Rbar + real(wp) :: R3Lbar, R3Rbar + real(wp) :: R3V2Lbar, R3V2Rbar + + real(wp), dimension(6) :: tau_e_L, tau_e_R + #:if not MFC_CASE_OPTIMIZATION and USING_AMD + real(wp), dimension(3) :: xi_field_L, xi_field_R + #:else + real(wp), dimension(num_dims) :: xi_field_L, xi_field_R + #:endif + real(wp) :: G_L, G_R + + real(wp) :: vel_L_rms, vel_R_rms, vel_avg_rms + real(wp) :: vel_L_tmp, vel_R_tmp + real(wp) :: rho_Star, E_Star, p_Star, p_K_Star, vel_K_star + real(wp) :: pres_SL, pres_SR, Ms_L, Ms_R + real(wp) :: flux_ene_e + real(wp) :: zcoef, pcorr !< low Mach number correction + + integer :: Re_max, i, j, k, l, q !< Generic loop iterators + + ! Populating the buffers of the left and right Riemann problem + ! states variables, based on the choice of boundary conditions + + call s_populate_riemann_states_variables_buffers( & + qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, dqL_prim_dx_vf, & + dqL_prim_dy_vf, & + dqL_prim_dz_vf, & + qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf, dqR_prim_dx_vf, & + dqR_prim_dy_vf, & + dqR_prim_dz_vf, & + norm_dir, ix, iy, iz) + + ! Reshaping inputted data based on dimensional splitting direction + + call s_initialize_riemann_solver( & + flux_src_vf, & + norm_dir) + + #:for NORM_DIR, XYZ in [(1, 'x'), (2, 'y'), (3, 'z')] + + if (norm_dir == ${NORM_DIR}$) then + + ! 6-EQUATION MODEL WITH HLLC + if (model_eqns == 3) then + !ME3 + $:GPU_PARALLEL_LOOP(collapse=3, private='[i,j,k,l, q, vel_L, vel_R, Re_L, Re_R, alpha_L, alpha_R, Ys_L, Ys_R, Xs_L, Xs_R, Gamma_iL, Gamma_iR, Cp_iL, Cp_iR, Yi_avg, Phi_avg, h_iL, h_iR, h_avg_2, tau_e_L, tau_e_R, flux_ene_e, xi_field_L, xi_field_R, pcorr, zcoef, rho_L, rho_R, pres_L, pres_R, E_L, E_R, H_L, H_R, Cp_avg, Cv_avg, T_avg, eps, c_sum_Yi_Phi, T_L, T_R, Y_L, Y_R, MW_L, MW_R, R_gas_L, R_gas_R, Cp_L, Cp_R, Cv_L, Cv_R, Gamm_L, Gamm_R, gamma_L, gamma_R, pi_inf_L, pi_inf_R, qv_L, qv_R, qv_avg, c_L, c_R, G_L, G_R, rho_avg, H_avg, c_avg, gamma_avg, ptilde_L, ptilde_R, vel_L_rms, vel_R_rms, vel_avg_rms, vel_L_tmp, vel_R_tmp, Ms_L, Ms_R, pres_SL, pres_SR, alpha_L_sum, alpha_R_sum, rho_Star, E_Star, p_Star, p_K_Star, vel_K_star, s_L, s_R, s_M, s_P, s_S, xi_M, xi_P, xi_L, xi_R, xi_MP, xi_PP, Re_visc_per_phase_L, Re_visc_per_phase_R]') + do l = is3%beg, is3%end + do k = is2%beg, is2%end + do j = is1%beg, is1%end + + vel_L_rms = 0._wp; vel_R_rms = 0._wp + rho_L = 0._wp; rho_R = 0._wp + gamma_L = 0._wp; gamma_R = 0._wp + pi_inf_L = 0._wp; pi_inf_R = 0._wp + qv_L = 0._wp; qv_R = 0._wp + alpha_L_sum = 0._wp; alpha_R_sum = 0._wp + + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_dims + vel_L(i) = qL_prim_rs${XYZ}$_vf(j, k, l, contxe + i) + vel_R(i) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, contxe + i) + vel_L_rms = vel_L_rms + vel_L(i)**2._wp + vel_R_rms = vel_R_rms + vel_R(i)**2._wp + end do + + pres_L = qL_prim_rs${XYZ}$_vf(j, k, l, E_idx) + pres_R = qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx) + + rho_L = 0._wp + gamma_L = 0._wp + pi_inf_L = 0._wp + qv_L = 0._wp + + rho_R = 0._wp + gamma_R = 0._wp + pi_inf_R = 0._wp + qv_R = 0._wp + + alpha_L_sum = 0._wp + alpha_R_sum = 0._wp + + if (mpp_lim) then + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_fluids + qL_prim_rs${XYZ}$_vf(j, k, l, i) = max(0._wp, qL_prim_rs${XYZ}$_vf(j, k, l, i)) + qL_prim_rs${XYZ}$_vf(j, k, l, E_idx + i) = min(max(0._wp, qL_prim_rs${XYZ}$_vf(j, k, l, E_idx + i)), 1._wp) + alpha_L_sum = alpha_L_sum + qL_prim_rs${XYZ}$_vf(j, k, l, E_idx + i) + end do + + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_fluids + qR_prim_rs${XYZ}$_vf(j + 1, k, l, i) = max(0._wp, qR_prim_rs${XYZ}$_vf(j + 1, k, l, i)) + qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx + i) = min(max(0._wp, qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx + i)), 1._wp) + alpha_R_sum = alpha_R_sum + qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx + i) + end do + + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_fluids + qL_prim_rs${XYZ}$_vf(j, k, l, E_idx + i) = qL_prim_rs${XYZ}$_vf(j, k, l, E_idx + i)/max(alpha_L_sum, sgm_eps) + qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx + i) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx + i)/max(alpha_R_sum, sgm_eps) + end do + end if + + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_fluids + rho_L = rho_L + qL_prim_rs${XYZ}$_vf(j, k, l, i) + gamma_L = gamma_L + qL_prim_rs${XYZ}$_vf(j, k, l, E_idx + i)*gammas(i) + pi_inf_L = pi_inf_L + qL_prim_rs${XYZ}$_vf(j, k, l, E_idx + i)*pi_infs(i) + qv_L = qv_L + qL_prim_rs${XYZ}$_vf(j, k, l, i)*qvs(i) + + rho_R = rho_R + qR_prim_rs${XYZ}$_vf(j + 1, k, l, i) + gamma_R = gamma_R + qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx + i)*gammas(i) + pi_inf_R = pi_inf_R + qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx + i)*pi_infs(i) + qv_R = qv_R + qR_prim_rs${XYZ}$_vf(j + 1, k, l, i)*qvs(i) + + alpha_L(i) = qL_prim_rs${XYZ}$_vf(j, k, l, advxb + i - 1) + alpha_R(i) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, advxb + i - 1) + end do + + if (viscous) then + ! Map rotated (j,k,l) to physical (x,y,z) indices + #:if NORM_DIR == 1 + call s_compute_re_visc(q_prim_vf, & + alpha_L, j, k, l, Re_visc_per_phase_L) + call s_compute_re_visc(q_prim_vf, & + alpha_R, j + 1, k, l, Re_visc_per_phase_R) + #:elif NORM_DIR == 2 + call s_compute_re_visc(q_prim_vf, & + alpha_L, k, j, l, Re_visc_per_phase_L) + call s_compute_re_visc(q_prim_vf, & + alpha_R, k, j + 1, l, Re_visc_per_phase_R) + #:else + call s_compute_re_visc(q_prim_vf, & + alpha_L, l, k, j, Re_visc_per_phase_L) + call s_compute_re_visc(q_prim_vf, & + alpha_R, l, k, j + 1, Re_visc_per_phase_R) + #:endif + call s_compute_mixture_re( & + alpha_L, Re_visc_per_phase_L, Re_L) + call s_compute_mixture_re( & + alpha_R, Re_visc_per_phase_R, Re_R) + end if + + E_L = gamma_L*pres_L + pi_inf_L + 5.e-1_wp*rho_L*vel_L_rms + qv_L + E_R = gamma_R*pres_R + pi_inf_R + 5.e-1_wp*rho_R*vel_R_rms + qv_R + + ! ENERGY ADJUSTMENTS FOR HYPOELASTIC ENERGY + if (hypoelasticity) then + $:GPU_LOOP(parallelism='[seq]') + do i = 1, strxe - strxb + 1 + tau_e_L(i) = qL_prim_rs${XYZ}$_vf(j, k, l, strxb - 1 + i) + tau_e_R(i) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, strxb - 1 + i) + end do + G_L = 0._wp; G_R = 0._wp + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_fluids + G_L = G_L + alpha_L(i)*Gs_rs(i) + G_R = G_R + alpha_R(i)*Gs_rs(i) + end do + $:GPU_LOOP(parallelism='[seq]') + do i = 1, strxe - strxb + 1 + ! Elastic contribution to energy if G large enough + if ((G_L > verysmall) .and. (G_R > verysmall)) then + E_L = E_L + (tau_e_L(i)*tau_e_L(i))/(4._wp*G_L) + E_R = E_R + (tau_e_R(i)*tau_e_R(i))/(4._wp*G_R) + ! Additional terms in 2D and 3D + if ((i == 2) .or. (i == 4) .or. (i == 5)) then + E_L = E_L + (tau_e_L(i)*tau_e_L(i))/(4._wp*G_L) + E_R = E_R + (tau_e_R(i)*tau_e_R(i))/(4._wp*G_R) + end if + end if + end do + end if + + ! ENERGY ADJUSTMENTS FOR HYPERELASTIC ENERGY + if (hyperelasticity) then + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_dims + xi_field_L(i) = qL_prim_rs${XYZ}$_vf(j, k, l, xibeg - 1 + i) + xi_field_R(i) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, xibeg - 1 + i) + end do + G_L = 0._wp; G_R = 0._wp; + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_fluids + ! Mixture left and right shear modulus + G_L = G_L + alpha_L(i)*Gs_rs(i) + G_R = G_R + alpha_R(i)*Gs_rs(i) + end do + ! Elastic contribution to energy if G large enough + if (G_L > verysmall .and. G_R > verysmall) then + E_L = E_L + G_L*qL_prim_rs${XYZ}$_vf(j, k, l, xiend + 1) + E_R = E_R + G_R*qR_prim_rs${XYZ}$_vf(j + 1, k, l, xiend + 1) + end if + $:GPU_LOOP(parallelism='[seq]') + do i = 1, b_size - 1 + tau_e_L(i) = qL_prim_rs${XYZ}$_vf(j, k, l, strxb - 1 + i) + tau_e_R(i) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, strxb - 1 + i) + end do + end if + + H_L = (E_L + pres_L)/rho_L + H_R = (E_R + pres_R)/rho_R + + @:compute_average_state() + + call s_compute_speed_of_sound(pres_L, rho_L, gamma_L, pi_inf_L, H_L, alpha_L, & + vel_L_rms, 0._wp, c_L, qv_L) + + call s_compute_speed_of_sound(pres_R, rho_R, gamma_R, pi_inf_R, H_R, alpha_R, & + vel_R_rms, 0._wp, c_R, qv_R) + + !> The computation of c_avg does not require all the variables, and therefore the non '_avg' + ! variables are placeholders to call the subroutine. + call s_compute_speed_of_sound(pres_R, rho_avg, gamma_avg, pi_inf_R, H_avg, alpha_R, & + vel_avg_rms, 0._wp, c_avg, qv_avg) + + if (viscous) then + $:GPU_LOOP(parallelism='[seq]') + do i = 1, 2 + Re_avg_rs${XYZ}$_vf(j, k, l, i) = 2._wp/(1._wp/Re_L(i) + 1._wp/Re_R(i)) + end do + end if + + ! Low Mach correction + if (low_Mach == 2) then + @:compute_low_Mach_correction() + end if + + ! COMPUTING THE DIRECT WAVE SPEEDS + if (wave_speeds == 1) then + if (elasticity) then + s_L = min(vel_L(dir_idx(1)) - sqrt(c_L*c_L + & + (((4._wp*G_L)/3._wp) + tau_e_L(dir_idx_tau(1)))/rho_L), vel_R(dir_idx(1)) - sqrt(c_R*c_R + & + (((4._wp*G_R)/3._wp) + tau_e_R(dir_idx_tau(1)))/rho_R)) + s_R = max(vel_R(dir_idx(1)) + sqrt(c_R*c_R + & + (((4._wp*G_R)/3._wp) + tau_e_R(dir_idx_tau(1)))/rho_R), vel_L(dir_idx(1)) + sqrt(c_L*c_L + & + (((4._wp*G_L)/3._wp) + tau_e_L(dir_idx_tau(1)))/rho_L)) + s_S = (pres_R - tau_e_R(dir_idx_tau(1)) - pres_L + & + tau_e_L(dir_idx_tau(1)) + rho_L*vel_L(dir_idx(1))*(s_L - vel_L(dir_idx(1))) - & + rho_R*vel_R(dir_idx(1))*(s_R - vel_R(dir_idx(1))))/(rho_L*(s_L - vel_L(dir_idx(1))) - & + rho_R*(s_R - vel_R(dir_idx(1)))) + else + s_L = min(vel_L(dir_idx(1)) - c_L, vel_R(dir_idx(1)) - c_R) + s_R = max(vel_R(dir_idx(1)) + c_R, vel_L(dir_idx(1)) + c_L) + s_S = (pres_R - pres_L + rho_L*vel_L(dir_idx(1))* & + (s_L - vel_L(dir_idx(1))) - rho_R*vel_R(dir_idx(1))*(s_R - vel_R(dir_idx(1)))) & + /(rho_L*(s_L - vel_L(dir_idx(1))) - rho_R*(s_R - vel_R(dir_idx(1)))) + + end if + elseif (wave_speeds == 2) then + pres_SL = 5.e-1_wp*(pres_L + pres_R + rho_avg*c_avg* & + (vel_L(dir_idx(1)) - & + vel_R(dir_idx(1)))) + + pres_SR = pres_SL + + Ms_L = max(1._wp, sqrt(1._wp + ((5.e-1_wp + gamma_L)/(1._wp + gamma_L))* & + (pres_SL/pres_L - 1._wp)*pres_L/ & + ((pres_L + pi_inf_L/(1._wp + gamma_L))))) + Ms_R = max(1._wp, sqrt(1._wp + ((5.e-1_wp + gamma_R)/(1._wp + gamma_R))* & + (pres_SR/pres_R - 1._wp)*pres_R/ & + ((pres_R + pi_inf_R/(1._wp + gamma_R))))) + + s_L = vel_L(dir_idx(1)) - c_L*Ms_L + s_R = vel_R(dir_idx(1)) + c_R*Ms_R + + s_S = 5.e-1_wp*((vel_L(dir_idx(1)) + vel_R(dir_idx(1))) + & + (pres_L - pres_R)/ & + (rho_avg*c_avg)) + end if + + ! follows Einfeldt et al. + ! s_M/P = min/max(0.,s_L/R) + s_M = min(0._wp, s_L); s_P = max(0._wp, s_R) + + ! goes with q_star_L/R = xi_L/R * (variable) + ! xi_L/R = ( ( s_L/R - u_L/R )/(s_L/R - s_star) ) + xi_L = (s_L - vel_L(dir_idx(1)))/(s_L - s_S) + xi_R = (s_R - vel_R(dir_idx(1)))/(s_R - s_S) + + ! goes with numerical star velocity in x/y/z directions + ! xi_P/M = 0.5 +/m sgn(0.5,s_star) + xi_M = (5.e-1_wp + sign(0.5_wp, s_S)) + xi_P = (5.e-1_wp - sign(0.5_wp, s_S)) + + ! goes with the numerical velocity in x/y/z directions + ! xi_P/M (pressure) = min/max(0. sgn(1,sL/sR)) + xi_MP = -min(0._wp, sign(1._wp, s_L)) + xi_PP = max(0._wp, sign(1._wp, s_R)) + + E_star = xi_M*(E_L + xi_MP*(xi_L*(E_L + (s_S - vel_L(dir_idx(1)))* & + (rho_L*s_S + pres_L/(s_L - vel_L(dir_idx(1))))) - E_L)) + & + xi_P*(E_R + xi_PP*(xi_R*(E_R + (s_S - vel_R(dir_idx(1)))* & + (rho_R*s_S + pres_R/(s_R - vel_R(dir_idx(1))))) - E_R)) + p_Star = xi_M*(pres_L + xi_MP*(rho_L*(s_L - vel_L(dir_idx(1)))*(s_S - vel_L(dir_idx(1))))) + & + xi_P*(pres_R + xi_PP*(rho_R*(s_R - vel_R(dir_idx(1)))*(s_S - vel_R(dir_idx(1))))) + + rho_Star = xi_M*(rho_L*(xi_MP*xi_L + 1._wp - xi_MP)) + & + xi_P*(rho_R*(xi_PP*xi_R + 1._wp - xi_PP)) + + vel_K_Star = vel_L(dir_idx(1))*(1._wp - xi_MP) + xi_MP*vel_R(dir_idx(1)) + & + xi_MP*xi_PP*(s_S - vel_R(dir_idx(1))) + + ! Low Mach correction + if (low_Mach == 1) then + @:compute_low_Mach_correction() + else + pcorr = 0._wp + end if + + ! COMPUTING FLUXES + ! MASS FLUX. + $:GPU_LOOP(parallelism='[seq]') + do i = 1, contxe + flux_rs${XYZ}$_vf(j, k, l, i) = & + xi_M*qL_prim_rs${XYZ}$_vf(j, k, l, i)*(vel_L(dir_idx(1)) + s_M*(xi_L - 1._wp)) + & + xi_P*qR_prim_rs${XYZ}$_vf(j + 1, k, l, i)*(vel_R(dir_idx(1)) + s_P*(xi_R - 1._wp)) + end do + + ! MOMENTUM FLUX. + ! f = \rho u u - \sigma, q = \rho u, q_star = \xi * \rho*(s_star, v, w) + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_dims + flux_rs${XYZ}$_vf(j, k, l, contxe + dir_idx(i)) = rho_Star*vel_K_Star* & + (dir_flg(dir_idx(i))*vel_K_Star + (1._wp - dir_flg(dir_idx(i)))*(xi_M*vel_L(dir_idx(i)) + xi_P*vel_R(dir_idx(i)))) + dir_flg(dir_idx(i))*p_Star & + + (s_M/s_L)*(s_P/s_R)*dir_flg(dir_idx(i))*pcorr + end do + + ! ENERGY FLUX. + ! f = u*(E-\sigma), q = E, q_star = \xi*E+(s-u)(\rho s_star - \sigma/(s-u)) + flux_rs${XYZ}$_vf(j, k, l, E_idx) = (E_star + p_Star)*vel_K_Star & + + (s_M/s_L)*(s_P/s_R)*pcorr*s_S + + ! ELASTICITY. Elastic shear stress additions for the momentum and energy flux + if (elasticity) then + flux_ene_e = 0._wp; + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_dims + ! MOMENTUM ELASTIC FLUX. + flux_rs${XYZ}$_vf(j, k, l, contxe + dir_idx(i)) = & + flux_rs${XYZ}$_vf(j, k, l, contxe + dir_idx(i)) & + - xi_M*tau_e_L(dir_idx_tau(i)) - xi_P*tau_e_R(dir_idx_tau(i)) + ! ENERGY ELASTIC FLUX. + flux_ene_e = flux_ene_e - & + xi_M*(vel_L(dir_idx(i))*tau_e_L(dir_idx_tau(i)) + & + s_M*(xi_L*((s_S - vel_L(i))*(tau_e_L(dir_idx_tau(i))/(s_L - vel_L(i)))))) - & + xi_P*(vel_R(dir_idx(i))*tau_e_R(dir_idx_tau(i)) + & + s_P*(xi_R*((s_S - vel_R(i))*(tau_e_R(dir_idx_tau(i))/(s_R - vel_R(i)))))) + end do + flux_rs${XYZ}$_vf(j, k, l, E_idx) = flux_rs${XYZ}$_vf(j, k, l, E_idx) + flux_ene_e + end if + + ! VOLUME FRACTION FLUX. + $:GPU_LOOP(parallelism='[seq]') + do i = advxb, advxe + flux_rs${XYZ}$_vf(j, k, l, i) = & + xi_M*qL_prim_rs${XYZ}$_vf(j, k, l, i)*s_S + & + xi_P*qR_prim_rs${XYZ}$_vf(j + 1, k, l, i)*s_S + end do + + ! SOURCE TERM FOR VOLUME FRACTION ADVECTION FLUX. + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_dims + vel_src_rs${XYZ}$_vf(j, k, l, dir_idx(i)) = & + xi_M*(vel_L(dir_idx(i)) + dir_flg(dir_idx(i))*(s_S*(xi_MP*(xi_L - 1) + 1) - vel_L(dir_idx(i)))) + & + xi_P*(vel_R(dir_idx(i)) + dir_flg(dir_idx(i))*(s_S*(xi_PP*(xi_R - 1) + 1) - vel_R(dir_idx(i)))) + end do + + ! INTERNAL ENERGIES ADVECTION FLUX. + ! K-th pressure and velocity in preparation for the internal energy flux + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_fluids + p_K_Star = xi_M*(xi_MP*((pres_L + pi_infs(i)/(1._wp + gammas(i)))* & + xi_L**(1._wp/gammas(i) + 1._wp) - pi_infs(i)/(1._wp + gammas(i)) - pres_L) + pres_L) + & + xi_P*(xi_PP*((pres_R + pi_infs(i)/(1._wp + gammas(i)))* & + xi_R**(1._wp/gammas(i) + 1._wp) - pi_infs(i)/(1._wp + gammas(i)) - pres_R) + pres_R) + + flux_rs${XYZ}$_vf(j, k, l, i + intxb - 1) = & + ((xi_M*qL_prim_rs${XYZ}$_vf(j, k, l, i + advxb - 1) + xi_P*qR_prim_rs${XYZ}$_vf(j + 1, k, l, i + advxb - 1))* & + (gammas(i)*p_K_Star + pi_infs(i)) + & + (xi_M*qL_prim_rs${XYZ}$_vf(j, k, l, i + contxb - 1) + xi_P*qR_prim_rs${XYZ}$_vf(j + 1, k, l, i + contxb - 1))* & + qvs(i))*vel_K_Star & + + (s_M/s_L)*(s_P/s_R)*pcorr*s_S*(xi_M*qL_prim_rs${XYZ}$_vf(j, k, l, i + advxb - 1) + xi_P*qR_prim_rs${XYZ}$_vf(j + 1, k, l, i + advxb - 1)) + end do + + flux_src_rs${XYZ}$_vf(j, k, l, advxb) = vel_src_rs${XYZ}$_vf(j, k, l, dir_idx(1)) + + ! HYPOELASTIC STRESS EVOLUTION FLUX. + if (hypoelasticity) then + $:GPU_LOOP(parallelism='[seq]') + do i = 1, strxe - strxb + 1 + flux_rs${XYZ}$_vf(j, k, l, strxb - 1 + i) = & + xi_M*(s_S/(s_L - s_S))*(s_L*rho_L*tau_e_L(i) - rho_L*vel_L(dir_idx(1))*tau_e_L(i)) + & + xi_P*(s_S/(s_R - s_S))*(s_R*rho_R*tau_e_R(i) - rho_R*vel_R(dir_idx(1))*tau_e_R(i)) + end do + end if + + ! REFERENCE MAP FLUX. + if (hyperelasticity) then + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_dims + flux_rs${XYZ}$_vf(j, k, l, xibeg - 1 + i) = & + xi_M*(s_S/(s_L - s_S))*(s_L*rho_L*xi_field_L(i) & + - rho_L*vel_L(dir_idx(1))*xi_field_L(i)) + & + xi_P*(s_S/(s_R - s_S))*(s_R*rho_R*xi_field_R(i) & + - rho_R*vel_R(dir_idx(1))*xi_field_R(i)) + end do + end if + + ! COLOR FUNCTION FLUX + if (surface_tension) then + flux_rs${XYZ}$_vf(j, k, l, c_idx) = & + (xi_M*qL_prim_rs${XYZ}$_vf(j, k, l, c_idx) + & + xi_P*qR_prim_rs${XYZ}$_vf(j + 1, k, l, c_idx))*s_S + end if + + ! Geometrical source flux for cylindrical coordinates + #:if (NORM_DIR == 2) + if (cyl_coord) then + !Substituting the advective flux into the inviscid geometrical source flux + $:GPU_LOOP(parallelism='[seq]') + do i = 1, E_idx + flux_gsrc_rs${XYZ}$_vf(j, k, l, i) = flux_rs${XYZ}$_vf(j, k, l, i) + end do + $:GPU_LOOP(parallelism='[seq]') + do i = intxb, intxe + flux_gsrc_rs${XYZ}$_vf(j, k, l, i) = flux_rs${XYZ}$_vf(j, k, l, i) + end do + ! Recalculating the radial momentum geometric source flux + flux_gsrc_rs${XYZ}$_vf(j, k, l, momxb - 1 + dir_idx(1)) = & + flux_gsrc_rs${XYZ}$_vf(j, k, l, momxb - 1 + dir_idx(1)) - p_Star + ! Geometrical source of the void fraction(s) is zero + $:GPU_LOOP(parallelism='[seq]') + do i = advxb, advxe + flux_gsrc_rs${XYZ}$_vf(j, k, l, i) = 0._wp + end do + end if + #:endif + #:if (NORM_DIR == 3) + if (grid_geometry == 3) then + $:GPU_LOOP(parallelism='[seq]') + do i = 1, sys_size + flux_gsrc_rs${XYZ}$_vf(j, k, l, i) = 0._wp + end do + flux_gsrc_rs${XYZ}$_vf(j, k, l, momxb - 1 + dir_idx(1)) = & + flux_gsrc_rs${XYZ}$_vf(j, k, l, momxb - 1 + dir_idx(1)) - p_Star + + flux_gsrc_rs${XYZ}$_vf(j, k, l, momxe) = flux_rs${XYZ}$_vf(j, k, l, momxb + 1) + end if + #:endif + + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + + elseif (model_eqns == 4) then + !ME4 + $:GPU_PARALLEL_LOOP(collapse=3, private='[i, q, alpha_rho_L, alpha_rho_R, vel_L, vel_R, alpha_L, alpha_R, nbub_L, nbub_R, rho_L, rho_R, pres_L, pres_R, E_L, E_R, H_L, H_R, Cp_avg, Cv_avg, T_avg, eps, c_sum_Yi_Phi, T_L, T_R, Y_L, Y_R, MW_L, MW_R, R_gas_L, R_gas_R, Cp_L, Cp_R, Gamm_L, Gamm_R, gamma_L, gamma_R, pi_inf_L, pi_inf_R, qv_L, qv_R, qv_avg,c_L, c_R, G_L, G_R, rho_avg, H_avg, c_avg, gamma_avg, ptilde_L, ptilde_R, vel_L_rms, vel_R_rms, vel_avg_rms, vel_L_tmp, vel_R_tmp, Ms_L, Ms_R, pres_SL, pres_SR, alpha_L_sum, alpha_R_sum, rho_Star, E_Star, p_Star, p_K_Star, vel_K_star, s_L, s_R, s_M, s_P, s_S, xi_M, xi_P, xi_L, xi_R, xi_MP, xi_PP, Re_visc_per_phase_L, Re_visc_per_phase_R]') + do l = is3%beg, is3%end + do k = is2%beg, is2%end + do j = is1%beg, is1%end + + vel_L_rms = 0._wp; vel_R_rms = 0._wp + rho_L = 0._wp; rho_R = 0._wp + gamma_L = 0._wp; gamma_R = 0._wp + pi_inf_L = 0._wp; pi_inf_R = 0._wp + qv_L = 0._wp; qv_R = 0._wp + + $:GPU_LOOP(parallelism='[seq]') + do i = 1, contxe + alpha_rho_L(i) = qL_prim_rs${XYZ}$_vf(j, k, l, i) + alpha_rho_R(i) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, i) + end do + + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_dims + vel_L(i) = qL_prim_rs${XYZ}$_vf(j, k, l, contxe + i) + vel_R(i) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, contxe + i) + vel_L_rms = vel_L_rms + vel_L(i)**2._wp + vel_R_rms = vel_R_rms + vel_R(i)**2._wp + end do + + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_fluids + alpha_L(i) = qL_prim_rs${XYZ}$_vf(j, k, l, E_idx + i) + alpha_R(i) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx + i) + end do + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_fluids + alpha_L(i) = qL_prim_rs${XYZ}$_vf(j, k, l, E_idx + i) + alpha_R(i) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx + i) + end do + + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_fluids + rho_L = rho_L + alpha_rho_L(i) + gamma_L = gamma_L + alpha_L(i)*gammas(i) + pi_inf_L = pi_inf_L + alpha_L(i)*pi_infs(i) + qv_L = qv_L + alpha_rho_L(i)*qvs(i) + + rho_R = rho_R + alpha_rho_R(i) + gamma_R = gamma_R + alpha_R(i)*gammas(i) + pi_inf_R = pi_inf_R + alpha_R(i)*pi_infs(i) + qv_R = qv_R + alpha_rho_R(i)*qvs(i) + end do + + pres_L = qL_prim_rs${XYZ}$_vf(j, k, l, E_idx) + pres_R = qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx) + + E_L = gamma_L*pres_L + pi_inf_L + 5.e-1_wp*rho_L*vel_L_rms + qv_L + E_R = gamma_R*pres_R + pi_inf_R + 5.e-1_wp*rho_R*vel_R_rms + qv_R + + H_L = (E_L + pres_L)/rho_L + H_R = (E_R + pres_R)/rho_R + + @:compute_average_state() + + call s_compute_speed_of_sound(pres_L, rho_L, gamma_L, pi_inf_L, H_L, alpha_L, & + vel_L_rms, 0._wp, c_L, qv_L) + + call s_compute_speed_of_sound(pres_R, rho_R, gamma_R, pi_inf_R, H_R, alpha_R, & + vel_R_rms, 0._wp, c_R, qv_R) + + !> The computation of c_avg does not require all the variables, and therefore the non '_avg' + ! variables are placeholders to call the subroutine. + + call s_compute_speed_of_sound(pres_R, rho_avg, gamma_avg, pi_inf_R, H_avg, alpha_R, & + vel_avg_rms, 0._wp, c_avg, qv_avg) + + if (wave_speeds == 1) then + s_L = min(vel_L(dir_idx(1)) - c_L, vel_R(dir_idx(1)) - c_R) + s_R = max(vel_R(dir_idx(1)) + c_R, vel_L(dir_idx(1)) + c_L) + + s_S = (pres_R - pres_L + rho_L*vel_L(dir_idx(1))* & + (s_L - vel_L(dir_idx(1))) - & + rho_R*vel_R(dir_idx(1))* & + (s_R - vel_R(dir_idx(1)))) & + /(rho_L*(s_L - vel_L(dir_idx(1))) - & + rho_R*(s_R - vel_R(dir_idx(1)))) + elseif (wave_speeds == 2) then + pres_SL = 5.e-1_wp*(pres_L + pres_R + rho_avg*c_avg* & + (vel_L(dir_idx(1)) - & + vel_R(dir_idx(1)))) + + pres_SR = pres_SL + + Ms_L = max(1._wp, sqrt(1._wp + ((5.e-1_wp + gamma_L)/(1._wp + gamma_L))* & + (pres_SL/pres_L - 1._wp)*pres_L/ & + ((pres_L + pi_inf_L/(1._wp + gamma_L))))) + Ms_R = max(1._wp, sqrt(1._wp + ((5.e-1_wp + gamma_R)/(1._wp + gamma_R))* & + (pres_SR/pres_R - 1._wp)*pres_R/ & + ((pres_R + pi_inf_R/(1._wp + gamma_R))))) + + s_L = vel_L(dir_idx(1)) - c_L*Ms_L + s_R = vel_R(dir_idx(1)) + c_R*Ms_R + + s_S = 5.e-1_wp*((vel_L(dir_idx(1)) + vel_R(dir_idx(1))) + & + (pres_L - pres_R)/ & + (rho_avg*c_avg)) + end if + + ! follows Einfeldt et al. + ! s_M/P = min/max(0.,s_L/R) + s_M = min(0._wp, s_L); s_P = max(0._wp, s_R) + + ! goes with q_star_L/R = xi_L/R * (variable) + ! xi_L/R = ( ( s_L/R - u_L/R )/(s_L/R - s_star) ) + xi_L = (s_L - vel_L(dir_idx(1)))/(s_L - s_S) + xi_R = (s_R - vel_R(dir_idx(1)))/(s_R - s_S) + + ! goes with numerical velocity in x/y/z directions + ! xi_P/M = 0.5 +/m sgn(0.5,s_star) + xi_M = (5.e-1_wp + sign(5.e-1_wp, s_S)) + xi_P = (5.e-1_wp - sign(5.e-1_wp, s_S)) + + $:GPU_LOOP(parallelism='[seq]') + do i = 1, contxe + flux_rs${XYZ}$_vf(j, k, l, i) = & + xi_M*alpha_rho_L(i) & + *(vel_L(dir_idx(1)) + s_M*(xi_L - 1._wp)) & + + xi_P*alpha_rho_R(i) & + *(vel_R(dir_idx(1)) + s_P*(xi_R - 1._wp)) + end do + + ! Momentum flux. + ! f = \rho u u + p I, q = \rho u, q_star = \xi * \rho*(s_star, v, w) + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_dims + flux_rs${XYZ}$_vf(j, k, l, contxe + dir_idx(i)) = & + xi_M*(rho_L*(vel_L(dir_idx(1))* & + vel_L(dir_idx(i)) + & + s_M*(xi_L*(dir_flg(dir_idx(i))*s_S + & + (1._wp - dir_flg(dir_idx(i)))* & + vel_L(dir_idx(i))) - vel_L(dir_idx(i)))) + & + dir_flg(dir_idx(i))*pres_L) & + + xi_P*(rho_R*(vel_R(dir_idx(1))* & + vel_R(dir_idx(i)) + & + s_P*(xi_R*(dir_flg(dir_idx(i))*s_S + & + (1._wp - dir_flg(dir_idx(i)))* & + vel_R(dir_idx(i))) - vel_R(dir_idx(i)))) + & + dir_flg(dir_idx(i))*pres_R) + end do + + if (bubbles_euler) then + ! Put p_tilde in + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_dims + flux_rs${XYZ}$_vf(j, k, l, contxe + dir_idx(i)) = & + flux_rs${XYZ}$_vf(j, k, l, contxe + dir_idx(i)) + & + xi_M*(dir_flg(dir_idx(i))*(-1._wp*ptilde_L)) & + + xi_P*(dir_flg(dir_idx(i))*(-1._wp*ptilde_R)) + end do + end if + + flux_rs${XYZ}$_vf(j, k, l, E_idx) = 0._wp + + $:GPU_LOOP(parallelism='[seq]') + do i = alf_idx, alf_idx !only advect the void fraction + flux_rs${XYZ}$_vf(j, k, l, i) = & + xi_M*qL_prim_rs${XYZ}$_vf(j, k, l, i) & + *(vel_L(dir_idx(1)) + s_M*(xi_L - 1._wp)) & + + xi_P*qR_prim_rs${XYZ}$_vf(j + 1, k, l, i) & + *(vel_R(dir_idx(1)) + s_P*(xi_R - 1._wp)) + end do + + ! Source for volume fraction advection equation + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_dims + + vel_src_rs${XYZ}$_vf(j, k, l, dir_idx(i)) = 0._wp + !IF ( (model_eqns == 4) .or. (num_fluids==1) ) vel_src_rs_vf(dir_idx(i))%sf(j,k,l) = 0._wp + end do + + flux_src_rs${XYZ}$_vf(j, k, l, advxb) = vel_src_rs${XYZ}$_vf(j, k, l, dir_idx(1)) + + ! Add advection flux for bubble variables + if (bubbles_euler) then + $:GPU_LOOP(parallelism='[seq]') + do i = bubxb, bubxe + flux_rs${XYZ}$_vf(j, k, l, i) = & + xi_M*nbub_L*qL_prim_rs${XYZ}$_vf(j, k, l, i) & + *(vel_L(dir_idx(1)) + s_M*(xi_L - 1._wp)) & + + xi_P*nbub_R*qR_prim_rs${XYZ}$_vf(j + 1, k, l, i) & + *(vel_R(dir_idx(1)) + s_P*(xi_R - 1._wp)) + end do + end if + + ! Geometrical source flux for cylindrical coordinates + + #:if (NORM_DIR == 2) + if (cyl_coord) then + ! Substituting the advective flux into the inviscid geometrical source flux + $:GPU_LOOP(parallelism='[seq]') + do i = 1, E_idx + flux_gsrc_rs${XYZ}$_vf(j, k, l, i) = flux_rs${XYZ}$_vf(j, k, l, i) + end do + ! Recalculating the radial momentum geometric source flux + flux_gsrc_rs${XYZ}$_vf(j, k, l, contxe + dir_idx(1)) = & + xi_M*(rho_L*(vel_L(dir_idx(1))* & + vel_L(dir_idx(1)) + & + s_M*(xi_L*(dir_flg(dir_idx(1))*s_S + & + (1._wp - dir_flg(dir_idx(1)))* & + vel_L(dir_idx(1))) - vel_L(dir_idx(1))))) & + + xi_P*(rho_R*(vel_R(dir_idx(1))* & + vel_R(dir_idx(1)) + & + s_P*(xi_R*(dir_flg(dir_idx(1))*s_S + & + (1._wp - dir_flg(dir_idx(1)))* & + vel_R(dir_idx(1))) - vel_R(dir_idx(1))))) + ! Geometrical source of the void fraction(s) is zero + $:GPU_LOOP(parallelism='[seq]') + do i = advxb, advxe + flux_gsrc_rs${XYZ}$_vf(j, k, l, i) = 0._wp + end do + end if + #:endif + #:if (NORM_DIR == 3) + if (grid_geometry == 3) then + $:GPU_LOOP(parallelism='[seq]') + do i = 1, sys_size + flux_gsrc_rs${XYZ}$_vf(j, k, l, i) = 0._wp + end do + flux_gsrc_rs${XYZ}$_vf(j, k, l, momxb + 1) = & + -xi_M*(rho_L*(vel_L(dir_idx(1))* & + vel_L(dir_idx(1)) + & + s_M*(xi_L*(dir_flg(dir_idx(1))*s_S + & + (1._wp - dir_flg(dir_idx(1)))* & + vel_L(dir_idx(1))) - vel_L(dir_idx(1))))) & + - xi_P*(rho_R*(vel_R(dir_idx(1))* & + vel_R(dir_idx(1)) + & + s_P*(xi_R*(dir_flg(dir_idx(1))*s_S + & + (1._wp - dir_flg(dir_idx(1)))* & + vel_R(dir_idx(1))) - vel_R(dir_idx(1))))) + flux_gsrc_rs${XYZ}$_vf(j, k, l, momxe) = flux_rs${XYZ}$_vf(j, k, l, momxb + 1) + end if + #:endif + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + + elseif (model_eqns == 2 .and. bubbles_euler) then + $:GPU_PARALLEL_LOOP(collapse=3, private='[i, q, R0_L, R0_R, V0_L, V0_R, P0_L, P0_R, pbw_L, pbw_R, vel_L, vel_R, rho_avg, alpha_L, alpha_R, h_avg, gamma_avg, Re_L, Re_R, pcorr, zcoef, rho_L, rho_R, pres_L, pres_R, E_L, E_R, H_L, H_R, gamma_L, gamma_R, pi_inf_L, pi_inf_R, qv_L, qv_R, qv_avg, c_L, c_R, c_avg, vel_L_rms, vel_R_rms, vel_avg_rms, vel_L_tmp, vel_R_tmp, Ms_L, Ms_R, pres_SL, pres_SR, alpha_L_sum, alpha_R_sum, s_L, s_R, s_M, s_P, s_S, xi_M, xi_P, xi_L, xi_R, xi_MP, xi_PP, nbub_L, nbub_R, PbwR3Lbar, PbwR3Rbar, R3Lbar, R3Rbar, R3V2Lbar, R3V2Rbar, Re_visc_per_phase_L, Re_visc_per_phase_R]') + do l = is3%beg, is3%end + do k = is2%beg, is2%end + do j = is1%beg, is1%end + + vel_L_rms = 0._wp; vel_R_rms = 0._wp + rho_L = 0._wp; rho_R = 0._wp + gamma_L = 0._wp; gamma_R = 0._wp + pi_inf_L = 0._wp; pi_inf_R = 0._wp + qv_L = 0._wp; qv_R = 0._wp + + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_fluids + alpha_L(i) = qL_prim_rs${XYZ}$_vf(j, k, l, E_idx + i) + alpha_R(i) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx + i) + end do + + vel_L_rms = 0._wp; vel_R_rms = 0._wp + + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_dims + vel_L(i) = qL_prim_rs${XYZ}$_vf(j, k, l, contxe + i) + vel_R(i) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, contxe + i) + vel_L_rms = vel_L_rms + vel_L(i)**2._wp + vel_R_rms = vel_R_rms + vel_R(i)**2._wp + end do + + ! Retain this in the refactor + if (mpp_lim .and. (num_fluids > 2)) then + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_fluids + rho_L = rho_L + qL_prim_rs${XYZ}$_vf(j, k, l, i) + gamma_L = gamma_L + qL_prim_rs${XYZ}$_vf(j, k, l, E_idx + i)*gammas(i) + pi_inf_L = pi_inf_L + qL_prim_rs${XYZ}$_vf(j, k, l, E_idx + i)*pi_infs(i) + qv_L = qv_L + qL_prim_rs${XYZ}$_vf(j, k, l, i)*qvs(i) + rho_R = rho_R + qR_prim_rs${XYZ}$_vf(j + 1, k, l, i) + gamma_R = gamma_R + qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx + i)*gammas(i) + pi_inf_R = pi_inf_R + qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx + i)*pi_infs(i) + qv_R = qv_R + qR_prim_rs${XYZ}$_vf(j + 1, k, l, i)*qvs(i) + end do + else if (num_fluids > 2) then + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_fluids - 1 + rho_L = rho_L + qL_prim_rs${XYZ}$_vf(j, k, l, i) + gamma_L = gamma_L + qL_prim_rs${XYZ}$_vf(j, k, l, E_idx + i)*gammas(i) + pi_inf_L = pi_inf_L + qL_prim_rs${XYZ}$_vf(j, k, l, E_idx + i)*pi_infs(i) + qv_L = qv_L + qL_prim_rs${XYZ}$_vf(j, k, l, i)*qvs(i) + rho_R = rho_R + qR_prim_rs${XYZ}$_vf(j + 1, k, l, i) + gamma_R = gamma_R + qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx + i)*gammas(i) + pi_inf_R = pi_inf_R + qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx + i)*pi_infs(i) + qv_R = qv_R + qR_prim_rs${XYZ}$_vf(j + 1, k, l, i)*qvs(i) + end do + else + rho_L = qL_prim_rs${XYZ}$_vf(j, k, l, 1) + gamma_L = gammas(1) + pi_inf_L = pi_infs(1) + qv_L = qvs(1) + rho_R = qR_prim_rs${XYZ}$_vf(j + 1, k, l, 1) + gamma_R = gammas(1) + pi_inf_R = pi_infs(1) + qv_R = qvs(1) + end if + + if (viscous) then + if (num_fluids == 1) then ! Need to consider case with num_fluids >= 2 + ! Map rotated (j,k,l) to physical (x,y,z) indices + #:if NORM_DIR == 1 + call s_compute_re_visc(q_prim_vf, & + alpha_L, j, k, l, Re_visc_per_phase_L) + call s_compute_re_visc(q_prim_vf, & + alpha_R, j + 1, k, l, Re_visc_per_phase_R) + #:elif NORM_DIR == 2 + call s_compute_re_visc(q_prim_vf, & + alpha_L, k, j, l, Re_visc_per_phase_L) + call s_compute_re_visc(q_prim_vf, & + alpha_R, k, j + 1, l, Re_visc_per_phase_R) + #:else + call s_compute_re_visc(q_prim_vf, & + alpha_L, l, k, j, Re_visc_per_phase_L) + call s_compute_re_visc(q_prim_vf, & + alpha_R, l, k, j + 1, Re_visc_per_phase_R) + #:endif + call s_compute_mixture_re( & + alpha_L, Re_visc_per_phase_L, Re_L) + call s_compute_mixture_re( & + alpha_R, Re_visc_per_phase_R, Re_R) + end if + end if + + pres_L = qL_prim_rs${XYZ}$_vf(j, k, l, E_idx) + pres_R = qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx) + + E_L = gamma_L*pres_L + pi_inf_L + 5.e-1_wp*rho_L*vel_L_rms + E_R = gamma_R*pres_R + pi_inf_R + 5.e-1_wp*rho_R*vel_R_rms + + H_L = (E_L + pres_L)/rho_L + H_R = (E_R + pres_R)/rho_R + + if (avg_state == 2) then + $:GPU_LOOP(parallelism='[seq]') + do i = 1, nb + R0_L(i) = qL_prim_rs${XYZ}$_vf(j, k, l, rs(i)) + R0_R(i) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, rs(i)) + + V0_L(i) = qL_prim_rs${XYZ}$_vf(j, k, l, vs(i)) + V0_R(i) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, vs(i)) + if (.not. polytropic .and. .not. qbmm) then + P0_L(i) = qL_prim_rs${XYZ}$_vf(j, k, l, ps(i)) + P0_R(i) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, ps(i)) + end if + end do + + if (.not. qbmm) then + if (adv_n) then + nbub_L = qL_prim_rs${XYZ}$_vf(j, k, l, n_idx) + nbub_R = qR_prim_rs${XYZ}$_vf(j + 1, k, l, n_idx) + else + nbub_L = 0._wp + nbub_R = 0._wp + $:GPU_LOOP(parallelism='[seq]') + do i = 1, nb + nbub_L = nbub_L + (R0_L(i)**3._wp)*weight(i) + nbub_R = nbub_R + (R0_R(i)**3._wp)*weight(i) + end do + + nbub_L = (3._wp/(4._wp*pi))*qL_prim_rs${XYZ}$_vf(j, k, l, E_idx + num_fluids)/nbub_L + nbub_R = (3._wp/(4._wp*pi))*qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx + num_fluids)/nbub_R + end if + else + !nb stored in 0th moment of first R0 bin in variable conversion module + nbub_L = qL_prim_rs${XYZ}$_vf(j, k, l, bubxb) + nbub_R = qR_prim_rs${XYZ}$_vf(j + 1, k, l, bubxb) + end if + + $:GPU_LOOP(parallelism='[seq]') + do i = 1, nb + if (.not. qbmm) then + pbw_L(i) = f_cpbw_KM(R0(i), R0_L(i), V0_L(i), P0_L(i)) + pbw_R(i) = f_cpbw_KM(R0(i), R0_R(i), V0_R(i), P0_R(i)) + end if + end do + + if (qbmm) then + PbwR3Lbar = mom_sp_rs${XYZ}$_vf(j, k, l, 4) + PbwR3Rbar = mom_sp_rs${XYZ}$_vf(j + 1, k, l, 4) + + R3Lbar = mom_sp_rs${XYZ}$_vf(j, k, l, 1) + R3Rbar = mom_sp_rs${XYZ}$_vf(j + 1, k, l, 1) + + R3V2Lbar = mom_sp_rs${XYZ}$_vf(j, k, l, 3) + R3V2Rbar = mom_sp_rs${XYZ}$_vf(j + 1, k, l, 3) + else + + PbwR3Lbar = 0._wp + PbwR3Rbar = 0._wp + + R3Lbar = 0._wp + R3Rbar = 0._wp + + R3V2Lbar = 0._wp + R3V2Rbar = 0._wp + + $:GPU_LOOP(parallelism='[seq]') + do i = 1, nb + PbwR3Lbar = PbwR3Lbar + pbw_L(i)*(R0_L(i)**3._wp)*weight(i) + PbwR3Rbar = PbwR3Rbar + pbw_R(i)*(R0_R(i)**3._wp)*weight(i) + + R3Lbar = R3Lbar + (R0_L(i)**3._wp)*weight(i) + R3Rbar = R3Rbar + (R0_R(i)**3._wp)*weight(i) + + R3V2Lbar = R3V2Lbar + (R0_L(i)**3._wp)*(V0_L(i)**2._wp)*weight(i) + R3V2Rbar = R3V2Rbar + (R0_R(i)**3._wp)*(V0_R(i)**2._wp)*weight(i) + end do + end if + + rho_avg = 5.e-1_wp*(rho_L + rho_R) + H_avg = 5.e-1_wp*(H_L + H_R) + gamma_avg = 5.e-1_wp*(gamma_L + gamma_R) + qv_avg = 5.e-1_wp*(qv_L + qv_R) + vel_avg_rms = 0._wp + + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_dims + vel_avg_rms = vel_avg_rms + (5.e-1_wp*(vel_L(i) + vel_R(i)))**2._wp + end do + + end if + + call s_compute_speed_of_sound(pres_L, rho_L, gamma_L, pi_inf_L, H_L, alpha_L, & + vel_L_rms, 0._wp, c_L, qv_L) + + call s_compute_speed_of_sound(pres_R, rho_R, gamma_R, pi_inf_R, H_R, alpha_R, & + vel_R_rms, 0._wp, c_R, qv_R) + + !> The computation of c_avg does not require all the variables, and therefore the non '_avg' + ! variables are placeholders to call the subroutine. + call s_compute_speed_of_sound(pres_R, rho_avg, gamma_avg, pi_inf_R, H_avg, alpha_R, & + vel_avg_rms, 0._wp, c_avg, qv_avg) + + if (viscous) then + $:GPU_LOOP(parallelism='[seq]') + do i = 1, 2 + Re_avg_rs${XYZ}$_vf(j, k, l, i) = 2._wp/(1._wp/Re_L(i) + 1._wp/Re_R(i)) + end do + end if + + ! Low Mach correction + if (low_Mach == 2) then + @:compute_low_Mach_correction() + end if + + if (wave_speeds == 1) then + s_L = min(vel_L(dir_idx(1)) - c_L, vel_R(dir_idx(1)) - c_R) + s_R = max(vel_R(dir_idx(1)) + c_R, vel_L(dir_idx(1)) + c_L) + + s_S = (pres_R - pres_L + rho_L*vel_L(dir_idx(1))* & + (s_L - vel_L(dir_idx(1))) - & + rho_R*vel_R(dir_idx(1))* & + (s_R - vel_R(dir_idx(1)))) & + /(rho_L*(s_L - vel_L(dir_idx(1))) - & + rho_R*(s_R - vel_R(dir_idx(1)))) + elseif (wave_speeds == 2) then + pres_SL = 5.e-1_wp*(pres_L + pres_R + rho_avg*c_avg* & + (vel_L(dir_idx(1)) - & + vel_R(dir_idx(1)))) + + pres_SR = pres_SL + + Ms_L = max(1._wp, sqrt(1._wp + ((5.e-1_wp + gamma_L)/(1._wp + gamma_L))* & + (pres_SL/pres_L - 1._wp)*pres_L/ & + ((pres_L + pi_inf_L/(1._wp + gamma_L))))) + Ms_R = max(1._wp, sqrt(1._wp + ((5.e-1_wp + gamma_R)/(1._wp + gamma_R))* & + (pres_SR/pres_R - 1._wp)*pres_R/ & + ((pres_R + pi_inf_R/(1._wp + gamma_R))))) + + s_L = vel_L(dir_idx(1)) - c_L*Ms_L + s_R = vel_R(dir_idx(1)) + c_R*Ms_R + + s_S = 5.e-1_wp*((vel_L(dir_idx(1)) + vel_R(dir_idx(1))) + & + (pres_L - pres_R)/ & + (rho_avg*c_avg)) + end if + + ! follows Einfeldt et al. + ! s_M/P = min/max(0.,s_L/R) + s_M = min(0._wp, s_L); s_P = max(0._wp, s_R) + + ! goes with q_star_L/R = xi_L/R * (variable) + ! xi_L/R = ( ( s_L/R - u_L/R )/(s_L/R - s_star) ) + xi_L = (s_L - vel_L(dir_idx(1)))/(s_L - s_S) + xi_R = (s_R - vel_R(dir_idx(1)))/(s_R - s_S) + + ! goes with numerical velocity in x/y/z directions + ! xi_P/M = 0.5 +/m sgn(0.5,s_star) + xi_M = (5.e-1_wp + sign(5.e-1_wp, s_S)) + xi_P = (5.e-1_wp - sign(5.e-1_wp, s_S)) + + ! Low Mach correction + if (low_Mach == 1) then + @:compute_low_Mach_correction() + else + pcorr = 0._wp + end if + + $:GPU_LOOP(parallelism='[seq]') + do i = 1, contxe + flux_rs${XYZ}$_vf(j, k, l, i) = & + xi_M*qL_prim_rs${XYZ}$_vf(j, k, l, i) & + *(vel_L(dir_idx(1)) + s_M*(xi_L - 1._wp)) & + + xi_P*qR_prim_rs${XYZ}$_vf(j + 1, k, l, i) & + *(vel_R(dir_idx(1)) + s_P*(xi_R - 1._wp)) + end do + + if (bubbles_euler .and. (num_fluids > 1)) then + ! Kill mass transport @ gas density + flux_rs${XYZ}$_vf(j, k, l, contxe) = 0._wp + end if + + ! Momentum flux. + ! f = \rho u u + p I, q = \rho u, q_star = \xi * \rho*(s_star, v, w) + + ! Include p_tilde + + if (avg_state == 2) then + if (alpha_L(num_fluids) < small_alf .or. R3Lbar < small_alf) then + pres_L = pres_L - alpha_L(num_fluids)*pres_L + else + pres_L = pres_L - alpha_L(num_fluids)*(pres_L - PbwR3Lbar/R3Lbar - & + rho_L*R3V2Lbar/R3Lbar) + end if + + if (alpha_R(num_fluids) < small_alf .or. R3Rbar < small_alf) then + pres_R = pres_R - alpha_R(num_fluids)*pres_R + else + pres_R = pres_R - alpha_R(num_fluids)*(pres_R - PbwR3Rbar/R3Rbar - & + rho_R*R3V2Rbar/R3Rbar) + end if + end if + + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_dims + flux_rs${XYZ}$_vf(j, k, l, contxe + dir_idx(i)) = & + xi_M*(rho_L*(vel_L(dir_idx(1))* & + vel_L(dir_idx(i)) + & + s_M*(xi_L*(dir_flg(dir_idx(i))*s_S + & + (1._wp - dir_flg(dir_idx(i)))* & + vel_L(dir_idx(i))) - vel_L(dir_idx(i)))) + & + dir_flg(dir_idx(i))*(pres_L)) & + + xi_P*(rho_R*(vel_R(dir_idx(1))* & + vel_R(dir_idx(i)) + & + s_P*(xi_R*(dir_flg(dir_idx(i))*s_S + & + (1._wp - dir_flg(dir_idx(i)))* & + vel_R(dir_idx(i))) - vel_R(dir_idx(i)))) + & + dir_flg(dir_idx(i))*(pres_R)) & + + (s_M/s_L)*(s_P/s_R)*dir_flg(dir_idx(i))*pcorr + end do + + ! Energy flux. + ! f = u*(E+p), q = E, q_star = \xi*E+(s-u)(\rho s_star + p/(s-u)) + flux_rs${XYZ}$_vf(j, k, l, E_idx) = & + xi_M*(vel_L(dir_idx(1))*(E_L + pres_L) + & + s_M*(xi_L*(E_L + (s_S - vel_L(dir_idx(1)))* & + (rho_L*s_S + (pres_L)/ & + (s_L - vel_L(dir_idx(1))))) - E_L)) & + + xi_P*(vel_R(dir_idx(1))*(E_R + pres_R) + & + s_P*(xi_R*(E_R + (s_S - vel_R(dir_idx(1)))* & + (rho_R*s_S + (pres_R)/ & + (s_R - vel_R(dir_idx(1))))) - E_R)) & + + (s_M/s_L)*(s_P/s_R)*pcorr*s_S + + ! Volume fraction flux + $:GPU_LOOP(parallelism='[seq]') + do i = advxb, advxe + flux_rs${XYZ}$_vf(j, k, l, i) = & + xi_M*qL_prim_rs${XYZ}$_vf(j, k, l, i) & + *(vel_L(dir_idx(1)) + s_M*(xi_L - 1._wp)) & + + xi_P*qR_prim_rs${XYZ}$_vf(j + 1, k, l, i) & + *(vel_R(dir_idx(1)) + s_P*(xi_R - 1._wp)) + end do + + ! Source for volume fraction advection equation + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_dims + vel_src_rs${XYZ}$_vf(j, k, l, dir_idx(i)) = & + xi_M*(vel_L(dir_idx(i)) + & + dir_flg(dir_idx(i))* & + s_M*(xi_L - 1._wp)) & + + xi_P*(vel_R(dir_idx(i)) + & + dir_flg(dir_idx(i))* & + s_P*(xi_R - 1._wp)) + + !IF ( (model_eqns == 4) .or. (num_fluids==1) ) vel_src_rs_vf(dir_idx(i))%sf(j,k,l) = 0._wp + end do + + flux_src_rs${XYZ}$_vf(j, k, l, advxb) = vel_src_rs${XYZ}$_vf(j, k, l, dir_idx(1)) + + ! Add advection flux for bubble variables + $:GPU_LOOP(parallelism='[seq]') + do i = bubxb, bubxe + flux_rs${XYZ}$_vf(j, k, l, i) = & + xi_M*nbub_L*qL_prim_rs${XYZ}$_vf(j, k, l, i) & + *(vel_L(dir_idx(1)) + s_M*(xi_L - 1._wp)) & + + xi_P*nbub_R*qR_prim_rs${XYZ}$_vf(j + 1, k, l, i) & + *(vel_R(dir_idx(1)) + s_P*(xi_R - 1._wp)) + end do + + if (qbmm) then + flux_rs${XYZ}$_vf(j, k, l, bubxb) = & + xi_M*nbub_L & + *(vel_L(dir_idx(1)) + s_M*(xi_L - 1._wp)) & + + xi_P*nbub_R & + *(vel_R(dir_idx(1)) + s_P*(xi_R - 1._wp)) + end if + + if (adv_n) then + flux_rs${XYZ}$_vf(j, k, l, n_idx) = & + xi_M*nbub_L & + *(vel_L(dir_idx(1)) + s_M*(xi_L - 1._wp)) & + + xi_P*nbub_R & + *(vel_R(dir_idx(1)) + s_P*(xi_R - 1._wp)) + end if + + ! Geometrical source flux for cylindrical coordinates + #:if (NORM_DIR == 2) + if (cyl_coord) then + ! Substituting the advective flux into the inviscid geometrical source flux + $:GPU_LOOP(parallelism='[seq]') + do i = 1, E_idx + flux_gsrc_rs${XYZ}$_vf(j, k, l, i) = flux_rs${XYZ}$_vf(j, k, l, i) + end do + ! Recalculating the radial momentum geometric source flux + flux_gsrc_rs${XYZ}$_vf(j, k, l, contxe + dir_idx(1)) = & + xi_M*(rho_L*(vel_L(dir_idx(1))* & + vel_L(dir_idx(1)) + & + s_M*(xi_L*(dir_flg(dir_idx(1))*s_S + & + (1._wp - dir_flg(dir_idx(1)))* & + vel_L(dir_idx(1))) - vel_L(dir_idx(1))))) & + + xi_P*(rho_R*(vel_R(dir_idx(1))* & + vel_R(dir_idx(1)) + & + s_P*(xi_R*(dir_flg(dir_idx(1))*s_S + & + (1._wp - dir_flg(dir_idx(1)))* & + vel_R(dir_idx(1))) - vel_R(dir_idx(1))))) + ! Geometrical source of the void fraction(s) is zero + $:GPU_LOOP(parallelism='[seq]') + do i = advxb, advxe + flux_gsrc_rs${XYZ}$_vf(j, k, l, i) = 0._wp + end do + end if + #:endif + #:if (NORM_DIR == 3) + if (grid_geometry == 3) then + $:GPU_LOOP(parallelism='[seq]') + do i = 1, sys_size + flux_gsrc_rs${XYZ}$_vf(j, k, l, i) = 0._wp + end do + + flux_gsrc_rs${XYZ}$_vf(j, k, l, momxb + 1) = & + -xi_M*(rho_L*(vel_L(dir_idx(1))* & + vel_L(dir_idx(1)) + & + s_M*(xi_L*(dir_flg(dir_idx(1))*s_S + & + (1._wp - dir_flg(dir_idx(1)))* & + vel_L(dir_idx(1))) - vel_L(dir_idx(1))))) & + - xi_P*(rho_R*(vel_R(dir_idx(1))* & + vel_R(dir_idx(1)) + & + s_P*(xi_R*(dir_flg(dir_idx(1))*s_S + & + (1._wp - dir_flg(dir_idx(1)))* & + vel_R(dir_idx(1))) - vel_R(dir_idx(1))))) + flux_gsrc_rs${XYZ}$_vf(j, k, l, momxe) = flux_rs${XYZ}$_vf(j, k, l, momxb + 1) + + end if + #:endif + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + else + ! 5-EQUATION MODEL WITH HLLC + $:GPU_PARALLEL_LOOP(collapse=3, private='[Re_max, i, q, T_L, T_R, vel_L_rms, vel_R_rms, pres_L, pres_R, rho_L, gamma_L, pi_inf_L, qv_L, rho_R, gamma_R, pi_inf_R, qv_R, alpha_L_sum, alpha_R_sum, E_L, E_R, MW_L, MW_R, R_gas_L, R_gas_R, Cp_L, Cp_R, Cv_L, Cv_R, Gamm_L, Gamm_R, Y_L, Y_R, H_L, H_R, qv_avg, rho_avg, gamma_avg, H_avg, c_L, c_R, c_avg, s_P, s_M, xi_P, xi_M, xi_L, xi_R, Ms_L, Ms_R, pres_SL, pres_SR, vel_L, vel_R, Re_L, Re_R, alpha_L, alpha_R, s_L, s_R, s_S, vel_avg_rms, pcorr, zcoef, vel_L_tmp, vel_R_tmp, Ys_L, Ys_R, Xs_L, Xs_R, Gamma_iL, Gamma_iR, Cp_iL, Cp_iR, tau_e_L, tau_e_R, xi_field_L, xi_field_R, Yi_avg,Phi_avg, h_iL, h_iR, h_avg_2, G_L, G_R, Re_visc_per_phase_L, Re_visc_per_phase_R]', copyin='[is1, is2, is3]') + do l = is3%beg, is3%end + do k = is2%beg, is2%end + do j = is1%beg, is1%end + + vel_L_rms = 0._wp; vel_R_rms = 0._wp + rho_L = 0._wp; rho_R = 0._wp + gamma_L = 0._wp; gamma_R = 0._wp + pi_inf_L = 0._wp; pi_inf_R = 0._wp + qv_L = 0._wp; qv_R = 0._wp + alpha_L_sum = 0._wp; alpha_R_sum = 0._wp + + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_fluids + alpha_L(i) = qL_prim_rs${XYZ}$_vf(j, k, l, E_idx + i) + alpha_R(i) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx + i) + end do + + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_dims + vel_L(i) = qL_prim_rs${XYZ}$_vf(j, k, l, contxe + i) + vel_R(i) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, contxe + i) + vel_L_rms = vel_L_rms + vel_L(i)**2._wp + vel_R_rms = vel_R_rms + vel_R(i)**2._wp + end do + + pres_L = qL_prim_rs${XYZ}$_vf(j, k, l, E_idx) + pres_R = qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx) + + ! Change this by splitting it into the cases + ! present in the bubbles_euler + if (mpp_lim) then + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_fluids + qL_prim_rs${XYZ}$_vf(j, k, l, i) = max(0._wp, qL_prim_rs${XYZ}$_vf(j, k, l, i)) + qL_prim_rs${XYZ}$_vf(j, k, l, E_idx + i) = min(max(0._wp, qL_prim_rs${XYZ}$_vf(j, k, l, E_idx + i)), 1._wp) + qR_prim_rs${XYZ}$_vf(j + 1, k, l, i) = max(0._wp, qR_prim_rs${XYZ}$_vf(j + 1, k, l, i)) + qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx + i) = min(max(0._wp, qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx + i)), 1._wp) + alpha_L_sum = alpha_L_sum + qL_prim_rs${XYZ}$_vf(j, k, l, E_idx + i) + alpha_R_sum = alpha_R_sum + qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx + i) + end do + + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_fluids + qL_prim_rs${XYZ}$_vf(j, k, l, E_idx + i) = qL_prim_rs${XYZ}$_vf(j, k, l, E_idx + i)/max(alpha_L_sum, sgm_eps) + qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx + i) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx + i)/max(alpha_R_sum, sgm_eps) + end do + end if + + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_fluids + rho_L = rho_L + qL_prim_rs${XYZ}$_vf(j, k, l, i) + gamma_L = gamma_L + qL_prim_rs${XYZ}$_vf(j, k, l, E_idx + i)*gammas(i) + pi_inf_L = pi_inf_L + qL_prim_rs${XYZ}$_vf(j, k, l, E_idx + i)*pi_infs(i) + qv_L = qv_L + qL_prim_rs${XYZ}$_vf(j, k, l, i)*qvs(i) + + rho_R = rho_R + qR_prim_rs${XYZ}$_vf(j + 1, k, l, i) + gamma_R = gamma_R + qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx + i)*gammas(i) + pi_inf_R = pi_inf_R + qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx + i)*pi_infs(i) + qv_R = qv_R + qR_prim_rs${XYZ}$_vf(j + 1, k, l, i)*qvs(i) + end do + + Re_max = 0 + if (Re_size(1) > 0) Re_max = 1 + if (Re_size(2) > 0) Re_max = 2 + + if (viscous) then + ! Map rotated (j,k,l) to physical (x,y,z) indices + #:if NORM_DIR == 1 + call s_compute_re_visc(q_prim_vf, & + alpha_L, j, k, l, Re_visc_per_phase_L) + call s_compute_re_visc(q_prim_vf, & + alpha_R, j + 1, k, l, Re_visc_per_phase_R) + #:elif NORM_DIR == 2 + call s_compute_re_visc(q_prim_vf, & + alpha_L, k, j, l, Re_visc_per_phase_L) + call s_compute_re_visc(q_prim_vf, & + alpha_R, k, j + 1, l, Re_visc_per_phase_R) + #:else + call s_compute_re_visc(q_prim_vf, & + alpha_L, l, k, j, Re_visc_per_phase_L) + call s_compute_re_visc(q_prim_vf, & + alpha_R, l, k, j + 1, Re_visc_per_phase_R) + #:endif + call s_compute_mixture_re( & + alpha_L, Re_visc_per_phase_L, Re_L) + call s_compute_mixture_re( & + alpha_R, Re_visc_per_phase_R, Re_R) + end if + + if (chemistry) then + c_sum_Yi_Phi = 0.0_wp + $:GPU_LOOP(parallelism='[seq]') + do i = chemxb, chemxe + Ys_L(i - chemxb + 1) = qL_prim_rs${XYZ}$_vf(j, k, l, i) + Ys_R(i - chemxb + 1) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, i) + end do + + call get_mixture_molecular_weight(Ys_L, MW_L) + call get_mixture_molecular_weight(Ys_R, MW_R) + + #:if USING_AMD + Xs_L(:) = Ys_L(:)*MW_L/molecular_weights_nonparameter(:) + Xs_R(:) = Ys_R(:)*MW_R/molecular_weights_nonparameter(:) + #:else + Xs_L(:) = Ys_L(:)*MW_L/molecular_weights(:) + Xs_R(:) = Ys_R(:)*MW_R/molecular_weights(:) + #:endif + + R_gas_L = gas_constant/MW_L + R_gas_R = gas_constant/MW_R + + T_L = pres_L/rho_L/R_gas_L + T_R = pres_R/rho_R/R_gas_R + + call get_species_specific_heats_r(T_L, Cp_iL) + call get_species_specific_heats_r(T_R, Cp_iR) + + if (chem_params%gamma_method == 1) then + !> gamma_method = 1: Ref. Section 2.3.1 Formulation of doi:10.7907/ZKW8-ES97. + Gamma_iL = Cp_iL/(Cp_iL - 1.0_wp) + Gamma_iR = Cp_iR/(Cp_iR - 1.0_wp) + + gamma_L = sum(Xs_L(:)/(Gamma_iL(:) - 1.0_wp)) + gamma_R = sum(Xs_R(:)/(Gamma_iR(:) - 1.0_wp)) + else if (chem_params%gamma_method == 2) then + !> gamma_method = 2: c_p / c_v where c_p, c_v are specific heats. + call get_mixture_specific_heat_cp_mass(T_L, Ys_L, Cp_L) + call get_mixture_specific_heat_cp_mass(T_R, Ys_R, Cp_R) + call get_mixture_specific_heat_cv_mass(T_L, Ys_L, Cv_L) + call get_mixture_specific_heat_cv_mass(T_R, Ys_R, Cv_R) + + Gamm_L = Cp_L/Cv_L; Gamm_R = Cp_R/Cv_R + gamma_L = 1.0_wp/(Gamm_L - 1.0_wp); gamma_R = 1.0_wp/(Gamm_R - 1.0_wp) + end if + + call get_mixture_energy_mass(T_L, Ys_L, E_L) + call get_mixture_energy_mass(T_R, Ys_R, E_R) + + E_L = rho_L*E_L + 5.e-1*rho_L*vel_L_rms + E_R = rho_R*E_R + 5.e-1*rho_R*vel_R_rms + H_L = (E_L + pres_L)/rho_L + H_R = (E_R + pres_R)/rho_R + else + E_L = gamma_L*pres_L + pi_inf_L + 5.e-1*rho_L*vel_L_rms + qv_L + E_R = gamma_R*pres_R + pi_inf_R + 5.e-1*rho_R*vel_R_rms + qv_R + + H_L = (E_L + pres_L)/rho_L + H_R = (E_R + pres_R)/rho_R + end if + + ! ENERGY ADJUSTMENTS FOR HYPOELASTIC ENERGY + if (hypoelasticity) then + $:GPU_LOOP(parallelism='[seq]') + do i = 1, strxe - strxb + 1 + tau_e_L(i) = qL_prim_rs${XYZ}$_vf(j, k, l, strxb - 1 + i) + tau_e_R(i) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, strxb - 1 + i) + end do + G_L = 0._wp + G_R = 0._wp + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_fluids + G_L = G_L + alpha_L(i)*Gs_rs(i) + G_R = G_R + alpha_R(i)*Gs_rs(i) + end do + $:GPU_LOOP(parallelism='[seq]') + do i = 1, strxe - strxb + 1 + ! Elastic contribution to energy if G large enough + if ((G_L > verysmall) .and. (G_R > verysmall)) then + E_L = E_L + (tau_e_L(i)*tau_e_L(i))/(4._wp*G_L) + E_R = E_R + (tau_e_R(i)*tau_e_R(i))/(4._wp*G_R) + ! Additional terms in 2D and 3D + if ((i == 2) .or. (i == 4) .or. (i == 5)) then + E_L = E_L + (tau_e_L(i)*tau_e_L(i))/(4._wp*G_L) + E_R = E_R + (tau_e_R(i)*tau_e_R(i))/(4._wp*G_R) + end if + end if + end do + end if + + ! ENERGY ADJUSTMENTS FOR HYPERELASTIC ENERGY + if (hyperelasticity) then + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_dims + xi_field_L(i) = qL_prim_rs${XYZ}$_vf(j, k, l, xibeg - 1 + i) + xi_field_R(i) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, xibeg - 1 + i) + end do + G_L = 0._wp + G_R = 0._wp + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_fluids + ! Mixture left and right shear modulus + G_L = G_L + alpha_L(i)*Gs_rs(i) + G_R = G_R + alpha_R(i)*Gs_rs(i) + end do + ! Elastic contribution to energy if G large enough + if (G_L > verysmall .and. G_R > verysmall) then + E_L = E_L + G_L*qL_prim_rs${XYZ}$_vf(j, k, l, xiend + 1) + E_R = E_R + G_R*qR_prim_rs${XYZ}$_vf(j + 1, k, l, xiend + 1) + end if + $:GPU_LOOP(parallelism='[seq]') + do i = 1, b_size - 1 + tau_e_L(i) = qL_prim_rs${XYZ}$_vf(j, k, l, strxb - 1 + i) + tau_e_R(i) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, strxb - 1 + i) + end do + end if + + H_L = (E_L + pres_L)/rho_L + H_R = (E_R + pres_R)/rho_R + + @:compute_average_state() + + call s_compute_speed_of_sound(pres_L, rho_L, gamma_L, pi_inf_L, H_L, alpha_L, & + vel_L_rms, 0._wp, c_L, qv_L) + + call s_compute_speed_of_sound(pres_R, rho_R, gamma_R, pi_inf_R, H_R, alpha_R, & + vel_R_rms, 0._wp, c_R, qv_R) + + !> The computation of c_avg does not require all the variables, and therefore the non '_avg' + ! variables are placeholders to call the subroutine. + call s_compute_speed_of_sound(pres_R, rho_avg, gamma_avg, pi_inf_R, H_avg, alpha_R, & + vel_avg_rms, c_sum_Yi_Phi, c_avg, qv_avg) + + if (viscous) then + if (chemistry) then + call compute_viscosity_and_inversion(T_L, Ys_L, T_R, Ys_R, Re_L(1), Re_R(1)) + end if + $:GPU_LOOP(parallelism='[seq]') + do i = 1, 2 + Re_avg_rs${XYZ}$_vf(j, k, l, i) = 2._wp/(1._wp/Re_L(i) + 1._wp/Re_R(i)) + end do + end if + + ! Low Mach correction + if (low_Mach == 2) then + @:compute_low_Mach_correction() + end if + + if (wave_speeds == 1) then + if (elasticity) then + s_L = min(vel_L(dir_idx(1)) - sqrt(c_L*c_L + & + (((4._wp*G_L)/3._wp) + tau_e_L(dir_idx_tau(1)))/rho_L), vel_R(dir_idx(1)) - sqrt(c_R*c_R + & + (((4._wp*G_R)/3._wp) + tau_e_R(dir_idx_tau(1)))/rho_R)) + s_R = max(vel_R(dir_idx(1)) + sqrt(c_R*c_R + & + (((4._wp*G_R)/3._wp) + tau_e_R(dir_idx_tau(1)))/rho_R), vel_L(dir_idx(1)) + sqrt(c_L*c_L + & + (((4._wp*G_L)/3._wp) + tau_e_L(dir_idx_tau(1)))/rho_L)) + s_S = (pres_R - tau_e_R(dir_idx_tau(1)) - pres_L + & + tau_e_L(dir_idx_tau(1)) + rho_L*vel_L(dir_idx(1))*(s_L - vel_L(dir_idx(1))) - & + rho_R*vel_R(dir_idx(1))*(s_R - vel_R(dir_idx(1))))/(rho_L*(s_L - vel_L(dir_idx(1))) - & + rho_R*(s_R - vel_R(dir_idx(1)))) + else + s_L = min(vel_L(dir_idx(1)) - c_L, vel_R(dir_idx(1)) - c_R) + s_R = max(vel_R(dir_idx(1)) + c_R, vel_L(dir_idx(1)) + c_L) + s_S = (pres_R - pres_L + rho_L*vel_L(dir_idx(1))* & + (s_L - vel_L(dir_idx(1))) - rho_R*vel_R(dir_idx(1))*(s_R - vel_R(dir_idx(1)))) & + /(rho_L*(s_L - vel_L(dir_idx(1))) - rho_R*(s_R - vel_R(dir_idx(1)))) + + end if + elseif (wave_speeds == 2) then + pres_SL = 5.e-1_wp*(pres_L + pres_R + rho_avg*c_avg* & + (vel_L(dir_idx(1)) - & + vel_R(dir_idx(1)))) + + pres_SR = pres_SL + + Ms_L = max(1._wp, sqrt(1._wp + ((5.e-1_wp + gamma_L)/(1._wp + gamma_L))* & + (pres_SL/pres_L - 1._wp)*pres_L/ & + ((pres_L + pi_inf_L/(1._wp + gamma_L))))) + Ms_R = max(1._wp, sqrt(1._wp + ((5.e-1_wp + gamma_R)/(1._wp + gamma_R))* & + (pres_SR/pres_R - 1._wp)*pres_R/ & + ((pres_R + pi_inf_R/(1._wp + gamma_R))))) + + s_L = vel_L(dir_idx(1)) - c_L*Ms_L + s_R = vel_R(dir_idx(1)) + c_R*Ms_R + + s_S = 5.e-1_wp*((vel_L(dir_idx(1)) + vel_R(dir_idx(1))) + & + (pres_L - pres_R)/ & + (rho_avg*c_avg)) + end if + + ! follows Einfeldt et al. + ! s_M/P = min/max(0.,s_L/R) + s_M = min(0._wp, s_L); s_P = max(0._wp, s_R) + + ! goes with q_star_L/R = xi_L/R * (variable) + ! xi_L/R = ( ( s_L/R - u_L/R )/(s_L/R - s_star) ) + xi_L = (s_L - vel_L(dir_idx(1)))/(s_L - s_S) + xi_R = (s_R - vel_R(dir_idx(1)))/(s_R - s_S) + + ! goes with numerical velocity in x/y/z directions + ! xi_P/M = 0.5 +/m sgn(0.5,s_star) + xi_M = (5.e-1_wp + sign(5.e-1_wp, s_S)) + xi_P = (5.e-1_wp - sign(5.e-1_wp, s_S)) + + ! Low Mach correction + if (low_Mach == 1) then + @:compute_low_Mach_correction() + else + pcorr = 0._wp + end if + + ! COMPUTING THE HLLC FLUXES + ! MASS FLUX. + $:GPU_LOOP(parallelism='[seq]') + do i = 1, contxe + flux_rs${XYZ}$_vf(j, k, l, i) = & + xi_M*qL_prim_rs${XYZ}$_vf(j, k, l, i) & + *(vel_L(dir_idx(1)) + s_M*(xi_L - 1._wp)) & + + xi_P*qR_prim_rs${XYZ}$_vf(j + 1, k, l, i) & + *(vel_R(dir_idx(1)) + s_P*(xi_R - 1._wp)) + end do + + ! MOMENTUM FLUX. + ! f = \rho u u - \sigma, q = \rho u, q_star = \xi * \rho*(s_star, v, w) + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_dims + flux_rs${XYZ}$_vf(j, k, l, contxe + dir_idx(i)) = & + xi_M*(rho_L*(vel_L(dir_idx(1))* & + vel_L(dir_idx(i)) + & + s_M*(xi_L*(dir_flg(dir_idx(i))*s_S + & + (1._wp - dir_flg(dir_idx(i)))* & + vel_L(dir_idx(i))) - vel_L(dir_idx(i)))) + & + dir_flg(dir_idx(i))*(pres_L)) & + + xi_P*(rho_R*(vel_R(dir_idx(1))* & + vel_R(dir_idx(i)) + & + s_P*(xi_R*(dir_flg(dir_idx(i))*s_S + & + (1._wp - dir_flg(dir_idx(i)))* & + vel_R(dir_idx(i))) - vel_R(dir_idx(i)))) + & + dir_flg(dir_idx(i))*(pres_R)) & + + (s_M/s_L)*(s_P/s_R)*dir_flg(dir_idx(i))*pcorr + end do + + ! ENERGY FLUX. + ! f = u*(E-\sigma), q = E, q_star = \xi*E+(s-u)(\rho s_star - \sigma/(s-u)) + flux_rs${XYZ}$_vf(j, k, l, E_idx) = & + xi_M*(vel_L(dir_idx(1))*(E_L + pres_L) + & + s_M*(xi_L*(E_L + (s_S - vel_L(dir_idx(1)))* & + (rho_L*s_S + pres_L/ & + (s_L - vel_L(dir_idx(1))))) - E_L)) & + + xi_P*(vel_R(dir_idx(1))*(E_R + pres_R) + & + s_P*(xi_R*(E_R + (s_S - vel_R(dir_idx(1)))* & + (rho_R*s_S + pres_R/ & + (s_R - vel_R(dir_idx(1))))) - E_R)) & + + (s_M/s_L)*(s_P/s_R)*pcorr*s_S + + ! ELASTICITY. Elastic shear stress additions for the momentum and energy flux + if (elasticity) then + flux_ene_e = 0._wp + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_dims + ! MOMENTUM ELASTIC FLUX. + flux_rs${XYZ}$_vf(j, k, l, contxe + dir_idx(i)) = & + flux_rs${XYZ}$_vf(j, k, l, contxe + dir_idx(i)) & + - xi_M*tau_e_L(dir_idx_tau(i)) - xi_P*tau_e_R(dir_idx_tau(i)) + ! ENERGY ELASTIC FLUX. + flux_ene_e = flux_ene_e - & + xi_M*(vel_L(dir_idx(i))*tau_e_L(dir_idx_tau(i)) + & + s_M*(xi_L*((s_S - vel_L(i))*(tau_e_L(dir_idx_tau(i))/(s_L - vel_L(i)))))) - & + xi_P*(vel_R(dir_idx(i))*tau_e_R(dir_idx_tau(i)) + & + s_P*(xi_R*((s_S - vel_R(i))*(tau_e_R(dir_idx_tau(i))/(s_R - vel_R(i)))))) + end do + flux_rs${XYZ}$_vf(j, k, l, E_idx) = flux_rs${XYZ}$_vf(j, k, l, E_idx) + flux_ene_e + end if + + ! HYPOELASTIC STRESS EVOLUTION FLUX. + if (hypoelasticity) then + $:GPU_LOOP(parallelism='[seq]') + do i = 1, strxe - strxb + 1 + flux_rs${XYZ}$_vf(j, k, l, strxb - 1 + i) = & + xi_M*(s_S/(s_L - s_S))*(s_L*rho_L*tau_e_L(i) - rho_L*vel_L(dir_idx(1))*tau_e_L(i)) + & + xi_P*(s_S/(s_R - s_S))*(s_R*rho_R*tau_e_R(i) - rho_R*vel_R(dir_idx(1))*tau_e_R(i)) + end do + end if + + ! VOLUME FRACTION FLUX. + $:GPU_LOOP(parallelism='[seq]') + do i = advxb, advxe + flux_rs${XYZ}$_vf(j, k, l, i) = & + xi_M*qL_prim_rs${XYZ}$_vf(j, k, l, i) & + *(vel_L(dir_idx(1)) + s_M*(xi_L - 1._wp)) & + + xi_P*qR_prim_rs${XYZ}$_vf(j + 1, k, l, i) & + *(vel_R(dir_idx(1)) + s_P*(xi_R - 1._wp)) + end do + + ! VOLUME FRACTION SOURCE FLUX. + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_dims + vel_src_rs${XYZ}$_vf(j, k, l, dir_idx(i)) = & + xi_M*(vel_L(dir_idx(i)) + & + dir_flg(dir_idx(i))* & + s_M*(xi_L - 1._wp)) & + + xi_P*(vel_R(dir_idx(i)) + & + dir_flg(dir_idx(i))* & + s_P*(xi_R - 1._wp)) + end do + + ! COLOR FUNCTION FLUX + if (surface_tension) then + flux_rs${XYZ}$_vf(j, k, l, c_idx) = & + xi_M*qL_prim_rs${XYZ}$_vf(j, k, l, c_idx) & + *(vel_L(dir_idx(1)) + s_M*(xi_L - 1._wp)) & + + xi_P*qR_prim_rs${XYZ}$_vf(j + 1, k, l, c_idx) & + *(vel_R(dir_idx(1)) + s_P*(xi_R - 1._wp)) + end if + + ! REFERENCE MAP FLUX. + if (hyperelasticity) then + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_dims + flux_rs${XYZ}$_vf(j, k, l, xibeg - 1 + i) = & + xi_M*(s_S/(s_L - s_S))*(s_L*rho_L*xi_field_L(i) & + - rho_L*vel_L(dir_idx(1))*xi_field_L(i)) + & + xi_P*(s_S/(s_R - s_S))*(s_R*rho_R*xi_field_R(i) & + - rho_R*vel_R(dir_idx(1))*xi_field_R(i)) + end do + end if + + flux_src_rs${XYZ}$_vf(j, k, l, advxb) = vel_src_rs${XYZ}$_vf(j, k, l, dir_idx(1)) + + if (chemistry) then + $:GPU_LOOP(parallelism='[seq]') + do i = chemxb, chemxe + Y_L = qL_prim_rs${XYZ}$_vf(j, k, l, i) + Y_R = qR_prim_rs${XYZ}$_vf(j + 1, k, l, i) + + flux_rs${XYZ}$_vf(j, k, l, i) = xi_M*rho_L*Y_L*(vel_L(dir_idx(1)) + s_M*(xi_L - 1._wp)) & + + xi_P*rho_R*Y_R*(vel_R(dir_idx(1)) + s_P*(xi_R - 1._wp)) + flux_src_rs${XYZ}$_vf(j, k, l, i) = 0.0_wp + end do + end if + + ! Geometrical source flux for cylindrical coordinates + #:if (NORM_DIR == 2) + if (cyl_coord) then + !Substituting the advective flux into the inviscid geometrical source flux + $:GPU_LOOP(parallelism='[seq]') + do i = 1, E_idx + flux_gsrc_rs${XYZ}$_vf(j, k, l, i) = flux_rs${XYZ}$_vf(j, k, l, i) + end do + ! Recalculating the radial momentum geometric source flux + flux_gsrc_rs${XYZ}$_vf(j, k, l, contxe + dir_idx(1)) = & + xi_M*(rho_L*(vel_L(dir_idx(1))* & + vel_L(dir_idx(1)) + & + s_M*(xi_L*(dir_flg(dir_idx(1))*s_S + & + (1._wp - dir_flg(dir_idx(1)))* & + vel_L(dir_idx(1))) - vel_L(dir_idx(1))))) & + + xi_P*(rho_R*(vel_R(dir_idx(1))* & + vel_R(dir_idx(1)) + & + s_P*(xi_R*(dir_flg(dir_idx(1))*s_S + & + (1._wp - dir_flg(dir_idx(1)))* & + vel_R(dir_idx(1))) - vel_R(dir_idx(1))))) + ! Geometrical source of the void fraction(s) is zero + $:GPU_LOOP(parallelism='[seq]') + do i = advxb, advxe + flux_gsrc_rs${XYZ}$_vf(j, k, l, i) = 0._wp + end do + end if + #:endif + #:if (NORM_DIR == 3) + if (grid_geometry == 3) then + $:GPU_LOOP(parallelism='[seq]') + do i = 1, sys_size + flux_gsrc_rs${XYZ}$_vf(j, k, l, i) = 0._wp + end do + + flux_gsrc_rs${XYZ}$_vf(j, k, l, momxb + 1) = & + -xi_M*(rho_L*(vel_L(dir_idx(1))* & + vel_L(dir_idx(1)) + & + s_M*(xi_L*(dir_flg(dir_idx(1))*s_S + & + (1._wp - dir_flg(dir_idx(1)))* & + vel_L(dir_idx(1))) - vel_L(dir_idx(1))))) & + - xi_P*(rho_R*(vel_R(dir_idx(1))* & + vel_R(dir_idx(1)) + & + s_P*(xi_R*(dir_flg(dir_idx(1))*s_S + & + (1._wp - dir_flg(dir_idx(1)))* & + vel_R(dir_idx(1))) - vel_R(dir_idx(1))))) + flux_gsrc_rs${XYZ}$_vf(j, k, l, momxe) = flux_rs${XYZ}$_vf(j, k, l, momxb + 1) + + end if + #:endif + + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + end if + end if + #:endfor + ! Computing HLLC flux and source flux for Euler system of equations + + if (viscous .or. dummy) then + if (weno_Re_flux) then + call s_compute_viscous_source_flux( & + qL_prim_vf(momxb:momxe), & + dqL_prim_dx_vf(momxb:momxe), & + dqL_prim_dy_vf(momxb:momxe), & + dqL_prim_dz_vf(momxb:momxe), & + qR_prim_vf(momxb:momxe), & + dqR_prim_dx_vf(momxb:momxe), & + dqR_prim_dy_vf(momxb:momxe), & + dqR_prim_dz_vf(momxb:momxe), & + flux_src_vf, norm_dir, ix, iy, iz) + else + call s_compute_viscous_source_flux( & + q_prim_vf(momxb:momxe), & + dqL_prim_dx_vf(momxb:momxe), & + dqL_prim_dy_vf(momxb:momxe), & + dqL_prim_dz_vf(momxb:momxe), & + q_prim_vf(momxb:momxe), & + dqR_prim_dx_vf(momxb:momxe), & + dqR_prim_dy_vf(momxb:momxe), & + dqR_prim_dz_vf(momxb:momxe), & + flux_src_vf, norm_dir, ix, iy, iz) + end if + end if + + if (surface_tension) then + call s_compute_capillary_source_flux( & + vel_src_rsx_vf, & + vel_src_rsy_vf, & + vel_src_rsz_vf, & + flux_src_vf, & + norm_dir, isx, isy, isz) + end if + + call s_finalize_riemann_solver(flux_vf, flux_src_vf, & + flux_gsrc_vf, & + norm_dir) + + end subroutine s_hllc_riemann_solver + + !> HLLD Riemann solver resolves 5 of the 7 waves of MHD equations: + !! 1 entropy wave, 2 Alfvén waves, 2 fast magnetosonic waves. + subroutine s_hlld_riemann_solver(qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, & + dqL_prim_dx_vf, dqL_prim_dy_vf, dqL_prim_dz_vf, & + qL_prim_vf, & + qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf, & + dqR_prim_dx_vf, dqR_prim_dy_vf, dqR_prim_dz_vf, & + qR_prim_vf, & + q_prim_vf, & + flux_vf, flux_src_vf, flux_gsrc_vf, & + norm_dir, ix, iy, iz) + + real(wp), dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:), intent(inout) :: qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, & + qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf + + type(scalar_field), allocatable, dimension(:), intent(inout) :: dqL_prim_dx_vf, dqR_prim_dx_vf, & + dqL_prim_dy_vf, dqR_prim_dy_vf, & + dqL_prim_dz_vf, dqR_prim_dz_vf + + type(scalar_field), allocatable, dimension(:), intent(inout) :: qL_prim_vf, qR_prim_vf + + type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf + type(scalar_field), dimension(sys_size), intent(inout) :: flux_vf, flux_src_vf, flux_gsrc_vf + + integer, intent(in) :: norm_dir + type(int_bounds_info), intent(in) :: ix, iy, iz + + ! Local variables: + #:if not MFC_CASE_OPTIMIZATION and USING_AMD + real(wp), dimension(3) :: alpha_L, alpha_R, alpha_rho_L, alpha_rho_R + #:else + real(wp), dimension(num_fluids) :: alpha_L, alpha_R, alpha_rho_L, alpha_rho_R + #:endif + type(riemann_states_vec3) :: vel + type(riemann_states) :: rho, pres, E, H_no_mag + type(riemann_states) :: gamma, pi_inf, qv + type(riemann_states) :: vel_rms + + type(riemann_states_vec3) :: B + type(riemann_states) :: c, c_fast, pres_mag + + ! HLLD speeds and intermediate state variables: + real(wp) :: s_L, s_R, s_M, s_starL, s_starR + real(wp) :: pTot_L, pTot_R, p_star, rhoL_star, rhoR_star, E_starL, E_starR + + real(wp), dimension(7) :: U_L, U_R, U_starL, U_starR, U_doubleL, U_doubleR + real(wp), dimension(7) :: F_L, F_R, F_starL, F_starR, F_hlld + + ! Indices for U and F: (rho, rho*vel(1), rho*vel(2), rho*vel(3), By, Bz, E) + ! Note: vel and B are permutated, so vel(1) is the normal velocity, and x is the normal direction + ! Note: Bx is omitted as the magnetic flux is always zero in the normal direction + + real(wp) :: sqrt_rhoL_star, sqrt_rhoR_star, denom_ds, sign_Bx + real(wp) :: vL_star, vR_star, wL_star, wR_star + real(wp) :: v_double, w_double, By_double, Bz_double, E_doubleL, E_doubleR, E_double + + integer :: i, j, k, l + + call s_populate_riemann_states_variables_buffers( & + qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, dqL_prim_dx_vf, & + dqL_prim_dy_vf, dqL_prim_dz_vf, & + qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf, dqR_prim_dx_vf, & + dqR_prim_dy_vf, dqR_prim_dz_vf, & + norm_dir, ix, iy, iz) + + call s_initialize_riemann_solver( & + flux_src_vf, norm_dir) + + #:for NORM_DIR, XYZ in [(1, 'x'), (2, 'y'), (3, 'z')] + if (norm_dir == ${NORM_DIR}$) then + $:GPU_PARALLEL_LOOP(collapse=3, private='[alpha_rho_L, alpha_rho_R, vel, alpha_L, alpha_R, rho, pres,E, H_no_mag, gamma, pi_inf, qv, vel_rms, B, c, c_fast, pres_mag, U_L, U_R, U_starL, U_starR, U_doubleL, U_doubleR, F_L, F_R, F_starL, F_starR, F_hlld, s_L, s_R, s_M, s_starL, s_starR, pTot_L, pTot_R, p_star, rhoL_star, rhoR_star, E_starL, E_starR, sqrt_rhoL_star, sqrt_rhoR_star, denom_ds, sign_Bx, vL_star, vR_star, wL_star, wR_star, v_double, w_double, By_double, Bz_double, E_doubleL, E_doubleR, E_double]', copyin='[norm_dir]') + do l = is3%beg, is3%end + do k = is2%beg, is2%end + do j = is1%beg, is1%end + + ! (1) Extract the left/right primitive states + do i = 1, contxe + alpha_rho_L(i) = qL_prim_rs${XYZ}$_vf(j, k, l, i) + alpha_rho_R(i) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, i) + end do + + ! NOTE: unlike HLL & HLLC, vel_L here is permutated by dir_idx for simpler logic + do i = 1, num_vels + vel%L(i) = qL_prim_rs${XYZ}$_vf(j, k, l, contxe + dir_idx(i)) + vel%R(i) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, contxe + dir_idx(i)) + end do + + vel_rms%L = sum(vel%L**2._wp) + vel_rms%R = sum(vel%R**2._wp) + + do i = 1, num_fluids + alpha_L(i) = qL_prim_rs${XYZ}$_vf(j, k, l, E_idx + i) + alpha_R(i) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx + i) + end do + + pres%L = qL_prim_rs${XYZ}$_vf(j, k, l, E_idx) + pres%R = qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx) + + ! NOTE: unlike HLL, Bx, By, Bz are permutated by dir_idx for simpler logic + if (mhd) then + if (n == 0) then ! 1D: constant Bx; By, Bz as variables; only in x so not permutated + B%L = [Bx0, qL_prim_rs${XYZ}$_vf(j, k, l, B_idx%beg), qL_prim_rs${XYZ}$_vf(j, k, l, B_idx%beg + 1)] + B%R = [Bx0, qR_prim_rs${XYZ}$_vf(j + 1, k, l, B_idx%beg), qR_prim_rs${XYZ}$_vf(j + 1, k, l, B_idx%beg + 1)] + else ! 2D/3D: Bx, By, Bz as variables + B%L = [qL_prim_rs${XYZ}$_vf(j, k, l, B_idx%beg + dir_idx(1) - 1), & + qL_prim_rs${XYZ}$_vf(j, k, l, B_idx%beg + dir_idx(2) - 1), & + qL_prim_rs${XYZ}$_vf(j, k, l, B_idx%beg + dir_idx(3) - 1)] + B%R = [qR_prim_rs${XYZ}$_vf(j + 1, k, l, B_idx%beg + dir_idx(1) - 1), & + qR_prim_rs${XYZ}$_vf(j + 1, k, l, B_idx%beg + dir_idx(2) - 1), & + qR_prim_rs${XYZ}$_vf(j + 1, k, l, B_idx%beg + dir_idx(3) - 1)] + end if + end if + + ! Sum properties of all fluid components + rho%L = 0._wp; gamma%L = 0._wp; pi_inf%L = 0._wp; qv%L = 0._wp + rho%R = 0._wp; gamma%R = 0._wp; pi_inf%R = 0._wp; qv%R = 0._wp + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_fluids + rho%L = rho%L + alpha_rho_L(i) + gamma%L = gamma%L + alpha_L(i)*gammas(i) + pi_inf%L = pi_inf%L + alpha_L(i)*pi_infs(i) + qv%L = qv%L + alpha_rho_L(i)*qvs(i) + + rho%R = rho%R + alpha_rho_R(i) + gamma%R = gamma%R + alpha_R(i)*gammas(i) + pi_inf%R = pi_inf%R + alpha_R(i)*pi_infs(i) + qv%R = qv%R + alpha_rho_R(i)*qvs(i) + end do + + pres_mag%L = 0.5_wp*sum(B%L**2._wp) + pres_mag%R = 0.5_wp*sum(B%R**2._wp) + E%L = gamma%L*pres%L + pi_inf%L + 0.5_wp*rho%L*vel_rms%L + qv%L + pres_mag%L + E%R = gamma%R*pres%R + pi_inf%R + 0.5_wp*rho%R*vel_rms%R + qv%R + pres_mag%R ! includes magnetic energy + H_no_mag%L = (E%L + pres%L - pres_mag%L)/rho%L + H_no_mag%R = (E%R + pres%R - pres_mag%R)/rho%R ! stagnation enthalpy here excludes magnetic energy (only used to find speed of sound) + + ! (2) Compute fast wave speeds + call s_compute_speed_of_sound(pres%L, rho%L, gamma%L, pi_inf%L, H_no_mag%L, alpha_L, vel_rms%L, 0._wp, c%L, qv%L) + call s_compute_speed_of_sound(pres%R, rho%R, gamma%R, pi_inf%R, H_no_mag%R, alpha_R, vel_rms%R, 0._wp, c%R, qv%R) + call s_compute_fast_magnetosonic_speed(rho%L, c%L, B%L, norm_dir, c_fast%L, H_no_mag%L) + call s_compute_fast_magnetosonic_speed(rho%R, c%R, B%R, norm_dir, c_fast%R, H_no_mag%R) + + ! (3) Compute contact speed s_M [Miyoshi Equ. (38)] + s_L = min(vel%L(1) - c_fast%L, vel%R(1) - c_fast%R) + s_R = max(vel%R(1) + c_fast%R, vel%L(1) + c_fast%L) + + pTot_L = pres%L + pres_mag%L + pTot_R = pres%R + pres_mag%R + + s_M = (((s_R - vel%R(1))*rho%R*vel%R(1) - & + (s_L - vel%L(1))*rho%L*vel%L(1) - pTot_R + pTot_L)/ & + ((s_R - vel%R(1))*rho%R - (s_L - vel%L(1))*rho%L)) + + ! (4) Compute star state variables + rhoL_star = rho%L*(s_L - vel%L(1))/(s_L - s_M) + rhoR_star = rho%R*(s_R - vel%R(1))/(s_R - s_M) + p_star = pTot_L + rho%L*(s_L - vel%L(1))*(s_M - vel%L(1))/(s_L - s_M) + E_starL = ((s_L - vel%L(1))*E%L - pTot_L*vel%L(1) + p_star*s_M)/(s_L - s_M) + E_starR = ((s_R - vel%R(1))*E%R - pTot_R*vel%R(1) + p_star*s_M)/(s_R - s_M) + + ! (5) Compute left/right state vectors and fluxes + U_L = [rho%L, rho%L*vel%L(1:3), B%L(2:3), E%L] + U_starL = [rhoL_star, rhoL_star*s_M, rhoL_star*vel%L(2:3), B%L(2:3), E_starL] + U_R = [rho%R, rho%R*vel%R(1:3), B%R(2:3), E%R] + U_starR = [rhoR_star, rhoR_star*s_M, rhoR_star*vel%R(2:3), B%R(2:3), E_starR] + + ! Compute the left/right fluxes + F_L(1) = U_L(2) + F_L(2) = U_L(2)*vel%L(1) - B%L(1)*B%L(1) + pTot_L + F_L(3:4) = U_L(2)*vel%L(2:3) - B%L(1)*B%L(2:3) + F_L(5:6) = vel%L(1)*B%L(2:3) - vel%L(2:3)*B%L(1) + F_L(7) = (E%L + pTot_L)*vel%L(1) - B%L(1)*(vel%L(1)*B%L(1) + vel%L(2)*B%L(2) + vel%L(3)*B%L(3)) + + F_R(1) = U_R(2) + F_R(2) = U_R(2)*vel%R(1) - B%R(1)*B%R(1) + pTot_R + F_R(3:4) = U_R(2)*vel%R(2:3) - B%R(1)*B%R(2:3) + F_R(5:6) = vel%R(1)*B%R(2:3) - vel%R(2:3)*B%R(1) + F_R(7) = (E%R + pTot_R)*vel%R(1) - B%R(1)*(vel%R(1)*B%R(1) + vel%R(2)*B%R(2) + vel%R(3)*B%R(3)) + ! Compute the star flux using HLL relation + F_starL = F_L + s_L*(U_starL - U_L) + F_starR = F_R + s_R*(U_starR - U_R) + ! Compute the rotational (Alfvén) speeds + s_starL = s_M - abs(B%L(1))/sqrt(rhoL_star) + s_starR = s_M + abs(B%L(1))/sqrt(rhoR_star) + ! Compute the double–star states [Miyoshi Eqns. (59)-(62)] + sqrt_rhoL_star = sqrt(rhoL_star); sqrt_rhoR_star = sqrt(rhoR_star) + vL_star = vel%L(2); wL_star = vel%L(3) + vR_star = vel%R(2); wR_star = vel%R(3) + + ! (6) Compute the double–star states [Miyoshi Eqns. (59)-(62)] + denom_ds = sqrt_rhoL_star + sqrt_rhoR_star + sign_Bx = sign(1._wp, B%L(1)) + v_double = (sqrt_rhoL_star*vL_star + sqrt_rhoR_star*vR_star + (B%R(2) - B%L(2))*sign_Bx)/denom_ds + w_double = (sqrt_rhoL_star*wL_star + sqrt_rhoR_star*wR_star + (B%R(3) - B%L(3))*sign_Bx)/denom_ds + By_double = (sqrt_rhoL_star*B%R(2) + sqrt_rhoR_star*B%L(2) + sqrt_rhoL_star*sqrt_rhoR_star*(vR_star - vL_star)*sign_Bx)/denom_ds + Bz_double = (sqrt_rhoL_star*B%R(3) + sqrt_rhoR_star*B%L(3) + sqrt_rhoL_star*sqrt_rhoR_star*(wR_star - wL_star)*sign_Bx)/denom_ds + + E_doubleL = E_starL - sqrt_rhoL_star*((vL_star*B%L(2) + wL_star*B%L(3)) - (v_double*By_double + w_double*Bz_double))*sign_Bx + E_doubleR = E_starR + sqrt_rhoR_star*((vR_star*B%R(2) + wR_star*B%R(3)) - (v_double*By_double + w_double*Bz_double))*sign_Bx + E_double = 0.5_wp*(E_doubleL + E_doubleR) + + U_doubleL = [rhoL_star, rhoL_star*s_M, rhoL_star*v_double, rhoL_star*w_double, By_double, Bz_double, E_double] + U_doubleR = [rhoR_star, rhoR_star*s_M, rhoR_star*v_double, rhoR_star*w_double, By_double, Bz_double, E_double] + + ! (11) Choose HLLD flux based on wave-speed regions + if (0.0_wp <= s_L) then + F_hlld = F_L + else if (0.0_wp <= s_starL) then + F_hlld = F_L + s_L*(U_starL - U_L) + else if (0.0_wp <= s_M) then + F_hlld = F_starL + s_starL*(U_doubleL - U_starL) + else if (0.0_wp <= s_starR) then + F_hlld = F_starR + s_starR*(U_doubleR - U_starR) + else if (0.0_wp <= s_R) then + F_hlld = F_R + s_R*(U_starR - U_R) + else + F_hlld = F_R + end if + + ! (12) Reorder and write temporary variables to the flux array + ! Mass + flux_rs${XYZ}$_vf(j, k, l, 1) = F_hlld(1) ! TODO multi-component + ! Momentum + flux_rs${XYZ}$_vf(j, k, l, contxe + dir_idx(1)) = F_hlld(2) + flux_rs${XYZ}$_vf(j, k, l, contxe + dir_idx(2)) = F_hlld(3) + flux_rs${XYZ}$_vf(j, k, l, contxe + dir_idx(3)) = F_hlld(4) + ! Magnetic field + if (n == 0) then + flux_rs${XYZ}$_vf(j, k, l, B_idx%beg) = F_hlld(5) + flux_rs${XYZ}$_vf(j, k, l, B_idx%beg + 1) = F_hlld(6) + else + flux_rs${XYZ}$_vf(j, k, l, B_idx%beg + dir_idx(2) - 1) = F_hlld(5) + flux_rs${XYZ}$_vf(j, k, l, B_idx%beg + dir_idx(3) - 1) = F_hlld(6) + end if + ! Energy + flux_rs${XYZ}$_vf(j, k, l, E_idx) = F_hlld(7) + ! Partial fraction + $:GPU_LOOP(parallelism='[seq]') + do i = advxb, advxe + flux_rs${XYZ}$_vf(j, k, l, i) = 0._wp ! TODO multi-component (zero for now) + end do + + flux_src_rs${XYZ}$_vf(j, k, l, advxb) = 0._wp + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + end if + #:endfor + + call s_finalize_riemann_solver(flux_vf, flux_src_vf, flux_gsrc_vf, & + norm_dir) + end subroutine s_hlld_riemann_solver + + !> The computation of parameters, the allocation of memory, + !! the association of pointers and/or the execution of any + !! other procedures that are necessary to setup the module. + impure subroutine s_initialize_riemann_solvers_module + + ! Allocating the variables that will be utilized to formulate the + ! left, right, and average states of the Riemann problem, as well + ! the Riemann problem solution + integer :: i, j + + @:ALLOCATE(Gs_rs(1:num_fluids)) + + do i = 1, num_fluids + Gs_rs(i) = fluid_pp(i)%G + end do + $:GPU_UPDATE(device='[Gs_rs]') + + if (viscous) then + $:GPU_UPDATE(device='[Re_idx,Re_size]') + end if + + $:GPU_ENTER_DATA(copyin='[is1,is2,is3,isx,isy,isz]') + + is1%beg = -1; is2%beg = 0; is3%beg = 0 + is1%end = m; is2%end = n; is3%end = p + + @:ALLOCATE(flux_rsx_vf(is1%beg:is1%end, & + is2%beg:is2%end, & + is3%beg:is3%end, 1:sys_size)) + @:ALLOCATE(flux_gsrc_rsx_vf(is1%beg:is1%end, & + is2%beg:is2%end, & + is3%beg:is3%end, 1:sys_size)) + @:ALLOCATE(flux_src_rsx_vf(is1%beg:is1%end, & + is2%beg:is2%end, & + is3%beg:is3%end, advxb:sys_size)) + @:ALLOCATE(vel_src_rsx_vf(is1%beg:is1%end, & + is2%beg:is2%end, & + is3%beg:is3%end, 1:num_vels)) + if (qbmm) then + @:ALLOCATE(mom_sp_rsx_vf(is1%beg:is1%end + 1, is2%beg:is2%end, is3%beg:is3%end, 1:4)) + end if + + if (viscous) then + @:ALLOCATE(Re_avg_rsx_vf(is1%beg:is1%end, & + is2%beg:is2%end, & + is3%beg:is3%end, 1:2)) + end if + + if (n == 0) return + + is1%beg = -1; is2%beg = 0; is3%beg = 0 + is1%end = n; is2%end = m; is3%end = p + + @:ALLOCATE(flux_rsy_vf(is1%beg:is1%end, & + is2%beg:is2%end, & + is3%beg:is3%end, 1:sys_size)) + @:ALLOCATE(flux_gsrc_rsy_vf(is1%beg:is1%end, & + is2%beg:is2%end, & + is3%beg:is3%end, 1:sys_size)) + @:ALLOCATE(flux_src_rsy_vf(is1%beg:is1%end, & + is2%beg:is2%end, & + is3%beg:is3%end, advxb:sys_size)) + @:ALLOCATE(vel_src_rsy_vf(is1%beg:is1%end, & + is2%beg:is2%end, & + is3%beg:is3%end, 1:num_vels)) + + if (qbmm) then + @:ALLOCATE(mom_sp_rsy_vf(is1%beg:is1%end + 1, is2%beg:is2%end, is3%beg:is3%end, 1:4)) + end if + + if (viscous) then + @:ALLOCATE(Re_avg_rsy_vf(is1%beg:is1%end, & + is2%beg:is2%end, & + is3%beg:is3%end, 1:2)) + end if + + if (p == 0) return + + is1%beg = -1; is2%beg = 0; is3%beg = 0 + is1%end = p; is2%end = n; is3%end = m + + @:ALLOCATE(flux_rsz_vf(is1%beg:is1%end, & + is2%beg:is2%end, & + is3%beg:is3%end, 1:sys_size)) + @:ALLOCATE(flux_gsrc_rsz_vf(is1%beg:is1%end, & + is2%beg:is2%end, & + is3%beg:is3%end, 1:sys_size)) + @:ALLOCATE(flux_src_rsz_vf(is1%beg:is1%end, & + is2%beg:is2%end, & + is3%beg:is3%end, advxb:sys_size)) + @:ALLOCATE(vel_src_rsz_vf(is1%beg:is1%end, & + is2%beg:is2%end, & + is3%beg:is3%end, 1:num_vels)) + + if (qbmm) then + @:ALLOCATE(mom_sp_rsz_vf(is1%beg:is1%end + 1, is2%beg:is2%end, is3%beg:is3%end, 1:4)) + end if + + if (viscous) then + @:ALLOCATE(Re_avg_rsz_vf(is1%beg:is1%end, & + is2%beg:is2%end, & + is3%beg:is3%end, 1:2)) + end if + + end subroutine s_initialize_riemann_solvers_module + + !> The purpose of this subroutine is to populate the buffers + !! of the left and right Riemann states variables, depending + !! on the boundary conditions. + !! @param qL_prim_rsx_vf Left WENO-reconstructed cell-boundary values (x-dir) + !! @param qL_prim_rsy_vf Left WENO-reconstructed cell-boundary values (y-dir) + !! @param qL_prim_rsz_vf Left WENO-reconstructed cell-boundary values (z-dir) + !! @param dqL_prim_dx_vf The left WENO-reconstructed cell-boundary values of the + !! first-order x-dir spatial derivatives + !! @param dqL_prim_dy_vf The left WENO-reconstructed cell-boundary values of the + !! first-order y-dir spatial derivatives + !! @param dqL_prim_dz_vf The left WENO-reconstructed cell-boundary values of the + !! first-order z-dir spatial derivatives + !! @param qR_prim_rsx_vf Right WENO-reconstructed cell-boundary values (x-dir) + !! @param qR_prim_rsy_vf Right WENO-reconstructed cell-boundary values (y-dir) + !! @param qR_prim_rsz_vf Right WENO-reconstructed cell-boundary values (z-dir) + !! @param dqR_prim_dx_vf The right WENO-reconstructed cell-boundary values of the + !! first-order x-dir spatial derivatives + !! @param dqR_prim_dy_vf The right WENO-reconstructed cell-boundary values of the + !! first-order y-dir spatial derivatives + !! @param dqR_prim_dz_vf The right WENO-reconstructed cell-boundary values of the + !! first-order z-dir spatial derivatives + !! @param norm_dir Dir. splitting direction + !! @param ix Index bounds in the x-dir + !! @param iy Index bounds in the y-dir + !! @param iz Index bounds in the z-dir + subroutine s_populate_riemann_states_variables_buffers( & + qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, dqL_prim_dx_vf, & + dqL_prim_dy_vf, & + dqL_prim_dz_vf, & + qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf, dqR_prim_dx_vf, & + dqR_prim_dy_vf, & + dqR_prim_dz_vf, & + norm_dir, ix, iy, iz) + + real(wp), dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:), intent(inout) :: qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf + + type(scalar_field), & + allocatable, dimension(:), & + intent(inout) :: dqL_prim_dx_vf, dqR_prim_dx_vf, & + dqL_prim_dy_vf, dqR_prim_dy_vf, & + dqL_prim_dz_vf, dqR_prim_dz_vf + + integer, intent(in) :: norm_dir + type(int_bounds_info), intent(in) :: ix, iy, iz + + integer :: i, j, k, l !< Generic loop iterator + + if (norm_dir == 1) then + is1 = ix; is2 = iy; is3 = iz + dir_idx = (/1, 2, 3/); dir_flg = (/1._wp, 0._wp, 0._wp/) + elseif (norm_dir == 2) then + is1 = iy; is2 = ix; is3 = iz + dir_idx = (/2, 1, 3/); dir_flg = (/0._wp, 1._wp, 0._wp/) + else + is1 = iz; is2 = iy; is3 = ix + dir_idx = (/3, 1, 2/); dir_flg = (/0._wp, 0._wp, 1._wp/) + end if + + $:GPU_UPDATE(device='[is1,is2,is3]') + + if (elasticity) then + if (norm_dir == 1) then + dir_idx_tau = (/1, 2, 4/) + else if (norm_dir == 2) then + dir_idx_tau = (/3, 2, 5/) + else + dir_idx_tau = (/6, 4, 5/) + end if + end if + + isx = ix; isy = iy; isz = iz + ! for stuff in the same module + $:GPU_UPDATE(device='[isx,isy,isz]') + ! for stuff in different modules + $:GPU_UPDATE(device='[dir_idx,dir_flg,dir_idx_tau]') + + ! Population of Buffers in x-direction + if (norm_dir == 1) then + + if (bc_x%beg == BC_RIEMANN_EXTRAP) then ! Riemann state extrap. BC at beginning + $:GPU_PARALLEL_LOOP(collapse=3) + do i = 1, sys_size + do l = is3%beg, is3%end + do k = is2%beg, is2%end + qL_prim_rsx_vf(-1, k, l, i) = & + qR_prim_rsx_vf(0, k, l, i) + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + + if (viscous .or. dummy) then + $:GPU_PARALLEL_LOOP(collapse=3) + do i = momxb, momxe + do l = isz%beg, isz%end + do k = isy%beg, isy%end + + dqL_prim_dx_vf(i)%sf(-1, k, l) = & + dqR_prim_dx_vf(i)%sf(0, k, l) + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + + if (n > 0) then + $:GPU_PARALLEL_LOOP(collapse=3) + do i = momxb, momxe + do l = isz%beg, isz%end + do k = isy%beg, isy%end + + dqL_prim_dy_vf(i)%sf(-1, k, l) = & + dqR_prim_dy_vf(i)%sf(0, k, l) + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + + if (p > 0) then + $:GPU_PARALLEL_LOOP(collapse=3) + do i = momxb, momxe + do l = isz%beg, isz%end + do k = isy%beg, isy%end + + dqL_prim_dz_vf(i)%sf(-1, k, l) = & + dqR_prim_dz_vf(i)%sf(0, k, l) + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + end if + + end if + + end if + + end if + + if (bc_x%end == BC_RIEMANN_EXTRAP) then ! Riemann state extrap. BC at end + + $:GPU_PARALLEL_LOOP(collapse=3) + do i = 1, sys_size + do l = is3%beg, is3%end + do k = is2%beg, is2%end + qR_prim_rsx_vf(m + 1, k, l, i) = & + qL_prim_rsx_vf(m, k, l, i) + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + + if (viscous .or. dummy) then + + $:GPU_PARALLEL_LOOP(collapse=3) + do i = momxb, momxe + do l = isz%beg, isz%end + do k = isy%beg, isy%end + + dqR_prim_dx_vf(i)%sf(m + 1, k, l) = & + dqL_prim_dx_vf(i)%sf(m, k, l) + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + + if (n > 0) then + $:GPU_PARALLEL_LOOP(collapse=3) + do i = momxb, momxe + do l = isz%beg, isz%end + do k = isy%beg, isy%end + + dqR_prim_dy_vf(i)%sf(m + 1, k, l) = & + dqL_prim_dy_vf(i)%sf(m, k, l) + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + + if (p > 0) then + $:GPU_PARALLEL_LOOP(collapse=3) + do i = momxb, momxe + do l = isz%beg, isz%end + do k = isy%beg, isy%end + + dqR_prim_dz_vf(i)%sf(m + 1, k, l) = & + dqL_prim_dz_vf(i)%sf(m, k, l) + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + end if + + end if + + end if + + end if + ! END: Population of Buffers in x-direction + + ! Population of Buffers in y-direction + elseif (norm_dir == 2) then + + if (bc_y%beg == BC_RIEMANN_EXTRAP) then ! Riemann state extrap. BC at beginning + $:GPU_PARALLEL_LOOP(collapse=3) + do i = 1, sys_size + do l = is3%beg, is3%end + do k = is2%beg, is2%end + qL_prim_rsy_vf(-1, k, l, i) = & + qR_prim_rsy_vf(0, k, l, i) + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + + if (viscous .or. dummy) then + + $:GPU_PARALLEL_LOOP(collapse=3) + do i = momxb, momxe + do l = isz%beg, isz%end + do j = isx%beg, isx%end + dqL_prim_dx_vf(i)%sf(j, -1, l) = & + dqR_prim_dx_vf(i)%sf(j, 0, l) + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + + $:GPU_PARALLEL_LOOP(collapse=3) + do i = momxb, momxe + do l = isz%beg, isz%end + do j = isx%beg, isx%end + dqL_prim_dy_vf(i)%sf(j, -1, l) = & + dqR_prim_dy_vf(i)%sf(j, 0, l) + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + + if (p > 0) then + $:GPU_PARALLEL_LOOP(collapse=3) + do i = momxb, momxe + do l = isz%beg, isz%end + do j = isx%beg, isx%end + dqL_prim_dz_vf(i)%sf(j, -1, l) = & + dqR_prim_dz_vf(i)%sf(j, 0, l) + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + end if + + end if + + end if + + if (bc_y%end == BC_RIEMANN_EXTRAP) then ! Riemann state extrap. BC at end + + $:GPU_PARALLEL_LOOP(collapse=3) + do i = 1, sys_size + do l = is3%beg, is3%end + do k = is2%beg, is2%end + qR_prim_rsy_vf(n + 1, k, l, i) = & + qL_prim_rsy_vf(n, k, l, i) + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + + if (viscous .or. dummy) then + + $:GPU_PARALLEL_LOOP(collapse=3) + do i = momxb, momxe + do l = isz%beg, isz%end + do j = isx%beg, isx%end + dqR_prim_dx_vf(i)%sf(j, n + 1, l) = & + dqL_prim_dx_vf(i)%sf(j, n, l) + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + + $:GPU_PARALLEL_LOOP(collapse=3) + do i = momxb, momxe + do l = isz%beg, isz%end + do j = isx%beg, isx%end + dqR_prim_dy_vf(i)%sf(j, n + 1, l) = & + dqL_prim_dy_vf(i)%sf(j, n, l) + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + + if (p > 0) then + $:GPU_PARALLEL_LOOP(collapse=3) + do i = momxb, momxe + do l = isz%beg, isz%end + do j = isx%beg, isx%end + dqR_prim_dz_vf(i)%sf(j, n + 1, l) = & + dqL_prim_dz_vf(i)%sf(j, n, l) + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + end if + + end if + + end if + ! END: Population of Buffers in y-direction + + ! Population of Buffers in z-direction + else + + if (bc_z%beg == BC_RIEMANN_EXTRAP) then ! Riemann state extrap. BC at beginning + $:GPU_PARALLEL_LOOP(collapse=3) + do i = 1, sys_size + do l = is3%beg, is3%end + do k = is2%beg, is2%end + qL_prim_rsz_vf(-1, k, l, i) = & + qR_prim_rsz_vf(0, k, l, i) + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + + if (viscous .or. dummy) then + $:GPU_PARALLEL_LOOP(collapse=3) + do i = momxb, momxe + do k = isy%beg, isy%end + do j = isx%beg, isx%end + dqL_prim_dx_vf(i)%sf(j, k, -1) = & + dqR_prim_dx_vf(i)%sf(j, k, 0) + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + $:GPU_PARALLEL_LOOP(collapse=3) + do i = momxb, momxe + do k = isy%beg, isy%end + do j = isx%beg, isx%end + dqL_prim_dy_vf(i)%sf(j, k, -1) = & + dqR_prim_dy_vf(i)%sf(j, k, 0) + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + $:GPU_PARALLEL_LOOP(collapse=3) + do i = momxb, momxe + do k = isy%beg, isy%end + do j = isx%beg, isx%end + dqL_prim_dz_vf(i)%sf(j, k, -1) = & + dqR_prim_dz_vf(i)%sf(j, k, 0) + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + end if + + end if + + if (bc_z%end == BC_RIEMANN_EXTRAP) then ! Riemann state extrap. BC at end + + $:GPU_PARALLEL_LOOP(collapse=3) + do i = 1, sys_size + do l = is3%beg, is3%end + do k = is2%beg, is2%end + qR_prim_rsz_vf(p + 1, k, l, i) = & + qL_prim_rsz_vf(p, k, l, i) + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + + if (viscous .or. dummy) then + $:GPU_PARALLEL_LOOP(collapse=3) + do i = momxb, momxe + do k = isy%beg, isy%end + do j = isx%beg, isx%end + dqR_prim_dx_vf(i)%sf(j, k, p + 1) = & + dqL_prim_dx_vf(i)%sf(j, k, p) + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + + $:GPU_PARALLEL_LOOP(collapse=3) + do i = momxb, momxe + do k = isy%beg, isy%end + do j = isx%beg, isx%end + dqR_prim_dy_vf(i)%sf(j, k, p + 1) = & + dqL_prim_dy_vf(i)%sf(j, k, p) + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + + $:GPU_PARALLEL_LOOP(collapse=3) + do i = momxb, momxe + do k = isy%beg, isy%end + do j = isx%beg, isx%end + dqR_prim_dz_vf(i)%sf(j, k, p + 1) = & + dqL_prim_dz_vf(i)%sf(j, k, p) + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + end if + + end if + + end if + ! END: Population of Buffers in z-direction + + end subroutine s_populate_riemann_states_variables_buffers + + !> The computation of parameters, the allocation of memory, + !! the association of pointers and/or the execution of any + !! other procedures needed to configure the chosen Riemann + !! solver algorithm. + !! @param flux_src_vf Intra-cell fluxes sources + !! @param norm_dir Dir. splitting direction + subroutine s_initialize_riemann_solver( & + flux_src_vf, & + norm_dir) + + type(scalar_field), & + dimension(sys_size), & + intent(inout) :: flux_src_vf + + integer, intent(in) :: norm_dir + + integer :: i, j, k, l ! Generic loop iterators + + ! Reshaping Inputted Data in x-direction + + if (norm_dir == 1) then + + if (viscous .or. (surface_tension) .or. dummy) then + + $:GPU_PARALLEL_LOOP(collapse=4) + do i = momxb, E_idx + do l = is3%beg, is3%end + do k = is2%beg, is2%end + do j = is1%beg, is1%end + flux_src_vf(i)%sf(j, k, l) = 0._wp + end do + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + end if + + if (chem_params%diffusion) then + $:GPU_PARALLEL_LOOP(collapse=4) + do i = E_idx, chemxe + do l = is3%beg, is3%end + do k = is2%beg, is2%end + do j = is1%beg, is1%end + if (i == E_idx .or. i >= chemxb) then + flux_src_vf(i)%sf(j, k, l) = 0._wp + end if + end do + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + end if + + if (qbmm) then + $:GPU_PARALLEL_LOOP(collapse=4) + do i = 1, 4 + do l = is3%beg, is3%end + do k = is2%beg, is2%end + do j = is1%beg, is1%end + 1 + mom_sp_rsx_vf(j, k, l, i) = mom_sp(i)%sf(j, k, l) + end do + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + end if + + ! Reshaping Inputted Data in y-direction + elseif (norm_dir == 2) then + + if (viscous .or. (surface_tension) .or. dummy) then + $:GPU_PARALLEL_LOOP(collapse=4) + do i = momxb, E_idx + do l = is3%beg, is3%end + do j = is1%beg, is1%end + do k = is2%beg, is2%end + flux_src_vf(i)%sf(k, j, l) = 0._wp + end do + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + end if + + if (chem_params%diffusion) then + $:GPU_PARALLEL_LOOP(collapse=4) + do i = E_idx, chemxe + do l = is3%beg, is3%end + do j = is1%beg, is1%end + do k = is2%beg, is2%end + if (i == E_idx .or. i >= chemxb) then + flux_src_vf(i)%sf(k, j, l) = 0._wp + end if + end do + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + end if + + if (qbmm) then + $:GPU_PARALLEL_LOOP(collapse=4) + do i = 1, 4 + do l = is3%beg, is3%end + do k = is2%beg, is2%end + do j = is1%beg, is1%end + 1 + mom_sp_rsy_vf(j, k, l, i) = mom_sp(i)%sf(k, j, l) + end do + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + end if + + ! Reshaping Inputted Data in z-direction + else + + if (viscous .or. (surface_tension) .or. dummy) then + $:GPU_PARALLEL_LOOP(collapse=4) + do i = momxb, E_idx + do j = is1%beg, is1%end + do k = is2%beg, is2%end + do l = is3%beg, is3%end + flux_src_vf(i)%sf(l, k, j) = 0._wp + end do + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + end if + + if (chem_params%diffusion) then + $:GPU_PARALLEL_LOOP(collapse=4) + do i = E_idx, chemxe + do j = is1%beg, is1%end + do k = is2%beg, is2%end + do l = is3%beg, is3%end + if (i == E_idx .or. i >= chemxb) then + flux_src_vf(i)%sf(l, k, j) = 0._wp + end if + end do + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + end if + + if (qbmm) then + $:GPU_PARALLEL_LOOP(collapse=4) + do i = 1, 4 + do l = is3%beg, is3%end + do k = is2%beg, is2%end + do j = is1%beg, is1%end + 1 + mom_sp_rsz_vf(j, k, l, i) = mom_sp(i)%sf(l, k, j) + end do + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + end if + + end if + + end subroutine s_initialize_riemann_solver + + !> @brief Computes cylindrical viscous source flux contributions for momentum and energy. + !! Calculates Cartesian components of the stress tensor using averaged velocity derivatives + !! and cylindrical geometric factors, then updates `flux_src_vf`. + !! Assumes x-dir is axial (z_cyl), y-dir is radial (r_cyl), z-dir is azimuthal (theta_cyl for derivatives). + !! @param[in] velL_vf Left boundary velocity (\f$v_x, v_y, v_z\f$) (num_dims scalar_field). + !! @param[in] dvelL_dx_vf Left boundary \f$\partial v_i/\partial x\f$ (num_dims scalar_field). + !! @param[in] dvelL_dy_vf Left boundary \f$\partial v_i/\partial y\f$ (num_dims scalar_field). + !! @param[in] dvelL_dz_vf Left boundary \f$\partial v_i/\partial z\f$ (num_dims scalar_field). + !! @param[in] velR_vf Right boundary velocity (\f$v_x, v_y, v_z\f$) (num_dims scalar_field). + !! @param[in] dvelR_dx_vf Right boundary \f$\partial v_i/\partial x\f$ (num_dims scalar_field). + !! @param[in] dvelR_dy_vf Right boundary \f$\partial v_i/\partial y\f$ (num_dims scalar_field). + !! @param[in] dvelR_dz_vf Right boundary \f$\partial v_i/\partial z\f$ (num_dims scalar_field). + !! @param[inout] flux_src_vf Intercell source flux array to update (sys_size scalar_field). + !! @param[in] norm_dir Interface normal direction (1=x-face, 2=y-face, 3=z-face). + !! @param[in] ix Global X-direction loop bounds (int_bounds_info). + !! @param[in] iy Global Y-direction loop bounds (int_bounds_info). + !! @param[in] iz Global Z-direction loop bounds (int_bounds_info). + subroutine s_compute_cylindrical_viscous_source_flux(velL_vf, & + dvelL_dx_vf, dvelL_dy_vf, dvelL_dz_vf, & + velR_vf, & + dvelR_dx_vf, dvelR_dy_vf, dvelR_dz_vf, & + flux_src_vf, norm_dir, ix, iy, iz) + + type(scalar_field), dimension(num_dims), intent(in) :: velL_vf, velR_vf + type(scalar_field), dimension(num_dims), intent(in) :: dvelL_dx_vf, dvelR_dx_vf + type(scalar_field), dimension(num_dims), intent(in) :: dvelL_dy_vf, dvelR_dy_vf + type(scalar_field), dimension(num_dims), intent(in) :: dvelL_dz_vf, dvelR_dz_vf + type(scalar_field), dimension(sys_size), intent(inout) :: flux_src_vf + integer, intent(in) :: norm_dir + type(int_bounds_info), intent(in) :: ix, iy, iz + + ! Local variables + #:if not MFC_CASE_OPTIMIZATION and USING_AMD + real(wp), dimension(3) :: avg_v_int !!< Averaged interface velocity (\f$v_x, v_y, v_z\f$) (grid directions). + real(wp), dimension(3) :: avg_dvdx_int !!< Averaged interface \f$\partial v_i/\partial x\f$ (grid dir 1). + real(wp), dimension(3) :: avg_dvdy_int !!< Averaged interface \f$\partial v_i/\partial y\f$ (grid dir 2). + real(wp), dimension(3) :: avg_dvdz_int !!< Averaged interface \f$\partial v_i/\partial z\f$ (grid dir 3). + real(wp), dimension(3) :: vel_src_int !!< Interface velocity (\f$v_1,v_2,v_3\f$) (grid directions) for viscous work. + real(wp), dimension(3) :: stress_vector_shear !!< Shear stress vector (\f$\sigma_{N1}, \sigma_{N2}, \sigma_{N3}\f$) on N-face (grid directions). + #:else + real(wp), dimension(num_dims) :: avg_v_int !!< Averaged interface velocity (\f$v_x, v_y, v_z\f$) (grid directions). + real(wp), dimension(num_dims) :: avg_dvdx_int !!< Averaged interface \f$\partial v_i/\partial x\f$ (grid dir 1). + real(wp), dimension(num_dims) :: avg_dvdy_int !!< Averaged interface \f$\partial v_i/\partial y\f$ (grid dir 2). + real(wp), dimension(num_dims) :: avg_dvdz_int !!< Averaged interface \f$\partial v_i/\partial z\f$ (grid dir 3). + real(wp), dimension(num_dims) :: vel_src_int !!< Interface velocity (\f$v_1,v_2,v_3\f$) (grid directions) for viscous work. + real(wp), dimension(num_dims) :: stress_vector_shear !!< Shear stress vector (\f$\sigma_{N1}, \sigma_{N2}, \sigma_{N3}\f$) on N-face (grid directions). + #:endif + real(wp) :: stress_normal_bulk !!< Normal bulk stress component \f$\sigma_{NN}\f$ on N-face. + + real(wp) :: Re_s, Re_b !!< Effective interface shear and bulk Reynolds numbers. + real(wp) :: r_eff !!< Effective radius at interface for cylindrical terms. + real(wp) :: div_v_term_const !!< Common term \f$-(2/3)(\nabla \cdot \mathbf{v}) / \text{Re}_s\f$ for shear stress diagonal. + real(wp) :: divergence_cyl !!< Full divergence \f$\nabla \cdot \mathbf{v}\f$ in cylindrical coordinates. + + integer :: j, k, l !!< Loop iterators for \f$x, y, z\f$ grid directions. + integer :: i_vel !!< Loop iterator for velocity components. + integer :: idx_rp(3) !!< Indices \f$(j,k,l)\f$ of 'right' point for averaging. + + $:GPU_PARALLEL_LOOP(collapse=3, private='[idx_rp, avg_v_int, avg_dvdx_int, avg_dvdy_int, avg_dvdz_int, Re_s, Re_b, vel_src_int, r_eff, divergence_cyl, stress_vector_shear, stress_normal_bulk, div_v_term_const]') + do l = iz%beg, iz%end + do k = iy%beg, iy%end + do j = ix%beg, ix%end + + ! Determine indices for the 'right' state for averaging across the interface + idx_rp = [j, k, l] + idx_rp(norm_dir) = idx_rp(norm_dir) + 1 + + ! Average velocities and their derivatives at the interface + ! For cylindrical: x-dir ~ axial (z_cyl), y-dir ~ radial (r_cyl), z-dir ~ azimuthal (theta_cyl) + $:GPU_LOOP(parallelism='[seq]') + do i_vel = 1, num_dims + avg_v_int(i_vel) = 0.5_wp*(velL_vf(i_vel)%sf(j, k, l) + velR_vf(i_vel)%sf(idx_rp(1), idx_rp(2), idx_rp(3))) + + avg_dvdx_int(i_vel) = 0.5_wp*(dvelL_dx_vf(i_vel)%sf(j, k, l) + & + dvelR_dx_vf(i_vel)%sf(idx_rp(1), idx_rp(2), idx_rp(3))) + if (num_dims > 1) then + avg_dvdy_int(i_vel) = 0.5_wp*(dvelL_dy_vf(i_vel)%sf(j, k, l) + & + dvelR_dy_vf(i_vel)%sf(idx_rp(1), idx_rp(2), idx_rp(3))) + else + avg_dvdy_int(i_vel) = 0.0_wp + end if + if (num_dims > 2) then + avg_dvdz_int(i_vel) = 0.5_wp*(dvelL_dz_vf(i_vel)%sf(j, k, l) + & + dvelR_dz_vf(i_vel)%sf(idx_rp(1), idx_rp(2), idx_rp(3))) + else + avg_dvdz_int(i_vel) = 0.0_wp + end if + end do + + ! Get Re numbers and interface velocity for viscous work + select case (norm_dir) + case (1) ! x-face (axial face in z_cyl direction) + Re_s = Re_avg_rsx_vf(j, k, l, 1) + Re_b = Re_avg_rsx_vf(j, k, l, 2) + vel_src_int = vel_src_rsx_vf(j, k, l, 1:num_dims) + r_eff = y_cc(k) + case (2) ! y-face (radial face in r_cyl direction) + Re_s = Re_avg_rsy_vf(k, j, l, 1) + Re_b = Re_avg_rsy_vf(k, j, l, 2) + vel_src_int = vel_src_rsy_vf(k, j, l, 1:num_dims) + r_eff = y_cb(k) + case (3) ! z-face (azimuthal face in theta_cyl direction) + Re_s = Re_avg_rsz_vf(l, k, j, 1) + Re_b = Re_avg_rsz_vf(l, k, j, 2) + vel_src_int = vel_src_rsz_vf(l, k, j, 1:num_dims) + r_eff = y_cc(k) + end select + + ! Divergence in cylindrical coordinates (vx=vz_cyl, vy=vr_cyl, vz=vtheta_cyl) + #:if not MFC_CASE_OPTIMIZATION or num_dims > 1 + divergence_cyl = avg_dvdx_int(1) + avg_dvdy_int(2) + avg_v_int(2)/r_eff + if (num_dims > 2) then + #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 + divergence_cyl = divergence_cyl + avg_dvdz_int(3)/r_eff + #:endif + end if + #:endif + + stress_vector_shear = 0.0_wp + stress_normal_bulk = 0.0_wp + + if (shear_stress) then + div_v_term_const = -(2.0_wp/3.0_wp)*divergence_cyl/Re_s + + select case (norm_dir) + case (1) ! X-face (axial normal, z_cyl) + stress_vector_shear(1) = (2.0_wp*avg_dvdx_int(1))/Re_s + div_v_term_const + if (num_dims > 1) then + #:if not MFC_CASE_OPTIMIZATION or num_dims > 1 + stress_vector_shear(2) = (avg_dvdy_int(1) + avg_dvdx_int(2))/Re_s + #:endif + end if + if (num_dims > 2) then + #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 + stress_vector_shear(3) = (avg_dvdz_int(1)/r_eff + avg_dvdx_int(3))/Re_s + #:endif + end if + case (2) ! Y-face (radial normal, r_cyl) + if (num_dims > 1) then + #:if not MFC_CASE_OPTIMIZATION or num_dims > 1 + stress_vector_shear(1) = (avg_dvdy_int(1) + avg_dvdx_int(2))/Re_s + stress_vector_shear(2) = (2.0_wp*avg_dvdy_int(2))/Re_s + div_v_term_const + if (num_dims > 2) then + #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 + stress_vector_shear(3) = (avg_dvdz_int(2)/r_eff - avg_v_int(3)/r_eff + avg_dvdy_int(3))/Re_s + #:endif + end if + #:endif + else + stress_vector_shear(1) = (2.0_wp*avg_dvdx_int(1))/Re_s + div_v_term_const + end if + case (3) ! Z-face (azimuthal normal, theta_cyl) + if (num_dims > 2) then + #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 + stress_vector_shear(1) = (avg_dvdz_int(1)/r_eff + avg_dvdx_int(3))/Re_s + stress_vector_shear(2) = (avg_dvdz_int(2)/r_eff - avg_v_int(3)/r_eff + avg_dvdy_int(3))/Re_s + stress_vector_shear(3) = (2.0_wp*(avg_dvdz_int(3)/r_eff + avg_v_int(2)/r_eff))/Re_s + div_v_term_const + #:endif + end if + end select + + $:GPU_LOOP(parallelism='[seq]') + do i_vel = 1, num_dims + flux_src_vf(momxb + i_vel - 1)%sf(j, k, l) = flux_src_vf(momxb + i_vel - 1)%sf(j, k, l) - stress_vector_shear(i_vel) + flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - vel_src_int(i_vel)*stress_vector_shear(i_vel) + end do + end if + + if (bulk_stress) then + stress_normal_bulk = divergence_cyl/Re_b + + flux_src_vf(momxb + norm_dir - 1)%sf(j, k, l) = flux_src_vf(momxb + norm_dir - 1)%sf(j, k, l) - stress_normal_bulk + flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - vel_src_int(norm_dir)*stress_normal_bulk + end if + + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + + end subroutine s_compute_cylindrical_viscous_source_flux + + !> @brief Computes Cartesian viscous source flux contributions for momentum and energy. + !! Calculates averaged velocity gradients, gets Re and interface velocities, + !! calls helpers for shear/bulk stress, then updates `flux_src_vf`. + !! @param[in] dvelL_dx_vf Left boundary d(vel)/dx (num_dims scalar_field). + !! @param[in] dvelL_dy_vf Left boundary d(vel)/dy (num_dims scalar_field). + !! @param[in] dvelL_dz_vf Left boundary d(vel)/dz (num_dims scalar_field). + !! @param[in] dvelR_dx_vf Right boundary d(vel)/dx (num_dims scalar_field). + !! @param[in] dvelR_dy_vf Right boundary d(vel)/dy (num_dims scalar_field). + !! @param[in] dvelR_dz_vf Right boundary d(vel)/dz (num_dims scalar_field). + !! @param[inout] flux_src_vf Intercell source flux array to update (sys_size scalar_field). + !! @param[in] norm_dir Interface normal direction (1=x, 2=y, 3=z). + subroutine s_compute_cartesian_viscous_source_flux(dvelL_dx_vf, & + dvelL_dy_vf, & + dvelL_dz_vf, & + dvelR_dx_vf, & + dvelR_dy_vf, & + dvelR_dz_vf, & + flux_src_vf, & + norm_dir) + + ! Arguments + type(scalar_field), dimension(num_dims), intent(in) :: dvelL_dx_vf, dvelR_dx_vf + type(scalar_field), dimension(num_dims), intent(in) :: dvelL_dy_vf, dvelR_dy_vf + type(scalar_field), dimension(num_dims), intent(in) :: dvelL_dz_vf, dvelR_dz_vf + type(scalar_field), dimension(sys_size), intent(inout) :: flux_src_vf + integer, intent(in) :: norm_dir + + ! Local variables + #:if not MFC_CASE_OPTIMIZATION and USING_AMD + real(wp), dimension(3, 3) :: vel_grad_avg !< Averaged velocity gradient tensor `d(vel_i)/d(coord_j)`. + real(wp), dimension(3, 3) :: current_tau_shear !< Current shear stress tensor. + real(wp), dimension(3, 3) :: current_tau_bulk !< Current bulk stress tensor. + real(wp), dimension(3) :: vel_src_at_interface !< Interface velocities (u,v,w) for viscous work. + #:else + real(wp), dimension(num_dims, num_dims) :: vel_grad_avg !< Averaged velocity gradient tensor `d(vel_i)/d(coord_j)`. + real(wp), dimension(num_dims, num_dims) :: current_tau_shear !< Current shear stress tensor. + real(wp), dimension(num_dims, num_dims) :: current_tau_bulk !< Current bulk stress tensor. + real(wp), dimension(num_dims) :: vel_src_at_interface !< Interface velocities (u,v,w) for viscous work. + #:endif + integer, dimension(3) :: idx_right_phys !< Physical (j,k,l) indices for right state. + + real(wp) :: Re_shear !< Interface shear Reynolds number. + real(wp) :: Re_bulk !< Interface bulk Reynolds number. + + integer :: j_loop !< Physical x-index loop iterator. + integer :: k_loop !< Physical y-index loop iterator. + integer :: l_loop !< Physical z-index loop iterator. + integer :: i_dim !< Generic dimension/component iterator. + integer :: vel_comp_idx !< Velocity component iterator (1=u, 2=v, 3=w). + + real(wp) :: divergence_v !< Velocity divergence at interface. + + $:GPU_PARALLEL_LOOP(collapse=3, private='[idx_right_phys, vel_grad_avg, current_tau_shear, current_tau_bulk, vel_src_at_interface, Re_shear, Re_bulk, divergence_v, i_dim, vel_comp_idx]') + do l_loop = isz%beg, isz%end + do k_loop = isy%beg, isy%end + do j_loop = isx%beg, isx%end + + idx_right_phys(1) = j_loop + idx_right_phys(2) = k_loop + idx_right_phys(3) = l_loop + idx_right_phys(norm_dir) = idx_right_phys(norm_dir) + 1 + + vel_grad_avg = 0.0_wp + do vel_comp_idx = 1, num_dims + vel_grad_avg(vel_comp_idx, 1) = 0.5_wp*(dvelL_dx_vf(vel_comp_idx)%sf(j_loop, k_loop, l_loop) + & + dvelR_dx_vf(vel_comp_idx)%sf(idx_right_phys(1), idx_right_phys(2), idx_right_phys(3))) + if (num_dims > 1) then + #:if not MFC_CASE_OPTIMIZATION or num_dims > 1 + vel_grad_avg(vel_comp_idx, 2) = 0.5_wp*(dvelL_dy_vf(vel_comp_idx)%sf(j_loop, k_loop, l_loop) + & + dvelR_dy_vf(vel_comp_idx)%sf(idx_right_phys(1), idx_right_phys(2), idx_right_phys(3))) + #:endif + end if + if (num_dims > 2) then + #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 + vel_grad_avg(vel_comp_idx, 3) = 0.5_wp*(dvelL_dz_vf(vel_comp_idx)%sf(j_loop, k_loop, l_loop) + & + dvelR_dz_vf(vel_comp_idx)%sf(idx_right_phys(1), idx_right_phys(2), idx_right_phys(3))) + #:endif + end if + end do + + divergence_v = 0.0_wp + do i_dim = 1, num_dims + divergence_v = divergence_v + vel_grad_avg(i_dim, i_dim) + end do + + vel_src_at_interface = 0.0_wp + if (norm_dir == 1) then + Re_shear = Re_avg_rsx_vf(j_loop, k_loop, l_loop, 1) + Re_bulk = Re_avg_rsx_vf(j_loop, k_loop, l_loop, 2) + do i_dim = 1, num_dims + vel_src_at_interface(i_dim) = vel_src_rsx_vf(j_loop, k_loop, l_loop, i_dim) + end do + else if (norm_dir == 2) then + Re_shear = Re_avg_rsy_vf(k_loop, j_loop, l_loop, 1) + Re_bulk = Re_avg_rsy_vf(k_loop, j_loop, l_loop, 2) + do i_dim = 1, num_dims + vel_src_at_interface(i_dim) = vel_src_rsy_vf(k_loop, j_loop, l_loop, i_dim) + end do + else + Re_shear = Re_avg_rsz_vf(l_loop, k_loop, j_loop, 1) + Re_bulk = Re_avg_rsz_vf(l_loop, k_loop, j_loop, 2) + do i_dim = 1, num_dims + vel_src_at_interface(i_dim) = vel_src_rsz_vf(l_loop, k_loop, j_loop, i_dim) + end do + end if + + if (shear_stress) then + ! current_tau_shear = 0.0_wp + call s_calculate_shear_stress_tensor(vel_grad_avg, Re_shear, divergence_v, current_tau_shear) + + do i_dim = 1, num_dims + flux_src_vf(momxb + i_dim - 1)%sf(j_loop, k_loop, l_loop) = & + flux_src_vf(momxb + i_dim - 1)%sf(j_loop, k_loop, l_loop) - current_tau_shear(norm_dir, i_dim) + + flux_src_vf(E_idx)%sf(j_loop, k_loop, l_loop) = & + flux_src_vf(E_idx)%sf(j_loop, k_loop, l_loop) - & + vel_src_at_interface(i_dim)*current_tau_shear(norm_dir, i_dim) + end do + end if + + if (bulk_stress) then + ! current_tau_bulk = 0.0_wp + call s_calculate_bulk_stress_tensor(Re_bulk, divergence_v, current_tau_bulk) + + do i_dim = 1, num_dims + flux_src_vf(momxb + i_dim - 1)%sf(j_loop, k_loop, l_loop) = & + flux_src_vf(momxb + i_dim - 1)%sf(j_loop, k_loop, l_loop) - current_tau_bulk(norm_dir, i_dim) + + flux_src_vf(E_idx)%sf(j_loop, k_loop, l_loop) = & + flux_src_vf(E_idx)%sf(j_loop, k_loop, l_loop) - & + vel_src_at_interface(i_dim)*current_tau_bulk(norm_dir, i_dim) + end do + end if + + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + + end subroutine s_compute_cartesian_viscous_source_flux + + !> @brief Calculates shear stress tensor components. + !! tau_ij_shear = ( (dui/dxj + duj/dxi) - (2/3)*(div_v)*delta_ij ) / Re_shear + !! @param[in] vel_grad_avg Averaged velocity gradient tensor (d(vel_i)/d(coord_j)). + !! @param[in] Re_shear Shear Reynolds number. + !! @param[in] divergence_v Velocity divergence (du/dx + dv/dy + dw/dz). + !! @param[out] tau_shear_out Calculated shear stress tensor (stress on i-face, j-direction). + subroutine s_calculate_shear_stress_tensor(vel_grad_avg, Re_shear, divergence_v, tau_shear_out) + $:GPU_ROUTINE(parallelism='[seq]') + + ! Arguments + #:if not MFC_CASE_OPTIMIZATION and USING_AMD + real(wp), dimension(3, 3), intent(in) :: vel_grad_avg + real(wp), dimension(3, 3), intent(out) :: tau_shear_out + #:else + real(wp), dimension(num_dims, num_dims), intent(in) :: vel_grad_avg + real(wp), dimension(num_dims, num_dims), intent(out) :: tau_shear_out + #:endif + real(wp), intent(in) :: Re_shear + real(wp), intent(in) :: divergence_v + + ! Local variables + integer :: i_dim !< Loop iterator for face normal. + integer :: j_dim !< Loop iterator for force component direction. + + tau_shear_out = 0.0_wp + + do i_dim = 1, num_dims + do j_dim = 1, num_dims + tau_shear_out(i_dim, j_dim) = (vel_grad_avg(j_dim, i_dim) + vel_grad_avg(i_dim, j_dim))/Re_shear + if (i_dim == j_dim) then + tau_shear_out(i_dim, j_dim) = tau_shear_out(i_dim, j_dim) - & + (2.0_wp/3.0_wp)*divergence_v/Re_shear + end if + end do + end do + + end subroutine s_calculate_shear_stress_tensor + + !> @brief Calculates bulk stress tensor components (diagonal only). + !! tau_ii_bulk = (div_v) / Re_bulk. Off-diagonals are zero. + !! @param[in] Re_bulk Bulk Reynolds number. + !! @param[in] divergence_v Velocity divergence (du/dx + dv/dy + dw/dz). + !! @param[out] tau_bulk_out Calculated bulk stress tensor (stress on i-face, i-direction). + subroutine s_calculate_bulk_stress_tensor(Re_bulk, divergence_v, tau_bulk_out) + $:GPU_ROUTINE(parallelism='[seq]') + + ! Arguments + real(wp), intent(in) :: Re_bulk + real(wp), intent(in) :: divergence_v + #:if not MFC_CASE_OPTIMIZATION and USING_AMD + real(wp), dimension(3, 3), intent(out) :: tau_bulk_out + #:else + real(wp), dimension(num_dims, num_dims), intent(out) :: tau_bulk_out + #:endif + + ! Local variables + integer :: i_dim !< Loop iterator for diagonal components. + + tau_bulk_out = 0.0_wp + + do i_dim = 1, num_dims + tau_bulk_out(i_dim, i_dim) = divergence_v/Re_bulk + end do + + end subroutine s_calculate_bulk_stress_tensor + + !> Deallocation and/or disassociation procedures that are + !! needed to finalize the selected Riemann problem solver + !! @param flux_vf Intercell fluxes + !! @param flux_src_vf Intercell source fluxes + !! @param flux_gsrc_vf Intercell geometric source fluxes + !! @param norm_dir Dimensional splitting coordinate direction + subroutine s_finalize_riemann_solver(flux_vf, flux_src_vf, & + flux_gsrc_vf, & + norm_dir) + + type(scalar_field), & + dimension(sys_size), & + intent(inout) :: flux_vf, flux_src_vf, flux_gsrc_vf + + integer, intent(in) :: norm_dir + + integer :: i, j, k, l !< Generic loop iterators + + ! Reshaping Outputted Data in y-direction + if (norm_dir == 2) then + $:GPU_PARALLEL_LOOP(collapse=4) + do i = 1, sys_size + do l = is3%beg, is3%end + do j = is1%beg, is1%end + do k = is2%beg, is2%end + flux_vf(i)%sf(k, j, l) = & + flux_rsy_vf(j, k, l, i) + end do + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + + if (cyl_coord) then + $:GPU_PARALLEL_LOOP(collapse=4) + do i = 1, sys_size + do l = is3%beg, is3%end + do j = is1%beg, is1%end + do k = is2%beg, is2%end + flux_gsrc_vf(i)%sf(k, j, l) = & + flux_gsrc_rsy_vf(j, k, l, i) + end do + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + end if + + $:GPU_PARALLEL_LOOP(collapse=3) + do l = is3%beg, is3%end + do j = is1%beg, is1%end + do k = is2%beg, is2%end + flux_src_vf(advxb)%sf(k, j, l) = & + flux_src_rsy_vf(j, k, l, advxb) + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + + if (riemann_solver == 1 .or. riemann_solver == 4) then + $:GPU_PARALLEL_LOOP(collapse=4) + do i = advxb + 1, advxe + do l = is3%beg, is3%end + do j = is1%beg, is1%end + do k = is2%beg, is2%end + flux_src_vf(i)%sf(k, j, l) = & + flux_src_rsy_vf(j, k, l, i) + end do + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + + end if + ! Reshaping Outputted Data in z-direction + elseif (norm_dir == 3) then + $:GPU_PARALLEL_LOOP(collapse=4) + do i = 1, sys_size + do j = is1%beg, is1%end + do k = is2%beg, is2%end + do l = is3%beg, is3%end + + flux_vf(i)%sf(l, k, j) = & + flux_rsz_vf(j, k, l, i) + end do + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + if (grid_geometry == 3) then + $:GPU_PARALLEL_LOOP(collapse=4) + do i = 1, sys_size + do j = is1%beg, is1%end + do k = is2%beg, is2%end + do l = is3%beg, is3%end + + flux_gsrc_vf(i)%sf(l, k, j) = & + flux_gsrc_rsz_vf(j, k, l, i) + end do + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + end if + + $:GPU_PARALLEL_LOOP(collapse=3) + do j = is1%beg, is1%end + do k = is2%beg, is2%end + do l = is3%beg, is3%end + flux_src_vf(advxb)%sf(l, k, j) = & + flux_src_rsz_vf(j, k, l, advxb) + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + + if (riemann_solver == 1 .or. riemann_solver == 4) then + $:GPU_PARALLEL_LOOP(collapse=4) + do i = advxb + 1, advxe + do j = is1%beg, is1%end + do k = is2%beg, is2%end + do l = is3%beg, is3%end + flux_src_vf(i)%sf(l, k, j) = & + flux_src_rsz_vf(j, k, l, i) + end do + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + + end if + elseif (norm_dir == 1) then + $:GPU_PARALLEL_LOOP(collapse=4) + do i = 1, sys_size + do l = is3%beg, is3%end + do k = is2%beg, is2%end + do j = is1%beg, is1%end + flux_vf(i)%sf(j, k, l) = & + flux_rsx_vf(j, k, l, i) + end do + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + + $:GPU_PARALLEL_LOOP(collapse=3) + do l = is3%beg, is3%end + do k = is2%beg, is2%end + do j = is1%beg, is1%end + flux_src_vf(advxb)%sf(j, k, l) = & + flux_src_rsx_vf(j, k, l, advxb) + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + + if (riemann_solver == 1 .or. riemann_solver == 4) then + $:GPU_PARALLEL_LOOP(collapse=4) + do i = advxb + 1, advxe + do l = is3%beg, is3%end + do k = is2%beg, is2%end + do j = is1%beg, is1%end + flux_src_vf(i)%sf(j, k, l) = & + flux_src_rsx_vf(j, k, l, i) + end do + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + end if + end if + + end subroutine s_finalize_riemann_solver + + !> Module deallocation and/or disassociation procedures + impure subroutine s_finalize_riemann_solvers_module + + if (viscous) then + @:DEALLOCATE(Re_avg_rsx_vf) + end if + @:DEALLOCATE(vel_src_rsx_vf) + @:DEALLOCATE(flux_rsx_vf) + @:DEALLOCATE(flux_src_rsx_vf) + @:DEALLOCATE(flux_gsrc_rsx_vf) + if (qbmm) then + @:DEALLOCATE(mom_sp_rsx_vf) + end if + + if (n == 0) return + + if (viscous) then + @:DEALLOCATE(Re_avg_rsy_vf) + end if + @:DEALLOCATE(vel_src_rsy_vf) + @:DEALLOCATE(flux_rsy_vf) + @:DEALLOCATE(flux_src_rsy_vf) + @:DEALLOCATE(flux_gsrc_rsy_vf) + if (qbmm) then + @:DEALLOCATE(mom_sp_rsy_vf) + end if + + if (p == 0) return + + if (viscous) then + @:DEALLOCATE(Re_avg_rsz_vf) + end if + @:DEALLOCATE(vel_src_rsz_vf) + @:DEALLOCATE(flux_rsz_vf) + @:DEALLOCATE(flux_src_rsz_vf) + @:DEALLOCATE(flux_gsrc_rsz_vf) + if (qbmm) then + @:DEALLOCATE(mom_sp_rsz_vf) + end if + + end subroutine s_finalize_riemann_solvers_module + +end module m_riemann_solvers diff --git a/src/simulation/m_time_steppers.fpp b/src/simulation/m_time_steppers.fpp index 2835055667..a38c72e845 100644 --- a/src/simulation/m_time_steppers.fpp +++ b/src/simulation/m_time_steppers.fpp @@ -1,1061 +1,1075 @@ -!> -!! @file -!! @brief Contains module m_time_steppers - -#:include 'macros.fpp' -#:include 'case.fpp' - -!> @brief Total-variation-diminishing (TVD) Runge--Kutta time integrators (1st-, 2nd-, and 3rd-order SSP) -module m_time_steppers - - use m_derived_types !< Definitions of the derived types - - use m_global_parameters !< Definitions of the global parameters - - use m_rhs !< Right-hane-side (RHS) evaluation procedures - - use m_pressure_relaxation !< Pressure relaxation procedures - - use m_data_output !< Run-time info & solution data output procedures - - use m_bubbles_EE !< Ensemble-averaged bubble dynamics routines - - use m_bubbles_EL !< Lagrange bubble dynamics routines - - use m_ibm - - use m_hyperelastic - - use m_mpi_proxy !< Message passing interface (MPI) module proxy - - use m_boundary_common - - use m_helper - - use m_sim_helpers - - use m_fftw - - use m_nvtx - - use m_thermochem, only: num_species - - use m_body_forces - - use m_derived_variables - - implicit none - - type(vector_field), allocatable, dimension(:) :: q_cons_ts !< - !! Cell-average conservative variables at each time-stage (TS) - - type(scalar_field), allocatable, dimension(:) :: q_prim_vf !< - !! Cell-average primitive variables at the current time-stage - - type(scalar_field), allocatable, dimension(:) :: rhs_vf !< - !! Cell-average RHS variables at the current time-stage - - type(integer_field), allocatable, dimension(:, :) :: bc_type !< - !! Boundary condition identifiers - - type(vector_field), allocatable, dimension(:) :: q_prim_ts1, q_prim_ts2 !< - !! Cell-average primitive variables at consecutive TIMESTEPS - - real(wp), allocatable, dimension(:, :, :, :, :) :: rhs_pb - - type(scalar_field) :: q_T_sf !< - !! Cell-average temperature variables at the current time-stage - - real(wp), allocatable, dimension(:, :, :, :, :) :: rhs_mv - - real(wp), allocatable, dimension(:, :, :) :: max_dt - - integer, private :: num_ts !< - !! Number of time stages in the time-stepping scheme - - integer :: stor !< storage index - real(wp), allocatable, dimension(:, :) :: rk_coef - integer, private :: num_probe_ts - - $:GPU_DECLARE(create='[q_cons_ts,q_prim_vf,q_T_sf,rhs_vf,q_prim_ts1,q_prim_ts2,rhs_mv,rhs_pb,max_dt,rk_coef,stor,bc_type]') - -!> @cond -#if defined(__NVCOMPILER_GPU_UNIFIED_MEM) - real(stp), allocatable, dimension(:, :, :, :), pinned, target :: q_cons_ts_pool_host -#elif defined(FRONTIER_UNIFIED) - real(stp), pointer, contiguous, dimension(:, :, :, :) :: q_cons_ts_pool_host, q_cons_ts_pool_device - integer(kind=8) :: pool_dims(4), pool_starts(4) - integer(kind=8) :: pool_size - type(c_ptr) :: cptr_host, cptr_device -#endif -!> @endcond - -contains - - !> The computation of parameters, the allocation of memory, - !! the association of pointers and/or the execution of any - !! other procedures that are necessary to setup the module. - impure subroutine s_initialize_time_steppers_module -#ifdef FRONTIER_UNIFIED - use hipfort - use hipfort_hipmalloc - use hipfort_check -#if defined(MFC_OpenACC) - use openacc -#endif -#endif - integer :: i, j !< Generic loop iterators - - ! Setting number of time-stages for selected time-stepping scheme - if (time_stepper == 1) then - num_ts = 1 - elseif (any(time_stepper == (/2, 3/))) then - num_ts = 2 - end if - - if (probe_wrt) then - num_probe_ts = 2 - end if - - ! Allocating the cell-average conservative variables - @:ALLOCATE(q_cons_ts(1:num_ts)) - @:PREFER_GPU(q_cons_ts) - - do i = 1, num_ts - @:ALLOCATE(q_cons_ts(i)%vf(1:sys_size)) - @:PREFER_GPU(q_cons_ts(i)%vf) - end do - -!> @cond -#if defined(__NVCOMPILER_GPU_UNIFIED_MEM) - if (num_ts == 2 .and. nv_uvm_out_of_core) then - ! host allocation for q_cons_ts(2)%vf(j)%sf for all j - allocate (q_cons_ts_pool_host(idwbuff(1)%beg:idwbuff(1)%end, & - idwbuff(2)%beg:idwbuff(2)%end, & - idwbuff(3)%beg:idwbuff(3)%end, & - 1:sys_size)) - end if - - do j = 1, sys_size - ! q_cons_ts(1) lives on the device - @:ALLOCATE(q_cons_ts(1)%vf(j)%sf(idwbuff(1)%beg:idwbuff(1)%end, & - idwbuff(2)%beg:idwbuff(2)%end, & - idwbuff(3)%beg:idwbuff(3)%end)) - @:PREFER_GPU(q_cons_ts(1)%vf(j)%sf) - if (num_ts == 2) then - if (nv_uvm_out_of_core) then - ! q_cons_ts(2) lives on the host - q_cons_ts(2)%vf(j)%sf(idwbuff(1)%beg:idwbuff(1)%end, & - idwbuff(2)%beg:idwbuff(2)%end, & - idwbuff(3)%beg:idwbuff(3)%end) => q_cons_ts_pool_host(:, :, :, j) - else - @:ALLOCATE(q_cons_ts(2)%vf(j)%sf(idwbuff(1)%beg:idwbuff(1)%end, & - idwbuff(2)%beg:idwbuff(2)%end, & - idwbuff(3)%beg:idwbuff(3)%end)) - @:PREFER_GPU(q_cons_ts(2)%vf(j)%sf) - end if - end if - end do - - do i = 1, num_ts - @:ACC_SETUP_VFs(q_cons_ts(i)) - end do -#elif defined(FRONTIER_UNIFIED) - ! Allocate to memory regions using hip calls - ! that we will attach pointers to - do i = 1, 3 - pool_dims(i) = idwbuff(i)%end - idwbuff(i)%beg + 1 - pool_starts(i) = idwbuff(i)%beg - end do - pool_dims(4) = sys_size - pool_starts(4) = 1 -#ifdef MFC_MIXED_PRECISION - pool_size = 1_8*(idwbuff(1)%end - idwbuff(1)%beg + 1)*(idwbuff(2)%end - idwbuff(2)%beg + 1)*(idwbuff(3)%end - idwbuff(3)%beg + 1)*sys_size - call hipCheck(hipMalloc_(cptr_device, pool_size*2_8)) - call c_f_pointer(cptr_device, q_cons_ts_pool_device, shape=pool_dims) - q_cons_ts_pool_device(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:) => q_cons_ts_pool_device - - call hipCheck(hipMallocManaged_(cptr_host, pool_size*2_8, hipMemAttachGlobal)) - call c_f_pointer(cptr_host, q_cons_ts_pool_host, shape=pool_dims) - q_cons_ts_pool_host(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:) => q_cons_ts_pool_host -#else - ! Doing hipMalloc then mapping should be most performant - call hipCheck(hipMalloc(q_cons_ts_pool_device, dims8=pool_dims, lbounds8=pool_starts)) - ! Without this map CCE will still create a device copy, because it's silly like that -#if defined(MFC_OpenACC) - call acc_map_data(q_cons_ts_pool_device, c_loc(q_cons_ts_pool_device), c_sizeof(q_cons_ts_pool_device)) -#endif - ! CCE see it can access this and will leave it on the host. It will stay on the host so long as HSA_XNACK=1 - ! NOTE: WE CANNOT DO ATOMICS INTO THIS MEMORY. We have to change a property to use atomics here - ! Otherwise leaving this as fine-grained will actually help performance since it can't be cached in GPU L2 - if (num_ts == 2) then - call hipCheck(hipMallocManaged(q_cons_ts_pool_host, dims8=pool_dims, lbounds8=pool_starts, flags=hipMemAttachGlobal)) -#if defined(MFC_OpenMP) - call hipCheck(hipMemAdvise(c_loc(q_cons_ts_pool_host), c_sizeof(q_cons_ts_pool_host), hipMemAdviseSetPreferredLocation, -1)) -#endif - end if -#endif - - do j = 1, sys_size - ! q_cons_ts(1) lives on the device - q_cons_ts(1)%vf(j)%sf(idwbuff(1)%beg:idwbuff(1)%end, & - idwbuff(2)%beg:idwbuff(2)%end, & - idwbuff(3)%beg:idwbuff(3)%end) => q_cons_ts_pool_device(:, :, :, j) - if (num_ts == 2) then - ! q_cons_ts(2) lives on the host - q_cons_ts(2)%vf(j)%sf(idwbuff(1)%beg:idwbuff(1)%end, & - idwbuff(2)%beg:idwbuff(2)%end, & - idwbuff(3)%beg:idwbuff(3)%end) => q_cons_ts_pool_host(:, :, :, j) - end if - end do - - do i = 1, num_ts - @:ACC_SETUP_VFs(q_cons_ts(i)) - do j = 1, sys_size - $:GPU_UPDATE(device='[q_cons_ts(i)%vf(j)]') - end do - end do -#else -!> @endcond - do i = 1, num_ts - do j = 1, sys_size - @:ALLOCATE(q_cons_ts(i)%vf(j)%sf(idwbuff(1)%beg:idwbuff(1)%end, & - idwbuff(2)%beg:idwbuff(2)%end, & - idwbuff(3)%beg:idwbuff(3)%end)) - end do - @:ACC_SETUP_VFs(q_cons_ts(i)) - end do -!> @cond -#endif -!> @endcond - - ! Allocating the cell-average primitive ts variables - if (probe_wrt) then - @:ALLOCATE(q_prim_ts1(1:num_probe_ts)) - - do i = 1, num_probe_ts - @:ALLOCATE(q_prim_ts1(i)%vf(1:sys_size)) - end do - - do i = 1, num_probe_ts - do j = 1, sys_size - @:ALLOCATE(q_prim_ts1(i)%vf(j)%sf(idwbuff(1)%beg:idwbuff(1)%end, & - idwbuff(2)%beg:idwbuff(2)%end, & - idwbuff(3)%beg:idwbuff(3)%end)) - end do - @:ACC_SETUP_VFs(q_prim_ts1(i)) - end do - - @:ALLOCATE(q_prim_ts2(1:num_probe_ts)) - - do i = 1, num_probe_ts - @:ALLOCATE(q_prim_ts2(i)%vf(1:sys_size)) - end do - - do i = 1, num_probe_ts - do j = 1, sys_size - @:ALLOCATE(q_prim_ts2(i)%vf(j)%sf(idwbuff(1)%beg:idwbuff(1)%end, & - idwbuff(2)%beg:idwbuff(2)%end, & - idwbuff(3)%beg:idwbuff(3)%end)) - end do - @:ACC_SETUP_VFs(q_prim_ts2(i)) - end do - end if - - ! Allocating the cell-average primitive variables - @:ALLOCATE(q_prim_vf(1:sys_size)) - - if (.not. igr) then - do i = 1, adv_idx%end - @:ALLOCATE(q_prim_vf(i)%sf(idwbuff(1)%beg:idwbuff(1)%end, & - idwbuff(2)%beg:idwbuff(2)%end, & - idwbuff(3)%beg:idwbuff(3)%end)) - @:ACC_SETUP_SFs(q_prim_vf(i)) - end do - - if (bubbles_euler) then - do i = bub_idx%beg, bub_idx%end - @:ALLOCATE(q_prim_vf(i)%sf(idwbuff(1)%beg:idwbuff(1)%end, & - idwbuff(2)%beg:idwbuff(2)%end, & - idwbuff(3)%beg:idwbuff(3)%end)) - @:ACC_SETUP_SFs(q_prim_vf(i)) - end do - if (adv_n) then - @:ALLOCATE(q_prim_vf(n_idx)%sf(idwbuff(1)%beg:idwbuff(1)%end, & - idwbuff(2)%beg:idwbuff(2)%end, & - idwbuff(3)%beg:idwbuff(3)%end)) - @:ACC_SETUP_SFs(q_prim_vf(n_idx)) - end if - end if - - if (mhd) then - do i = B_idx%beg, B_idx%end - @:ALLOCATE(q_prim_vf(i)%sf(idwbuff(1)%beg:idwbuff(1)%end, & - idwbuff(2)%beg:idwbuff(2)%end, & - idwbuff(3)%beg:idwbuff(3)%end)) - @:ACC_SETUP_SFs(q_prim_vf(i)) - end do - end if - - if (elasticity) then - do i = stress_idx%beg, stress_idx%end - @:ALLOCATE(q_prim_vf(i)%sf(idwbuff(1)%beg:idwbuff(1)%end, & - idwbuff(2)%beg:idwbuff(2)%end, & - idwbuff(3)%beg:idwbuff(3)%end)) - @:ACC_SETUP_SFs(q_prim_vf(i)) - end do - end if - - if (hyperelasticity) then - do i = xibeg, xiend + 1 - @:ALLOCATE(q_prim_vf(i)%sf(idwbuff(1)%beg:idwbuff(1)%end, & - idwbuff(2)%beg:idwbuff(2)%end, & - idwbuff(3)%beg:idwbuff(3)%end)) - @:ACC_SETUP_SFs(q_prim_vf(i)) - end do - end if - - if (cont_damage) then - @:ALLOCATE(q_prim_vf(damage_idx)%sf(idwbuff(1)%beg:idwbuff(1)%end, & - idwbuff(2)%beg:idwbuff(2)%end, & - idwbuff(3)%beg:idwbuff(3)%end)) - @:ACC_SETUP_SFs(q_prim_vf(damage_idx)) - end if - - if (hyper_cleaning) then - @:ALLOCATE(q_prim_vf(psi_idx)%sf(idwbuff(1)%beg:idwbuff(1)%end, & - idwbuff(2)%beg:idwbuff(2)%end, & - idwbuff(3)%beg:idwbuff(3)%end)) - @:ACC_SETUP_SFs(q_prim_vf(psi_idx)) - end if - - if (model_eqns == 3) then - do i = internalEnergies_idx%beg, internalEnergies_idx%end - @:ALLOCATE(q_prim_vf(i)%sf(idwbuff(1)%beg:idwbuff(1)%end, & - idwbuff(2)%beg:idwbuff(2)%end, & - idwbuff(3)%beg:idwbuff(3)%end)) - @:ACC_SETUP_SFs(q_prim_vf(i)) - end do - end if - - if (surface_tension) then - @:ALLOCATE(q_prim_vf(c_idx)%sf(idwbuff(1)%beg:idwbuff(1)%end, & - idwbuff(2)%beg:idwbuff(2)%end, & - idwbuff(3)%beg:idwbuff(3)%end)) - @:ACC_SETUP_SFs(q_prim_vf(c_idx)) - end if - - if (chemistry) then - do i = chemxb, chemxe - @:ALLOCATE(q_prim_vf(i)%sf(idwbuff(1)%beg:idwbuff(1)%end, & - idwbuff(2)%beg:idwbuff(2)%end, & - idwbuff(3)%beg:idwbuff(3)%end)) - @:ACC_SETUP_SFs(q_prim_vf(i)) - end do - - @:ALLOCATE(q_T_sf%sf(idwbuff(1)%beg:idwbuff(1)%end, & - idwbuff(2)%beg:idwbuff(2)%end, & - idwbuff(3)%beg:idwbuff(3)%end)) - @:ACC_SETUP_SFs(q_T_sf) - end if - end if - - @:ALLOCATE(pb_ts(1:2)) - !Initialize bubble variables pb and mv at all quadrature nodes for all R0 bins - if (qbmm .and. (.not. polytropic)) then - @:ALLOCATE(pb_ts(1)%sf(idwbuff(1)%beg:idwbuff(1)%end, & - idwbuff(2)%beg:idwbuff(2)%end, & - idwbuff(3)%beg:idwbuff(3)%end, 1:nnode, 1:nb)) - @:ACC_SETUP_SFs(pb_ts(1)) - - @:ALLOCATE(pb_ts(2)%sf(idwbuff(1)%beg:idwbuff(1)%end, & - idwbuff(2)%beg:idwbuff(2)%end, & - idwbuff(3)%beg:idwbuff(3)%end, 1:nnode, 1:nb)) - @:ACC_SETUP_SFs(pb_ts(2)) - - @:ALLOCATE(rhs_pb(idwbuff(1)%beg:idwbuff(1)%end, & - idwbuff(2)%beg:idwbuff(2)%end, & - idwbuff(3)%beg:idwbuff(3)%end, 1:nnode, 1:nb)) - else if (qbmm .and. polytropic) then - @:ALLOCATE(pb_ts(1)%sf(idwbuff(1)%beg:idwbuff(1)%beg + 1, & - idwbuff(2)%beg:idwbuff(2)%beg + 1, & - idwbuff(3)%beg:idwbuff(3)%beg + 1, 1:nnode, 1:nb)) - @:ACC_SETUP_SFs(pb_ts(1)) - - @:ALLOCATE(pb_ts(2)%sf(idwbuff(1)%beg:idwbuff(1)%beg + 1, & - idwbuff(2)%beg:idwbuff(2)%beg + 1, & - idwbuff(3)%beg:idwbuff(3)%beg + 1, 1:nnode, 1:nb)) - @:ACC_SETUP_SFs(pb_ts(2)) - - @:ALLOCATE(rhs_pb(idwbuff(1)%beg:idwbuff(1)%beg + 1, & - idwbuff(2)%beg:idwbuff(2)%beg + 1, & - idwbuff(3)%beg:idwbuff(3)%beg + 1, 1:nnode, 1:nb)) - else - @:ALLOCATE(pb_ts(1)%sf(0,0,0,0,0)) - @:ACC_SETUP_SFs(pb_ts(1)) - - @:ALLOCATE(pb_ts(2)%sf(0,0,0,0,0)) - @:ACC_SETUP_SFs(pb_ts(2)) - - @:ALLOCATE(rhs_pb(0,0,0,0,0)) - end if - - @:ALLOCATE(mv_ts(1:2)) - - if (qbmm .and. (.not. polytropic)) then - @:ALLOCATE(mv_ts(1)%sf(idwbuff(1)%beg:idwbuff(1)%end, & - idwbuff(2)%beg:idwbuff(2)%end, & - idwbuff(3)%beg:idwbuff(3)%end, 1:nnode, 1:nb)) - @:ACC_SETUP_SFs(mv_ts(1)) - - @:ALLOCATE(mv_ts(2)%sf(idwbuff(1)%beg:idwbuff(1)%end, & - idwbuff(2)%beg:idwbuff(2)%end, & - idwbuff(3)%beg:idwbuff(3)%end, 1:nnode, 1:nb)) - @:ACC_SETUP_SFs(mv_ts(2)) - - @:ALLOCATE(rhs_mv(idwbuff(1)%beg:idwbuff(1)%end, & - idwbuff(2)%beg:idwbuff(2)%end, & - idwbuff(3)%beg:idwbuff(3)%end, 1:nnode, 1:nb)) - - else if (qbmm .and. polytropic) then - @:ALLOCATE(mv_ts(1)%sf(idwbuff(1)%beg:idwbuff(1)%beg + 1, & - idwbuff(2)%beg:idwbuff(2)%beg + 1, & - idwbuff(3)%beg:idwbuff(3)%beg + 1, 1:nnode, 1:nb)) - @:ACC_SETUP_SFs(mv_ts(1)) - - @:ALLOCATE(mv_ts(2)%sf(idwbuff(1)%beg:idwbuff(1)%beg + 1, & - idwbuff(2)%beg:idwbuff(2)%beg + 1, & - idwbuff(3)%beg:idwbuff(3)%beg + 1, 1:nnode, 1:nb)) - @:ACC_SETUP_SFs(mv_ts(2)) - - @:ALLOCATE(rhs_mv(idwbuff(1)%beg:idwbuff(1)%beg + 1, & - idwbuff(2)%beg:idwbuff(2)%beg + 1, & - idwbuff(3)%beg:idwbuff(3)%beg + 1, 1:nnode, 1:nb)) - else - @:ALLOCATE(mv_ts(1)%sf(0,0,0,0,0)) - @:ACC_SETUP_SFs(mv_ts(1)) - - @:ALLOCATE(mv_ts(2)%sf(0,0,0,0,0)) - @:ACC_SETUP_SFs(mv_ts(2)) - - @:ALLOCATE(rhs_mv(0,0,0,0,0)) - end if - - ! Allocating the cell-average RHS variables - @:ALLOCATE(rhs_vf(1:sys_size)) - @:PREFER_GPU(rhs_vf) - - if (igr) then - do i = 1, sys_size - @:ALLOCATE(rhs_vf(i)%sf(-1:m+1,-1:n+1,-1:p+1)) - @:ACC_SETUP_SFs(rhs_vf(i)) - @:PREFER_GPU(rhs_vf(i)%sf) - end do - else - do i = 1, sys_size - @:ALLOCATE(rhs_vf(i)%sf(0:m, 0:n, 0:p)) - @:ACC_SETUP_SFs(rhs_vf(i)) - end do - end if - - ! Opening and writing the header of the run-time information file - if (proc_rank == 0 .and. run_time_info) then - call s_open_run_time_information_file() - end if - - if (cfl_dt) then - @:ALLOCATE(max_dt(0:m, 0:n, 0:p)) - end if - - ! Allocating arrays to store the bc types - @:ALLOCATE(bc_type(1:num_dims,1:2)) - - @:ALLOCATE(bc_type(1,1)%sf(0:0,0:n,0:p)) - @:ALLOCATE(bc_type(1,2)%sf(0:0,0:n,0:p)) - #:if not MFC_CASE_OPTIMIZATION or num_dims > 1 - if (n > 0) then - @:ALLOCATE(bc_type(2,1)%sf(-buff_size:m+buff_size,0:0,0:p)) - @:ALLOCATE(bc_type(2,2)%sf(-buff_size:m+buff_size,0:0,0:p)) - #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 - if (p > 0) then - @:ALLOCATE(bc_type(3,1)%sf(-buff_size:m+buff_size,-buff_size:n+buff_size,0:0)) - @:ALLOCATE(bc_type(3,2)%sf(-buff_size:m+buff_size,-buff_size:n+buff_size,0:0)) - end if - #:endif - end if - #:endif - - do i = 1, num_dims - do j = 1, 2 - @:ACC_SETUP_SFs(bc_type(i,j)) - end do - end do - - if (any(time_stepper == (/1, 2, 3/))) then - ! temporary array index for TVD RK - if (time_stepper == 1) then - stor = 1 - else - stor = 2 - end if - - ! TVD RK coefficients - @:ALLOCATE (rk_coef(time_stepper, 4)) - if (time_stepper == 1) then - rk_coef(1, :) = (/1._wp, 0._wp, 1._wp, 1._wp/) - else if (time_stepper == 2) then - rk_coef(1, :) = (/1._wp, 0._wp, 1._wp, 1._wp/) - rk_coef(2, :) = (/1._wp, 1._wp, 1._wp, 2._wp/) - else if (time_stepper == 3) then - rk_coef(1, :) = (/1._wp, 0._wp, 1._wp, 1._wp/) - rk_coef(2, :) = (/1._wp, 3._wp, 1._wp, 4._wp/) - rk_coef(3, :) = (/2._wp, 1._wp, 2._wp, 3._wp/) - end if - $:GPU_UPDATE(device='[rk_coef, stor]') - end if - - end subroutine s_initialize_time_steppers_module - - !> @brief Advances the solution one full step using a TVD Runge-Kutta time integrator. - impure subroutine s_tvd_rk(t_step, time_avg, nstage) -#ifdef _CRAYFTN - !DIR$ OPTIMIZE (-haggress) -#endif - integer, intent(in) :: t_step - real(wp), intent(inout) :: time_avg - integer, intent(in) :: nstage - - integer :: i, j, k, l, q, s !< Generic loop iterator - real(wp) :: start, finish - integer :: dest - - call cpu_time(start) - call nvtxStartRange("TIMESTEP") - - ! Adaptive dt: initial stage - if (adap_dt) call s_adaptive_dt_bubble(1) - - do s = 1, nstage - call s_compute_rhs(q_cons_ts(1)%vf, q_T_sf, q_prim_vf, bc_type, rhs_vf, pb_ts(1)%sf, rhs_pb, mv_ts(1)%sf, rhs_mv, t_step, time_avg, s) - - if (s == 1) then - if (run_time_info) then - if (igr .or. dummy) then - call s_write_run_time_information(q_cons_ts(1)%vf, t_step) - end if - if (.not. igr .or. dummy) then - call s_write_run_time_information(q_prim_vf, t_step) - end if - end if - - if (probe_wrt) then - call s_time_step_cycling(t_step) - call s_compute_derived_variables(t_step, q_cons_ts(1)%vf, q_prim_ts1, q_prim_ts2) - end if - - if (cfl_dt) then - if (mytime >= t_stop) return - else - if (t_step == t_step_stop) return - end if - end if - - if (bubbles_lagrange .and. .not. adap_dt) call s_update_lagrange_tdv_rk(stage=s) - $:GPU_PARALLEL_LOOP(collapse=4) - do i = 1, sys_size - do l = 0, p - do k = 0, n - do j = 0, m - if (s == 1 .and. nstage > 1) then - q_cons_ts(stor)%vf(i)%sf(j, k, l) = & - q_cons_ts(1)%vf(i)%sf(j, k, l) - end if - if (igr) then - q_cons_ts(1)%vf(i)%sf(j, k, l) = & - (rk_coef(s, 1)*q_cons_ts(1)%vf(i)%sf(j, k, l) & - + rk_coef(s, 2)*q_cons_ts(stor)%vf(i)%sf(j, k, l) & - + rk_coef(s, 3)*rhs_vf(i)%sf(j, k, l))/rk_coef(s, 4) - else - q_cons_ts(1)%vf(i)%sf(j, k, l) = & - (rk_coef(s, 1)*q_cons_ts(1)%vf(i)%sf(j, k, l) & - + rk_coef(s, 2)*q_cons_ts(stor)%vf(i)%sf(j, k, l) & - + rk_coef(s, 3)*dt*rhs_vf(i)%sf(j, k, l))/rk_coef(s, 4) - end if - end do - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - !Evolve pb and mv for non-polytropic qbmm - if (qbmm .and. (.not. polytropic)) then - $:GPU_PARALLEL_LOOP(collapse=5) - do i = 1, nb - do l = 0, p - do k = 0, n - do j = 0, m - do q = 1, nnode - if (s == 1 .and. nstage > 1) then - pb_ts(stor)%sf(j, k, l, q, i) = & - pb_ts(1)%sf(j, k, l, q, i) - mv_ts(stor)%sf(j, k, l, q, i) = & - mv_ts(1)%sf(j, k, l, q, i) - end if - pb_ts(1)%sf(j, k, l, q, i) = & - (rk_coef(s, 1)*pb_ts(1)%sf(j, k, l, q, i) & - + rk_coef(s, 2)*pb_ts(stor)%sf(j, k, l, q, i) & - + rk_coef(s, 3)*dt*rhs_pb(j, k, l, q, i))/rk_coef(s, 4) - mv_ts(1)%sf(j, k, l, q, i) = & - (rk_coef(s, 1)*mv_ts(1)%sf(j, k, l, q, i) & - + rk_coef(s, 2)*mv_ts(stor)%sf(j, k, l, q, i) & - + rk_coef(s, 3)*dt*rhs_mv(j, k, l, q, i))/rk_coef(s, 4) - end do - end do - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - end if - - if (bodyForces) call s_apply_bodyforces(q_cons_ts(1)%vf, q_prim_vf, rhs_vf, rk_coef(s, 3)*dt/rk_coef(s, 4)) - - if (grid_geometry == 3) call s_apply_fourier_filter(q_cons_ts(1)%vf) - - if (model_eqns == 3 .and. (.not. relax)) then - call s_pressure_relaxation_procedure(q_cons_ts(1)%vf) - end if - - if (adv_n) call s_comp_alpha_from_n(q_cons_ts(1)%vf) - - if (ib) then - ! check if any IBMS are moving, and if so, update the markers, ghost points, levelsets, and levelset norms - if (moving_immersed_boundary_flag) then - call s_propagate_immersed_boundaries(s) - end if - - ! update the ghost fluid properties point values based on IB state - if (qbmm .and. .not. polytropic) then - call s_ibm_correct_state(q_cons_ts(1)%vf, q_prim_vf, pb_ts(1)%sf, mv_ts(1)%sf) - else - call s_ibm_correct_state(q_cons_ts(1)%vf, q_prim_vf) - end if - end if - - end do - - if (moving_immersed_boundary_flag) call s_wrap_periodic_ibs() - - ! Adaptive dt: final stage - if (adap_dt) call s_adaptive_dt_bubble(3) - - call nvtxEndRange - call cpu_time(finish) - - wall_time = abs(finish - start) - - if (t_step >= 2) then - wall_time_avg = (wall_time + (t_step - 2)*wall_time_avg)/(t_step - 1) - else - wall_time_avg = 0._wp - end if - - end subroutine s_tvd_rk - - !> Bubble source part in Strang operator splitting scheme - !! @param stage Current time-stage - impure subroutine s_adaptive_dt_bubble(stage) - - integer, intent(in) :: stage - - type(vector_field) :: gm_alpha_qp - - call s_convert_conservative_to_primitive_variables( & - q_cons_ts(1)%vf, & - q_T_sf, & - q_prim_vf, & - idwint) - - if (bubbles_euler) then - - call s_compute_bubble_EE_source(q_cons_ts(1)%vf, q_prim_vf, rhs_vf, divu) - call s_comp_alpha_from_n(q_cons_ts(1)%vf) - - elseif (bubbles_lagrange) then - - call s_populate_variables_buffers(bc_type, q_prim_vf, pb_ts(1)%sf, mv_ts(1)%sf) - call s_compute_bubble_EL_dynamics(q_prim_vf, stage) - call s_transfer_data_to_tmp() - call s_smear_voidfraction() - if (stage == 3) then - if (lag_params%write_bubbles_stats) call s_calculate_lag_bubble_stats() - if (lag_params%write_bubbles) then - $:GPU_UPDATE(host='[gas_p,gas_mv,intfc_rad,intfc_vel]') - call s_write_lag_particles(mytime) - end if - call s_write_void_evol(mytime) - end if - - end if - - end subroutine s_adaptive_dt_bubble - - !> @brief Computes the global time step size from CFL stability constraints across all cells. - impure subroutine s_compute_dt() - - real(wp) :: rho !< Cell-avg. density - #:if not MFC_CASE_OPTIMIZATION and USING_AMD - real(wp), dimension(3) :: vel !< Cell-avg. velocity - real(wp), dimension(3) :: alpha !< Cell-avg. volume fraction - #:else - real(wp), dimension(num_vels) :: vel !< Cell-avg. velocity - real(wp), dimension(num_fluids) :: alpha !< Cell-avg. volume fraction - #:endif - real(wp) :: vel_sum !< Cell-avg. velocity sum - real(wp) :: pres !< Cell-avg. pressure - real(wp) :: gamma !< Cell-avg. sp. heat ratio - real(wp) :: pi_inf !< Cell-avg. liquid stiffness function - real(wp) :: qv !< Cell-avg. fluid reference energy - real(wp) :: c !< Cell-avg. sound speed - real(wp) :: H !< Cell-avg. enthalpy - real(wp), dimension(2) :: Re !< Cell-avg. Reynolds numbers - type(vector_field) :: gm_alpha_qp - - real(wp) :: dt_local - integer :: j, k, l !< Generic loop iterators - - if (.not. igr .or. dummy) then - call s_convert_conservative_to_primitive_variables( & - q_cons_ts(1)%vf, & - q_T_sf, & - q_prim_vf, & - idwint) - end if - - $:GPU_PARALLEL_LOOP(collapse=3, private='[vel, alpha, Re, rho, vel_sum, pres, gamma, pi_inf, c, H, qv]') - do l = 0, p - do k = 0, n - do j = 0, m - if (igr) then - call s_compute_enthalpy(q_cons_ts(1)%vf, pres, rho, gamma, pi_inf, Re, H, alpha, vel, vel_sum, qv, j, k, l) - else - call s_compute_enthalpy(q_prim_vf, pres, rho, gamma, pi_inf, Re, H, alpha, vel, vel_sum, qv, j, k, l) - end if - - ! Compute mixture sound speed - call s_compute_speed_of_sound(pres, rho, gamma, pi_inf, H, alpha, vel_sum, 0._wp, c, qv) - - call s_compute_dt_from_cfl(vel, c, max_dt, rho, Re, j, k, l) - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - - #:call GPU_PARALLEL(copyout='[dt_local]', copyin='[max_dt]') - dt_local = minval(max_dt) - #:endcall GPU_PARALLEL - - if (num_procs == 1) then - dt = dt_local - else - call s_mpi_allreduce_min(dt_local, dt) - end if - - $:GPU_UPDATE(device='[dt]') - - end subroutine s_compute_dt - - !> This subroutine applies the body forces source term at each - !! Runge-Kutta stage - !! @param q_cons_vf Conservative variables - !! @param q_prim_vf_in Primitive variables - !! @param rhs_vf_in Right-hand side variables - subroutine s_apply_bodyforces(q_cons_vf, q_prim_vf_in, rhs_vf_in, ldt) - - type(scalar_field), dimension(1:sys_size), intent(inout) :: q_cons_vf - type(scalar_field), dimension(1:sys_size), intent(in) :: q_prim_vf_in - type(scalar_field), dimension(1:sys_size), intent(inout) :: rhs_vf_in - - real(wp), intent(in) :: ldt !< local dt - - integer :: i, j, k, l - - call nvtxStartRange("RHS-BODYFORCES") - call s_compute_body_forces_rhs(q_prim_vf_in, q_cons_vf, rhs_vf_in) - - $:GPU_PARALLEL_LOOP(collapse=4) - do i = momxb, E_idx - do l = 0, p - do k = 0, n - do j = 0, m - q_cons_vf(i)%sf(j, k, l) = q_cons_vf(i)%sf(j, k, l) + & - ldt*rhs_vf_in(i)%sf(j, k, l) - end do - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - - call nvtxEndRange - - end subroutine s_apply_bodyforces - - !> @brief Updates immersed boundary positions and velocities at the current Runge-Kutta stage. - subroutine s_propagate_immersed_boundaries(s) - - integer, intent(in) :: s - integer :: i - logical :: forces_computed - - call nvtxStartRange("PROPAGATE-IMMERSED-BOUNDARIES") - - forces_computed = .false. - - do i = 1, num_ibs - if (s == 1) then - patch_ib(i)%step_vel = patch_ib(i)%vel - patch_ib(i)%step_angular_vel = patch_ib(i)%angular_vel - patch_ib(i)%step_angles = patch_ib(i)%angles - patch_ib(i)%step_x_centroid = patch_ib(i)%x_centroid - patch_ib(i)%step_y_centroid = patch_ib(i)%y_centroid - patch_ib(i)%step_z_centroid = patch_ib(i)%z_centroid - end if - - if (patch_ib(i)%moving_ibm > 0) then - patch_ib(i)%vel = (rk_coef(s, 1)*patch_ib(i)%step_vel + rk_coef(s, 2)*patch_ib(i)%vel)/rk_coef(s, 4) - patch_ib(i)%angular_vel = (rk_coef(s, 1)*patch_ib(i)%step_angular_vel + rk_coef(s, 2)*patch_ib(i)%angular_vel)/rk_coef(s, 4) - - if (patch_ib(i)%moving_ibm == 1) then - ! plug in analytic velocities for 1-way coupling, if it exists - @:mib_analytical() - else if (patch_ib(i)%moving_ibm == 2) then ! if we are using two-way coupling, apply force and torque - ! compute the force and torque on the IB from the fluid - if (.not. forces_computed) then - call s_compute_ib_forces(q_prim_vf, fluid_pp) - forces_computed = .true. - end if - - ! update the velocity from the force value - patch_ib(i)%vel = patch_ib(i)%vel + rk_coef(s, 3)*dt*(patch_ib(i)%force/patch_ib(i)%mass)/rk_coef(s, 4) - - ! update the angular velocity with the torque value - patch_ib(i)%angular_vel = (patch_ib(i)%angular_vel*patch_ib(i)%moment) + (rk_coef(s, 3)*dt*patch_ib(i)%torque/rk_coef(s, 4)) ! add the torque to the angular momentum - call s_compute_moment_of_inertia(i, patch_ib(i)%angular_vel) ! update the moment of inertia to be based on the direction of the angular momentum - patch_ib(i)%angular_vel = patch_ib(i)%angular_vel/patch_ib(i)%moment ! convert back to angular velocity with the new moment of inertia - end if - - ! Update the angle of the IB - patch_ib(i)%angles = (rk_coef(s, 1)*patch_ib(i)%step_angles + rk_coef(s, 2)*patch_ib(i)%angles + rk_coef(s, 3)*patch_ib(i)%angular_vel*dt)/rk_coef(s, 4) - - ! Update the position of the IB - patch_ib(i)%x_centroid = (rk_coef(s, 1)*patch_ib(i)%step_x_centroid + rk_coef(s, 2)*patch_ib(i)%x_centroid + rk_coef(s, 3)*patch_ib(i)%vel(1)*dt)/rk_coef(s, 4) - patch_ib(i)%y_centroid = (rk_coef(s, 1)*patch_ib(i)%step_y_centroid + rk_coef(s, 2)*patch_ib(i)%y_centroid + rk_coef(s, 3)*patch_ib(i)%vel(2)*dt)/rk_coef(s, 4) - patch_ib(i)%z_centroid = (rk_coef(s, 1)*patch_ib(i)%step_z_centroid + rk_coef(s, 2)*patch_ib(i)%z_centroid + rk_coef(s, 3)*patch_ib(i)%vel(3)*dt)/rk_coef(s, 4) - end if - end do - - call s_update_mib(num_ibs) - - call nvtxEndRange - - end subroutine s_propagate_immersed_boundaries - - !> This subroutine saves the temporary q_prim_vf vector - !! into the q_prim_ts vector that is then used in p_main - !! @param t_step current time-step - subroutine s_time_step_cycling(t_step) - - integer, intent(in) :: t_step - - integer :: i, j, k, l !< Generic loop iterator - - if (t_step == t_step_start) then - $:GPU_PARALLEL_LOOP(collapse=4) - do i = 1, sys_size - do l = 0, p - do k = 0, n - do j = 0, m - q_prim_ts2(2)%vf(i)%sf(j, k, l) = q_prim_vf(i)%sf(j, k, l) - end do - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - elseif (t_step == t_step_start + 1) then - $:GPU_PARALLEL_LOOP(collapse=4) - do i = 1, sys_size - do l = 0, p - do k = 0, n - do j = 0, m - q_prim_ts2(1)%vf(i)%sf(j, k, l) = q_prim_vf(i)%sf(j, k, l) - end do - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - elseif (t_step == t_step_start + 2) then - $:GPU_PARALLEL_LOOP(collapse=4) - do i = 1, sys_size - do l = 0, p - do k = 0, n - do j = 0, m - q_prim_ts1(2)%vf(i)%sf(j, k, l) = q_prim_vf(i)%sf(j, k, l) - end do - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - elseif (t_step == t_step_start + 3) then - $:GPU_PARALLEL_LOOP(collapse=4) - do i = 1, sys_size - do l = 0, p - do k = 0, n - do j = 0, m - q_prim_ts1(1)%vf(i)%sf(j, k, l) = q_prim_vf(i)%sf(j, k, l) - end do - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - else ! All other timesteps - $:GPU_PARALLEL_LOOP(collapse=4) - do i = 1, sys_size - do l = 0, p - do k = 0, n - do j = 0, m - q_prim_ts2(2)%vf(i)%sf(j, k, l) = q_prim_ts2(1)%vf(i)%sf(j, k, l) - q_prim_ts2(1)%vf(i)%sf(j, k, l) = q_prim_ts1(2)%vf(i)%sf(j, k, l) - q_prim_ts1(2)%vf(i)%sf(j, k, l) = q_prim_ts1(1)%vf(i)%sf(j, k, l) - q_prim_ts1(1)%vf(i)%sf(j, k, l) = q_prim_vf(i)%sf(j, k, l) - end do - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - end if - - end subroutine s_time_step_cycling - - !> Module deallocation and/or disassociation procedures - impure subroutine s_finalize_time_steppers_module -#ifdef FRONTIER_UNIFIED - use hipfort - use hipfort_hipmalloc - use hipfort_check -#endif - integer :: i, j !< Generic loop iterators - - ! Deallocating the cell-average conservative variables -#if defined(__NVCOMPILER_GPU_UNIFIED_MEM) - do j = 1, sys_size - @:DEALLOCATE(q_cons_ts(1)%vf(j)%sf) - if (num_ts == 2) then - if (nv_uvm_out_of_core) then - nullify (q_cons_ts(2)%vf(j)%sf) - else - @:DEALLOCATE(q_cons_ts(2)%vf(j)%sf) - end if - end if - end do - if (num_ts == 2 .and. nv_uvm_out_of_core) then - deallocate (q_cons_ts_pool_host) - end if -#elif defined(FRONTIER_UNIFIED) - do i = 1, num_ts - do j = 1, sys_size - nullify (q_cons_ts(i)%vf(j)%sf) - end do - end do -#ifdef MFC_MIXED_PRECISION - call hipCheck(hipHostFree_(c_loc(q_cons_ts_pool_host))) - nullify (q_cons_ts_pool_host) - call hipCheck(hipFree_(c_loc(q_cons_ts_pool_device))) - nullify (q_cons_ts_pool_device) -#else - call hipCheck(hipHostFree(q_cons_ts_pool_host)) - call hipCheck(hipFree(q_cons_ts_pool_device)) -#endif -#else - do i = 1, num_ts - do j = 1, sys_size - @:DEALLOCATE(q_cons_ts(i)%vf(j)%sf) - end do - end do -#endif - do i = 1, num_ts - @:DEALLOCATE(q_cons_ts(i)%vf) - end do - - @:DEALLOCATE(q_cons_ts) - - ! Deallocating the cell-average primitive ts variables - if (probe_wrt) then - do i = 1, num_probe_ts - do j = 1, sys_size - @:DEALLOCATE(q_prim_ts1(i)%vf(j)%sf,q_prim_ts2(i)%vf(j)%sf ) - end do - @:DEALLOCATE(q_prim_ts1(i)%vf, q_prim_ts2(i)%vf) - end do - @:DEALLOCATE(q_prim_ts1, q_prim_ts2) - end if - - if (.not. igr) then - ! Deallocating the cell-average primitive variables - do i = 1, adv_idx%end - @:DEALLOCATE(q_prim_vf(i)%sf) - end do - - if (mhd) then - do i = B_idx%beg, B_idx%end - @:DEALLOCATE(q_prim_vf(i)%sf) - end do - end if - - if (elasticity) then - do i = stress_idx%beg, stress_idx%end - @:DEALLOCATE(q_prim_vf(i)%sf) - end do - end if - - if (hyperelasticity) then - do i = xibeg, xiend + 1 - @:DEALLOCATE(q_prim_vf(i)%sf) - end do - end if - - if (cont_damage) then - @:DEALLOCATE(q_prim_vf(damage_idx)%sf) - end if - - if (hyper_cleaning) then - @:DEALLOCATE(q_prim_vf(psi_idx)%sf) - end if - - if (bubbles_euler) then - do i = bub_idx%beg, bub_idx%end - @:DEALLOCATE(q_prim_vf(i)%sf) - end do - end if - - if (model_eqns == 3) then - do i = internalEnergies_idx%beg, internalEnergies_idx%end - @:DEALLOCATE(q_prim_vf(i)%sf) - end do - end if - end if - - @:DEALLOCATE(q_prim_vf) - - ! Deallocating the cell-average RHS variables - do i = 1, sys_size - @:DEALLOCATE(rhs_vf(i)%sf) - end do - - @:DEALLOCATE(rhs_vf) - - ! Writing the footer of and closing the run-time information file - if (proc_rank == 0 .and. run_time_info) then - call s_close_run_time_information_file() - end if - - end subroutine s_finalize_time_steppers_module - -end module m_time_steppers +!> +!! @file +!! @brief Contains module m_time_steppers + +#:include 'macros.fpp' +#:include 'case.fpp' + +!> @brief Total-variation-diminishing (TVD) Runge--Kutta time integrators (1st-, 2nd-, and 3rd-order SSP) +module m_time_steppers + + use m_derived_types !< Definitions of the derived types + + use m_global_parameters !< Definitions of the global parameters + + use m_rhs !< Right-hane-side (RHS) evaluation procedures + + use m_pressure_relaxation !< Pressure relaxation procedures + + use m_data_output !< Run-time info & solution data output procedures + + use m_bubbles_EE !< Ensemble-averaged bubble dynamics routines + + use m_bubbles_EL !< Lagrange bubble dynamics routines + + use m_ibm + + use m_hyperelastic + + use m_mpi_proxy !< Message passing interface (MPI) module proxy + + use m_boundary_common + + use m_helper + + use m_sim_helpers + + use m_fftw + + use m_nvtx + + use m_thermochem, only: num_species + + use m_body_forces + + use m_derived_variables + + use m_re_visc !< Non-Newtonian viscosity computations + + implicit none + + type(vector_field), allocatable, dimension(:) :: q_cons_ts !< + !! Cell-average conservative variables at each time-stage (TS) + + type(scalar_field), allocatable, dimension(:) :: q_prim_vf !< + !! Cell-average primitive variables at the current time-stage + + type(scalar_field), allocatable, dimension(:) :: rhs_vf !< + !! Cell-average RHS variables at the current time-stage + + type(integer_field), allocatable, dimension(:, :) :: bc_type !< + !! Boundary condition identifiers + + type(vector_field), allocatable, dimension(:) :: q_prim_ts1, q_prim_ts2 !< + !! Cell-average primitive variables at consecutive TIMESTEPS + + real(wp), allocatable, dimension(:, :, :, :, :) :: rhs_pb + + type(scalar_field) :: q_T_sf !< + !! Cell-average temperature variables at the current time-stage + + real(wp), allocatable, dimension(:, :, :, :, :) :: rhs_mv + + real(wp), allocatable, dimension(:, :, :) :: max_dt + + integer, private :: num_ts !< + !! Number of time stages in the time-stepping scheme + + integer :: stor !< storage index + real(wp), allocatable, dimension(:, :) :: rk_coef + integer, private :: num_probe_ts + + $:GPU_DECLARE(create='[q_cons_ts,q_prim_vf,q_T_sf,rhs_vf,q_prim_ts1,q_prim_ts2,rhs_mv,rhs_pb,max_dt,rk_coef,stor,bc_type]') + +!> @cond +#if defined(__NVCOMPILER_GPU_UNIFIED_MEM) + real(stp), allocatable, dimension(:, :, :, :), pinned, target :: q_cons_ts_pool_host +#elif defined(FRONTIER_UNIFIED) + real(stp), pointer, contiguous, dimension(:, :, :, :) :: q_cons_ts_pool_host, q_cons_ts_pool_device + integer(kind=8) :: pool_dims(4), pool_starts(4) + integer(kind=8) :: pool_size + type(c_ptr) :: cptr_host, cptr_device +#endif +!> @endcond + +contains + + !> The computation of parameters, the allocation of memory, + !! the association of pointers and/or the execution of any + !! other procedures that are necessary to setup the module. + impure subroutine s_initialize_time_steppers_module +#ifdef FRONTIER_UNIFIED + use hipfort + use hipfort_hipmalloc + use hipfort_check +#if defined(MFC_OpenACC) + use openacc +#endif +#endif + integer :: i, j !< Generic loop iterators + + ! Setting number of time-stages for selected time-stepping scheme + if (time_stepper == 1) then + num_ts = 1 + elseif (any(time_stepper == (/2, 3/))) then + num_ts = 2 + end if + + if (probe_wrt) then + num_probe_ts = 2 + end if + + ! Allocating the cell-average conservative variables + @:ALLOCATE(q_cons_ts(1:num_ts)) + @:PREFER_GPU(q_cons_ts) + + do i = 1, num_ts + @:ALLOCATE(q_cons_ts(i)%vf(1:sys_size)) + @:PREFER_GPU(q_cons_ts(i)%vf) + end do + +!> @cond +#if defined(__NVCOMPILER_GPU_UNIFIED_MEM) + if (num_ts == 2 .and. nv_uvm_out_of_core) then + ! host allocation for q_cons_ts(2)%vf(j)%sf for all j + allocate (q_cons_ts_pool_host(idwbuff(1)%beg:idwbuff(1)%end, & + idwbuff(2)%beg:idwbuff(2)%end, & + idwbuff(3)%beg:idwbuff(3)%end, & + 1:sys_size)) + end if + + do j = 1, sys_size + ! q_cons_ts(1) lives on the device + @:ALLOCATE(q_cons_ts(1)%vf(j)%sf(idwbuff(1)%beg:idwbuff(1)%end, & + idwbuff(2)%beg:idwbuff(2)%end, & + idwbuff(3)%beg:idwbuff(3)%end)) + @:PREFER_GPU(q_cons_ts(1)%vf(j)%sf) + if (num_ts == 2) then + if (nv_uvm_out_of_core) then + ! q_cons_ts(2) lives on the host + q_cons_ts(2)%vf(j)%sf(idwbuff(1)%beg:idwbuff(1)%end, & + idwbuff(2)%beg:idwbuff(2)%end, & + idwbuff(3)%beg:idwbuff(3)%end) => q_cons_ts_pool_host(:, :, :, j) + else + @:ALLOCATE(q_cons_ts(2)%vf(j)%sf(idwbuff(1)%beg:idwbuff(1)%end, & + idwbuff(2)%beg:idwbuff(2)%end, & + idwbuff(3)%beg:idwbuff(3)%end)) + @:PREFER_GPU(q_cons_ts(2)%vf(j)%sf) + end if + end if + end do + + do i = 1, num_ts + @:ACC_SETUP_VFs(q_cons_ts(i)) + end do +#elif defined(FRONTIER_UNIFIED) + ! Allocate to memory regions using hip calls + ! that we will attach pointers to + do i = 1, 3 + pool_dims(i) = idwbuff(i)%end - idwbuff(i)%beg + 1 + pool_starts(i) = idwbuff(i)%beg + end do + pool_dims(4) = sys_size + pool_starts(4) = 1 +#ifdef MFC_MIXED_PRECISION + pool_size = 1_8*(idwbuff(1)%end - idwbuff(1)%beg + 1)*(idwbuff(2)%end - idwbuff(2)%beg + 1)*(idwbuff(3)%end - idwbuff(3)%beg + 1)*sys_size + call hipCheck(hipMalloc_(cptr_device, pool_size*2_8)) + call c_f_pointer(cptr_device, q_cons_ts_pool_device, shape=pool_dims) + q_cons_ts_pool_device(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:) => q_cons_ts_pool_device + + call hipCheck(hipMallocManaged_(cptr_host, pool_size*2_8, hipMemAttachGlobal)) + call c_f_pointer(cptr_host, q_cons_ts_pool_host, shape=pool_dims) + q_cons_ts_pool_host(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:) => q_cons_ts_pool_host +#else + ! Doing hipMalloc then mapping should be most performant + call hipCheck(hipMalloc(q_cons_ts_pool_device, dims8=pool_dims, lbounds8=pool_starts)) + ! Without this map CCE will still create a device copy, because it's silly like that +#if defined(MFC_OpenACC) + call acc_map_data(q_cons_ts_pool_device, c_loc(q_cons_ts_pool_device), c_sizeof(q_cons_ts_pool_device)) +#endif + ! CCE see it can access this and will leave it on the host. It will stay on the host so long as HSA_XNACK=1 + ! NOTE: WE CANNOT DO ATOMICS INTO THIS MEMORY. We have to change a property to use atomics here + ! Otherwise leaving this as fine-grained will actually help performance since it can't be cached in GPU L2 + if (num_ts == 2) then + call hipCheck(hipMallocManaged(q_cons_ts_pool_host, dims8=pool_dims, lbounds8=pool_starts, flags=hipMemAttachGlobal)) +#if defined(MFC_OpenMP) + call hipCheck(hipMemAdvise(c_loc(q_cons_ts_pool_host), c_sizeof(q_cons_ts_pool_host), hipMemAdviseSetPreferredLocation, -1)) +#endif + end if +#endif + + do j = 1, sys_size + ! q_cons_ts(1) lives on the device + q_cons_ts(1)%vf(j)%sf(idwbuff(1)%beg:idwbuff(1)%end, & + idwbuff(2)%beg:idwbuff(2)%end, & + idwbuff(3)%beg:idwbuff(3)%end) => q_cons_ts_pool_device(:, :, :, j) + if (num_ts == 2) then + ! q_cons_ts(2) lives on the host + q_cons_ts(2)%vf(j)%sf(idwbuff(1)%beg:idwbuff(1)%end, & + idwbuff(2)%beg:idwbuff(2)%end, & + idwbuff(3)%beg:idwbuff(3)%end) => q_cons_ts_pool_host(:, :, :, j) + end if + end do + + do i = 1, num_ts + @:ACC_SETUP_VFs(q_cons_ts(i)) + do j = 1, sys_size + $:GPU_UPDATE(device='[q_cons_ts(i)%vf(j)]') + end do + end do +#else +!> @endcond + do i = 1, num_ts + do j = 1, sys_size + @:ALLOCATE(q_cons_ts(i)%vf(j)%sf(idwbuff(1)%beg:idwbuff(1)%end, & + idwbuff(2)%beg:idwbuff(2)%end, & + idwbuff(3)%beg:idwbuff(3)%end)) + end do + @:ACC_SETUP_VFs(q_cons_ts(i)) + end do +!> @cond +#endif +!> @endcond + + ! Allocating the cell-average primitive ts variables + if (probe_wrt) then + @:ALLOCATE(q_prim_ts1(1:num_probe_ts)) + + do i = 1, num_probe_ts + @:ALLOCATE(q_prim_ts1(i)%vf(1:sys_size)) + end do + + do i = 1, num_probe_ts + do j = 1, sys_size + @:ALLOCATE(q_prim_ts1(i)%vf(j)%sf(idwbuff(1)%beg:idwbuff(1)%end, & + idwbuff(2)%beg:idwbuff(2)%end, & + idwbuff(3)%beg:idwbuff(3)%end)) + end do + @:ACC_SETUP_VFs(q_prim_ts1(i)) + end do + + @:ALLOCATE(q_prim_ts2(1:num_probe_ts)) + + do i = 1, num_probe_ts + @:ALLOCATE(q_prim_ts2(i)%vf(1:sys_size)) + end do + + do i = 1, num_probe_ts + do j = 1, sys_size + @:ALLOCATE(q_prim_ts2(i)%vf(j)%sf(idwbuff(1)%beg:idwbuff(1)%end, & + idwbuff(2)%beg:idwbuff(2)%end, & + idwbuff(3)%beg:idwbuff(3)%end)) + end do + @:ACC_SETUP_VFs(q_prim_ts2(i)) + end do + end if + + ! Allocating the cell-average primitive variables + @:ALLOCATE(q_prim_vf(1:sys_size)) + + if (.not. igr) then + do i = 1, adv_idx%end + @:ALLOCATE(q_prim_vf(i)%sf(idwbuff(1)%beg:idwbuff(1)%end, & + idwbuff(2)%beg:idwbuff(2)%end, & + idwbuff(3)%beg:idwbuff(3)%end)) + @:ACC_SETUP_SFs(q_prim_vf(i)) + end do + + if (bubbles_euler) then + do i = bub_idx%beg, bub_idx%end + @:ALLOCATE(q_prim_vf(i)%sf(idwbuff(1)%beg:idwbuff(1)%end, & + idwbuff(2)%beg:idwbuff(2)%end, & + idwbuff(3)%beg:idwbuff(3)%end)) + @:ACC_SETUP_SFs(q_prim_vf(i)) + end do + if (adv_n) then + @:ALLOCATE(q_prim_vf(n_idx)%sf(idwbuff(1)%beg:idwbuff(1)%end, & + idwbuff(2)%beg:idwbuff(2)%end, & + idwbuff(3)%beg:idwbuff(3)%end)) + @:ACC_SETUP_SFs(q_prim_vf(n_idx)) + end if + end if + + if (mhd) then + do i = B_idx%beg, B_idx%end + @:ALLOCATE(q_prim_vf(i)%sf(idwbuff(1)%beg:idwbuff(1)%end, & + idwbuff(2)%beg:idwbuff(2)%end, & + idwbuff(3)%beg:idwbuff(3)%end)) + @:ACC_SETUP_SFs(q_prim_vf(i)) + end do + end if + + if (elasticity) then + do i = stress_idx%beg, stress_idx%end + @:ALLOCATE(q_prim_vf(i)%sf(idwbuff(1)%beg:idwbuff(1)%end, & + idwbuff(2)%beg:idwbuff(2)%end, & + idwbuff(3)%beg:idwbuff(3)%end)) + @:ACC_SETUP_SFs(q_prim_vf(i)) + end do + end if + + if (hyperelasticity) then + do i = xibeg, xiend + 1 + @:ALLOCATE(q_prim_vf(i)%sf(idwbuff(1)%beg:idwbuff(1)%end, & + idwbuff(2)%beg:idwbuff(2)%end, & + idwbuff(3)%beg:idwbuff(3)%end)) + @:ACC_SETUP_SFs(q_prim_vf(i)) + end do + end if + + if (cont_damage) then + @:ALLOCATE(q_prim_vf(damage_idx)%sf(idwbuff(1)%beg:idwbuff(1)%end, & + idwbuff(2)%beg:idwbuff(2)%end, & + idwbuff(3)%beg:idwbuff(3)%end)) + @:ACC_SETUP_SFs(q_prim_vf(damage_idx)) + end if + + if (hyper_cleaning) then + @:ALLOCATE(q_prim_vf(psi_idx)%sf(idwbuff(1)%beg:idwbuff(1)%end, & + idwbuff(2)%beg:idwbuff(2)%end, & + idwbuff(3)%beg:idwbuff(3)%end)) + @:ACC_SETUP_SFs(q_prim_vf(psi_idx)) + end if + + if (model_eqns == 3) then + do i = internalEnergies_idx%beg, internalEnergies_idx%end + @:ALLOCATE(q_prim_vf(i)%sf(idwbuff(1)%beg:idwbuff(1)%end, & + idwbuff(2)%beg:idwbuff(2)%end, & + idwbuff(3)%beg:idwbuff(3)%end)) + @:ACC_SETUP_SFs(q_prim_vf(i)) + end do + end if + + if (surface_tension) then + @:ALLOCATE(q_prim_vf(c_idx)%sf(idwbuff(1)%beg:idwbuff(1)%end, & + idwbuff(2)%beg:idwbuff(2)%end, & + idwbuff(3)%beg:idwbuff(3)%end)) + @:ACC_SETUP_SFs(q_prim_vf(c_idx)) + end if + + if (chemistry) then + do i = chemxb, chemxe + @:ALLOCATE(q_prim_vf(i)%sf(idwbuff(1)%beg:idwbuff(1)%end, & + idwbuff(2)%beg:idwbuff(2)%end, & + idwbuff(3)%beg:idwbuff(3)%end)) + @:ACC_SETUP_SFs(q_prim_vf(i)) + end do + + @:ALLOCATE(q_T_sf%sf(idwbuff(1)%beg:idwbuff(1)%end, & + idwbuff(2)%beg:idwbuff(2)%end, & + idwbuff(3)%beg:idwbuff(3)%end)) + @:ACC_SETUP_SFs(q_T_sf) + end if + end if + + @:ALLOCATE(pb_ts(1:2)) + !Initialize bubble variables pb and mv at all quadrature nodes for all R0 bins + if (qbmm .and. (.not. polytropic)) then + @:ALLOCATE(pb_ts(1)%sf(idwbuff(1)%beg:idwbuff(1)%end, & + idwbuff(2)%beg:idwbuff(2)%end, & + idwbuff(3)%beg:idwbuff(3)%end, 1:nnode, 1:nb)) + @:ACC_SETUP_SFs(pb_ts(1)) + + @:ALLOCATE(pb_ts(2)%sf(idwbuff(1)%beg:idwbuff(1)%end, & + idwbuff(2)%beg:idwbuff(2)%end, & + idwbuff(3)%beg:idwbuff(3)%end, 1:nnode, 1:nb)) + @:ACC_SETUP_SFs(pb_ts(2)) + + @:ALLOCATE(rhs_pb(idwbuff(1)%beg:idwbuff(1)%end, & + idwbuff(2)%beg:idwbuff(2)%end, & + idwbuff(3)%beg:idwbuff(3)%end, 1:nnode, 1:nb)) + else if (qbmm .and. polytropic) then + @:ALLOCATE(pb_ts(1)%sf(idwbuff(1)%beg:idwbuff(1)%beg + 1, & + idwbuff(2)%beg:idwbuff(2)%beg + 1, & + idwbuff(3)%beg:idwbuff(3)%beg + 1, 1:nnode, 1:nb)) + @:ACC_SETUP_SFs(pb_ts(1)) + + @:ALLOCATE(pb_ts(2)%sf(idwbuff(1)%beg:idwbuff(1)%beg + 1, & + idwbuff(2)%beg:idwbuff(2)%beg + 1, & + idwbuff(3)%beg:idwbuff(3)%beg + 1, 1:nnode, 1:nb)) + @:ACC_SETUP_SFs(pb_ts(2)) + + @:ALLOCATE(rhs_pb(idwbuff(1)%beg:idwbuff(1)%beg + 1, & + idwbuff(2)%beg:idwbuff(2)%beg + 1, & + idwbuff(3)%beg:idwbuff(3)%beg + 1, 1:nnode, 1:nb)) + else + @:ALLOCATE(pb_ts(1)%sf(0,0,0,0,0)) + @:ACC_SETUP_SFs(pb_ts(1)) + + @:ALLOCATE(pb_ts(2)%sf(0,0,0,0,0)) + @:ACC_SETUP_SFs(pb_ts(2)) + + @:ALLOCATE(rhs_pb(0,0,0,0,0)) + end if + + @:ALLOCATE(mv_ts(1:2)) + + if (qbmm .and. (.not. polytropic)) then + @:ALLOCATE(mv_ts(1)%sf(idwbuff(1)%beg:idwbuff(1)%end, & + idwbuff(2)%beg:idwbuff(2)%end, & + idwbuff(3)%beg:idwbuff(3)%end, 1:nnode, 1:nb)) + @:ACC_SETUP_SFs(mv_ts(1)) + + @:ALLOCATE(mv_ts(2)%sf(idwbuff(1)%beg:idwbuff(1)%end, & + idwbuff(2)%beg:idwbuff(2)%end, & + idwbuff(3)%beg:idwbuff(3)%end, 1:nnode, 1:nb)) + @:ACC_SETUP_SFs(mv_ts(2)) + + @:ALLOCATE(rhs_mv(idwbuff(1)%beg:idwbuff(1)%end, & + idwbuff(2)%beg:idwbuff(2)%end, & + idwbuff(3)%beg:idwbuff(3)%end, 1:nnode, 1:nb)) + + else if (qbmm .and. polytropic) then + @:ALLOCATE(mv_ts(1)%sf(idwbuff(1)%beg:idwbuff(1)%beg + 1, & + idwbuff(2)%beg:idwbuff(2)%beg + 1, & + idwbuff(3)%beg:idwbuff(3)%beg + 1, 1:nnode, 1:nb)) + @:ACC_SETUP_SFs(mv_ts(1)) + + @:ALLOCATE(mv_ts(2)%sf(idwbuff(1)%beg:idwbuff(1)%beg + 1, & + idwbuff(2)%beg:idwbuff(2)%beg + 1, & + idwbuff(3)%beg:idwbuff(3)%beg + 1, 1:nnode, 1:nb)) + @:ACC_SETUP_SFs(mv_ts(2)) + + @:ALLOCATE(rhs_mv(idwbuff(1)%beg:idwbuff(1)%beg + 1, & + idwbuff(2)%beg:idwbuff(2)%beg + 1, & + idwbuff(3)%beg:idwbuff(3)%beg + 1, 1:nnode, 1:nb)) + else + @:ALLOCATE(mv_ts(1)%sf(0,0,0,0,0)) + @:ACC_SETUP_SFs(mv_ts(1)) + + @:ALLOCATE(mv_ts(2)%sf(0,0,0,0,0)) + @:ACC_SETUP_SFs(mv_ts(2)) + + @:ALLOCATE(rhs_mv(0,0,0,0,0)) + end if + + ! Allocating the cell-average RHS variables + @:ALLOCATE(rhs_vf(1:sys_size)) + @:PREFER_GPU(rhs_vf) + + if (igr) then + do i = 1, sys_size + @:ALLOCATE(rhs_vf(i)%sf(-1:m+1,-1:n+1,-1:p+1)) + @:ACC_SETUP_SFs(rhs_vf(i)) + @:PREFER_GPU(rhs_vf(i)%sf) + end do + else + do i = 1, sys_size + @:ALLOCATE(rhs_vf(i)%sf(0:m, 0:n, 0:p)) + @:ACC_SETUP_SFs(rhs_vf(i)) + end do + end if + + ! Opening and writing the header of the run-time information file + if (proc_rank == 0 .and. run_time_info) then + call s_open_run_time_information_file() + end if + + if (cfl_dt) then + @:ALLOCATE(max_dt(0:m, 0:n, 0:p)) + end if + + ! Allocating arrays to store the bc types + @:ALLOCATE(bc_type(1:num_dims,1:2)) + + @:ALLOCATE(bc_type(1,1)%sf(0:0,0:n,0:p)) + @:ALLOCATE(bc_type(1,2)%sf(0:0,0:n,0:p)) + #:if not MFC_CASE_OPTIMIZATION or num_dims > 1 + if (n > 0) then + @:ALLOCATE(bc_type(2,1)%sf(-buff_size:m+buff_size,0:0,0:p)) + @:ALLOCATE(bc_type(2,2)%sf(-buff_size:m+buff_size,0:0,0:p)) + #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 + if (p > 0) then + @:ALLOCATE(bc_type(3,1)%sf(-buff_size:m+buff_size,-buff_size:n+buff_size,0:0)) + @:ALLOCATE(bc_type(3,2)%sf(-buff_size:m+buff_size,-buff_size:n+buff_size,0:0)) + end if + #:endif + end if + #:endif + + do i = 1, num_dims + do j = 1, 2 + @:ACC_SETUP_SFs(bc_type(i,j)) + end do + end do + + if (any(time_stepper == (/1, 2, 3/))) then + ! temporary array index for TVD RK + if (time_stepper == 1) then + stor = 1 + else + stor = 2 + end if + + ! TVD RK coefficients + @:ALLOCATE (rk_coef(time_stepper, 4)) + if (time_stepper == 1) then + rk_coef(1, :) = (/1._wp, 0._wp, 1._wp, 1._wp/) + else if (time_stepper == 2) then + rk_coef(1, :) = (/1._wp, 0._wp, 1._wp, 1._wp/) + rk_coef(2, :) = (/1._wp, 1._wp, 1._wp, 2._wp/) + else if (time_stepper == 3) then + rk_coef(1, :) = (/1._wp, 0._wp, 1._wp, 1._wp/) + rk_coef(2, :) = (/1._wp, 3._wp, 1._wp, 4._wp/) + rk_coef(3, :) = (/2._wp, 1._wp, 2._wp, 3._wp/) + end if + $:GPU_UPDATE(device='[rk_coef, stor]') + end if + + end subroutine s_initialize_time_steppers_module + + !> @brief Advances the solution one full step using a TVD Runge-Kutta time integrator. + impure subroutine s_tvd_rk(t_step, time_avg, nstage) +#ifdef _CRAYFTN + !DIR$ OPTIMIZE (-haggress) +#endif + integer, intent(in) :: t_step + real(wp), intent(inout) :: time_avg + integer, intent(in) :: nstage + + integer :: i, j, k, l, q, s !< Generic loop iterator + real(wp) :: start, finish + integer :: dest + + call cpu_time(start) + call nvtxStartRange("TIMESTEP") + + ! Adaptive dt: initial stage + if (adap_dt) call s_adaptive_dt_bubble(1) + + do s = 1, nstage + call s_compute_rhs(q_cons_ts(1)%vf, q_T_sf, q_prim_vf, bc_type, rhs_vf, pb_ts(1)%sf, rhs_pb, mv_ts(1)%sf, rhs_mv, t_step, time_avg, s) + + if (s == 1) then + if (run_time_info) then + if (igr .or. dummy) then + call s_write_run_time_information(q_cons_ts(1)%vf, t_step) + end if + if (.not. igr .or. dummy) then + call s_write_run_time_information(q_prim_vf, t_step) + end if + end if + + if (probe_wrt) then + call s_time_step_cycling(t_step) + call s_compute_derived_variables(t_step, q_cons_ts(1)%vf, q_prim_ts1, q_prim_ts2) + end if + + if (cfl_dt) then + if (mytime >= t_stop) return + else + if (t_step == t_step_stop) return + end if + end if + + if (bubbles_lagrange .and. .not. adap_dt) call s_update_lagrange_tdv_rk(stage=s) + $:GPU_PARALLEL_LOOP(collapse=4) + do i = 1, sys_size + do l = 0, p + do k = 0, n + do j = 0, m + if (s == 1 .and. nstage > 1) then + q_cons_ts(stor)%vf(i)%sf(j, k, l) = & + q_cons_ts(1)%vf(i)%sf(j, k, l) + end if + if (igr) then + q_cons_ts(1)%vf(i)%sf(j, k, l) = & + (rk_coef(s, 1)*q_cons_ts(1)%vf(i)%sf(j, k, l) & + + rk_coef(s, 2)*q_cons_ts(stor)%vf(i)%sf(j, k, l) & + + rk_coef(s, 3)*rhs_vf(i)%sf(j, k, l))/rk_coef(s, 4) + else + q_cons_ts(1)%vf(i)%sf(j, k, l) = & + (rk_coef(s, 1)*q_cons_ts(1)%vf(i)%sf(j, k, l) & + + rk_coef(s, 2)*q_cons_ts(stor)%vf(i)%sf(j, k, l) & + + rk_coef(s, 3)*dt*rhs_vf(i)%sf(j, k, l))/rk_coef(s, 4) + end if + end do + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + !Evolve pb and mv for non-polytropic qbmm + if (qbmm .and. (.not. polytropic)) then + $:GPU_PARALLEL_LOOP(collapse=5) + do i = 1, nb + do l = 0, p + do k = 0, n + do j = 0, m + do q = 1, nnode + if (s == 1 .and. nstage > 1) then + pb_ts(stor)%sf(j, k, l, q, i) = & + pb_ts(1)%sf(j, k, l, q, i) + mv_ts(stor)%sf(j, k, l, q, i) = & + mv_ts(1)%sf(j, k, l, q, i) + end if + pb_ts(1)%sf(j, k, l, q, i) = & + (rk_coef(s, 1)*pb_ts(1)%sf(j, k, l, q, i) & + + rk_coef(s, 2)*pb_ts(stor)%sf(j, k, l, q, i) & + + rk_coef(s, 3)*dt*rhs_pb(j, k, l, q, i))/rk_coef(s, 4) + mv_ts(1)%sf(j, k, l, q, i) = & + (rk_coef(s, 1)*mv_ts(1)%sf(j, k, l, q, i) & + + rk_coef(s, 2)*mv_ts(stor)%sf(j, k, l, q, i) & + + rk_coef(s, 3)*dt*rhs_mv(j, k, l, q, i))/rk_coef(s, 4) + end do + end do + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + end if + + if (bodyForces) call s_apply_bodyforces(q_cons_ts(1)%vf, q_prim_vf, rhs_vf, rk_coef(s, 3)*dt/rk_coef(s, 4)) + + if (grid_geometry == 3) call s_apply_fourier_filter(q_cons_ts(1)%vf) + + if (model_eqns == 3 .and. (.not. relax)) then + call s_pressure_relaxation_procedure(q_cons_ts(1)%vf) + end if + + if (adv_n) call s_comp_alpha_from_n(q_cons_ts(1)%vf) + + if (ib) then + ! check if any IBMS are moving, and if so, update the markers, ghost points, levelsets, and levelset norms + if (moving_immersed_boundary_flag) then + call s_propagate_immersed_boundaries(s) + end if + + ! update the ghost fluid properties point values based on IB state + if (qbmm .and. .not. polytropic) then + call s_ibm_correct_state(q_cons_ts(1)%vf, q_prim_vf, pb_ts(1)%sf, mv_ts(1)%sf) + else + call s_ibm_correct_state(q_cons_ts(1)%vf, q_prim_vf) + end if + end if + + end do + + if (moving_immersed_boundary_flag) call s_wrap_periodic_ibs() + + ! Adaptive dt: final stage + if (adap_dt) call s_adaptive_dt_bubble(3) + + call nvtxEndRange + call cpu_time(finish) + + wall_time = abs(finish - start) + + if (t_step >= 2) then + wall_time_avg = (wall_time + (t_step - 2)*wall_time_avg)/(t_step - 1) + else + wall_time_avg = 0._wp + end if + + end subroutine s_tvd_rk + + !> Bubble source part in Strang operator splitting scheme + !! @param stage Current time-stage + impure subroutine s_adaptive_dt_bubble(stage) + + integer, intent(in) :: stage + + type(vector_field) :: gm_alpha_qp + + call s_convert_conservative_to_primitive_variables( & + q_cons_ts(1)%vf, & + q_T_sf, & + q_prim_vf, & + idwint) + + if (bubbles_euler) then + + call s_compute_bubble_EE_source(q_cons_ts(1)%vf, q_prim_vf, rhs_vf, divu) + call s_comp_alpha_from_n(q_cons_ts(1)%vf) + + elseif (bubbles_lagrange) then + + call s_populate_variables_buffers(bc_type, q_prim_vf, pb_ts(1)%sf, mv_ts(1)%sf) + call s_compute_bubble_EL_dynamics(q_prim_vf, stage) + call s_transfer_data_to_tmp() + call s_smear_voidfraction() + if (stage == 3) then + if (lag_params%write_bubbles_stats) call s_calculate_lag_bubble_stats() + if (lag_params%write_bubbles) then + $:GPU_UPDATE(host='[gas_p,gas_mv,intfc_rad,intfc_vel]') + call s_write_lag_particles(mytime) + end if + call s_write_void_evol(mytime) + end if + + end if + + end subroutine s_adaptive_dt_bubble + + !> @brief Computes the global time step size from CFL stability constraints across all cells. + impure subroutine s_compute_dt() + + real(wp) :: rho !< Cell-avg. density + #:if not MFC_CASE_OPTIMIZATION and USING_AMD + real(wp), dimension(3) :: vel !< Cell-avg. velocity + real(wp), dimension(3) :: alpha !< Cell-avg. volume fraction + real(wp), dimension(3, 2) :: Re_visc_per_phase !< Per-phase Re_visc + #:else + real(wp), dimension(num_vels) :: vel !< Cell-avg. velocity + real(wp), dimension(num_fluids) :: alpha !< Cell-avg. volume fraction + real(wp), dimension(num_fluids, 2) :: Re_visc_per_phase !< Per-phase Re_visc + #:endif + real(wp) :: vel_sum !< Cell-avg. velocity sum + real(wp) :: pres !< Cell-avg. pressure + real(wp) :: gamma !< Cell-avg. sp. heat ratio + real(wp) :: pi_inf !< Cell-avg. liquid stiffness function + real(wp) :: qv !< Cell-avg. fluid reference energy + real(wp) :: c !< Cell-avg. sound speed + real(wp) :: H !< Cell-avg. enthalpy + real(wp), dimension(2) :: Re !< Cell-avg. Reynolds numbers + type(vector_field) :: gm_alpha_qp + + real(wp) :: dt_local + integer :: j, k, l !< Generic loop iterators + + if (.not. igr .or. dummy) then + call s_convert_conservative_to_primitive_variables( & + q_cons_ts(1)%vf, & + q_T_sf, & + q_prim_vf, & + idwint) + end if + + $:GPU_PARALLEL_LOOP(collapse=3, private='[vel, alpha, Re, Re_visc_per_phase, rho, vel_sum, pres, gamma, pi_inf, c, H, qv]') + do l = 0, p + do k = 0, n + do j = 0, m + if (igr) then + call s_compute_enthalpy(q_cons_ts(1)%vf, pres, rho, gamma, pi_inf, Re, H, alpha, vel, vel_sum, qv, j, k, l) + else + call s_compute_enthalpy(q_prim_vf, pres, rho, gamma, pi_inf, Re, H, alpha, vel, vel_sum, qv, j, k, l) + end if + + ! For non-Newtonian fluids, compute variable Re based on shear rate + if (any_non_newtonian) then + if (igr) then + call s_compute_re_visc(q_cons_ts(1)%vf, alpha, j, k, l, Re_visc_per_phase) + else + call s_compute_re_visc(q_prim_vf, alpha, j, k, l, Re_visc_per_phase) + end if + call s_compute_mixture_re(alpha, Re_visc_per_phase, Re) + end if + + ! Compute mixture sound speed + call s_compute_speed_of_sound(pres, rho, gamma, pi_inf, H, alpha, vel_sum, 0._wp, c, qv) + + call s_compute_dt_from_cfl(vel, c, max_dt, rho, Re, j, k, l) + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + + #:call GPU_PARALLEL(copyout='[dt_local]', copyin='[max_dt]') + dt_local = minval(max_dt) + #:endcall GPU_PARALLEL + + if (num_procs == 1) then + dt = dt_local + else + call s_mpi_allreduce_min(dt_local, dt) + end if + + $:GPU_UPDATE(device='[dt]') + + end subroutine s_compute_dt + + !> This subroutine applies the body forces source term at each + !! Runge-Kutta stage + !! @param q_cons_vf Conservative variables + !! @param q_prim_vf_in Primitive variables + !! @param rhs_vf_in Right-hand side variables + subroutine s_apply_bodyforces(q_cons_vf, q_prim_vf_in, rhs_vf_in, ldt) + + type(scalar_field), dimension(1:sys_size), intent(inout) :: q_cons_vf + type(scalar_field), dimension(1:sys_size), intent(in) :: q_prim_vf_in + type(scalar_field), dimension(1:sys_size), intent(inout) :: rhs_vf_in + + real(wp), intent(in) :: ldt !< local dt + + integer :: i, j, k, l + + call nvtxStartRange("RHS-BODYFORCES") + call s_compute_body_forces_rhs(q_prim_vf_in, q_cons_vf, rhs_vf_in) + + $:GPU_PARALLEL_LOOP(collapse=4) + do i = momxb, E_idx + do l = 0, p + do k = 0, n + do j = 0, m + q_cons_vf(i)%sf(j, k, l) = q_cons_vf(i)%sf(j, k, l) + & + ldt*rhs_vf_in(i)%sf(j, k, l) + end do + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + + call nvtxEndRange + + end subroutine s_apply_bodyforces + + !> @brief Updates immersed boundary positions and velocities at the current Runge-Kutta stage. + subroutine s_propagate_immersed_boundaries(s) + + integer, intent(in) :: s + integer :: i + logical :: forces_computed + + call nvtxStartRange("PROPAGATE-IMMERSED-BOUNDARIES") + + forces_computed = .false. + + do i = 1, num_ibs + if (s == 1) then + patch_ib(i)%step_vel = patch_ib(i)%vel + patch_ib(i)%step_angular_vel = patch_ib(i)%angular_vel + patch_ib(i)%step_angles = patch_ib(i)%angles + patch_ib(i)%step_x_centroid = patch_ib(i)%x_centroid + patch_ib(i)%step_y_centroid = patch_ib(i)%y_centroid + patch_ib(i)%step_z_centroid = patch_ib(i)%z_centroid + end if + + if (patch_ib(i)%moving_ibm > 0) then + patch_ib(i)%vel = (rk_coef(s, 1)*patch_ib(i)%step_vel + rk_coef(s, 2)*patch_ib(i)%vel)/rk_coef(s, 4) + patch_ib(i)%angular_vel = (rk_coef(s, 1)*patch_ib(i)%step_angular_vel + rk_coef(s, 2)*patch_ib(i)%angular_vel)/rk_coef(s, 4) + + if (patch_ib(i)%moving_ibm == 1) then + ! plug in analytic velocities for 1-way coupling, if it exists + @:mib_analytical() + else if (patch_ib(i)%moving_ibm == 2) then ! if we are using two-way coupling, apply force and torque + ! compute the force and torque on the IB from the fluid + if (.not. forces_computed) then + call s_compute_ib_forces(q_prim_vf, fluid_pp) + forces_computed = .true. + end if + + ! update the velocity from the force value + patch_ib(i)%vel = patch_ib(i)%vel + rk_coef(s, 3)*dt*(patch_ib(i)%force/patch_ib(i)%mass)/rk_coef(s, 4) + + ! update the angular velocity with the torque value + patch_ib(i)%angular_vel = (patch_ib(i)%angular_vel*patch_ib(i)%moment) + (rk_coef(s, 3)*dt*patch_ib(i)%torque/rk_coef(s, 4)) ! add the torque to the angular momentum + call s_compute_moment_of_inertia(i, patch_ib(i)%angular_vel) ! update the moment of inertia to be based on the direction of the angular momentum + patch_ib(i)%angular_vel = patch_ib(i)%angular_vel/patch_ib(i)%moment ! convert back to angular velocity with the new moment of inertia + end if + + ! Update the angle of the IB + patch_ib(i)%angles = (rk_coef(s, 1)*patch_ib(i)%step_angles + rk_coef(s, 2)*patch_ib(i)%angles + rk_coef(s, 3)*patch_ib(i)%angular_vel*dt)/rk_coef(s, 4) + + ! Update the position of the IB + patch_ib(i)%x_centroid = (rk_coef(s, 1)*patch_ib(i)%step_x_centroid + rk_coef(s, 2)*patch_ib(i)%x_centroid + rk_coef(s, 3)*patch_ib(i)%vel(1)*dt)/rk_coef(s, 4) + patch_ib(i)%y_centroid = (rk_coef(s, 1)*patch_ib(i)%step_y_centroid + rk_coef(s, 2)*patch_ib(i)%y_centroid + rk_coef(s, 3)*patch_ib(i)%vel(2)*dt)/rk_coef(s, 4) + patch_ib(i)%z_centroid = (rk_coef(s, 1)*patch_ib(i)%step_z_centroid + rk_coef(s, 2)*patch_ib(i)%z_centroid + rk_coef(s, 3)*patch_ib(i)%vel(3)*dt)/rk_coef(s, 4) + end if + end do + + call s_update_mib(num_ibs) + + call nvtxEndRange + + end subroutine s_propagate_immersed_boundaries + + !> This subroutine saves the temporary q_prim_vf vector + !! into the q_prim_ts vector that is then used in p_main + !! @param t_step current time-step + subroutine s_time_step_cycling(t_step) + + integer, intent(in) :: t_step + + integer :: i, j, k, l !< Generic loop iterator + + if (t_step == t_step_start) then + $:GPU_PARALLEL_LOOP(collapse=4) + do i = 1, sys_size + do l = 0, p + do k = 0, n + do j = 0, m + q_prim_ts2(2)%vf(i)%sf(j, k, l) = q_prim_vf(i)%sf(j, k, l) + end do + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + elseif (t_step == t_step_start + 1) then + $:GPU_PARALLEL_LOOP(collapse=4) + do i = 1, sys_size + do l = 0, p + do k = 0, n + do j = 0, m + q_prim_ts2(1)%vf(i)%sf(j, k, l) = q_prim_vf(i)%sf(j, k, l) + end do + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + elseif (t_step == t_step_start + 2) then + $:GPU_PARALLEL_LOOP(collapse=4) + do i = 1, sys_size + do l = 0, p + do k = 0, n + do j = 0, m + q_prim_ts1(2)%vf(i)%sf(j, k, l) = q_prim_vf(i)%sf(j, k, l) + end do + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + elseif (t_step == t_step_start + 3) then + $:GPU_PARALLEL_LOOP(collapse=4) + do i = 1, sys_size + do l = 0, p + do k = 0, n + do j = 0, m + q_prim_ts1(1)%vf(i)%sf(j, k, l) = q_prim_vf(i)%sf(j, k, l) + end do + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + else ! All other timesteps + $:GPU_PARALLEL_LOOP(collapse=4) + do i = 1, sys_size + do l = 0, p + do k = 0, n + do j = 0, m + q_prim_ts2(2)%vf(i)%sf(j, k, l) = q_prim_ts2(1)%vf(i)%sf(j, k, l) + q_prim_ts2(1)%vf(i)%sf(j, k, l) = q_prim_ts1(2)%vf(i)%sf(j, k, l) + q_prim_ts1(2)%vf(i)%sf(j, k, l) = q_prim_ts1(1)%vf(i)%sf(j, k, l) + q_prim_ts1(1)%vf(i)%sf(j, k, l) = q_prim_vf(i)%sf(j, k, l) + end do + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + end if + + end subroutine s_time_step_cycling + + !> Module deallocation and/or disassociation procedures + impure subroutine s_finalize_time_steppers_module +#ifdef FRONTIER_UNIFIED + use hipfort + use hipfort_hipmalloc + use hipfort_check +#endif + integer :: i, j !< Generic loop iterators + + ! Deallocating the cell-average conservative variables +#if defined(__NVCOMPILER_GPU_UNIFIED_MEM) + do j = 1, sys_size + @:DEALLOCATE(q_cons_ts(1)%vf(j)%sf) + if (num_ts == 2) then + if (nv_uvm_out_of_core) then + nullify (q_cons_ts(2)%vf(j)%sf) + else + @:DEALLOCATE(q_cons_ts(2)%vf(j)%sf) + end if + end if + end do + if (num_ts == 2 .and. nv_uvm_out_of_core) then + deallocate (q_cons_ts_pool_host) + end if +#elif defined(FRONTIER_UNIFIED) + do i = 1, num_ts + do j = 1, sys_size + nullify (q_cons_ts(i)%vf(j)%sf) + end do + end do +#ifdef MFC_MIXED_PRECISION + call hipCheck(hipHostFree_(c_loc(q_cons_ts_pool_host))) + nullify (q_cons_ts_pool_host) + call hipCheck(hipFree_(c_loc(q_cons_ts_pool_device))) + nullify (q_cons_ts_pool_device) +#else + call hipCheck(hipHostFree(q_cons_ts_pool_host)) + call hipCheck(hipFree(q_cons_ts_pool_device)) +#endif +#else + do i = 1, num_ts + do j = 1, sys_size + @:DEALLOCATE(q_cons_ts(i)%vf(j)%sf) + end do + end do +#endif + do i = 1, num_ts + @:DEALLOCATE(q_cons_ts(i)%vf) + end do + + @:DEALLOCATE(q_cons_ts) + + ! Deallocating the cell-average primitive ts variables + if (probe_wrt) then + do i = 1, num_probe_ts + do j = 1, sys_size + @:DEALLOCATE(q_prim_ts1(i)%vf(j)%sf,q_prim_ts2(i)%vf(j)%sf ) + end do + @:DEALLOCATE(q_prim_ts1(i)%vf, q_prim_ts2(i)%vf) + end do + @:DEALLOCATE(q_prim_ts1, q_prim_ts2) + end if + + if (.not. igr) then + ! Deallocating the cell-average primitive variables + do i = 1, adv_idx%end + @:DEALLOCATE(q_prim_vf(i)%sf) + end do + + if (mhd) then + do i = B_idx%beg, B_idx%end + @:DEALLOCATE(q_prim_vf(i)%sf) + end do + end if + + if (elasticity) then + do i = stress_idx%beg, stress_idx%end + @:DEALLOCATE(q_prim_vf(i)%sf) + end do + end if + + if (hyperelasticity) then + do i = xibeg, xiend + 1 + @:DEALLOCATE(q_prim_vf(i)%sf) + end do + end if + + if (cont_damage) then + @:DEALLOCATE(q_prim_vf(damage_idx)%sf) + end if + + if (hyper_cleaning) then + @:DEALLOCATE(q_prim_vf(psi_idx)%sf) + end if + + if (bubbles_euler) then + do i = bub_idx%beg, bub_idx%end + @:DEALLOCATE(q_prim_vf(i)%sf) + end do + end if + + if (model_eqns == 3) then + do i = internalEnergies_idx%beg, internalEnergies_idx%end + @:DEALLOCATE(q_prim_vf(i)%sf) + end do + end if + end if + + @:DEALLOCATE(q_prim_vf) + + ! Deallocating the cell-average RHS variables + do i = 1, sys_size + @:DEALLOCATE(rhs_vf(i)%sf) + end do + + @:DEALLOCATE(rhs_vf) + + ! Writing the footer of and closing the run-time information file + if (proc_rank == 0 .and. run_time_info) then + call s_close_run_time_information_file() + end if + + end subroutine s_finalize_time_steppers_module + +end module m_time_steppers diff --git a/src/simulation/m_viscous.fpp b/src/simulation/m_viscous.fpp index 6b1d9dbdf2..23e3b9e8fa 100644 --- a/src/simulation/m_viscous.fpp +++ b/src/simulation/m_viscous.fpp @@ -1,1622 +1,1578 @@ -!> -!! @file -!! @brief Contains module m_viscous -#:include 'case.fpp' -#:include 'macros.fpp' - -!> @brief Computes viscous stress tensors and diffusive flux contributions for the Navier--Stokes equations -module m_viscous - - use m_derived_types !< Definitions of the derived types - - use m_global_parameters !< Definitions of the global parameters - - use m_weno - - use m_muscl !< Monotonic Upstream-centered (MUSCL) - !! schemes for conservation laws - - use m_helper - - use m_finite_differences - - private; public s_get_viscous, & - s_compute_viscous_stress_cylindrical_boundary, & - s_initialize_viscous_module, & - s_reconstruct_cell_boundary_values_visc_deriv, & - s_finalize_viscous_module, & - s_compute_viscous_stress_tensor - - type(int_bounds_info) :: iv - type(int_bounds_info) :: is1_viscous, is2_viscous, is3_viscous - $:GPU_DECLARE(create='[is1_viscous,is2_viscous,is3_viscous,iv]') - - real(wp), allocatable, dimension(:, :) :: Res_viscous - $:GPU_DECLARE(create='[Res_viscous]') - -contains - - !> @brief Allocates and populates the viscous Reynolds number arrays and transfers data to the GPU. - impure subroutine s_initialize_viscous_module - - integer :: i, j !< generic loop iterators - - @:ALLOCATE(Res_viscous(1:2, 1:Re_size_max)) - - do i = 1, 2 - do j = 1, Re_size(i) - Res_viscous(i, j) = fluid_pp(Re_idx(i, j))%Re(i) - end do - end do - $:GPU_UPDATE(device='[Res_viscous,Re_idx,Re_size]') - $:GPU_ENTER_DATA(copyin='[is1_viscous,is2_viscous,is3_viscous,iv]') - - end subroutine s_initialize_viscous_module - - !> The purpose of this subroutine is to compute the viscous - ! stress tensor for the cells directly next to the axis in - ! cylindrical coordinates. This is necessary to avoid the - ! 1/r singularity that arises at the cell boundary coinciding - ! with the axis, i.e., y_cb(-1) = 0. - ! @param q_prim_vf Cell-average primitive variables - ! @param grad_x_vf Cell-average primitive variable derivatives, x-dir - ! @param grad_y_vf Cell-average primitive variable derivatives, y-dir - ! @param grad_z_vf Cell-average primitive variable derivatives, z-dir - subroutine s_compute_viscous_stress_cylindrical_boundary(q_prim_vf, grad_x_vf, grad_y_vf, grad_z_vf, & - tau_Re_vf, & - ix, iy, iz) - - type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf - type(scalar_field), dimension(num_dims), intent(in) :: grad_x_vf, grad_y_vf, grad_z_vf - type(scalar_field), dimension(1:sys_size), intent(inout) :: tau_Re_vf - type(int_bounds_info), intent(in) :: ix, iy, iz - - real(wp) :: rho_visc, gamma_visc, pi_inf_visc, alpha_visc_sum !< Mixture variables - real(wp), dimension(2) :: Re_visc - #:if not MFC_CASE_OPTIMIZATION and USING_AMD - real(wp), dimension(3) :: alpha_visc, alpha_rho_visc - real(wp), dimension(3, 3) :: tau_Re - #:else - real(wp), dimension(num_fluids) :: alpha_visc, alpha_rho_visc - real(wp), dimension(num_dims, num_dims) :: tau_Re - #:endif - - integer :: i, j, k, l, q !< Generic loop iterator - - is1_viscous = ix; is2_viscous = iy; is3_viscous = iz - - $:GPU_UPDATE(device='[is1_viscous,is2_viscous,is3_viscous]') - - $:GPU_PARALLEL_LOOP(collapse=3) - do l = is3_viscous%beg, is3_viscous%end - do k = is2_viscous%beg, is2_viscous%end - do j = is1_viscous%beg, is1_viscous%end - $:GPU_LOOP(parallelism='[seq]') - do i = momxb, E_idx - tau_Re_vf(i)%sf(j, k, l) = 0._wp - end do - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - - #:if not MFC_CASE_OPTIMIZATION or num_dims > 1 - if (shear_stress) then ! Shear stresses - $:GPU_PARALLEL_LOOP(collapse=3, private='[i,j,k,l,rho_visc, gamma_visc, pi_inf_visc, alpha_visc_sum ,alpha_visc, alpha_rho_visc, Re_visc, tau_Re]') - do l = is3_viscous%beg, is3_viscous%end - do k = -1, 1 - do j = is1_viscous%beg, is1_viscous%end - - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_fluids - alpha_rho_visc(i) = q_prim_vf(i)%sf(j, k, l) - if (bubbles_euler .and. num_fluids == 1) then - alpha_visc(i) = 1._wp - q_prim_vf(E_idx + i)%sf(j, k, l) - else - alpha_visc(i) = q_prim_vf(E_idx + i)%sf(j, k, l) - end if - end do - - if (bubbles_euler) then - rho_visc = 0._wp - gamma_visc = 0._wp - pi_inf_visc = 0._wp - - if (mpp_lim .and. (model_eqns == 2) .and. (num_fluids > 2)) then - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_fluids - rho_visc = rho_visc + alpha_rho_visc(i) - gamma_visc = gamma_visc + alpha_visc(i)*gammas(i) - pi_inf_visc = pi_inf_visc + alpha_visc(i)*pi_infs(i) - end do - else if ((model_eqns == 2) .and. (num_fluids > 2)) then - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_fluids - 1 - rho_visc = rho_visc + alpha_rho_visc(i) - gamma_visc = gamma_visc + alpha_visc(i)*gammas(i) - pi_inf_visc = pi_inf_visc + alpha_visc(i)*pi_infs(i) - end do - else - rho_visc = alpha_rho_visc(1) - gamma_visc = gammas(1) - pi_inf_visc = pi_infs(1) - end if - else - rho_visc = 0._wp - gamma_visc = 0._wp - pi_inf_visc = 0._wp - - alpha_visc_sum = 0._wp - - if (mpp_lim) then - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_fluids - alpha_rho_visc(i) = max(0._wp, alpha_rho_visc(i)) - alpha_visc(i) = min(max(0._wp, alpha_visc(i)), 1._wp) - alpha_visc_sum = alpha_visc_sum + alpha_visc(i) - end do - - alpha_visc = alpha_visc/max(alpha_visc_sum, sgm_eps) - - end if - - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_fluids - rho_visc = rho_visc + alpha_rho_visc(i) - gamma_visc = gamma_visc + alpha_visc(i)*gammas(i) - pi_inf_visc = pi_inf_visc + alpha_visc(i)*pi_infs(i) - end do - - if (viscous) then - $:GPU_LOOP(parallelism='[seq]') - do i = 1, 2 - Re_visc(i) = dflt_real - - if (Re_size(i) > 0) Re_visc(i) = 0._wp - $:GPU_LOOP(parallelism='[seq]') - do q = 1, Re_size(i) - Re_visc(i) = alpha_visc(Re_idx(i, q))/Res_viscous(i, q) & - + Re_visc(i) - end do - - Re_visc(i) = 1._wp/max(Re_visc(i), sgm_eps) - - end do - end if - end if - - tau_Re(2, 1) = (grad_y_vf(1)%sf(j, k, l) + & - grad_x_vf(2)%sf(j, k, l))/ & - Re_visc(1) - - tau_Re(2, 2) = (4._wp*grad_y_vf(2)%sf(j, k, l) & - - 2._wp*grad_x_vf(1)%sf(j, k, l) & - - 2._wp*q_prim_vf(momxb + 1)%sf(j, k, l)/y_cc(k))/ & - (3._wp*Re_visc(1)) - $:GPU_LOOP(parallelism='[seq]') - do i = 1, 2 - tau_Re_vf(contxe + i)%sf(j, k, l) = & - tau_Re_vf(contxe + i)%sf(j, k, l) - & - tau_Re(2, i) - - tau_Re_vf(E_idx)%sf(j, k, l) = & - tau_Re_vf(E_idx)%sf(j, k, l) - & - q_prim_vf(contxe + i)%sf(j, k, l)*tau_Re(2, i) - end do - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - end if - #:endif - - #:if not MFC_CASE_OPTIMIZATION or num_dims > 1 - if (bulk_stress) then ! Bulk stresses - $:GPU_PARALLEL_LOOP(collapse=3, private='[i,j,k,l,rho_visc, gamma_visc, pi_inf_visc, alpha_visc_sum ,alpha_visc, alpha_rho_visc, Re_visc, tau_Re]') - do l = is3_viscous%beg, is3_viscous%end - do k = -1, 1 - do j = is1_viscous%beg, is1_viscous%end - - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_fluids - alpha_rho_visc(i) = q_prim_vf(i)%sf(j, k, l) - if (bubbles_euler .and. num_fluids == 1) then - alpha_visc(i) = 1._wp - q_prim_vf(E_idx + i)%sf(j, k, l) - else - alpha_visc(i) = q_prim_vf(E_idx + i)%sf(j, k, l) - end if - end do - - if (bubbles_euler) then - rho_visc = 0._wp - gamma_visc = 0._wp - pi_inf_visc = 0._wp - - if (mpp_lim .and. (model_eqns == 2) .and. (num_fluids > 2)) then - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_fluids - rho_visc = rho_visc + alpha_rho_visc(i) - gamma_visc = gamma_visc + alpha_visc(i)*gammas(i) - pi_inf_visc = pi_inf_visc + alpha_visc(i)*pi_infs(i) - end do - else if ((model_eqns == 2) .and. (num_fluids > 2)) then - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_fluids - 1 - rho_visc = rho_visc + alpha_rho_visc(i) - gamma_visc = gamma_visc + alpha_visc(i)*gammas(i) - pi_inf_visc = pi_inf_visc + alpha_visc(i)*pi_infs(i) - end do - else - rho_visc = alpha_rho_visc(1) - gamma_visc = gammas(1) - pi_inf_visc = pi_infs(1) - end if - else - rho_visc = 0._wp - gamma_visc = 0._wp - pi_inf_visc = 0._wp - - alpha_visc_sum = 0._wp - - if (mpp_lim) then - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_fluids - alpha_rho_visc(i) = max(0._wp, alpha_rho_visc(i)) - alpha_visc(i) = min(max(0._wp, alpha_visc(i)), 1._wp) - alpha_visc_sum = alpha_visc_sum + alpha_visc(i) - end do - - alpha_visc = alpha_visc/max(alpha_visc_sum, sgm_eps) - - end if - - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_fluids - rho_visc = rho_visc + alpha_rho_visc(i) - gamma_visc = gamma_visc + alpha_visc(i)*gammas(i) - pi_inf_visc = pi_inf_visc + alpha_visc(i)*pi_infs(i) - end do - - if (viscous) then - $:GPU_LOOP(parallelism='[seq]') - do i = 1, 2 - Re_visc(i) = dflt_real - - if (Re_size(i) > 0) Re_visc(i) = 0._wp - $:GPU_LOOP(parallelism='[seq]') - do q = 1, Re_size(i) - Re_visc(i) = alpha_visc(Re_idx(i, q))/Res_viscous(i, q) & - + Re_visc(i) - end do - - Re_visc(i) = 1._wp/max(Re_visc(i), sgm_eps) - - end do - end if - end if - - tau_Re(2, 2) = (grad_x_vf(1)%sf(j, k, l) + & - grad_y_vf(2)%sf(j, k, l) + & - q_prim_vf(momxb + 1)%sf(j, k, l)/y_cc(k))/ & - Re_visc(2) - - tau_Re_vf(momxb + 1)%sf(j, k, l) = & - tau_Re_vf(momxb + 1)%sf(j, k, l) - & - tau_Re(2, 2) - - tau_Re_vf(E_idx)%sf(j, k, l) = & - tau_Re_vf(E_idx)%sf(j, k, l) - & - q_prim_vf(momxb + 1)%sf(j, k, l)*tau_Re(2, 2) - - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - end if - #:endif - - if (p == 0) return - #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 - - if (shear_stress) then ! Shear stresses - $:GPU_PARALLEL_LOOP(collapse=3, private='[alpha_visc, alpha_rho_visc, Re_visc, tau_Re]') - do l = is3_viscous%beg, is3_viscous%end - do k = -1, 1 - do j = is1_viscous%beg, is1_viscous%end - - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_fluids - alpha_rho_visc(i) = q_prim_vf(i)%sf(j, k, l) - if (bubbles_euler .and. num_fluids == 1) then - alpha_visc(i) = 1._wp - q_prim_vf(E_idx + i)%sf(j, k, l) - else - alpha_visc(i) = q_prim_vf(E_idx + i)%sf(j, k, l) - end if - end do - - if (bubbles_euler) then - rho_visc = 0._wp - gamma_visc = 0._wp - pi_inf_visc = 0._wp - - if (mpp_lim .and. (model_eqns == 2) .and. (num_fluids > 2)) then - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_fluids - rho_visc = rho_visc + alpha_rho_visc(i) - gamma_visc = gamma_visc + alpha_visc(i)*gammas(i) - pi_inf_visc = pi_inf_visc + alpha_visc(i)*pi_infs(i) - end do - else if ((model_eqns == 2) .and. (num_fluids > 2)) then - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_fluids - 1 - rho_visc = rho_visc + alpha_rho_visc(i) - gamma_visc = gamma_visc + alpha_visc(i)*gammas(i) - pi_inf_visc = pi_inf_visc + alpha_visc(i)*pi_infs(i) - end do - else - rho_visc = alpha_rho_visc(1) - gamma_visc = gammas(1) - pi_inf_visc = pi_infs(1) - end if - else - rho_visc = 0._wp - gamma_visc = 0._wp - pi_inf_visc = 0._wp - - alpha_visc_sum = 0._wp - - if (mpp_lim) then - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_fluids - alpha_rho_visc(i) = max(0._wp, alpha_rho_visc(i)) - alpha_visc(i) = min(max(0._wp, alpha_visc(i)), 1._wp) - alpha_visc_sum = alpha_visc_sum + alpha_visc(i) - end do - - alpha_visc = alpha_visc/max(alpha_visc_sum, sgm_eps) - - end if - - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_fluids - rho_visc = rho_visc + alpha_rho_visc(i) - gamma_visc = gamma_visc + alpha_visc(i)*gammas(i) - pi_inf_visc = pi_inf_visc + alpha_visc(i)*pi_infs(i) - end do - - if (viscous) then - $:GPU_LOOP(parallelism='[seq]') - do i = 1, 2 - Re_visc(i) = dflt_real - - if (Re_size(i) > 0) Re_visc(i) = 0._wp - $:GPU_LOOP(parallelism='[seq]') - do q = 1, Re_size(i) - Re_visc(i) = alpha_visc(Re_idx(i, q))/Res_viscous(i, q) & - + Re_visc(i) - end do - - Re_visc(i) = 1._wp/max(Re_visc(i), sgm_eps) - - end do - end if - end if - - tau_Re(2, 2) = -(2._wp/3._wp)*grad_z_vf(3)%sf(j, k, l)/y_cc(k)/ & - Re_visc(1) - - tau_Re(2, 3) = ((grad_z_vf(2)%sf(j, k, l) - & - q_prim_vf(momxe)%sf(j, k, l))/ & - y_cc(k) + grad_y_vf(3)%sf(j, k, l))/ & - Re_visc(1) - - $:GPU_LOOP(parallelism='[seq]') - do i = 2, 3 - tau_Re_vf(contxe + i)%sf(j, k, l) = & - tau_Re_vf(contxe + i)%sf(j, k, l) - & - tau_Re(2, i) - - tau_Re_vf(E_idx)%sf(j, k, l) = & - tau_Re_vf(E_idx)%sf(j, k, l) - & - q_prim_vf(contxe + i)%sf(j, k, l)*tau_Re(2, i) - end do - - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - end if - - if (bulk_stress) then ! Bulk stresses - $:GPU_PARALLEL_LOOP(collapse=3, private='[alpha_visc, alpha_rho_visc, Re_visc, tau_Re]') - do l = is3_viscous%beg, is3_viscous%end - do k = -1, 1 - do j = is1_viscous%beg, is1_viscous%end - - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_fluids - alpha_rho_visc(i) = q_prim_vf(i)%sf(j, k, l) - if (bubbles_euler .and. num_fluids == 1) then - alpha_visc(i) = 1._wp - q_prim_vf(E_idx + i)%sf(j, k, l) - else - alpha_visc(i) = q_prim_vf(E_idx + i)%sf(j, k, l) - end if - end do - - if (bubbles_euler) then - rho_visc = 0._wp - gamma_visc = 0._wp - pi_inf_visc = 0._wp - - if (mpp_lim .and. (model_eqns == 2) .and. (num_fluids > 2)) then - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_fluids - rho_visc = rho_visc + alpha_rho_visc(i) - gamma_visc = gamma_visc + alpha_visc(i)*gammas(i) - pi_inf_visc = pi_inf_visc + alpha_visc(i)*pi_infs(i) - end do - else if ((model_eqns == 2) .and. (num_fluids > 2)) then - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_fluids - 1 - rho_visc = rho_visc + alpha_rho_visc(i) - gamma_visc = gamma_visc + alpha_visc(i)*gammas(i) - pi_inf_visc = pi_inf_visc + alpha_visc(i)*pi_infs(i) - end do - else - rho_visc = alpha_rho_visc(1) - gamma_visc = gammas(1) - pi_inf_visc = pi_infs(1) - end if - else - rho_visc = 0._wp - gamma_visc = 0._wp - pi_inf_visc = 0._wp - - alpha_visc_sum = 0._wp - - if (mpp_lim) then - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_fluids - alpha_rho_visc(i) = max(0._wp, alpha_rho_visc(i)) - alpha_visc(i) = min(max(0._wp, alpha_visc(i)), 1._wp) - alpha_visc_sum = alpha_visc_sum + alpha_visc(i) - end do - - alpha_visc = alpha_visc/max(alpha_visc_sum, sgm_eps) - - end if - - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_fluids - rho_visc = rho_visc + alpha_rho_visc(i) - gamma_visc = gamma_visc + alpha_visc(i)*gammas(i) - pi_inf_visc = pi_inf_visc + alpha_visc(i)*pi_infs(i) - end do - - if (viscous) then - $:GPU_LOOP(parallelism='[seq]') - do i = 1, 2 - Re_visc(i) = dflt_real - - if (Re_size(i) > 0) Re_visc(i) = 0._wp - $:GPU_LOOP(parallelism='[seq]') - do q = 1, Re_size(i) - Re_visc(i) = alpha_visc(Re_idx(i, q))/Res_viscous(i, q) & - + Re_visc(i) - end do - - Re_visc(i) = 1._wp/max(Re_visc(i), sgm_eps) - - end do - end if - end if - - tau_Re(2, 2) = grad_z_vf(3)%sf(j, k, l)/y_cc(k)/ & - Re_visc(2) - - tau_Re_vf(momxb + 1)%sf(j, k, l) = & - tau_Re_vf(momxb + 1)%sf(j, k, l) - & - tau_Re(2, 2) - - tau_Re_vf(E_idx)%sf(j, k, l) = & - tau_Re_vf(E_idx)%sf(j, k, l) - & - q_prim_vf(momxb + 1)%sf(j, k, l)*tau_Re(2, 2) - - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - end if - #:endif - end subroutine s_compute_viscous_stress_cylindrical_boundary - - !> Computes viscous terms - !! @param qL_prim_rsx_vf Left reconstructed primitive variables in x - !! @param qL_prim_rsy_vf Left reconstructed primitive variables in y - !! @param qL_prim_rsz_vf Left reconstructed primitive variables in z - !! @param dqL_prim_dx_n Left primitive x-derivative - !! @param dqL_prim_dy_n Left primitive y-derivative - !! @param dqL_prim_dz_n Left primitive z-derivative - !! @param qL_prim Left cell-boundary primitive variables - !! @param qR_prim_rsx_vf Right reconstructed primitive variables in x - !! @param qR_prim_rsy_vf Right reconstructed primitive variables in y - !! @param qR_prim_rsz_vf Right reconstructed primitive variables in z - !! @param dqR_prim_dx_n Right primitive x-derivative - !! @param dqR_prim_dy_n Right primitive y-derivative - !! @param dqR_prim_dz_n Right primitive z-derivative - !! @param qR_prim Right cell-boundary primitive variables - !! @param q_prim_qp Cell-averaged primitive variables - !! @param dq_prim_dx_qp Cell-averaged primitive x-derivative - !! @param dq_prim_dy_qp Cell-averaged primitive y-derivative - !! @param dq_prim_dz_qp Cell-averaged primitive z-derivative - !! @param ix Index bounds in the x-direction - !! @param iy Index bounds in the y-direction - !! @param iz Index bounds in the z-direction - subroutine s_get_viscous(qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, & - dqL_prim_dx_n, dqL_prim_dy_n, dqL_prim_dz_n, & - qL_prim, & - qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf, & - dqR_prim_dx_n, dqR_prim_dy_n, dqR_prim_dz_n, & - qR_prim, & - q_prim_qp, & - dq_prim_dx_qp, dq_prim_dy_qp, dq_prim_dz_qp, & - ix, iy, iz) - - real(wp), dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:), & - intent(inout) :: qL_prim_rsx_vf, qR_prim_rsx_vf, & - qL_prim_rsy_vf, qR_prim_rsy_vf, & - qL_prim_rsz_vf, qR_prim_rsz_vf - - type(vector_field), dimension(num_dims), intent(inout) :: qL_prim, qR_prim - - type(vector_field), intent(in) :: q_prim_qp - - type(vector_field), dimension(1:num_dims), & - intent(inout) :: dqL_prim_dx_n, dqR_prim_dx_n, & - dqL_prim_dy_n, dqR_prim_dy_n, & - dqL_prim_dz_n, dqR_prim_dz_n - - type(vector_field), dimension(1), intent(inout) :: dq_prim_dx_qp, dq_prim_dy_qp, dq_prim_dz_qp - type(int_bounds_info), intent(in) :: ix, iy, iz - - integer :: i, j, k, l - - do i = 1, num_dims - - iv%beg = mom_idx%beg; iv%end = mom_idx%end - - $:GPU_UPDATE(device='[iv]') - - call s_reconstruct_cell_boundary_values_visc( & - q_prim_qp%vf(iv%beg:iv%end), & - qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, & - qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf, & - i, qL_prim(i)%vf(iv%beg:iv%end), qR_prim(i)%vf(iv%beg:iv%end), & - ix, iy, iz) - end do - - if (weno_Re_flux) then - ! Compute velocity gradient at cell centers using scalar - ! divergence theorem - do i = 1, num_dims - if (i == 1) then - call s_apply_scalar_divergence_theorem( & - qL_prim(i)%vf(iv%beg:iv%end), & - qR_prim(i)%vf(iv%beg:iv%end), & - dq_prim_dx_qp(1)%vf(iv%beg:iv%end), i, & - ix, iy, iz, iv, dx, m, buff_size) - elseif (i == 2) then - call s_apply_scalar_divergence_theorem( & - qL_prim(i)%vf(iv%beg:iv%end), & - qR_prim(i)%vf(iv%beg:iv%end), & - dq_prim_dy_qp(1)%vf(iv%beg:iv%end), i, & - ix, iy, iz, iv, dy, n, buff_size) - else - call s_apply_scalar_divergence_theorem( & - qL_prim(i)%vf(iv%beg:iv%end), & - qR_prim(i)%vf(iv%beg:iv%end), & - dq_prim_dz_qp(1)%vf(iv%beg:iv%end), i, & - ix, iy, iz, iv, dz, p, buff_size) - end if - end do - - else ! Compute velocity gradient at cell centers using finite differences - - iv%beg = mom_idx%beg; iv%end = mom_idx%end - $:GPU_UPDATE(device='[iv]') - - is1_viscous = ix; is2_viscous = iy; is3_viscous = iz - - $:GPU_UPDATE(device='[is1_viscous,is2_viscous,is3_viscous]') - - $:GPU_PARALLEL_LOOP(collapse=3) - do l = is3_viscous%beg, is3_viscous%end - do k = iy%beg, iy%end - do j = is1_viscous%beg + 1, is1_viscous%end - $:GPU_LOOP(parallelism='[seq]') - do i = iv%beg, iv%end - dqL_prim_dx_n(1)%vf(i)%sf(j, k, l) = & - (q_prim_qp%vf(i)%sf(j, k, l) - & - q_prim_qp%vf(i)%sf(j - 1, k, l))/ & - (x_cc(j) - x_cc(j - 1)) - end do - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - - $:GPU_PARALLEL_LOOP(collapse=3) - do l = is3_viscous%beg, is3_viscous%end - do k = is2_viscous%beg, is2_viscous%end - do j = is1_viscous%beg, is1_viscous%end - 1 - $:GPU_LOOP(parallelism='[seq]') - do i = iv%beg, iv%end - dqR_prim_dx_n(1)%vf(i)%sf(j, k, l) = & - (q_prim_qp%vf(i)%sf(j + 1, k, l) - & - q_prim_qp%vf(i)%sf(j, k, l))/ & - (x_cc(j + 1) - x_cc(j)) - end do - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - - if (n > 0) then - - #:if not MFC_CASE_OPTIMIZATION or num_dims > 1 - $:GPU_PARALLEL_LOOP(collapse=3) - do l = is3_viscous%beg, is3_viscous%end - do j = is2_viscous%beg + 1, is2_viscous%end - do k = is1_viscous%beg, is1_viscous%end - $:GPU_LOOP(parallelism='[seq]') - do i = iv%beg, iv%end - dqL_prim_dy_n(2)%vf(i)%sf(k, j, l) = & - (q_prim_qp%vf(i)%sf(k, j, l) - & - q_prim_qp%vf(i)%sf(k, j - 1, l))/ & - (y_cc(j) - y_cc(j - 1)) - end do - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - - $:GPU_PARALLEL_LOOP(collapse=3) - do l = is3_viscous%beg, is3_viscous%end - do j = is2_viscous%beg, is2_viscous%end - 1 - do k = is1_viscous%beg, is1_viscous%end - $:GPU_LOOP(parallelism='[seq]') - do i = iv%beg, iv%end - dqR_prim_dy_n(2)%vf(i)%sf(k, j, l) = & - (q_prim_qp%vf(i)%sf(k, j + 1, l) - & - q_prim_qp%vf(i)%sf(k, j, l))/ & - (y_cc(j + 1) - y_cc(j)) - end do - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - - $:GPU_PARALLEL_LOOP(collapse=3) - do l = is3_viscous%beg, is3_viscous%end - do j = is2_viscous%beg + 1, is2_viscous%end - do k = is1_viscous%beg + 1, is1_viscous%end - 1 - $:GPU_LOOP(parallelism='[seq]') - do i = iv%beg, iv%end - dqL_prim_dx_n(2)%vf(i)%sf(k, j, l) = & - (dqL_prim_dx_n(1)%vf(i)%sf(k, j, l) + & - dqR_prim_dx_n(1)%vf(i)%sf(k, j, l) + & - dqL_prim_dx_n(1)%vf(i)%sf(k, j - 1, l) + & - dqR_prim_dx_n(1)%vf(i)%sf(k, j - 1, l)) - - dqL_prim_dx_n(2)%vf(i)%sf(k, j, l) = 25.e-2_wp* & - dqL_prim_dx_n(2)%vf(i)%sf(k, j, l) - end do - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - - $:GPU_PARALLEL_LOOP(collapse=3) - do l = is3_viscous%beg, is3_viscous%end - do j = is2_viscous%beg, is2_viscous%end - 1 - do k = is1_viscous%beg + 1, is1_viscous%end - 1 - $:GPU_LOOP(parallelism='[seq]') - do i = iv%beg, iv%end - dqR_prim_dx_n(2)%vf(i)%sf(k, j, l) = & - (dqL_prim_dx_n(1)%vf(i)%sf(k, j + 1, l) + & - dqR_prim_dx_n(1)%vf(i)%sf(k, j + 1, l) + & - dqL_prim_dx_n(1)%vf(i)%sf(k, j, l) + & - dqR_prim_dx_n(1)%vf(i)%sf(k, j, l)) - - dqR_prim_dx_n(2)%vf(i)%sf(k, j, l) = 25.e-2_wp* & - dqR_prim_dx_n(2)%vf(i)%sf(k, j, l) - - end do - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - - $:GPU_PARALLEL_LOOP(collapse=3) - do l = is3_viscous%beg, is3_viscous%end - do k = is2_viscous%beg + 1, is2_viscous%end - 1 - do j = is1_viscous%beg + 1, is1_viscous%end - $:GPU_LOOP(parallelism='[seq]') - do i = iv%beg, iv%end - dqL_prim_dy_n(1)%vf(i)%sf(j, k, l) = & - (dqL_prim_dy_n(2)%vf(i)%sf(j, k, l) + & - dqR_prim_dy_n(2)%vf(i)%sf(j, k, l) + & - dqL_prim_dy_n(2)%vf(i)%sf(j - 1, k, l) + & - dqR_prim_dy_n(2)%vf(i)%sf(j - 1, k, l)) - - dqL_prim_dy_n(1)%vf(i)%sf(j, k, l) = 25.e-2_wp* & - dqL_prim_dy_n(1)%vf(i)%sf(j, k, l) - - end do - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - - $:GPU_PARALLEL_LOOP(collapse=3) - do l = is3_viscous%beg, is3_viscous%end - do k = is2_viscous%beg + 1, is2_viscous%end - 1 - do j = is1_viscous%beg, is1_viscous%end - 1 - $:GPU_LOOP(parallelism='[seq]') - do i = iv%beg, iv%end - dqR_prim_dy_n(1)%vf(i)%sf(j, k, l) = & - (dqL_prim_dy_n(2)%vf(i)%sf(j + 1, k, l) + & - dqR_prim_dy_n(2)%vf(i)%sf(j + 1, k, l) + & - dqL_prim_dy_n(2)%vf(i)%sf(j, k, l) + & - dqR_prim_dy_n(2)%vf(i)%sf(j, k, l)) - - dqR_prim_dy_n(1)%vf(i)%sf(j, k, l) = 25.e-2_wp* & - dqR_prim_dy_n(1)%vf(i)%sf(j, k, l) - - end do - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - - #:endif - - if (p > 0) then - #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 - $:GPU_PARALLEL_LOOP(collapse=3) - do j = is3_viscous%beg + 1, is3_viscous%end - do l = is2_viscous%beg, is2_viscous%end - do k = is1_viscous%beg, is1_viscous%end - $:GPU_LOOP(parallelism='[seq]') - do i = iv%beg, iv%end - - dqL_prim_dz_n(3)%vf(i)%sf(k, l, j) = & - (q_prim_qp%vf(i)%sf(k, l, j) - & - q_prim_qp%vf(i)%sf(k, l, j - 1))/ & - (z_cc(j) - z_cc(j - 1)) - end do - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - - $:GPU_PARALLEL_LOOP(collapse=3) - do j = is3_viscous%beg, is3_viscous%end - 1 - do l = is2_viscous%beg, is2_viscous%end - do k = is1_viscous%beg, is1_viscous%end - $:GPU_LOOP(parallelism='[seq]') - do i = iv%beg, iv%end - - dqR_prim_dz_n(3)%vf(i)%sf(k, l, j) = & - (q_prim_qp%vf(i)%sf(k, l, j + 1) - & - q_prim_qp%vf(i)%sf(k, l, j))/ & - (z_cc(j + 1) - z_cc(j)) - end do - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - - $:GPU_PARALLEL_LOOP(collapse=3) - do l = is3_viscous%beg + 1, is3_viscous%end - 1 - do k = is2_viscous%beg, is2_viscous%end - do j = is1_viscous%beg + 1, is1_viscous%end - $:GPU_LOOP(parallelism='[seq]') - do i = iv%beg, iv%end - - dqL_prim_dz_n(1)%vf(i)%sf(j, k, l) = & - (dqL_prim_dz_n(3)%vf(i)%sf(j, k, l) + & - dqR_prim_dz_n(3)%vf(i)%sf(j, k, l) + & - dqL_prim_dz_n(3)%vf(i)%sf(j - 1, k, l) + & - dqR_prim_dz_n(3)%vf(i)%sf(j - 1, k, l)) - - dqL_prim_dz_n(1)%vf(i)%sf(j, k, l) = 25.e-2_wp* & - dqL_prim_dz_n(1)%vf(i)%sf(j, k, l) - - end do - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - - $:GPU_PARALLEL_LOOP(collapse=3) - do l = is3_viscous%beg + 1, is3_viscous%end - 1 - do k = is2_viscous%beg, is2_viscous%end - do j = is1_viscous%beg, is1_viscous%end - 1 - $:GPU_LOOP(parallelism='[seq]') - do i = iv%beg, iv%end - - dqR_prim_dz_n(1)%vf(i)%sf(j, k, l) = & - (dqL_prim_dz_n(3)%vf(i)%sf(j + 1, k, l) + & - dqR_prim_dz_n(3)%vf(i)%sf(j + 1, k, l) + & - dqL_prim_dz_n(3)%vf(i)%sf(j, k, l) + & - dqR_prim_dz_n(3)%vf(i)%sf(j, k, l)) - - dqR_prim_dz_n(1)%vf(i)%sf(j, k, l) = 25.e-2_wp* & - dqR_prim_dz_n(1)%vf(i)%sf(j, k, l) - - end do - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - - $:GPU_PARALLEL_LOOP(collapse=3) - do l = is3_viscous%beg + 1, is3_viscous%end - 1 - do j = is2_viscous%beg + 1, is2_viscous%end - do k = is1_viscous%beg, is1_viscous%end - $:GPU_LOOP(parallelism='[seq]') - do i = iv%beg, iv%end - - dqL_prim_dz_n(2)%vf(i)%sf(k, j, l) = & - (dqL_prim_dz_n(3)%vf(i)%sf(k, j, l) + & - dqR_prim_dz_n(3)%vf(i)%sf(k, j, l) + & - dqL_prim_dz_n(3)%vf(i)%sf(k, j - 1, l) + & - dqR_prim_dz_n(3)%vf(i)%sf(k, j - 1, l)) - - dqL_prim_dz_n(2)%vf(i)%sf(k, j, l) = 25.e-2_wp* & - dqL_prim_dz_n(2)%vf(i)%sf(k, j, l) - - end do - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - - $:GPU_PARALLEL_LOOP(collapse=3) - do l = is3_viscous%beg + 1, is3_viscous%end - 1 - do j = is2_viscous%beg, is2_viscous%end - 1 - do k = is1_viscous%beg, is1_viscous%end - $:GPU_LOOP(parallelism='[seq]') - do i = iv%beg, iv%end - - dqR_prim_dz_n(2)%vf(i)%sf(k, j, l) = & - (dqL_prim_dz_n(3)%vf(i)%sf(k, j + 1, l) + & - dqR_prim_dz_n(3)%vf(i)%sf(k, j + 1, l) + & - dqL_prim_dz_n(3)%vf(i)%sf(k, j, l) + & - dqR_prim_dz_n(3)%vf(i)%sf(k, j, l)) - - dqR_prim_dz_n(2)%vf(i)%sf(k, j, l) = 25.e-2_wp* & - dqR_prim_dz_n(2)%vf(i)%sf(k, j, l) - - end do - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - - $:GPU_PARALLEL_LOOP(collapse=3) - do j = is3_viscous%beg + 1, is3_viscous%end - do l = is2_viscous%beg + 1, is2_viscous%end - 1 - do k = is1_viscous%beg, is1_viscous%end - $:GPU_LOOP(parallelism='[seq]') - do i = iv%beg, iv%end - - dqL_prim_dy_n(3)%vf(i)%sf(k, l, j) = & - (dqL_prim_dy_n(2)%vf(i)%sf(k, l, j) + & - dqR_prim_dy_n(2)%vf(i)%sf(k, l, j) + & - dqL_prim_dy_n(2)%vf(i)%sf(k, l, j - 1) + & - dqR_prim_dy_n(2)%vf(i)%sf(k, l, j - 1)) - - dqL_prim_dy_n(3)%vf(i)%sf(k, l, j) = 25.e-2_wp* & - dqL_prim_dy_n(3)%vf(i)%sf(k, l, j) - - end do - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - - $:GPU_PARALLEL_LOOP(collapse=3) - do j = is3_viscous%beg, is3_viscous%end - 1 - do l = is2_viscous%beg + 1, is2_viscous%end - 1 - do k = is1_viscous%beg, is1_viscous%end - $:GPU_LOOP(parallelism='[seq]') - do i = iv%beg, iv%end - - dqR_prim_dy_n(3)%vf(i)%sf(k, l, j) = & - (dqL_prim_dy_n(2)%vf(i)%sf(k, l, j + 1) + & - dqR_prim_dy_n(2)%vf(i)%sf(k, l, j + 1) + & - dqL_prim_dy_n(2)%vf(i)%sf(k, l, j) + & - dqR_prim_dy_n(2)%vf(i)%sf(k, l, j)) - - dqR_prim_dy_n(3)%vf(i)%sf(k, l, j) = 25.e-2_wp* & - dqR_prim_dy_n(3)%vf(i)%sf(k, l, j) - - end do - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - $:GPU_PARALLEL_LOOP(collapse=3) - do j = is3_viscous%beg + 1, is3_viscous%end - do l = is2_viscous%beg, is2_viscous%end - do k = is1_viscous%beg + 1, is1_viscous%end - 1 - $:GPU_LOOP(parallelism='[seq]') - do i = iv%beg, iv%end - - dqL_prim_dx_n(3)%vf(i)%sf(k, l, j) = & - (dqL_prim_dx_n(1)%vf(i)%sf(k, l, j) + & - dqR_prim_dx_n(1)%vf(i)%sf(k, l, j) + & - dqL_prim_dx_n(1)%vf(i)%sf(k, l, j - 1) + & - dqR_prim_dx_n(1)%vf(i)%sf(k, l, j - 1)) - - dqL_prim_dx_n(3)%vf(i)%sf(k, l, j) = 25.e-2_wp* & - dqL_prim_dx_n(3)%vf(i)%sf(k, l, j) - - end do - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - $:GPU_PARALLEL_LOOP(collapse=3) - do j = is3_viscous%beg, is3_viscous%end - 1 - do l = is2_viscous%beg, is2_viscous%end - do k = is1_viscous%beg + 1, is1_viscous%end - 1 - $:GPU_LOOP(parallelism='[seq]') - do i = iv%beg, iv%end - dqR_prim_dx_n(3)%vf(i)%sf(k, l, j) = & - (dqL_prim_dx_n(1)%vf(i)%sf(k, l, j + 1) + & - dqR_prim_dx_n(1)%vf(i)%sf(k, l, j + 1) + & - dqL_prim_dx_n(1)%vf(i)%sf(k, l, j) + & - dqR_prim_dx_n(1)%vf(i)%sf(k, l, j)) - - dqR_prim_dx_n(3)%vf(i)%sf(k, l, j) = 25.e-2_wp* & - dqR_prim_dx_n(3)%vf(i)%sf(k, l, j) - - end do - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - - do i = iv%beg, iv%end - call s_compute_fd_gradient(q_prim_qp%vf(i), & - dq_prim_dx_qp(1)%vf(i), & - dq_prim_dy_qp(1)%vf(i), & - dq_prim_dz_qp(1)%vf(i)) - end do - #:endif - - else - - do i = iv%beg, iv%end - call s_compute_fd_gradient(q_prim_qp%vf(i), & - dq_prim_dx_qp(1)%vf(i), & - dq_prim_dy_qp(1)%vf(i), & - dq_prim_dy_qp(1)%vf(i)) - end do - - end if - - else - - do i = iv%beg, iv%end - call s_compute_fd_gradient(q_prim_qp%vf(i), & - dq_prim_dx_qp(1)%vf(i), & - dq_prim_dx_qp(1)%vf(i), & - dq_prim_dx_qp(1)%vf(i)) - end do - - end if - - end if - - end subroutine s_get_viscous - - !> @brief Reconstructs left and right cell-boundary values of viscous primitive variables using WENO or MUSCL. - subroutine s_reconstruct_cell_boundary_values_visc(v_vf, vL_x, vL_y, vL_z, vR_x, vR_y, vR_z, & - norm_dir, vL_prim_vf, vR_prim_vf, ix, iy, iz) - - type(scalar_field), dimension(iv%beg:iv%end), intent(in) :: v_vf - type(scalar_field), dimension(iv%beg:iv%end), intent(inout) :: vL_prim_vf, vR_prim_vf - - real(wp), dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:), intent(inout) :: vL_x, vL_y, vL_z, vR_x, vR_y, vR_z - integer, intent(in) :: norm_dir - type(int_bounds_info), intent(in) :: ix, iy, iz - - integer :: recon_dir !< Coordinate direction of the WENO reconstruction - - integer :: i, j, k, l - - #:for SCHEME, TYPE in [('weno','WENO_TYPE'), ('muscl','MUSCL_TYPE')] - if (recon_type == ${TYPE}$ .or. dummy) then - ! Reconstruction in s1-direction - - if (norm_dir == 1) then - is1_viscous = ix; is2_viscous = iy; is3_viscous = iz - recon_dir = 1; is1_viscous%beg = is1_viscous%beg + ${SCHEME}$_polyn - is1_viscous%end = is1_viscous%end - ${SCHEME}$_polyn - - elseif (norm_dir == 2) then - is1_viscous = iy; is2_viscous = ix; is3_viscous = iz - recon_dir = 2; is1_viscous%beg = is1_viscous%beg + ${SCHEME}$_polyn - is1_viscous%end = is1_viscous%end - ${SCHEME}$_polyn - - else - is1_viscous = iz; is2_viscous = iy; is3_viscous = ix - recon_dir = 3; is1_viscous%beg = is1_viscous%beg + ${SCHEME}$_polyn - is1_viscous%end = is1_viscous%end - ${SCHEME}$_polyn - - end if - - $:GPU_UPDATE(device='[is1_viscous, is2_viscous, is3_viscous, iv]') - if (n > 0) then - if (p > 0) then - call s_${SCHEME}$ (v_vf(iv%beg:iv%end), & - vL_x(:, :, :, iv%beg:iv%end), vL_y(:, :, :, iv%beg:iv%end), vL_z(:, :, :, iv%beg:iv%end), vR_x(:, :, :, iv%beg:iv%end), vR_y(:, :, :, iv%beg:iv%end), vR_z(:, :, :, iv%beg:iv%end), & - recon_dir, & - is1_viscous, is2_viscous, is3_viscous) - else - call s_${SCHEME}$ (v_vf(iv%beg:iv%end), & - vL_x(:, :, :, iv%beg:iv%end), vL_y(:, :, :, iv%beg:iv%end), vL_z(:, :, :, :), vR_x(:, :, :, iv%beg:iv%end), vR_y(:, :, :, iv%beg:iv%end), vR_z(:, :, :, :), & - recon_dir, & - is1_viscous, is2_viscous, is3_viscous) - end if - else - call s_${SCHEME}$ (v_vf(iv%beg:iv%end), & - vL_x(:, :, :, iv%beg:iv%end), vL_y(:, :, :, :), vL_z(:, :, :, :), vR_x(:, :, :, iv%beg:iv%end), vR_y(:, :, :, :), vR_z(:, :, :, :), & - recon_dir, & - is1_viscous, is2_viscous, is3_viscous) - end if - end if - #:endfor - - if (viscous .or. dummy) then - if (weno_Re_flux) then - if (norm_dir == 2) then - $:GPU_PARALLEL_LOOP(collapse=4) - do i = iv%beg, iv%end - do l = is3_viscous%beg, is3_viscous%end - do j = is1_viscous%beg, is1_viscous%end - do k = is2_viscous%beg, is2_viscous%end - vL_prim_vf(i)%sf(k, j, l) = vL_y(j, k, l, i) - vR_prim_vf(i)%sf(k, j, l) = vR_y(j, k, l, i) - end do - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - elseif (norm_dir == 3) then - $:GPU_PARALLEL_LOOP(collapse=4) - do i = iv%beg, iv%end - do j = is1_viscous%beg, is1_viscous%end - do k = is2_viscous%beg, is2_viscous%end - do l = is3_viscous%beg, is3_viscous%end - vL_prim_vf(i)%sf(l, k, j) = vL_z(j, k, l, i) - vR_prim_vf(i)%sf(l, k, j) = vR_z(j, k, l, i) - end do - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - elseif (norm_dir == 1) then - $:GPU_PARALLEL_LOOP(collapse=4) - do i = iv%beg, iv%end - do l = is3_viscous%beg, is3_viscous%end - do k = is2_viscous%beg, is2_viscous%end - do j = is1_viscous%beg, is1_viscous%end - vL_prim_vf(i)%sf(j, k, l) = vL_x(j, k, l, i) - vR_prim_vf(i)%sf(j, k, l) = vR_x(j, k, l, i) - end do - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - end if - end if - end if - - end subroutine s_reconstruct_cell_boundary_values_visc - - !> @brief Reconstructs left and right cell-boundary values of viscous primitive variable derivatives using WENO or MUSCL. - subroutine s_reconstruct_cell_boundary_values_visc_deriv(v_vf, vL_x, vL_y, vL_z, vR_x, vR_y, vR_z, & - norm_dir, vL_prim_vf, vR_prim_vf, ix, iy, iz) - type(scalar_field), dimension(iv%beg:iv%end), intent(in) :: v_vf - real(wp), dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, iv%beg:), intent(inout) :: vL_x, vL_y, vL_z, vR_x, vR_y, vR_z - type(scalar_field), dimension(iv%beg:iv%end), intent(inout) :: vL_prim_vf, vR_prim_vf - type(int_bounds_info), intent(in) :: ix, iy, iz - - integer, intent(IN) :: norm_dir - - integer :: recon_dir !< Coordinate direction of the WENO reconstruction - - integer :: i, j, k, l - #:for SCHEME, TYPE in [('weno','WENO_TYPE'), ('muscl','MUSCL_TYPE')] - if (recon_type == ${TYPE}$) then - ! Reconstruction in s1-direction - - if (norm_dir == 1) then - is1_viscous = ix; is2_viscous = iy; is3_viscous = iz - recon_dir = 1; is1_viscous%beg = is1_viscous%beg + ${SCHEME}$_polyn - is1_viscous%end = is1_viscous%end - ${SCHEME}$_polyn - - elseif (norm_dir == 2) then - is1_viscous = iy; is2_viscous = ix; is3_viscous = iz - recon_dir = 2; is1_viscous%beg = is1_viscous%beg + ${SCHEME}$_polyn - is1_viscous%end = is1_viscous%end - ${SCHEME}$_polyn - - else - is1_viscous = iz; is2_viscous = iy; is3_viscous = ix - recon_dir = 3; is1_viscous%beg = is1_viscous%beg + ${SCHEME}$_polyn - is1_viscous%end = is1_viscous%end - ${SCHEME}$_polyn - - end if - $:GPU_UPDATE(device='[is1_viscous, is2_viscous, is3_viscous, iv]') - if (n > 0) then - if (p > 0) then - - call s_${SCHEME}$ (v_vf(iv%beg:iv%end), & - vL_x(:, :, :, iv%beg:iv%end), vL_y(:, :, :, iv%beg:iv%end), vL_z(:, :, :, iv%beg:iv%end), vR_x(:, :, :, iv%beg:iv%end), vR_y(:, :, :, iv%beg:iv%end), vR_z(:, :, :, iv%beg:iv%end), & - recon_dir, & - is1_viscous, is2_viscous, is3_viscous) - else - call s_${SCHEME}$ (v_vf(iv%beg:iv%end), & - vL_x(:, :, :, iv%beg:iv%end), vL_y(:, :, :, iv%beg:iv%end), vL_z(:, :, :, :), vR_x(:, :, :, iv%beg:iv%end), vR_y(:, :, :, iv%beg:iv%end), vR_z(:, :, :, :), & - recon_dir, & - is1_viscous, is2_viscous, is3_viscous) - end if - else - - call s_${SCHEME}$ (v_vf(iv%beg:iv%end), & - vL_x(:, :, :, iv%beg:iv%end), vL_y(:, :, :, :), vL_z(:, :, :, :), vR_x(:, :, :, iv%beg:iv%end), vR_y(:, :, :, :), vR_z(:, :, :, :), & - recon_dir, & - is1_viscous, is2_viscous, is3_viscous) - end if - end if - #:endfor - - if (viscous .or. dummy) then - if (weno_Re_flux) then - if (norm_dir == 2) then - $:GPU_PARALLEL_LOOP(collapse=4) - do i = iv%beg, iv%end - do l = is3_viscous%beg, is3_viscous%end - do j = is1_viscous%beg, is1_viscous%end - do k = is2_viscous%beg, is2_viscous%end - vL_prim_vf(i)%sf(k, j, l) = vL_y(j, k, l, i) - vR_prim_vf(i)%sf(k, j, l) = vR_y(j, k, l, i) - end do - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - elseif (norm_dir == 3) then - $:GPU_PARALLEL_LOOP(collapse=4) - do i = iv%beg, iv%end - do j = is1_viscous%beg, is1_viscous%end - do k = is2_viscous%beg, is2_viscous%end - do l = is3_viscous%beg, is3_viscous%end - vL_prim_vf(i)%sf(l, k, j) = vL_z(j, k, l, i) - vR_prim_vf(i)%sf(l, k, j) = vR_z(j, k, l, i) - end do - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - elseif (norm_dir == 1) then - $:GPU_PARALLEL_LOOP(collapse=4) - do i = iv%beg, iv%end - do l = is3_viscous%beg, is3_viscous%end - do k = is2_viscous%beg, is2_viscous%end - do j = is1_viscous%beg, is1_viscous%end - vL_prim_vf(i)%sf(j, k, l) = vL_x(j, k, l, i) - vR_prim_vf(i)%sf(j, k, l) = vR_x(j, k, l, i) - end do - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - end if - end if - end if - - end subroutine s_reconstruct_cell_boundary_values_visc_deriv - - !> The purpose of this subroutine is to employ the inputted - !! left and right cell-boundary integral-averaged variables - !! to compute the relevant cell-average first-order spatial - !! derivatives in the x-, y- or z-direction by means of the - !! scalar divergence theorem. - !! @param vL_vf Left cell-boundary integral averages - !! @param vR_vf Right cell-boundary integral averages - !! @param dv_ds_vf Cell-average first-order spatial derivatives - !! @param norm_dir Splitting coordinate direction - !! @param ix Index bounds in the x-direction - !! @param iy Index bounds in the y-direction - !! @param iz Index bounds in the z-direction - !! @param iv_in Variable index bounds - !! @param dL Cell width array - !! @param dim Dimension size - !! @param buff_size_in Buffer layer size - subroutine s_apply_scalar_divergence_theorem(vL_vf, vR_vf, & - dv_ds_vf, & - norm_dir, & - ix, iy, iz, iv_in, & - dL, dim, buff_size_in) - - ! arrays of cell widths - type(scalar_field), & - dimension(iv%beg:iv%end), & - intent(in) :: vL_vf, vR_vf - - type(scalar_field), & - dimension(iv%beg:iv%end), & - intent(inout) :: dv_ds_vf - - integer, intent(in) :: norm_dir - type(int_bounds_info), intent(in) :: ix, iy, iz, iv_in - integer, intent(in) :: dim, buff_size_in - real(wp), dimension(-buff_size_in:dim + buff_size_in), intent(in) :: dL - - integer :: i, j, k, l !< Generic loop iterators - - is1_viscous = ix - is2_viscous = iy - is3_viscous = iz - iv = iv_in - - $:GPU_UPDATE(device='[is1_viscous, is2_viscous, is3_viscous, iv]') - - ! First-Order Spatial Derivatives in x-direction - if (norm_dir == 1) then - - ! A general application of the scalar divergence theorem that - ! utilizes the left and right cell-boundary integral-averages, - ! inside each cell, or an arithmetic mean of these two at the - ! cell-boundaries, to calculate the cell-averaged first-order - ! spatial derivatives inside the cell. - - $:GPU_PARALLEL_LOOP(collapse=3) - do l = is3_viscous%beg, is3_viscous%end - do k = is2_viscous%beg, is2_viscous%end - do j = is1_viscous%beg + 1, is1_viscous%end - 1 - $:GPU_LOOP(parallelism='[seq]') - do i = iv%beg, iv%end - dv_ds_vf(i)%sf(j, k, l) = & - 1._wp/((1._wp + wa_flg)*dL(j)) & - *(wa_flg*vL_vf(i)%sf(j + 1, k, l) & - + vR_vf(i)%sf(j, k, l) & - - vL_vf(i)%sf(j, k, l) & - - wa_flg*vR_vf(i)%sf(j - 1, k, l)) - end do - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - - ! END: First-Order Spatial Derivatives in x-direction - - ! First-Order Spatial Derivatives in y-direction - elseif (norm_dir == 2) then - - ! A general application of the scalar divergence theorem that - ! utilizes the left and right cell-boundary integral-averages, - ! inside each cell, or an arithmetic mean of these two at the - ! cell-boundaries, to calculate the cell-averaged first-order - ! spatial derivatives inside the cell. - - $:GPU_PARALLEL_LOOP(collapse=3) - do l = is3_viscous%beg, is3_viscous%end - do k = is2_viscous%beg + 1, is2_viscous%end - 1 - do j = is1_viscous%beg, is1_viscous%end - $:GPU_LOOP(parallelism='[seq]') - do i = iv%beg, iv%end - dv_ds_vf(i)%sf(j, k, l) = & - 1._wp/((1._wp + wa_flg)*dL(k)) & - *(wa_flg*vL_vf(i)%sf(j, k + 1, l) & - + vR_vf(i)%sf(j, k, l) & - - vL_vf(i)%sf(j, k, l) & - - wa_flg*vR_vf(i)%sf(j, k - 1, l)) - end do - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - - ! END: First-Order Spatial Derivatives in y-direction - - ! First-Order Spatial Derivatives in z-direction - else - - ! A general application of the scalar divergence theorem that - ! utilizes the left and right cell-boundary integral-averages, - ! inside each cell, or an arithmetic mean of these two at the - ! cell-boundaries, to calculate the cell-averaged first-order - ! spatial derivatives inside the cell. - - $:GPU_PARALLEL_LOOP(collapse=3) - do l = is3_viscous%beg + 1, is3_viscous%end - 1 - do k = is2_viscous%beg, is2_viscous%end - do j = is1_viscous%beg, is1_viscous%end - $:GPU_LOOP(parallelism='[seq]') - do i = iv%beg, iv%end - dv_ds_vf(i)%sf(j, k, l) = & - 1._wp/((1._wp + wa_flg)*dL(l)) & - *(wa_flg*vL_vf(i)%sf(j, k, l + 1) & - + vR_vf(i)%sf(j, k, l) & - - vL_vf(i)%sf(j, k, l) & - - wa_flg*vR_vf(i)%sf(j, k, l - 1)) - end do - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - - end if - ! END: First-Order Spatial Derivatives in z-direction - - end subroutine s_apply_scalar_divergence_theorem - - !> Computes the scalar gradient fields via finite differences - !! @param var Variable to compute derivative of - !! @param grad_x First coordinate direction component of the derivative - !! @param grad_y Second coordinate direction component of the derivative - !! @param grad_z Third coordinate direction component of the derivative - subroutine s_compute_fd_gradient(var, grad_x, grad_y, grad_z) - - type(scalar_field), intent(in) :: var - type(scalar_field), intent(inout) :: grad_x - type(scalar_field), intent(inout) :: grad_y - type(scalar_field), intent(inout) :: grad_z - type(int_bounds_info) :: ix, iy, iz - - integer :: j, k, l !< Generic loop iterators - - ix%beg = 1 - buff_size; ix%end = m + buff_size - 1 - if (n > 0) then - iy%beg = 1 - buff_size; iy%end = n + buff_size - 1 - else - iy%beg = 0; iy%end = 0 - end if - - if (p > 0) then - iz%beg = 1 - buff_size; iz%end = p + buff_size - 1 - else - iz%beg = 0; iz%end = 0 - end if - - is1_viscous = ix; is2_viscous = iy; is3_viscous = iz - - $:GPU_UPDATE(device='[is1_viscous,is2_viscous,is3_viscous]') - - $:GPU_PARALLEL_LOOP(collapse=3) - do l = is3_viscous%beg, is3_viscous%end - do k = is2_viscous%beg, is2_viscous%end - do j = is1_viscous%beg, is1_viscous%end - grad_x%sf(j, k, l) = & - (var%sf(j + 1, k, l) - var%sf(j - 1, k, l))/ & - (x_cc(j + 1) - x_cc(j - 1)) - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - - if (n > 0) then - $:GPU_PARALLEL_LOOP(collapse=3) - do l = is3_viscous%beg, is3_viscous%end - do k = is2_viscous%beg, is2_viscous%end - do j = is1_viscous%beg, is1_viscous%end - grad_y%sf(j, k, l) = & - (var%sf(j, k + 1, l) - var%sf(j, k - 1, l))/ & - (y_cc(k + 1) - y_cc(k - 1)) - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - end if - - if (p > 0) then - $:GPU_PARALLEL_LOOP(collapse=3) - do l = is3_viscous%beg, is3_viscous%end - do k = is2_viscous%beg, is2_viscous%end - do j = is1_viscous%beg, is1_viscous%end - grad_z%sf(j, k, l) = & - (var%sf(j, k, l + 1) - var%sf(j, k, l - 1))/ & - (z_cc(l + 1) - z_cc(l - 1)) - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - end if - - $:GPU_PARALLEL_LOOP(collapse=2) - do l = idwbuff(3)%beg, idwbuff(3)%end - do k = idwbuff(2)%beg, idwbuff(2)%end - grad_x%sf(idwbuff(1)%beg, k, l) = & - (-3._wp*var%sf(idwbuff(1)%beg, k, l) + 4._wp*var%sf(idwbuff(1)%beg + 1, k, l) - var%sf(idwbuff(1)%beg + 2, k, l))/ & - (x_cc(idwbuff(1)%beg + 2) - x_cc(idwbuff(1)%beg)) - grad_x%sf(idwbuff(1)%end, k, l) = & - (+3._wp*var%sf(idwbuff(1)%end, k, l) - 4._wp*var%sf(idwbuff(1)%end - 1, k, l) + var%sf(idwbuff(1)%end - 2, k, l))/ & - (x_cc(idwbuff(1)%end) - x_cc(idwbuff(1)%end - 2)) - end do - end do - $:END_GPU_PARALLEL_LOOP() - if (n > 0) then - $:GPU_PARALLEL_LOOP(collapse=2) - do l = idwbuff(3)%beg, idwbuff(3)%end - do j = idwbuff(1)%beg, idwbuff(1)%end - grad_y%sf(j, idwbuff(2)%beg, l) = & - (-3._wp*var%sf(j, idwbuff(2)%beg, l) + 4._wp*var%sf(j, idwbuff(2)%beg + 1, l) - var%sf(j, idwbuff(2)%beg + 2, l))/ & - (y_cc(idwbuff(2)%beg + 2) - y_cc(idwbuff(2)%beg)) - grad_y%sf(j, idwbuff(2)%end, l) = & - (+3._wp*var%sf(j, idwbuff(2)%end, l) - 4._wp*var%sf(j, idwbuff(2)%end - 1, l) + var%sf(j, idwbuff(2)%end - 2, l))/ & - (y_cc(idwbuff(2)%end) - y_cc(idwbuff(2)%end - 2)) - end do - end do - $:END_GPU_PARALLEL_LOOP() - if (p > 0) then - $:GPU_PARALLEL_LOOP(collapse=2) - do k = idwbuff(2)%beg, idwbuff(2)%end - do j = idwbuff(1)%beg, idwbuff(1)%end - grad_z%sf(j, k, idwbuff(3)%beg) = & - (-3._wp*var%sf(j, k, idwbuff(3)%beg) + 4._wp*var%sf(j, k, idwbuff(3)%beg + 1) - var%sf(j, k, idwbuff(3)%beg + 2))/ & - (z_cc(idwbuff(3)%beg + 2) - z_cc(is3_viscous%beg)) - grad_z%sf(j, k, idwbuff(3)%end) = & - (+3._wp*var%sf(j, k, idwbuff(3)%end) - 4._wp*var%sf(j, k, idwbuff(3)%end - 1) + var%sf(j, k, idwbuff(3)%end - 2))/ & - (z_cc(idwbuff(3)%end) - z_cc(idwbuff(3)%end - 2)) - end do - end do - $:END_GPU_PARALLEL_LOOP() - end if - end if - - if (bc_x%beg <= BC_GHOST_EXTRAP) then - $:GPU_PARALLEL_LOOP(collapse=2) - do l = idwbuff(3)%beg, idwbuff(3)%end - do k = idwbuff(2)%beg, idwbuff(2)%end - grad_x%sf(0, k, l) = (-3._wp*var%sf(0, k, l) + 4._wp*var%sf(1, k, l) - var%sf(2, k, l))/ & - (x_cc(2) - x_cc(0)) - end do - end do - $:END_GPU_PARALLEL_LOOP() - end if - if (bc_x%end <= BC_GHOST_EXTRAP) then - $:GPU_PARALLEL_LOOP(collapse=2) - do l = idwbuff(3)%beg, idwbuff(3)%end - do k = idwbuff(2)%beg, idwbuff(2)%end - grad_x%sf(m, k, l) = (3._wp*var%sf(m, k, l) - 4._wp*var%sf(m - 1, k, l) + var%sf(m - 2, k, l))/ & - (x_cc(m) - x_cc(m - 2)) - end do - end do - $:END_GPU_PARALLEL_LOOP() - end if - if (n > 0) then - if (bc_y%beg <= BC_GHOST_EXTRAP .and. bc_y%beg /= BC_NULL) then - $:GPU_PARALLEL_LOOP(collapse=2) - do l = idwbuff(3)%beg, idwbuff(3)%end - do j = idwbuff(1)%beg, idwbuff(1)%end - grad_y%sf(j, 0, l) = (-3._wp*var%sf(j, 0, l) + 4._wp*var%sf(j, 1, l) - var%sf(j, 2, l))/ & - (y_cc(2) - y_cc(0)) - end do - end do - $:END_GPU_PARALLEL_LOOP() - end if - if (bc_y%end <= BC_GHOST_EXTRAP) then - $:GPU_PARALLEL_LOOP(collapse=2) - do l = idwbuff(3)%beg, idwbuff(3)%end - do j = idwbuff(1)%beg, idwbuff(1)%end - grad_y%sf(j, n, l) = (3._wp*var%sf(j, n, l) - 4._wp*var%sf(j, n - 1, l) + var%sf(j, n - 2, l))/ & - (y_cc(n) - y_cc(n - 2)) - end do - end do - $:END_GPU_PARALLEL_LOOP() - end if - if (p > 0) then - if (bc_z%beg <= BC_GHOST_EXTRAP) then - $:GPU_PARALLEL_LOOP(collapse=2) - do k = idwbuff(2)%beg, idwbuff(2)%end - do j = idwbuff(1)%beg, idwbuff(1)%end - grad_z%sf(j, k, 0) = & - (-3._wp*var%sf(j, k, 0) + 4._wp*var%sf(j, k, 1) - var%sf(j, k, 2))/ & - (z_cc(2) - z_cc(0)) - end do - end do - $:END_GPU_PARALLEL_LOOP() - end if - if (bc_z%end <= BC_GHOST_EXTRAP) then - $:GPU_PARALLEL_LOOP(collapse=2) - do k = idwbuff(2)%beg, idwbuff(2)%end - do j = idwbuff(1)%beg, idwbuff(1)%end - grad_z%sf(j, k, p) = & - (3._wp*var%sf(j, k, p) - 4._wp*var%sf(j, k, p - 1) + var%sf(j, k, p - 2))/ & - (z_cc(p) - z_cc(p - 2)) - end do - end do - $:END_GPU_PARALLEL_LOOP() - end if - end if - end if - - end subroutine s_compute_fd_gradient - - !> @brief Computes the viscous stress tensor at a single grid cell using finite-difference velocity gradients. - subroutine s_compute_viscous_stress_tensor(viscous_stress_tensor, q_prim_vf, dynamic_viscosity, i, j, k) - $:GPU_ROUTINE(parallelism='[seq]') - - real(wp), dimension(1:3, 1:3), intent(inout) :: viscous_stress_tensor - type(scalar_field), dimension(1:sys_size), intent(in) :: q_prim_vf - real(wp), intent(in) :: dynamic_viscosity - integer, intent(in) :: i, j, k - - real(wp), dimension(1:3, 1:3) :: velocity_gradient_tensor - real(wp), dimension(1:3) :: dx - real(wp) :: divergence - integer :: l, q ! iterators - - ! zero the viscous stress, collection of velocity diriviatives, and spacial finite differences - viscous_stress_tensor = 0._wp - velocity_gradient_tensor = 0._wp - dx = 0._wp - - ! get the change in x used in the finite difference equaiont - dx(1) = 0.5_wp*(x_cc(i + 1) - x_cc(i - 1)) - dx(2) = 0.5_wp*(y_cc(j + 1) - y_cc(j - 1)) - if (num_dims == 3) then - dx(3) = 0.5_wp*(z_cc(k + 1) - z_cc(k - 1)) - end if - - ! compute the velocity gradient tensor - do l = 1, num_dims - velocity_gradient_tensor(l, 1) = (q_prim_vf(momxb + l - 1)%sf(i + 1, j, k) - q_prim_vf(momxb + l - 1)%sf(i - 1, j, k))/(2._wp*dx(1)) - velocity_gradient_tensor(l, 2) = (q_prim_vf(momxb + l - 1)%sf(i, j + 1, k) - q_prim_vf(momxb + l - 1)%sf(i, j - 1, k))/(2._wp*dx(2)) - if (num_dims == 3) then - velocity_gradient_tensor(l, 3) = (q_prim_vf(momxb + l - 1)%sf(i, j, k + 1) - q_prim_vf(momxb + l - 1)%sf(i, j, k - 1))/(2._wp*dx(3)) - end if - end do - - ! compute divergence - divergence = 0._wp - do l = 1, num_dims - divergence = divergence + velocity_gradient_tensor(l, l) - end do - - ! set up the shear stress tensor - do l = 1, num_dims - do q = 1, num_dims - viscous_stress_tensor(l, q) = dynamic_viscosity*(velocity_gradient_tensor(l, q) + velocity_gradient_tensor(q, l)) - end do - end do - - ! populate the viscous_stress_tensor - do l = 1, num_dims - viscous_stress_tensor(l, l) = viscous_stress_tensor(l, l) - 2._wp*divergence*dynamic_viscosity/3._wp - end do - - if (num_dims == 2) then - do l = 1, 3 - viscous_stress_tensor(3, l) = 0._wp - viscous_stress_tensor(l, 3) = 0._wp - end do - end if - - end subroutine s_compute_viscous_stress_tensor - - !> @brief Deallocates the viscous Reynolds number arrays. - impure subroutine s_finalize_viscous_module() - - @:DEALLOCATE(Res_viscous) - - end subroutine s_finalize_viscous_module - -end module m_viscous +!> +!! @file +!! @brief Contains module m_viscous +#:include 'case.fpp' +#:include 'macros.fpp' + +!> @brief Computes viscous stress tensors and diffusive flux contributions for the Navier--Stokes equations +module m_viscous + + use m_derived_types !< Definitions of the derived types + + use m_global_parameters !< Definitions of the global parameters + + use m_weno + + use m_muscl !< Monotonic Upstream-centered (MUSCL) + !! schemes for conservation laws + + use m_helper + + use m_finite_differences + + use m_re_visc + + private; public s_get_viscous, & + s_compute_viscous_stress_cylindrical_boundary, & + s_initialize_viscous_module, & + s_reconstruct_cell_boundary_values_visc_deriv, & + s_finalize_viscous_module, & + s_compute_viscous_stress_tensor + + type(int_bounds_info) :: iv + type(int_bounds_info) :: is1_viscous, is2_viscous, is3_viscous + $:GPU_DECLARE(create='[is1_viscous,is2_viscous,is3_viscous,iv]') + + ! Note: Static Res_viscous array removed - s_compute_re_visc handles + ! both Newtonian and non-Newtonian cases dynamically + +contains + + !> @brief Allocates and populates the viscous Reynolds number arrays and transfers data to the GPU. + impure subroutine s_initialize_viscous_module + + $:GPU_UPDATE(device='[Re_idx,Re_size]') + $:GPU_ENTER_DATA(copyin='[is1_viscous,is2_viscous,is3_viscous,iv]') + + end subroutine s_initialize_viscous_module + + !> The purpose of this subroutine is to compute the viscous + ! stress tensor for the cells directly next to the axis in + ! cylindrical coordinates. This is necessary to avoid the + ! 1/r singularity that arises at the cell boundary coinciding + ! with the axis, i.e., y_cb(-1) = 0. + ! @param q_prim_vf Cell-average primitive variables + ! @param grad_x_vf Cell-average primitive variable derivatives, x-dir + ! @param grad_y_vf Cell-average primitive variable derivatives, y-dir + ! @param grad_z_vf Cell-average primitive variable derivatives, z-dir + subroutine s_compute_viscous_stress_cylindrical_boundary(q_prim_vf, grad_x_vf, grad_y_vf, grad_z_vf, & + tau_Re_vf, & + ix, iy, iz) + + type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf + type(scalar_field), dimension(num_dims), intent(in) :: grad_x_vf, grad_y_vf, grad_z_vf + type(scalar_field), dimension(1:sys_size), intent(inout) :: tau_Re_vf + type(int_bounds_info), intent(in) :: ix, iy, iz + + real(wp) :: rho_visc, gamma_visc, pi_inf_visc, alpha_visc_sum !< Mixture variables + real(wp), dimension(2) :: Re_visc + #:if not MFC_CASE_OPTIMIZATION and USING_AMD + real(wp), dimension(3) :: alpha_visc, alpha_rho_visc + real(wp), dimension(3, 3) :: tau_Re + real(wp), dimension(3, 2) :: Re_visc_nn + #:else + real(wp), dimension(num_fluids) :: alpha_visc, alpha_rho_visc + real(wp), dimension(num_dims, num_dims) :: tau_Re + real(wp), dimension(num_fluids, 2) :: Re_visc_nn + #:endif + + integer :: i, j, k, l, q !< Generic loop iterator + + is1_viscous = ix; is2_viscous = iy; is3_viscous = iz + + $:GPU_UPDATE(device='[is1_viscous,is2_viscous,is3_viscous]') + + $:GPU_PARALLEL_LOOP(collapse=3) + do l = is3_viscous%beg, is3_viscous%end + do k = is2_viscous%beg, is2_viscous%end + do j = is1_viscous%beg, is1_viscous%end + $:GPU_LOOP(parallelism='[seq]') + do i = momxb, E_idx + tau_Re_vf(i)%sf(j, k, l) = 0._wp + end do + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + + #:if not MFC_CASE_OPTIMIZATION or num_dims > 1 + if (shear_stress) then ! Shear stresses + $:GPU_PARALLEL_LOOP(collapse=3, private='[i,j,k,l,rho_visc, gamma_visc, pi_inf_visc, alpha_visc_sum ,alpha_visc, alpha_rho_visc, Re_visc, tau_Re]') + do l = is3_viscous%beg, is3_viscous%end + do k = -1, 1 + do j = is1_viscous%beg, is1_viscous%end + + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_fluids + alpha_rho_visc(i) = q_prim_vf(i)%sf(j, k, l) + if (bubbles_euler .and. num_fluids == 1) then + alpha_visc(i) = 1._wp - q_prim_vf(E_idx + i)%sf(j, k, l) + else + alpha_visc(i) = q_prim_vf(E_idx + i)%sf(j, k, l) + end if + end do + + if (bubbles_euler) then + rho_visc = 0._wp + gamma_visc = 0._wp + pi_inf_visc = 0._wp + + if (mpp_lim .and. (model_eqns == 2) .and. (num_fluids > 2)) then + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_fluids + rho_visc = rho_visc + alpha_rho_visc(i) + gamma_visc = gamma_visc + alpha_visc(i)*gammas(i) + pi_inf_visc = pi_inf_visc + alpha_visc(i)*pi_infs(i) + end do + else if ((model_eqns == 2) .and. (num_fluids > 2)) then + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_fluids - 1 + rho_visc = rho_visc + alpha_rho_visc(i) + gamma_visc = gamma_visc + alpha_visc(i)*gammas(i) + pi_inf_visc = pi_inf_visc + alpha_visc(i)*pi_infs(i) + end do + else + rho_visc = alpha_rho_visc(1) + gamma_visc = gammas(1) + pi_inf_visc = pi_infs(1) + end if + else + rho_visc = 0._wp + gamma_visc = 0._wp + pi_inf_visc = 0._wp + + alpha_visc_sum = 0._wp + + if (mpp_lim) then + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_fluids + alpha_rho_visc(i) = max(0._wp, alpha_rho_visc(i)) + alpha_visc(i) = min(max(0._wp, alpha_visc(i)), 1._wp) + alpha_visc_sum = alpha_visc_sum + alpha_visc(i) + end do + + alpha_visc = alpha_visc/max(alpha_visc_sum, sgm_eps) + + end if + + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_fluids + rho_visc = rho_visc + alpha_rho_visc(i) + gamma_visc = gamma_visc + alpha_visc(i)*gammas(i) + pi_inf_visc = pi_inf_visc + alpha_visc(i)*pi_infs(i) + end do + + if (viscous) then + call s_compute_re_visc(q_prim_vf, & + alpha_visc, j, k, l, & + Re_visc_nn, grad_x_vf, & + grad_y_vf, grad_z_vf) + call s_compute_mixture_re(alpha_visc, Re_visc_nn, Re_visc) + end if + end if + + tau_Re(2, 1) = (grad_y_vf(1)%sf(j, k, l) + & + grad_x_vf(2)%sf(j, k, l))/ & + Re_visc(1) + + tau_Re(2, 2) = (4._wp*grad_y_vf(2)%sf(j, k, l) & + - 2._wp*grad_x_vf(1)%sf(j, k, l) & + - 2._wp*q_prim_vf(momxb + 1)%sf(j, k, l)/y_cc(k))/ & + (3._wp*Re_visc(1)) + $:GPU_LOOP(parallelism='[seq]') + do i = 1, 2 + tau_Re_vf(contxe + i)%sf(j, k, l) = & + tau_Re_vf(contxe + i)%sf(j, k, l) - & + tau_Re(2, i) + + tau_Re_vf(E_idx)%sf(j, k, l) = & + tau_Re_vf(E_idx)%sf(j, k, l) - & + q_prim_vf(contxe + i)%sf(j, k, l)*tau_Re(2, i) + end do + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + end if + #:endif + + #:if not MFC_CASE_OPTIMIZATION or num_dims > 1 + if (bulk_stress) then ! Bulk stresses + $:GPU_PARALLEL_LOOP(collapse=3, private='[i,j,k,l,rho_visc, gamma_visc, pi_inf_visc, alpha_visc_sum ,alpha_visc, alpha_rho_visc, Re_visc, tau_Re]') + do l = is3_viscous%beg, is3_viscous%end + do k = -1, 1 + do j = is1_viscous%beg, is1_viscous%end + + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_fluids + alpha_rho_visc(i) = q_prim_vf(i)%sf(j, k, l) + if (bubbles_euler .and. num_fluids == 1) then + alpha_visc(i) = 1._wp - q_prim_vf(E_idx + i)%sf(j, k, l) + else + alpha_visc(i) = q_prim_vf(E_idx + i)%sf(j, k, l) + end if + end do + + if (bubbles_euler) then + rho_visc = 0._wp + gamma_visc = 0._wp + pi_inf_visc = 0._wp + + if (mpp_lim .and. (model_eqns == 2) .and. (num_fluids > 2)) then + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_fluids + rho_visc = rho_visc + alpha_rho_visc(i) + gamma_visc = gamma_visc + alpha_visc(i)*gammas(i) + pi_inf_visc = pi_inf_visc + alpha_visc(i)*pi_infs(i) + end do + else if ((model_eqns == 2) .and. (num_fluids > 2)) then + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_fluids - 1 + rho_visc = rho_visc + alpha_rho_visc(i) + gamma_visc = gamma_visc + alpha_visc(i)*gammas(i) + pi_inf_visc = pi_inf_visc + alpha_visc(i)*pi_infs(i) + end do + else + rho_visc = alpha_rho_visc(1) + gamma_visc = gammas(1) + pi_inf_visc = pi_infs(1) + end if + else + rho_visc = 0._wp + gamma_visc = 0._wp + pi_inf_visc = 0._wp + + alpha_visc_sum = 0._wp + + if (mpp_lim) then + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_fluids + alpha_rho_visc(i) = max(0._wp, alpha_rho_visc(i)) + alpha_visc(i) = min(max(0._wp, alpha_visc(i)), 1._wp) + alpha_visc_sum = alpha_visc_sum + alpha_visc(i) + end do + + alpha_visc = alpha_visc/max(alpha_visc_sum, sgm_eps) + + end if + + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_fluids + rho_visc = rho_visc + alpha_rho_visc(i) + gamma_visc = gamma_visc + alpha_visc(i)*gammas(i) + pi_inf_visc = pi_inf_visc + alpha_visc(i)*pi_infs(i) + end do + + if (viscous) then + call s_compute_re_visc(q_prim_vf, & + alpha_visc, j, k, l, & + Re_visc_nn, grad_x_vf, & + grad_y_vf, grad_z_vf) + call s_compute_mixture_re(alpha_visc, Re_visc_nn, Re_visc) + end if + end if + + tau_Re(2, 2) = (grad_x_vf(1)%sf(j, k, l) + & + grad_y_vf(2)%sf(j, k, l) + & + q_prim_vf(momxb + 1)%sf(j, k, l)/y_cc(k))/ & + Re_visc(2) + + tau_Re_vf(momxb + 1)%sf(j, k, l) = & + tau_Re_vf(momxb + 1)%sf(j, k, l) - & + tau_Re(2, 2) + + tau_Re_vf(E_idx)%sf(j, k, l) = & + tau_Re_vf(E_idx)%sf(j, k, l) - & + q_prim_vf(momxb + 1)%sf(j, k, l)*tau_Re(2, 2) + + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + end if + #:endif + + if (p == 0) return + #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 + + if (shear_stress) then ! Shear stresses + $:GPU_PARALLEL_LOOP(collapse=3, private='[alpha_visc, alpha_rho_visc, Re_visc, tau_Re]') + do l = is3_viscous%beg, is3_viscous%end + do k = -1, 1 + do j = is1_viscous%beg, is1_viscous%end + + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_fluids + alpha_rho_visc(i) = q_prim_vf(i)%sf(j, k, l) + if (bubbles_euler .and. num_fluids == 1) then + alpha_visc(i) = 1._wp - q_prim_vf(E_idx + i)%sf(j, k, l) + else + alpha_visc(i) = q_prim_vf(E_idx + i)%sf(j, k, l) + end if + end do + + if (bubbles_euler) then + rho_visc = 0._wp + gamma_visc = 0._wp + pi_inf_visc = 0._wp + + if (mpp_lim .and. (model_eqns == 2) .and. (num_fluids > 2)) then + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_fluids + rho_visc = rho_visc + alpha_rho_visc(i) + gamma_visc = gamma_visc + alpha_visc(i)*gammas(i) + pi_inf_visc = pi_inf_visc + alpha_visc(i)*pi_infs(i) + end do + else if ((model_eqns == 2) .and. (num_fluids > 2)) then + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_fluids - 1 + rho_visc = rho_visc + alpha_rho_visc(i) + gamma_visc = gamma_visc + alpha_visc(i)*gammas(i) + pi_inf_visc = pi_inf_visc + alpha_visc(i)*pi_infs(i) + end do + else + rho_visc = alpha_rho_visc(1) + gamma_visc = gammas(1) + pi_inf_visc = pi_infs(1) + end if + else + rho_visc = 0._wp + gamma_visc = 0._wp + pi_inf_visc = 0._wp + + alpha_visc_sum = 0._wp + + if (mpp_lim) then + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_fluids + alpha_rho_visc(i) = max(0._wp, alpha_rho_visc(i)) + alpha_visc(i) = min(max(0._wp, alpha_visc(i)), 1._wp) + alpha_visc_sum = alpha_visc_sum + alpha_visc(i) + end do + + alpha_visc = alpha_visc/max(alpha_visc_sum, sgm_eps) + + end if + + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_fluids + rho_visc = rho_visc + alpha_rho_visc(i) + gamma_visc = gamma_visc + alpha_visc(i)*gammas(i) + pi_inf_visc = pi_inf_visc + alpha_visc(i)*pi_infs(i) + end do + + if (viscous) then + call s_compute_re_visc(q_prim_vf, & + alpha_visc, j, k, l, & + Re_visc_nn, grad_x_vf, & + grad_y_vf, grad_z_vf) + call s_compute_mixture_re(alpha_visc, Re_visc_nn, Re_visc) + end if + end if + + tau_Re(2, 2) = -(2._wp/3._wp)*grad_z_vf(3)%sf(j, k, l)/y_cc(k)/ & + Re_visc(1) + + tau_Re(2, 3) = ((grad_z_vf(2)%sf(j, k, l) - & + q_prim_vf(momxe)%sf(j, k, l))/ & + y_cc(k) + grad_y_vf(3)%sf(j, k, l))/ & + Re_visc(1) + + $:GPU_LOOP(parallelism='[seq]') + do i = 2, 3 + tau_Re_vf(contxe + i)%sf(j, k, l) = & + tau_Re_vf(contxe + i)%sf(j, k, l) - & + tau_Re(2, i) + + tau_Re_vf(E_idx)%sf(j, k, l) = & + tau_Re_vf(E_idx)%sf(j, k, l) - & + q_prim_vf(contxe + i)%sf(j, k, l)*tau_Re(2, i) + end do + + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + end if + + if (bulk_stress) then ! Bulk stresses + $:GPU_PARALLEL_LOOP(collapse=3, private='[alpha_visc, alpha_rho_visc, Re_visc, tau_Re]') + do l = is3_viscous%beg, is3_viscous%end + do k = -1, 1 + do j = is1_viscous%beg, is1_viscous%end + + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_fluids + alpha_rho_visc(i) = q_prim_vf(i)%sf(j, k, l) + if (bubbles_euler .and. num_fluids == 1) then + alpha_visc(i) = 1._wp - q_prim_vf(E_idx + i)%sf(j, k, l) + else + alpha_visc(i) = q_prim_vf(E_idx + i)%sf(j, k, l) + end if + end do + + if (bubbles_euler) then + rho_visc = 0._wp + gamma_visc = 0._wp + pi_inf_visc = 0._wp + + if (mpp_lim .and. (model_eqns == 2) .and. (num_fluids > 2)) then + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_fluids + rho_visc = rho_visc + alpha_rho_visc(i) + gamma_visc = gamma_visc + alpha_visc(i)*gammas(i) + pi_inf_visc = pi_inf_visc + alpha_visc(i)*pi_infs(i) + end do + else if ((model_eqns == 2) .and. (num_fluids > 2)) then + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_fluids - 1 + rho_visc = rho_visc + alpha_rho_visc(i) + gamma_visc = gamma_visc + alpha_visc(i)*gammas(i) + pi_inf_visc = pi_inf_visc + alpha_visc(i)*pi_infs(i) + end do + else + rho_visc = alpha_rho_visc(1) + gamma_visc = gammas(1) + pi_inf_visc = pi_infs(1) + end if + else + rho_visc = 0._wp + gamma_visc = 0._wp + pi_inf_visc = 0._wp + + alpha_visc_sum = 0._wp + + if (mpp_lim) then + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_fluids + alpha_rho_visc(i) = max(0._wp, alpha_rho_visc(i)) + alpha_visc(i) = min(max(0._wp, alpha_visc(i)), 1._wp) + alpha_visc_sum = alpha_visc_sum + alpha_visc(i) + end do + + alpha_visc = alpha_visc/max(alpha_visc_sum, sgm_eps) + + end if + + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_fluids + rho_visc = rho_visc + alpha_rho_visc(i) + gamma_visc = gamma_visc + alpha_visc(i)*gammas(i) + pi_inf_visc = pi_inf_visc + alpha_visc(i)*pi_infs(i) + end do + + if (viscous) then + call s_compute_re_visc(q_prim_vf, & + alpha_visc, j, k, l, & + Re_visc_nn, grad_x_vf, & + grad_y_vf, grad_z_vf) + call s_compute_mixture_re(alpha_visc, Re_visc_nn, Re_visc) + end if + end if + + tau_Re(2, 2) = grad_z_vf(3)%sf(j, k, l)/y_cc(k)/ & + Re_visc(2) + + tau_Re_vf(momxb + 1)%sf(j, k, l) = & + tau_Re_vf(momxb + 1)%sf(j, k, l) - & + tau_Re(2, 2) + + tau_Re_vf(E_idx)%sf(j, k, l) = & + tau_Re_vf(E_idx)%sf(j, k, l) - & + q_prim_vf(momxb + 1)%sf(j, k, l)*tau_Re(2, 2) + + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + end if + #:endif + end subroutine s_compute_viscous_stress_cylindrical_boundary + + !> Computes viscous terms + !! @param qL_prim_rsx_vf Left reconstructed primitive variables in x + !! @param qL_prim_rsy_vf Left reconstructed primitive variables in y + !! @param qL_prim_rsz_vf Left reconstructed primitive variables in z + !! @param dqL_prim_dx_n Left primitive x-derivative + !! @param dqL_prim_dy_n Left primitive y-derivative + !! @param dqL_prim_dz_n Left primitive z-derivative + !! @param qL_prim Left cell-boundary primitive variables + !! @param qR_prim_rsx_vf Right reconstructed primitive variables in x + !! @param qR_prim_rsy_vf Right reconstructed primitive variables in y + !! @param qR_prim_rsz_vf Right reconstructed primitive variables in z + !! @param dqR_prim_dx_n Right primitive x-derivative + !! @param dqR_prim_dy_n Right primitive y-derivative + !! @param dqR_prim_dz_n Right primitive z-derivative + !! @param qR_prim Right cell-boundary primitive variables + !! @param q_prim_qp Cell-averaged primitive variables + !! @param dq_prim_dx_qp Cell-averaged primitive x-derivative + !! @param dq_prim_dy_qp Cell-averaged primitive y-derivative + !! @param dq_prim_dz_qp Cell-averaged primitive z-derivative + !! @param ix Index bounds in the x-direction + !! @param iy Index bounds in the y-direction + !! @param iz Index bounds in the z-direction + subroutine s_get_viscous(qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, & + dqL_prim_dx_n, dqL_prim_dy_n, dqL_prim_dz_n, & + qL_prim, & + qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf, & + dqR_prim_dx_n, dqR_prim_dy_n, dqR_prim_dz_n, & + qR_prim, & + q_prim_qp, & + dq_prim_dx_qp, dq_prim_dy_qp, dq_prim_dz_qp, & + ix, iy, iz) + + real(wp), dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:), & + intent(inout) :: qL_prim_rsx_vf, qR_prim_rsx_vf, & + qL_prim_rsy_vf, qR_prim_rsy_vf, & + qL_prim_rsz_vf, qR_prim_rsz_vf + + type(vector_field), dimension(num_dims), intent(inout) :: qL_prim, qR_prim + + type(vector_field), intent(in) :: q_prim_qp + + type(vector_field), dimension(1:num_dims), & + intent(inout) :: dqL_prim_dx_n, dqR_prim_dx_n, & + dqL_prim_dy_n, dqR_prim_dy_n, & + dqL_prim_dz_n, dqR_prim_dz_n + + type(vector_field), dimension(1), intent(inout) :: dq_prim_dx_qp, dq_prim_dy_qp, dq_prim_dz_qp + type(int_bounds_info), intent(in) :: ix, iy, iz + + integer :: i, j, k, l + + do i = 1, num_dims + + iv%beg = mom_idx%beg; iv%end = mom_idx%end + + $:GPU_UPDATE(device='[iv]') + + call s_reconstruct_cell_boundary_values_visc( & + q_prim_qp%vf(iv%beg:iv%end), & + qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, & + qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf, & + i, qL_prim(i)%vf(iv%beg:iv%end), qR_prim(i)%vf(iv%beg:iv%end), & + ix, iy, iz) + end do + + if (weno_Re_flux) then + ! Compute velocity gradient at cell centers using scalar + ! divergence theorem + do i = 1, num_dims + if (i == 1) then + call s_apply_scalar_divergence_theorem( & + qL_prim(i)%vf(iv%beg:iv%end), & + qR_prim(i)%vf(iv%beg:iv%end), & + dq_prim_dx_qp(1)%vf(iv%beg:iv%end), i, & + ix, iy, iz, iv, dx, m, buff_size) + elseif (i == 2) then + call s_apply_scalar_divergence_theorem( & + qL_prim(i)%vf(iv%beg:iv%end), & + qR_prim(i)%vf(iv%beg:iv%end), & + dq_prim_dy_qp(1)%vf(iv%beg:iv%end), i, & + ix, iy, iz, iv, dy, n, buff_size) + else + call s_apply_scalar_divergence_theorem( & + qL_prim(i)%vf(iv%beg:iv%end), & + qR_prim(i)%vf(iv%beg:iv%end), & + dq_prim_dz_qp(1)%vf(iv%beg:iv%end), i, & + ix, iy, iz, iv, dz, p, buff_size) + end if + end do + + else ! Compute velocity gradient at cell centers using finite differences + + iv%beg = mom_idx%beg; iv%end = mom_idx%end + $:GPU_UPDATE(device='[iv]') + + is1_viscous = ix; is2_viscous = iy; is3_viscous = iz + + $:GPU_UPDATE(device='[is1_viscous,is2_viscous,is3_viscous]') + + $:GPU_PARALLEL_LOOP(collapse=3) + do l = is3_viscous%beg, is3_viscous%end + do k = iy%beg, iy%end + do j = is1_viscous%beg + 1, is1_viscous%end + $:GPU_LOOP(parallelism='[seq]') + do i = iv%beg, iv%end + dqL_prim_dx_n(1)%vf(i)%sf(j, k, l) = & + (q_prim_qp%vf(i)%sf(j, k, l) - & + q_prim_qp%vf(i)%sf(j - 1, k, l))/ & + (x_cc(j) - x_cc(j - 1)) + end do + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + + $:GPU_PARALLEL_LOOP(collapse=3) + do l = is3_viscous%beg, is3_viscous%end + do k = is2_viscous%beg, is2_viscous%end + do j = is1_viscous%beg, is1_viscous%end - 1 + $:GPU_LOOP(parallelism='[seq]') + do i = iv%beg, iv%end + dqR_prim_dx_n(1)%vf(i)%sf(j, k, l) = & + (q_prim_qp%vf(i)%sf(j + 1, k, l) - & + q_prim_qp%vf(i)%sf(j, k, l))/ & + (x_cc(j + 1) - x_cc(j)) + end do + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + + if (n > 0) then + + #:if not MFC_CASE_OPTIMIZATION or num_dims > 1 + $:GPU_PARALLEL_LOOP(collapse=3) + do l = is3_viscous%beg, is3_viscous%end + do j = is2_viscous%beg + 1, is2_viscous%end + do k = is1_viscous%beg, is1_viscous%end + $:GPU_LOOP(parallelism='[seq]') + do i = iv%beg, iv%end + dqL_prim_dy_n(2)%vf(i)%sf(k, j, l) = & + (q_prim_qp%vf(i)%sf(k, j, l) - & + q_prim_qp%vf(i)%sf(k, j - 1, l))/ & + (y_cc(j) - y_cc(j - 1)) + end do + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + + $:GPU_PARALLEL_LOOP(collapse=3) + do l = is3_viscous%beg, is3_viscous%end + do j = is2_viscous%beg, is2_viscous%end - 1 + do k = is1_viscous%beg, is1_viscous%end + $:GPU_LOOP(parallelism='[seq]') + do i = iv%beg, iv%end + dqR_prim_dy_n(2)%vf(i)%sf(k, j, l) = & + (q_prim_qp%vf(i)%sf(k, j + 1, l) - & + q_prim_qp%vf(i)%sf(k, j, l))/ & + (y_cc(j + 1) - y_cc(j)) + end do + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + + $:GPU_PARALLEL_LOOP(collapse=3) + do l = is3_viscous%beg, is3_viscous%end + do j = is2_viscous%beg + 1, is2_viscous%end + do k = is1_viscous%beg + 1, is1_viscous%end - 1 + $:GPU_LOOP(parallelism='[seq]') + do i = iv%beg, iv%end + dqL_prim_dx_n(2)%vf(i)%sf(k, j, l) = & + (dqL_prim_dx_n(1)%vf(i)%sf(k, j, l) + & + dqR_prim_dx_n(1)%vf(i)%sf(k, j, l) + & + dqL_prim_dx_n(1)%vf(i)%sf(k, j - 1, l) + & + dqR_prim_dx_n(1)%vf(i)%sf(k, j - 1, l)) + + dqL_prim_dx_n(2)%vf(i)%sf(k, j, l) = 25.e-2_wp* & + dqL_prim_dx_n(2)%vf(i)%sf(k, j, l) + end do + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + + $:GPU_PARALLEL_LOOP(collapse=3) + do l = is3_viscous%beg, is3_viscous%end + do j = is2_viscous%beg, is2_viscous%end - 1 + do k = is1_viscous%beg + 1, is1_viscous%end - 1 + $:GPU_LOOP(parallelism='[seq]') + do i = iv%beg, iv%end + dqR_prim_dx_n(2)%vf(i)%sf(k, j, l) = & + (dqL_prim_dx_n(1)%vf(i)%sf(k, j + 1, l) + & + dqR_prim_dx_n(1)%vf(i)%sf(k, j + 1, l) + & + dqL_prim_dx_n(1)%vf(i)%sf(k, j, l) + & + dqR_prim_dx_n(1)%vf(i)%sf(k, j, l)) + + dqR_prim_dx_n(2)%vf(i)%sf(k, j, l) = 25.e-2_wp* & + dqR_prim_dx_n(2)%vf(i)%sf(k, j, l) + + end do + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + + $:GPU_PARALLEL_LOOP(collapse=3) + do l = is3_viscous%beg, is3_viscous%end + do k = is2_viscous%beg + 1, is2_viscous%end - 1 + do j = is1_viscous%beg + 1, is1_viscous%end + $:GPU_LOOP(parallelism='[seq]') + do i = iv%beg, iv%end + dqL_prim_dy_n(1)%vf(i)%sf(j, k, l) = & + (dqL_prim_dy_n(2)%vf(i)%sf(j, k, l) + & + dqR_prim_dy_n(2)%vf(i)%sf(j, k, l) + & + dqL_prim_dy_n(2)%vf(i)%sf(j - 1, k, l) + & + dqR_prim_dy_n(2)%vf(i)%sf(j - 1, k, l)) + + dqL_prim_dy_n(1)%vf(i)%sf(j, k, l) = 25.e-2_wp* & + dqL_prim_dy_n(1)%vf(i)%sf(j, k, l) + + end do + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + + $:GPU_PARALLEL_LOOP(collapse=3) + do l = is3_viscous%beg, is3_viscous%end + do k = is2_viscous%beg + 1, is2_viscous%end - 1 + do j = is1_viscous%beg, is1_viscous%end - 1 + $:GPU_LOOP(parallelism='[seq]') + do i = iv%beg, iv%end + dqR_prim_dy_n(1)%vf(i)%sf(j, k, l) = & + (dqL_prim_dy_n(2)%vf(i)%sf(j + 1, k, l) + & + dqR_prim_dy_n(2)%vf(i)%sf(j + 1, k, l) + & + dqL_prim_dy_n(2)%vf(i)%sf(j, k, l) + & + dqR_prim_dy_n(2)%vf(i)%sf(j, k, l)) + + dqR_prim_dy_n(1)%vf(i)%sf(j, k, l) = 25.e-2_wp* & + dqR_prim_dy_n(1)%vf(i)%sf(j, k, l) + + end do + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + + #:endif + + if (p > 0) then + #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 + $:GPU_PARALLEL_LOOP(collapse=3) + do j = is3_viscous%beg + 1, is3_viscous%end + do l = is2_viscous%beg, is2_viscous%end + do k = is1_viscous%beg, is1_viscous%end + $:GPU_LOOP(parallelism='[seq]') + do i = iv%beg, iv%end + + dqL_prim_dz_n(3)%vf(i)%sf(k, l, j) = & + (q_prim_qp%vf(i)%sf(k, l, j) - & + q_prim_qp%vf(i)%sf(k, l, j - 1))/ & + (z_cc(j) - z_cc(j - 1)) + end do + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + + $:GPU_PARALLEL_LOOP(collapse=3) + do j = is3_viscous%beg, is3_viscous%end - 1 + do l = is2_viscous%beg, is2_viscous%end + do k = is1_viscous%beg, is1_viscous%end + $:GPU_LOOP(parallelism='[seq]') + do i = iv%beg, iv%end + + dqR_prim_dz_n(3)%vf(i)%sf(k, l, j) = & + (q_prim_qp%vf(i)%sf(k, l, j + 1) - & + q_prim_qp%vf(i)%sf(k, l, j))/ & + (z_cc(j + 1) - z_cc(j)) + end do + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + + $:GPU_PARALLEL_LOOP(collapse=3) + do l = is3_viscous%beg + 1, is3_viscous%end - 1 + do k = is2_viscous%beg, is2_viscous%end + do j = is1_viscous%beg + 1, is1_viscous%end + $:GPU_LOOP(parallelism='[seq]') + do i = iv%beg, iv%end + + dqL_prim_dz_n(1)%vf(i)%sf(j, k, l) = & + (dqL_prim_dz_n(3)%vf(i)%sf(j, k, l) + & + dqR_prim_dz_n(3)%vf(i)%sf(j, k, l) + & + dqL_prim_dz_n(3)%vf(i)%sf(j - 1, k, l) + & + dqR_prim_dz_n(3)%vf(i)%sf(j - 1, k, l)) + + dqL_prim_dz_n(1)%vf(i)%sf(j, k, l) = 25.e-2_wp* & + dqL_prim_dz_n(1)%vf(i)%sf(j, k, l) + + end do + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + + $:GPU_PARALLEL_LOOP(collapse=3) + do l = is3_viscous%beg + 1, is3_viscous%end - 1 + do k = is2_viscous%beg, is2_viscous%end + do j = is1_viscous%beg, is1_viscous%end - 1 + $:GPU_LOOP(parallelism='[seq]') + do i = iv%beg, iv%end + + dqR_prim_dz_n(1)%vf(i)%sf(j, k, l) = & + (dqL_prim_dz_n(3)%vf(i)%sf(j + 1, k, l) + & + dqR_prim_dz_n(3)%vf(i)%sf(j + 1, k, l) + & + dqL_prim_dz_n(3)%vf(i)%sf(j, k, l) + & + dqR_prim_dz_n(3)%vf(i)%sf(j, k, l)) + + dqR_prim_dz_n(1)%vf(i)%sf(j, k, l) = 25.e-2_wp* & + dqR_prim_dz_n(1)%vf(i)%sf(j, k, l) + + end do + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + + $:GPU_PARALLEL_LOOP(collapse=3) + do l = is3_viscous%beg + 1, is3_viscous%end - 1 + do j = is2_viscous%beg + 1, is2_viscous%end + do k = is1_viscous%beg, is1_viscous%end + $:GPU_LOOP(parallelism='[seq]') + do i = iv%beg, iv%end + + dqL_prim_dz_n(2)%vf(i)%sf(k, j, l) = & + (dqL_prim_dz_n(3)%vf(i)%sf(k, j, l) + & + dqR_prim_dz_n(3)%vf(i)%sf(k, j, l) + & + dqL_prim_dz_n(3)%vf(i)%sf(k, j - 1, l) + & + dqR_prim_dz_n(3)%vf(i)%sf(k, j - 1, l)) + + dqL_prim_dz_n(2)%vf(i)%sf(k, j, l) = 25.e-2_wp* & + dqL_prim_dz_n(2)%vf(i)%sf(k, j, l) + + end do + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + + $:GPU_PARALLEL_LOOP(collapse=3) + do l = is3_viscous%beg + 1, is3_viscous%end - 1 + do j = is2_viscous%beg, is2_viscous%end - 1 + do k = is1_viscous%beg, is1_viscous%end + $:GPU_LOOP(parallelism='[seq]') + do i = iv%beg, iv%end + + dqR_prim_dz_n(2)%vf(i)%sf(k, j, l) = & + (dqL_prim_dz_n(3)%vf(i)%sf(k, j + 1, l) + & + dqR_prim_dz_n(3)%vf(i)%sf(k, j + 1, l) + & + dqL_prim_dz_n(3)%vf(i)%sf(k, j, l) + & + dqR_prim_dz_n(3)%vf(i)%sf(k, j, l)) + + dqR_prim_dz_n(2)%vf(i)%sf(k, j, l) = 25.e-2_wp* & + dqR_prim_dz_n(2)%vf(i)%sf(k, j, l) + + end do + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + + $:GPU_PARALLEL_LOOP(collapse=3) + do j = is3_viscous%beg + 1, is3_viscous%end + do l = is2_viscous%beg + 1, is2_viscous%end - 1 + do k = is1_viscous%beg, is1_viscous%end + $:GPU_LOOP(parallelism='[seq]') + do i = iv%beg, iv%end + + dqL_prim_dy_n(3)%vf(i)%sf(k, l, j) = & + (dqL_prim_dy_n(2)%vf(i)%sf(k, l, j) + & + dqR_prim_dy_n(2)%vf(i)%sf(k, l, j) + & + dqL_prim_dy_n(2)%vf(i)%sf(k, l, j - 1) + & + dqR_prim_dy_n(2)%vf(i)%sf(k, l, j - 1)) + + dqL_prim_dy_n(3)%vf(i)%sf(k, l, j) = 25.e-2_wp* & + dqL_prim_dy_n(3)%vf(i)%sf(k, l, j) + + end do + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + + $:GPU_PARALLEL_LOOP(collapse=3) + do j = is3_viscous%beg, is3_viscous%end - 1 + do l = is2_viscous%beg + 1, is2_viscous%end - 1 + do k = is1_viscous%beg, is1_viscous%end + $:GPU_LOOP(parallelism='[seq]') + do i = iv%beg, iv%end + + dqR_prim_dy_n(3)%vf(i)%sf(k, l, j) = & + (dqL_prim_dy_n(2)%vf(i)%sf(k, l, j + 1) + & + dqR_prim_dy_n(2)%vf(i)%sf(k, l, j + 1) + & + dqL_prim_dy_n(2)%vf(i)%sf(k, l, j) + & + dqR_prim_dy_n(2)%vf(i)%sf(k, l, j)) + + dqR_prim_dy_n(3)%vf(i)%sf(k, l, j) = 25.e-2_wp* & + dqR_prim_dy_n(3)%vf(i)%sf(k, l, j) + + end do + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + $:GPU_PARALLEL_LOOP(collapse=3) + do j = is3_viscous%beg + 1, is3_viscous%end + do l = is2_viscous%beg, is2_viscous%end + do k = is1_viscous%beg + 1, is1_viscous%end - 1 + $:GPU_LOOP(parallelism='[seq]') + do i = iv%beg, iv%end + + dqL_prim_dx_n(3)%vf(i)%sf(k, l, j) = & + (dqL_prim_dx_n(1)%vf(i)%sf(k, l, j) + & + dqR_prim_dx_n(1)%vf(i)%sf(k, l, j) + & + dqL_prim_dx_n(1)%vf(i)%sf(k, l, j - 1) + & + dqR_prim_dx_n(1)%vf(i)%sf(k, l, j - 1)) + + dqL_prim_dx_n(3)%vf(i)%sf(k, l, j) = 25.e-2_wp* & + dqL_prim_dx_n(3)%vf(i)%sf(k, l, j) + + end do + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + $:GPU_PARALLEL_LOOP(collapse=3) + do j = is3_viscous%beg, is3_viscous%end - 1 + do l = is2_viscous%beg, is2_viscous%end + do k = is1_viscous%beg + 1, is1_viscous%end - 1 + $:GPU_LOOP(parallelism='[seq]') + do i = iv%beg, iv%end + dqR_prim_dx_n(3)%vf(i)%sf(k, l, j) = & + (dqL_prim_dx_n(1)%vf(i)%sf(k, l, j + 1) + & + dqR_prim_dx_n(1)%vf(i)%sf(k, l, j + 1) + & + dqL_prim_dx_n(1)%vf(i)%sf(k, l, j) + & + dqR_prim_dx_n(1)%vf(i)%sf(k, l, j)) + + dqR_prim_dx_n(3)%vf(i)%sf(k, l, j) = 25.e-2_wp* & + dqR_prim_dx_n(3)%vf(i)%sf(k, l, j) + + end do + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + + do i = iv%beg, iv%end + call s_compute_fd_gradient(q_prim_qp%vf(i), & + dq_prim_dx_qp(1)%vf(i), & + dq_prim_dy_qp(1)%vf(i), & + dq_prim_dz_qp(1)%vf(i)) + end do + #:endif + + else + + do i = iv%beg, iv%end + call s_compute_fd_gradient(q_prim_qp%vf(i), & + dq_prim_dx_qp(1)%vf(i), & + dq_prim_dy_qp(1)%vf(i), & + dq_prim_dy_qp(1)%vf(i)) + end do + + end if + + else + + do i = iv%beg, iv%end + call s_compute_fd_gradient(q_prim_qp%vf(i), & + dq_prim_dx_qp(1)%vf(i), & + dq_prim_dx_qp(1)%vf(i), & + dq_prim_dx_qp(1)%vf(i)) + end do + + end if + + end if + + end subroutine s_get_viscous + + !> @brief Reconstructs left and right cell-boundary values of viscous primitive variables using WENO or MUSCL. + subroutine s_reconstruct_cell_boundary_values_visc(v_vf, vL_x, vL_y, vL_z, vR_x, vR_y, vR_z, & + norm_dir, vL_prim_vf, vR_prim_vf, ix, iy, iz) + + type(scalar_field), dimension(iv%beg:iv%end), intent(in) :: v_vf + type(scalar_field), dimension(iv%beg:iv%end), intent(inout) :: vL_prim_vf, vR_prim_vf + + real(wp), dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:), intent(inout) :: vL_x, vL_y, vL_z, vR_x, vR_y, vR_z + integer, intent(in) :: norm_dir + type(int_bounds_info), intent(in) :: ix, iy, iz + + integer :: recon_dir !< Coordinate direction of the WENO reconstruction + + integer :: i, j, k, l + + #:for SCHEME, TYPE in [('weno','WENO_TYPE'), ('muscl','MUSCL_TYPE')] + if (recon_type == ${TYPE}$ .or. dummy) then + ! Reconstruction in s1-direction + + if (norm_dir == 1) then + is1_viscous = ix; is2_viscous = iy; is3_viscous = iz + recon_dir = 1; is1_viscous%beg = is1_viscous%beg + ${SCHEME}$_polyn + is1_viscous%end = is1_viscous%end - ${SCHEME}$_polyn + + elseif (norm_dir == 2) then + is1_viscous = iy; is2_viscous = ix; is3_viscous = iz + recon_dir = 2; is1_viscous%beg = is1_viscous%beg + ${SCHEME}$_polyn + is1_viscous%end = is1_viscous%end - ${SCHEME}$_polyn + + else + is1_viscous = iz; is2_viscous = iy; is3_viscous = ix + recon_dir = 3; is1_viscous%beg = is1_viscous%beg + ${SCHEME}$_polyn + is1_viscous%end = is1_viscous%end - ${SCHEME}$_polyn + + end if + + $:GPU_UPDATE(device='[is1_viscous, is2_viscous, is3_viscous, iv]') + if (n > 0) then + if (p > 0) then + call s_${SCHEME}$ (v_vf(iv%beg:iv%end), & + vL_x(:, :, :, iv%beg:iv%end), vL_y(:, :, :, iv%beg:iv%end), vL_z(:, :, :, iv%beg:iv%end), vR_x(:, :, :, iv%beg:iv%end), vR_y(:, :, :, iv%beg:iv%end), vR_z(:, :, :, iv%beg:iv%end), & + recon_dir, & + is1_viscous, is2_viscous, is3_viscous) + else + call s_${SCHEME}$ (v_vf(iv%beg:iv%end), & + vL_x(:, :, :, iv%beg:iv%end), vL_y(:, :, :, iv%beg:iv%end), vL_z(:, :, :, :), vR_x(:, :, :, iv%beg:iv%end), vR_y(:, :, :, iv%beg:iv%end), vR_z(:, :, :, :), & + recon_dir, & + is1_viscous, is2_viscous, is3_viscous) + end if + else + call s_${SCHEME}$ (v_vf(iv%beg:iv%end), & + vL_x(:, :, :, iv%beg:iv%end), vL_y(:, :, :, :), vL_z(:, :, :, :), vR_x(:, :, :, iv%beg:iv%end), vR_y(:, :, :, :), vR_z(:, :, :, :), & + recon_dir, & + is1_viscous, is2_viscous, is3_viscous) + end if + end if + #:endfor + + if (viscous .or. dummy) then + if (weno_Re_flux) then + if (norm_dir == 2) then + $:GPU_PARALLEL_LOOP(collapse=4) + do i = iv%beg, iv%end + do l = is3_viscous%beg, is3_viscous%end + do j = is1_viscous%beg, is1_viscous%end + do k = is2_viscous%beg, is2_viscous%end + vL_prim_vf(i)%sf(k, j, l) = vL_y(j, k, l, i) + vR_prim_vf(i)%sf(k, j, l) = vR_y(j, k, l, i) + end do + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + elseif (norm_dir == 3) then + $:GPU_PARALLEL_LOOP(collapse=4) + do i = iv%beg, iv%end + do j = is1_viscous%beg, is1_viscous%end + do k = is2_viscous%beg, is2_viscous%end + do l = is3_viscous%beg, is3_viscous%end + vL_prim_vf(i)%sf(l, k, j) = vL_z(j, k, l, i) + vR_prim_vf(i)%sf(l, k, j) = vR_z(j, k, l, i) + end do + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + elseif (norm_dir == 1) then + $:GPU_PARALLEL_LOOP(collapse=4) + do i = iv%beg, iv%end + do l = is3_viscous%beg, is3_viscous%end + do k = is2_viscous%beg, is2_viscous%end + do j = is1_viscous%beg, is1_viscous%end + vL_prim_vf(i)%sf(j, k, l) = vL_x(j, k, l, i) + vR_prim_vf(i)%sf(j, k, l) = vR_x(j, k, l, i) + end do + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + end if + end if + end if + + end subroutine s_reconstruct_cell_boundary_values_visc + + !> @brief Reconstructs left and right cell-boundary values of viscous primitive variable derivatives using WENO or MUSCL. + subroutine s_reconstruct_cell_boundary_values_visc_deriv(v_vf, vL_x, vL_y, vL_z, vR_x, vR_y, vR_z, & + norm_dir, vL_prim_vf, vR_prim_vf, ix, iy, iz) + type(scalar_field), dimension(iv%beg:iv%end), intent(in) :: v_vf + real(wp), dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, iv%beg:), intent(inout) :: vL_x, vL_y, vL_z, vR_x, vR_y, vR_z + type(scalar_field), dimension(iv%beg:iv%end), intent(inout) :: vL_prim_vf, vR_prim_vf + type(int_bounds_info), intent(in) :: ix, iy, iz + + integer, intent(IN) :: norm_dir + + integer :: recon_dir !< Coordinate direction of the WENO reconstruction + + integer :: i, j, k, l + #:for SCHEME, TYPE in [('weno','WENO_TYPE'), ('muscl','MUSCL_TYPE')] + if (recon_type == ${TYPE}$) then + ! Reconstruction in s1-direction + + if (norm_dir == 1) then + is1_viscous = ix; is2_viscous = iy; is3_viscous = iz + recon_dir = 1; is1_viscous%beg = is1_viscous%beg + ${SCHEME}$_polyn + is1_viscous%end = is1_viscous%end - ${SCHEME}$_polyn + + elseif (norm_dir == 2) then + is1_viscous = iy; is2_viscous = ix; is3_viscous = iz + recon_dir = 2; is1_viscous%beg = is1_viscous%beg + ${SCHEME}$_polyn + is1_viscous%end = is1_viscous%end - ${SCHEME}$_polyn + + else + is1_viscous = iz; is2_viscous = iy; is3_viscous = ix + recon_dir = 3; is1_viscous%beg = is1_viscous%beg + ${SCHEME}$_polyn + is1_viscous%end = is1_viscous%end - ${SCHEME}$_polyn + + end if + $:GPU_UPDATE(device='[is1_viscous, is2_viscous, is3_viscous, iv]') + if (n > 0) then + if (p > 0) then + + call s_${SCHEME}$ (v_vf(iv%beg:iv%end), & + vL_x(:, :, :, iv%beg:iv%end), vL_y(:, :, :, iv%beg:iv%end), vL_z(:, :, :, iv%beg:iv%end), vR_x(:, :, :, iv%beg:iv%end), vR_y(:, :, :, iv%beg:iv%end), vR_z(:, :, :, iv%beg:iv%end), & + recon_dir, & + is1_viscous, is2_viscous, is3_viscous) + else + call s_${SCHEME}$ (v_vf(iv%beg:iv%end), & + vL_x(:, :, :, iv%beg:iv%end), vL_y(:, :, :, iv%beg:iv%end), vL_z(:, :, :, :), vR_x(:, :, :, iv%beg:iv%end), vR_y(:, :, :, iv%beg:iv%end), vR_z(:, :, :, :), & + recon_dir, & + is1_viscous, is2_viscous, is3_viscous) + end if + else + + call s_${SCHEME}$ (v_vf(iv%beg:iv%end), & + vL_x(:, :, :, iv%beg:iv%end), vL_y(:, :, :, :), vL_z(:, :, :, :), vR_x(:, :, :, iv%beg:iv%end), vR_y(:, :, :, :), vR_z(:, :, :, :), & + recon_dir, & + is1_viscous, is2_viscous, is3_viscous) + end if + end if + #:endfor + + if (viscous .or. dummy) then + if (weno_Re_flux) then + if (norm_dir == 2) then + $:GPU_PARALLEL_LOOP(collapse=4) + do i = iv%beg, iv%end + do l = is3_viscous%beg, is3_viscous%end + do j = is1_viscous%beg, is1_viscous%end + do k = is2_viscous%beg, is2_viscous%end + vL_prim_vf(i)%sf(k, j, l) = vL_y(j, k, l, i) + vR_prim_vf(i)%sf(k, j, l) = vR_y(j, k, l, i) + end do + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + elseif (norm_dir == 3) then + $:GPU_PARALLEL_LOOP(collapse=4) + do i = iv%beg, iv%end + do j = is1_viscous%beg, is1_viscous%end + do k = is2_viscous%beg, is2_viscous%end + do l = is3_viscous%beg, is3_viscous%end + vL_prim_vf(i)%sf(l, k, j) = vL_z(j, k, l, i) + vR_prim_vf(i)%sf(l, k, j) = vR_z(j, k, l, i) + end do + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + elseif (norm_dir == 1) then + $:GPU_PARALLEL_LOOP(collapse=4) + do i = iv%beg, iv%end + do l = is3_viscous%beg, is3_viscous%end + do k = is2_viscous%beg, is2_viscous%end + do j = is1_viscous%beg, is1_viscous%end + vL_prim_vf(i)%sf(j, k, l) = vL_x(j, k, l, i) + vR_prim_vf(i)%sf(j, k, l) = vR_x(j, k, l, i) + end do + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + end if + end if + end if + + end subroutine s_reconstruct_cell_boundary_values_visc_deriv + + !> The purpose of this subroutine is to employ the inputted + !! left and right cell-boundary integral-averaged variables + !! to compute the relevant cell-average first-order spatial + !! derivatives in the x-, y- or z-direction by means of the + !! scalar divergence theorem. + !! @param vL_vf Left cell-boundary integral averages + !! @param vR_vf Right cell-boundary integral averages + !! @param dv_ds_vf Cell-average first-order spatial derivatives + !! @param norm_dir Splitting coordinate direction + !! @param ix Index bounds in the x-direction + !! @param iy Index bounds in the y-direction + !! @param iz Index bounds in the z-direction + !! @param iv_in Variable index bounds + !! @param dL Cell width array + !! @param dim Dimension size + !! @param buff_size_in Buffer layer size + subroutine s_apply_scalar_divergence_theorem(vL_vf, vR_vf, & + dv_ds_vf, & + norm_dir, & + ix, iy, iz, iv_in, & + dL, dim, buff_size_in) + + ! arrays of cell widths + type(scalar_field), & + dimension(iv%beg:iv%end), & + intent(in) :: vL_vf, vR_vf + + type(scalar_field), & + dimension(iv%beg:iv%end), & + intent(inout) :: dv_ds_vf + + integer, intent(in) :: norm_dir + type(int_bounds_info), intent(in) :: ix, iy, iz, iv_in + integer, intent(in) :: dim, buff_size_in + real(wp), dimension(-buff_size_in:dim + buff_size_in), intent(in) :: dL + + integer :: i, j, k, l !< Generic loop iterators + + is1_viscous = ix + is2_viscous = iy + is3_viscous = iz + iv = iv_in + + $:GPU_UPDATE(device='[is1_viscous, is2_viscous, is3_viscous, iv]') + + ! First-Order Spatial Derivatives in x-direction + if (norm_dir == 1) then + + ! A general application of the scalar divergence theorem that + ! utilizes the left and right cell-boundary integral-averages, + ! inside each cell, or an arithmetic mean of these two at the + ! cell-boundaries, to calculate the cell-averaged first-order + ! spatial derivatives inside the cell. + + $:GPU_PARALLEL_LOOP(collapse=3) + do l = is3_viscous%beg, is3_viscous%end + do k = is2_viscous%beg, is2_viscous%end + do j = is1_viscous%beg + 1, is1_viscous%end - 1 + $:GPU_LOOP(parallelism='[seq]') + do i = iv%beg, iv%end + dv_ds_vf(i)%sf(j, k, l) = & + 1._wp/((1._wp + wa_flg)*dL(j)) & + *(wa_flg*vL_vf(i)%sf(j + 1, k, l) & + + vR_vf(i)%sf(j, k, l) & + - vL_vf(i)%sf(j, k, l) & + - wa_flg*vR_vf(i)%sf(j - 1, k, l)) + end do + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + + ! END: First-Order Spatial Derivatives in x-direction + + ! First-Order Spatial Derivatives in y-direction + elseif (norm_dir == 2) then + + ! A general application of the scalar divergence theorem that + ! utilizes the left and right cell-boundary integral-averages, + ! inside each cell, or an arithmetic mean of these two at the + ! cell-boundaries, to calculate the cell-averaged first-order + ! spatial derivatives inside the cell. + + $:GPU_PARALLEL_LOOP(collapse=3) + do l = is3_viscous%beg, is3_viscous%end + do k = is2_viscous%beg + 1, is2_viscous%end - 1 + do j = is1_viscous%beg, is1_viscous%end + $:GPU_LOOP(parallelism='[seq]') + do i = iv%beg, iv%end + dv_ds_vf(i)%sf(j, k, l) = & + 1._wp/((1._wp + wa_flg)*dL(k)) & + *(wa_flg*vL_vf(i)%sf(j, k + 1, l) & + + vR_vf(i)%sf(j, k, l) & + - vL_vf(i)%sf(j, k, l) & + - wa_flg*vR_vf(i)%sf(j, k - 1, l)) + end do + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + + ! END: First-Order Spatial Derivatives in y-direction + + ! First-Order Spatial Derivatives in z-direction + else + + ! A general application of the scalar divergence theorem that + ! utilizes the left and right cell-boundary integral-averages, + ! inside each cell, or an arithmetic mean of these two at the + ! cell-boundaries, to calculate the cell-averaged first-order + ! spatial derivatives inside the cell. + + $:GPU_PARALLEL_LOOP(collapse=3) + do l = is3_viscous%beg + 1, is3_viscous%end - 1 + do k = is2_viscous%beg, is2_viscous%end + do j = is1_viscous%beg, is1_viscous%end + $:GPU_LOOP(parallelism='[seq]') + do i = iv%beg, iv%end + dv_ds_vf(i)%sf(j, k, l) = & + 1._wp/((1._wp + wa_flg)*dL(l)) & + *(wa_flg*vL_vf(i)%sf(j, k, l + 1) & + + vR_vf(i)%sf(j, k, l) & + - vL_vf(i)%sf(j, k, l) & + - wa_flg*vR_vf(i)%sf(j, k, l - 1)) + end do + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + + end if + ! END: First-Order Spatial Derivatives in z-direction + + end subroutine s_apply_scalar_divergence_theorem + + !> Computes the scalar gradient fields via finite differences + !! @param var Variable to compute derivative of + !! @param grad_x First coordinate direction component of the derivative + !! @param grad_y Second coordinate direction component of the derivative + !! @param grad_z Third coordinate direction component of the derivative + subroutine s_compute_fd_gradient(var, grad_x, grad_y, grad_z) + + type(scalar_field), intent(in) :: var + type(scalar_field), intent(inout) :: grad_x + type(scalar_field), intent(inout) :: grad_y + type(scalar_field), intent(inout) :: grad_z + type(int_bounds_info) :: ix, iy, iz + + integer :: j, k, l !< Generic loop iterators + + ix%beg = 1 - buff_size; ix%end = m + buff_size - 1 + if (n > 0) then + iy%beg = 1 - buff_size; iy%end = n + buff_size - 1 + else + iy%beg = 0; iy%end = 0 + end if + + if (p > 0) then + iz%beg = 1 - buff_size; iz%end = p + buff_size - 1 + else + iz%beg = 0; iz%end = 0 + end if + + is1_viscous = ix; is2_viscous = iy; is3_viscous = iz + + $:GPU_UPDATE(device='[is1_viscous,is2_viscous,is3_viscous]') + + $:GPU_PARALLEL_LOOP(collapse=3) + do l = is3_viscous%beg, is3_viscous%end + do k = is2_viscous%beg, is2_viscous%end + do j = is1_viscous%beg, is1_viscous%end + grad_x%sf(j, k, l) = & + (var%sf(j + 1, k, l) - var%sf(j - 1, k, l))/ & + (x_cc(j + 1) - x_cc(j - 1)) + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + + if (n > 0) then + $:GPU_PARALLEL_LOOP(collapse=3) + do l = is3_viscous%beg, is3_viscous%end + do k = is2_viscous%beg, is2_viscous%end + do j = is1_viscous%beg, is1_viscous%end + grad_y%sf(j, k, l) = & + (var%sf(j, k + 1, l) - var%sf(j, k - 1, l))/ & + (y_cc(k + 1) - y_cc(k - 1)) + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + end if + + if (p > 0) then + $:GPU_PARALLEL_LOOP(collapse=3) + do l = is3_viscous%beg, is3_viscous%end + do k = is2_viscous%beg, is2_viscous%end + do j = is1_viscous%beg, is1_viscous%end + grad_z%sf(j, k, l) = & + (var%sf(j, k, l + 1) - var%sf(j, k, l - 1))/ & + (z_cc(l + 1) - z_cc(l - 1)) + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + end if + + $:GPU_PARALLEL_LOOP(collapse=2) + do l = idwbuff(3)%beg, idwbuff(3)%end + do k = idwbuff(2)%beg, idwbuff(2)%end + grad_x%sf(idwbuff(1)%beg, k, l) = & + (-3._wp*var%sf(idwbuff(1)%beg, k, l) + 4._wp*var%sf(idwbuff(1)%beg + 1, k, l) - var%sf(idwbuff(1)%beg + 2, k, l))/ & + (x_cc(idwbuff(1)%beg + 2) - x_cc(idwbuff(1)%beg)) + grad_x%sf(idwbuff(1)%end, k, l) = & + (+3._wp*var%sf(idwbuff(1)%end, k, l) - 4._wp*var%sf(idwbuff(1)%end - 1, k, l) + var%sf(idwbuff(1)%end - 2, k, l))/ & + (x_cc(idwbuff(1)%end) - x_cc(idwbuff(1)%end - 2)) + end do + end do + $:END_GPU_PARALLEL_LOOP() + if (n > 0) then + $:GPU_PARALLEL_LOOP(collapse=2) + do l = idwbuff(3)%beg, idwbuff(3)%end + do j = idwbuff(1)%beg, idwbuff(1)%end + grad_y%sf(j, idwbuff(2)%beg, l) = & + (-3._wp*var%sf(j, idwbuff(2)%beg, l) + 4._wp*var%sf(j, idwbuff(2)%beg + 1, l) - var%sf(j, idwbuff(2)%beg + 2, l))/ & + (y_cc(idwbuff(2)%beg + 2) - y_cc(idwbuff(2)%beg)) + grad_y%sf(j, idwbuff(2)%end, l) = & + (+3._wp*var%sf(j, idwbuff(2)%end, l) - 4._wp*var%sf(j, idwbuff(2)%end - 1, l) + var%sf(j, idwbuff(2)%end - 2, l))/ & + (y_cc(idwbuff(2)%end) - y_cc(idwbuff(2)%end - 2)) + end do + end do + $:END_GPU_PARALLEL_LOOP() + if (p > 0) then + $:GPU_PARALLEL_LOOP(collapse=2) + do k = idwbuff(2)%beg, idwbuff(2)%end + do j = idwbuff(1)%beg, idwbuff(1)%end + grad_z%sf(j, k, idwbuff(3)%beg) = & + (-3._wp*var%sf(j, k, idwbuff(3)%beg) + 4._wp*var%sf(j, k, idwbuff(3)%beg + 1) - var%sf(j, k, idwbuff(3)%beg + 2))/ & + (z_cc(idwbuff(3)%beg + 2) - z_cc(is3_viscous%beg)) + grad_z%sf(j, k, idwbuff(3)%end) = & + (+3._wp*var%sf(j, k, idwbuff(3)%end) - 4._wp*var%sf(j, k, idwbuff(3)%end - 1) + var%sf(j, k, idwbuff(3)%end - 2))/ & + (z_cc(idwbuff(3)%end) - z_cc(idwbuff(3)%end - 2)) + end do + end do + $:END_GPU_PARALLEL_LOOP() + end if + end if + + if (bc_x%beg <= BC_GHOST_EXTRAP) then + $:GPU_PARALLEL_LOOP(collapse=2) + do l = idwbuff(3)%beg, idwbuff(3)%end + do k = idwbuff(2)%beg, idwbuff(2)%end + grad_x%sf(0, k, l) = (-3._wp*var%sf(0, k, l) + 4._wp*var%sf(1, k, l) - var%sf(2, k, l))/ & + (x_cc(2) - x_cc(0)) + end do + end do + $:END_GPU_PARALLEL_LOOP() + end if + if (bc_x%end <= BC_GHOST_EXTRAP) then + $:GPU_PARALLEL_LOOP(collapse=2) + do l = idwbuff(3)%beg, idwbuff(3)%end + do k = idwbuff(2)%beg, idwbuff(2)%end + grad_x%sf(m, k, l) = (3._wp*var%sf(m, k, l) - 4._wp*var%sf(m - 1, k, l) + var%sf(m - 2, k, l))/ & + (x_cc(m) - x_cc(m - 2)) + end do + end do + $:END_GPU_PARALLEL_LOOP() + end if + if (n > 0) then + if (bc_y%beg <= BC_GHOST_EXTRAP .and. bc_y%beg /= BC_NULL) then + $:GPU_PARALLEL_LOOP(collapse=2) + do l = idwbuff(3)%beg, idwbuff(3)%end + do j = idwbuff(1)%beg, idwbuff(1)%end + grad_y%sf(j, 0, l) = (-3._wp*var%sf(j, 0, l) + 4._wp*var%sf(j, 1, l) - var%sf(j, 2, l))/ & + (y_cc(2) - y_cc(0)) + end do + end do + $:END_GPU_PARALLEL_LOOP() + end if + if (bc_y%end <= BC_GHOST_EXTRAP) then + $:GPU_PARALLEL_LOOP(collapse=2) + do l = idwbuff(3)%beg, idwbuff(3)%end + do j = idwbuff(1)%beg, idwbuff(1)%end + grad_y%sf(j, n, l) = (3._wp*var%sf(j, n, l) - 4._wp*var%sf(j, n - 1, l) + var%sf(j, n - 2, l))/ & + (y_cc(n) - y_cc(n - 2)) + end do + end do + $:END_GPU_PARALLEL_LOOP() + end if + if (p > 0) then + if (bc_z%beg <= BC_GHOST_EXTRAP) then + $:GPU_PARALLEL_LOOP(collapse=2) + do k = idwbuff(2)%beg, idwbuff(2)%end + do j = idwbuff(1)%beg, idwbuff(1)%end + grad_z%sf(j, k, 0) = & + (-3._wp*var%sf(j, k, 0) + 4._wp*var%sf(j, k, 1) - var%sf(j, k, 2))/ & + (z_cc(2) - z_cc(0)) + end do + end do + $:END_GPU_PARALLEL_LOOP() + end if + if (bc_z%end <= BC_GHOST_EXTRAP) then + $:GPU_PARALLEL_LOOP(collapse=2) + do k = idwbuff(2)%beg, idwbuff(2)%end + do j = idwbuff(1)%beg, idwbuff(1)%end + grad_z%sf(j, k, p) = & + (3._wp*var%sf(j, k, p) - 4._wp*var%sf(j, k, p - 1) + var%sf(j, k, p - 2))/ & + (z_cc(p) - z_cc(p - 2)) + end do + end do + $:END_GPU_PARALLEL_LOOP() + end if + end if + end if + + end subroutine s_compute_fd_gradient + + !> @brief Computes the viscous stress tensor at a single grid cell using finite-difference velocity gradients. + subroutine s_compute_viscous_stress_tensor(viscous_stress_tensor, q_prim_vf, dynamic_viscosity, i, j, k) + $:GPU_ROUTINE(parallelism='[seq]') + + real(wp), dimension(1:3, 1:3), intent(inout) :: viscous_stress_tensor + type(scalar_field), dimension(1:sys_size), intent(in) :: q_prim_vf + real(wp), intent(in) :: dynamic_viscosity + integer, intent(in) :: i, j, k + + real(wp), dimension(1:3, 1:3) :: velocity_gradient_tensor + real(wp), dimension(1:3) :: dx + real(wp) :: divergence + integer :: l, q ! iterators + + ! zero the viscous stress, collection of velocity diriviatives, and spacial finite differences + viscous_stress_tensor = 0._wp + velocity_gradient_tensor = 0._wp + dx = 0._wp + + ! get the change in x used in the finite difference equaiont + dx(1) = 0.5_wp*(x_cc(i + 1) - x_cc(i - 1)) + dx(2) = 0.5_wp*(y_cc(j + 1) - y_cc(j - 1)) + if (num_dims == 3) then + dx(3) = 0.5_wp*(z_cc(k + 1) - z_cc(k - 1)) + end if + + ! compute the velocity gradient tensor + do l = 1, num_dims + velocity_gradient_tensor(l, 1) = (q_prim_vf(momxb + l - 1)%sf(i + 1, j, k) - q_prim_vf(momxb + l - 1)%sf(i - 1, j, k))/(2._wp*dx(1)) + velocity_gradient_tensor(l, 2) = (q_prim_vf(momxb + l - 1)%sf(i, j + 1, k) - q_prim_vf(momxb + l - 1)%sf(i, j - 1, k))/(2._wp*dx(2)) + if (num_dims == 3) then + velocity_gradient_tensor(l, 3) = (q_prim_vf(momxb + l - 1)%sf(i, j, k + 1) - q_prim_vf(momxb + l - 1)%sf(i, j, k - 1))/(2._wp*dx(3)) + end if + end do + + ! compute divergence + divergence = 0._wp + do l = 1, num_dims + divergence = divergence + velocity_gradient_tensor(l, l) + end do + + ! set up the shear stress tensor + do l = 1, num_dims + do q = 1, num_dims + viscous_stress_tensor(l, q) = dynamic_viscosity*(velocity_gradient_tensor(l, q) + velocity_gradient_tensor(q, l)) + end do + end do + + ! populate the viscous_stress_tensor + do l = 1, num_dims + viscous_stress_tensor(l, l) = viscous_stress_tensor(l, l) - 2._wp*divergence*dynamic_viscosity/3._wp + end do + + if (num_dims == 2) then + do l = 1, 3 + viscous_stress_tensor(3, l) = 0._wp + viscous_stress_tensor(l, 3) = 0._wp + end do + end if + + end subroutine s_compute_viscous_stress_tensor + + impure subroutine s_finalize_viscous_module() + + end subroutine s_finalize_viscous_module + +end module m_viscous diff --git a/toolchain/mfc/params/definitions.py b/toolchain/mfc/params/definitions.py index 7c456b36fc..8828ea516e 100644 --- a/toolchain/mfc/params/definitions.py +++ b/toolchain/mfc/params/definitions.py @@ -1058,6 +1058,9 @@ def _load(): # pylint: disable=too-many-locals,too-many-statements _r(f"{px}G", REAL, {"elasticity"}, math=r"\f$G_k\f$") _r(f"{px}Re(1)", REAL, {"viscosity"}, math=r"\f$\mathrm{Re}_k\f$ (shear)") _r(f"{px}Re(2)", REAL, {"viscosity"}, math=r"\f$\mathrm{Re}_k\f$ (bulk)") + _r(f"{px}non_newtonian", LOG, {"viscosity"}) + for a in ["tau0", "K", "nn", "mu_max", "mu_min", "mu_bulk", "hb_m"]: + _r(f"{px}{a}", REAL, {"viscosity"}) # --- bub_pp (bubble properties) --- for a, sym in [("R0ref", r"\f$R_0\f$"), ("p0ref", r"\f$p_0\f$"), From f65762dfe874a2719a6aeafe98d698e4b12dbe64 Mon Sep 17 00:00:00 2001 From: jasontruong2707 Date: Mon, 9 Mar 2026 15:37:22 -0400 Subject: [PATCH 2/5] Update lid-driven cavity and Poiseuille example parameters --- .../Lid_driven_cavity_Re_100_n_0.5.png | Bin 0 -> 202715 bytes .../Lid_driven_cavity_Re_100_n_1.5.png | Bin 0 -> 195282 bytes .../Re_100_n_0.5/x_vy.csv | 257 ------------------ .../Re_100_n_0.5/y_vx.csv | 257 ------------------ examples/2D_poiseuille_nn/velocity_0.25.csv | 83 ------ examples/2D_poiseuille_nn/velocity_0.5.csv | 83 ------ examples/2D_poiseuille_nn/velocity_0.75.csv | 83 ------ examples/2D_poiseuille_nn/velocity_1.0.csv | 83 ------ examples/2D_poiseuille_nn/velocity_1.25.csv | 83 ------ examples/2D_poiseuille_nn/velocity_1.5.csv | 83 ------ examples/2D_poiseuille_nn/velocity_1.75.csv | 83 ------ examples/2D_poiseuille_nn/velocity_2.0.csv | 83 ------ .../2D_poiseuille_nn/velocity_profile.png | Bin 74689 -> 402701 bytes 13 files changed, 1178 deletions(-) create mode 100644 examples/2D_lid_driven_cavity_nn/Lid_driven_cavity_Re_100_n_0.5.png create mode 100644 examples/2D_lid_driven_cavity_nn/Lid_driven_cavity_Re_100_n_1.5.png delete mode 100644 examples/2D_lid_driven_cavity_nn/Re_100_n_0.5/x_vy.csv delete mode 100644 examples/2D_lid_driven_cavity_nn/Re_100_n_0.5/y_vx.csv delete mode 100644 examples/2D_poiseuille_nn/velocity_0.25.csv delete mode 100644 examples/2D_poiseuille_nn/velocity_0.5.csv delete mode 100644 examples/2D_poiseuille_nn/velocity_0.75.csv delete mode 100644 examples/2D_poiseuille_nn/velocity_1.0.csv delete mode 100644 examples/2D_poiseuille_nn/velocity_1.25.csv delete mode 100644 examples/2D_poiseuille_nn/velocity_1.5.csv delete mode 100644 examples/2D_poiseuille_nn/velocity_1.75.csv delete mode 100644 examples/2D_poiseuille_nn/velocity_2.0.csv diff --git a/examples/2D_lid_driven_cavity_nn/Lid_driven_cavity_Re_100_n_0.5.png b/examples/2D_lid_driven_cavity_nn/Lid_driven_cavity_Re_100_n_0.5.png new file mode 100644 index 0000000000000000000000000000000000000000..b589c6bdd84336c02a1c08c027bc8d7a68087ab6 GIT binary patch literal 202715 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 rBazv4;-_MIieJ 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

*tnZt$J7mn3)4VZtJ~cjwb;*(?_aU#X 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⩔hQSDhFiqLRHU-8;R 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

b<{rgU<)AgSU)e{IqDof`k^x9W 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

k-v6;4?`ApPbpF;wWnSzO}jog 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 f893f&)gro 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�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𝔬&Gz>9tuAJhfGxD`IF$a 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%0D;vrH#WFsd6jrS*Te9_i)u^1O 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 i@z)tnx8Z+whW80IWeb( Date: Mon, 9 Mar 2026 15:44:19 -0400 Subject: [PATCH 3/5] Add non-Newtonian parameter validation to case_validator.py --- toolchain/mfc/case_validator.py | 42 +++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/toolchain/mfc/case_validator.py b/toolchain/mfc/case_validator.py index 7f52c5fb46..8fc5b66ab1 100644 --- a/toolchain/mfc/case_validator.py +++ b/toolchain/mfc/case_validator.py @@ -183,6 +183,15 @@ "math": r"\mathrm{Re}_1 > 0, \quad \mathrm{Re}_2 > 0", "explanation": "Reynolds numbers must be positive. Not supported with model_eqns = 1.", }, + "check_non_newtonian": { + "title": "Non-Newtonian Viscosity", + "category": "Numerical Schemes", + "math": r"\mu = \frac{\tau_0}{\dot\gamma}(1 - e^{-m\dot\gamma}) + K\dot\gamma^{n-1}", + "explanation": ( + "Herschel-Bulkley non-Newtonian viscosity model. Requires viscous=T, " + "K > 0, nn > 0, tau0 >= 0, mu_min >= 0, mu_max > mu_min, hb_m > 0." + ), + }, # --- Feature Compatibility --- "check_mhd": { "title": "Magnetohydrodynamics (MHD)", @@ -1023,6 +1032,39 @@ def check_viscosity(self): self.prohibit(Re1 is None and viscous, f"viscous is set to true, but fluid_pp({i})%Re(1) is not specified") + def check_non_newtonian(self): + """Checks constraints on non-Newtonian fluid parameters""" + viscous = self.get('viscous', 'F') == 'T' + num_fluids = self.get('num_fluids', 1) + + for i in range(1, num_fluids + 1): + nn_flag = self.get(f'fluid_pp({i})%non_newtonian', 'F') == 'T' + if not nn_flag: + continue + + self.prohibit(not viscous, + f"fluid_pp({i})%non_newtonian requires viscous = T") + + K = self.get(f'fluid_pp({i})%K') + nn = self.get(f'fluid_pp({i})%nn') + tau0 = self.get(f'fluid_pp({i})%tau0') + mu_min = self.get(f'fluid_pp({i})%mu_min') + mu_max = self.get(f'fluid_pp({i})%mu_max') + hb_m = self.get(f'fluid_pp({i})%hb_m') + + self.prohibit(K is not None and K <= 0, + f"fluid_pp({i})%K (consistency index) must be > 0") + self.prohibit(nn is not None and nn <= 0, + f"fluid_pp({i})%nn (flow behavior index) must be > 0") + self.prohibit(tau0 is not None and tau0 < 0, + f"fluid_pp({i})%tau0 (yield stress) must be >= 0") + self.prohibit(mu_min is not None and mu_min < 0, + f"fluid_pp({i})%mu_min must be >= 0") + self.prohibit(mu_max is not None and mu_min is not None and mu_max <= mu_min, + f"fluid_pp({i})%mu_max must be > mu_min") + self.prohibit(hb_m is not None and hb_m <= 0, + f"fluid_pp({i})%hb_m (Papanastasiou parameter) must be > 0") + def check_mhd_simulation(self): """Checks MHD constraints specific to simulation""" mhd = self.get('mhd', 'F') == 'T' From 83f64dec8d75c01f4a04d3c4c6897db293883d89 Mon Sep 17 00:00:00 2001 From: jasontruong2707 Date: Mon, 9 Mar 2026 16:16:58 -0400 Subject: [PATCH 4/5] Fix IGR+non-Newtonian: use primitive variables for shear rate in s_compute_dt --- src/simulation/m_time_steppers.fpp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/simulation/m_time_steppers.fpp b/src/simulation/m_time_steppers.fpp index a38c72e845..c57338f9fd 100644 --- a/src/simulation/m_time_steppers.fpp +++ b/src/simulation/m_time_steppers.fpp @@ -726,7 +726,7 @@ contains real(wp) :: dt_local integer :: j, k, l !< Generic loop iterators - if (.not. igr .or. dummy) then + if (.not. igr .or. dummy .or. any_non_newtonian) then call s_convert_conservative_to_primitive_variables( & q_cons_ts(1)%vf, & q_T_sf, & @@ -745,12 +745,9 @@ contains end if ! For non-Newtonian fluids, compute variable Re based on shear rate + ! Always use q_prim_vf (velocities), not q_cons (momenta) if (any_non_newtonian) then - if (igr) then - call s_compute_re_visc(q_cons_ts(1)%vf, alpha, j, k, l, Re_visc_per_phase) - else - call s_compute_re_visc(q_prim_vf, alpha, j, k, l, Re_visc_per_phase) - end if + call s_compute_re_visc(q_prim_vf, alpha, j, k, l, Re_visc_per_phase) call s_compute_mixture_re(alpha, Re_visc_per_phase, Re) end if From 432f7f6b952fa04c6815c4d681c69714dd0f01c5 Mon Sep 17 00:00:00 2001 From: jasontruong2707 Date: Mon, 9 Mar 2026 16:21:27 -0400 Subject: [PATCH 5/5] Fix IBM non-Newtonian viscosity and IGR primitive variable bug --- src/simulation/m_ibm.fpp | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/simulation/m_ibm.fpp b/src/simulation/m_ibm.fpp index 9394bcf06a..c5b44d7c1f 100644 --- a/src/simulation/m_ibm.fpp +++ b/src/simulation/m_ibm.fpp @@ -27,6 +27,8 @@ module m_ibm use m_viscous + use m_hb_function + use m_model implicit none @@ -1013,15 +1015,14 @@ contains if (viscous) then do fluid_idx = 1, num_fluids - if (fluid_pp(fluid_idx)%non_newtonian) then - ! Non-Newtonian: use mu_max as reference viscosity for IBM - if (fluid_pp(fluid_idx)%mu_max < dflt_real .and. & - fluid_pp(fluid_idx)%mu_max > sgm_eps) then - dynamic_viscosities(fluid_idx) = fluid_pp(fluid_idx)%mu_max - else - dynamic_viscosities(fluid_idx) = fluid_pp(fluid_idx)%K - end if - else if (fluid_pp(fluid_idx)%Re(1) /= 0._wp) then + if (fluid_pp(fluid_idx)%non_newtonian) then + ! Non-Newtonian: compute reference viscosity at gdot = 1 + dynamic_viscosities(fluid_idx) = f_compute_hb_viscosity( & + fluid_pp(fluid_idx)%tau0, fluid_pp(fluid_idx)%K, & + fluid_pp(fluid_idx)%nn, fluid_pp(fluid_idx)%mu_min, & + fluid_pp(fluid_idx)%mu_max, 1._wp, & + fluid_pp(fluid_idx)%hb_m) + else if (fluid_pp(fluid_idx)%Re(1) /= 0._wp) then dynamic_viscosities(fluid_idx) = 1._wp/fluid_pp(fluid_idx)%Re(1) else dynamic_viscosities(fluid_idx) = 0._wp