MFC
Exascale flow solver
Loading...
Searching...
No Matches
m_phase_change.fpp.f90
Go to the documentation of this file.
1# 1 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
2!>
3!! @file
4!! @brief Contains module m_phase_change
5
6# 1 "/home/runner/work/MFC/MFC/src/common/include/case.fpp" 1
7! This file exists so that Fypp can be run without generating case.fpp files for
8! each target. This is useful when generating documentation, for example. This
9! should also let MFC be built with CMake directly, without invoking mfc.sh.
10
11! For pre-process.
12# 8 "/home/runner/work/MFC/MFC/src/common/include/case.fpp"
13
14! For moving immersed boundaries in simulation
15# 12 "/home/runner/work/MFC/MFC/src/common/include/case.fpp"
16# 6 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp" 2
17# 1 "/home/runner/work/MFC/MFC/src/common/include/macros.fpp" 1
18# 1 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp" 1
19# 1 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp" 1
20# 2 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
21# 3 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
22# 4 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
23# 5 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
24# 6 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
25
26# 8 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
27# 9 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
28# 10 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
29
30# 12 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
31# 1 "/home/runner/work/MFC/MFC/src/common/include/defaults/thermochem.fpp" 1
32! Default for Fypp runs outside the toolchain (e.g. documentation). Searched last, so the
33! build/include/<target>/thermochem.fpp the toolchain writes from m_thermochem takes precedence.
34# 4 "/home/runner/work/MFC/MFC/src/common/include/defaults/thermochem.fpp"
35# 5 "/home/runner/work/MFC/MFC/src/common/include/defaults/thermochem.fpp"
36# 13 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp" 2
37
38# 16 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
39# 17 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
40
41# 24 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
42
43# 53 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
44
45# 65 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
46
47# 75 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
48
49# 105 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
50
51# 117 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
52
53# 127 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
54
55# 174 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
56! New line at end of file is required for FYPP
57# 2 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp" 2
58# 1 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp" 1
59# 1 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp" 1
60# 2 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
61# 3 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
62# 4 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
63# 5 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
64# 6 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
65
66# 8 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
67# 9 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
68# 10 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
69
70# 12 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
71# 1 "/home/runner/work/MFC/MFC/src/common/include/defaults/thermochem.fpp" 1
72! Default for Fypp runs outside the toolchain (e.g. documentation). Searched last, so the
73! build/include/<target>/thermochem.fpp the toolchain writes from m_thermochem takes precedence.
74# 4 "/home/runner/work/MFC/MFC/src/common/include/defaults/thermochem.fpp"
75# 5 "/home/runner/work/MFC/MFC/src/common/include/defaults/thermochem.fpp"
76# 13 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp" 2
77
78# 16 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
79# 17 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
80
81# 24 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
82
83# 53 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
84
85# 65 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
86
87# 75 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
88
89# 105 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
90
91# 117 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
92
93# 127 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
94
95# 174 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
96! New line at end of file is required for FYPP
97# 2 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp" 2
98
99# 4 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
100# 5 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
101# 6 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
102# 7 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
103# 8 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
104
105# 20 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
106
107# 43 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
108
109# 48 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
110
111# 53 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
112
113# 58 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
114
115# 63 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
116
117# 68 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
118
119# 81 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
120
121# 95 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
122
123# 100 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
124
125# 105 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
126
127# 110 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
128
129# 115 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
130
131# 120 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
132
133# 125 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
134
135# 130 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
136
137# 135 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
138
139# 165 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
140
141# 219 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
142
143# 233 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
144
145# 258 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
146
147# 269 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
148
149# 271 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
150# 282 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
151
152# 332 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
153
154# 342 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
155
156# 352 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
157
158# 361 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
159
160# 378 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
161
162# 388 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
163
164# 395 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
165
166# 401 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
167
168# 407 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
169
170# 413 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
171
172# 419 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
173
174# 425 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
175! New line at end of file is required for FYPP
176# 3 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp" 2
177# 1 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp" 1
178# 1 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp" 1
179# 2 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
180# 3 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
181# 4 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
182# 5 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
183# 6 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
184
185# 8 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
186# 9 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
187# 10 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
188
189# 12 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
190# 1 "/home/runner/work/MFC/MFC/src/common/include/defaults/thermochem.fpp" 1
191! Default for Fypp runs outside the toolchain (e.g. documentation). Searched last, so the
192! build/include/<target>/thermochem.fpp the toolchain writes from m_thermochem takes precedence.
193# 4 "/home/runner/work/MFC/MFC/src/common/include/defaults/thermochem.fpp"
194# 5 "/home/runner/work/MFC/MFC/src/common/include/defaults/thermochem.fpp"
195# 13 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp" 2
196
197# 16 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
198# 17 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
199
200# 24 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
201
202# 53 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
203
204# 65 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
205
206# 75 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
207
208# 105 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
209
210# 117 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
211
212# 127 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
213
214# 174 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
215! New line at end of file is required for FYPP
216# 2 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp" 2
217
218# 7 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
219
220# 17 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
221
222# 22 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
223
224# 27 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
225
226# 32 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
227
228# 37 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
229
230# 42 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
231
232# 47 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
233
234# 52 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
235
236# 57 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
237
238# 62 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
239
240# 73 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
241
242# 78 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
243
244# 83 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
245
246# 88 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
247
248# 103 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
249
250# 131 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
251
252# 160 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
253
254# 175 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
255
256# 193 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
257
258# 215 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
259
260# 244 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
261
262# 259 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
263
264# 269 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
265
266# 278 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
267
268# 294 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
269
270# 304 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
271
272# 311 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
273! New line at end of file is required for FYPP
274# 4 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp" 2
275
276! GPU parallel region (scalar reductions, maxval/minval)
277# 23 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
278
279! GPU parallel loop over threads (most common GPU macro)
280# 43 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
281
282! Required closing for GPU_PARALLEL_LOOP
283# 55 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
284
285! Mark routine for device compilation
286# 112 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
287
288! Declare device-resident data
289# 130 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
290
291! Inner loop within a GPU parallel region
292# 145 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
293
294! Scoped GPU data region
295# 164 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
296
297! Host code with device pointers (for MPI with GPU buffers)
298# 193 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
299
300! Allocate device memory (unscoped)
301# 207 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
302
303! Free device memory
304# 219 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
305
306! Atomic operation on device
307# 231 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
308
309! End atomic capture block
310# 242 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
311
312! Copy data between host and device
313# 254 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
314
315! Synchronization barrier
316# 266 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
317
318! Import GPU library module (openacc or omp_lib)
319# 275 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
320
321! Emit code only for AMD compiler
322# 282 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
323
324! Emit code for non-Cray compilers
325# 289 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
326
327! Emit code only for Cray compiler
328# 296 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
329
330! Emit code for non-NVIDIA compilers
331# 303 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
332
333# 305 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
334# 306 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
335! New line at end of file is required for FYPP
336# 2 "/home/runner/work/MFC/MFC/src/common/include/macros.fpp" 2
337
338# 14 "/home/runner/work/MFC/MFC/src/common/include/macros.fpp"
339
340! Caution: This macro requires the use of a binding script to set CUDA_VISIBLE_DEVICES, such that we have one GPU device per MPI
341! rank. That's because for both cudaMemAdvise (preferred location) and cudaMemPrefetchAsync we use location = device_id = 0. For an
342! example see misc/nvidia_uvm/bind.sh.
343# 52 "/home/runner/work/MFC/MFC/src/common/include/macros.fpp"
344
345! Allocate and create GPU device memory
346# 72 "/home/runner/work/MFC/MFC/src/common/include/macros.fpp"
347
348! Free GPU device memory and deallocate
349# 80 "/home/runner/work/MFC/MFC/src/common/include/macros.fpp"
350
351! Cray-specific GPU pointer setup for vector fields
352# 104 "/home/runner/work/MFC/MFC/src/common/include/macros.fpp"
353
354! Cray-specific GPU pointer setup for scalar fields
355# 120 "/home/runner/work/MFC/MFC/src/common/include/macros.fpp"
356
357! Cray-specific GPU pointer setup for acoustic source spatials
358# 145 "/home/runner/work/MFC/MFC/src/common/include/macros.fpp"
359
360# 151 "/home/runner/work/MFC/MFC/src/common/include/macros.fpp"
361
362# 158 "/home/runner/work/MFC/MFC/src/common/include/macros.fpp"
363! New line at end of file is required for FYPP
364# 7 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp" 2
365
366!> @brief Phase transition relaxation solvers for liquid-vapor flows with cavitation and boiling
368
371 use m_mpi_proxy
373 use m_eos
374 use ieee_arithmetic
376 use m_constants, only: model_eqns_6eq
377
378 implicit none
379
380 private
382
383 !> @name Parameters for the first order transition phase change
384 !> @{
385 integer, parameter :: max_iter = 100000 !< max Newton iterations before accepting the last iterate
386 real(wp), parameter :: pcr = 4.94e7_wp !< Critical pressure of water [Pa]
387 real(wp), parameter :: tcr = 385.05_wp + 273.15_wp !< Critical temperature of water [K]
388 integer, parameter :: ptg_ls_max = 30 !< max backtracking-line-search halvings in the pTg solver
389 real(wp), parameter :: mixm = 1.0e-8_wp !< Mixture mass fraction threshold for triggering phase change
390 integer, parameter :: lp = 1 !< index for the liquid phase of the reacting fluid
391 integer, parameter :: vp = 2 !< index for the vapor phase of the reacting fluid
392 !> @}
393
394contains
395
396 !> Dispatch to the correct relaxation solver. Replaces the procedure pointer, which CCE is breaking on.
397 impure subroutine s_relaxation_solver(q_cons_vf)
398
399 type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf
400 ! This is empty because in current master the procedure pointer was never assigned
401
402 if (.not. (.false.)) then
403# 44 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
404 call s_mpi_abort("m_phase_change.fpp:44: " // "Assertion failed: .false.. " &
405# 44 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
406 & // "s_relaxation_solver called but it currently does nothing")
407# 44 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
408 end if
409# 45 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
410
411 end subroutine s_relaxation_solver
412
413 !> Initialize the phase change module (no module-level state to set up; the pT/pTg relaxation solvers are self-contained)
415
417
418 !> Apply pT- or pTg-equilibrium relaxation with mass depletion based on the incoming state conditions.
419 subroutine s_infinite_relaxation_k(q_cons_vf)
420
421 type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf
422 real(wp) :: ps !< equilibrium pressure
423 real(wp) :: ts !< equilibrium temperature
424 real(wp) :: rhoe, dyne, rhos !< total internal energy, kinetic energy, and total entropy
425 real(wp) :: rho, rm, m1, m2, mct !< total density, total reacting mass, individual reacting masses
426 real(wp) :: tvf !< total volume fraction
427 logical :: ptg_conv !< pTg Newton solver converged
428
429# 67 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
430 real(wp), dimension(num_fluids) :: p_infpt, sk, hk, gk, ek, rhok
431# 69 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
432
433 !> Generic loop iterators
434 integer :: i, j, k, l
435
436#ifdef _CRAYFTN
437#ifdef MFC_OpenACC
438 ! CCE 19 IPA workaround: prevent bring_routine_resident SIGSEGV DIR$ NOINLINE s_infinite_pt_relaxation_k DIR$ NOINLINE
439 ! s_infinite_ptg_relaxation_k DIR$ NOINLINE s_correct_partial_densities
440#endif
441#endif
442
443 ! starting equilibrium solver
444
445
446# 82 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
447
448# 82 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
449#if defined(MFC_OpenACC)
450# 82 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
451!$acc parallel loop collapse(3) gang vector default(present) private(i, j, k, l, p_infpT, sk, hk, gk, ek, rhok, pS, TS, rhoe, dynE, rhos, rho, rM, m1, m2, MCT, TvF, ptg_conv)
452# 82 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
453#elif defined(MFC_OpenMP)
454# 82 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
455
456# 82 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
457
458# 82 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
459
460# 82 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
461!$omp target teams loop defaultmap(firstprivate:scalar) bind(teams,parallel) collapse(3) defaultmap(tofrom:aggregate) defaultmap(tofrom:allocatable) defaultmap(tofrom:pointer) &
462# 82 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
463!$omp& private(i, j, k, l, p_infpT, sk, hk, gk, ek, rhok, pS, TS, rhoe, dynE, rhos, rho, rM, m1, m2, MCT, TvF, ptg_conv)
464# 82 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
465#endif
466# 84 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
467 do j = 0, m
468 do k = 0, n
469 do l = 0, p
470 rho = 0.0_wp; tvf = 0.0_wp
471
472# 88 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
473#if defined(MFC_OpenACC)
474# 88 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
475!$acc loop seq
476# 88 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
477#elif defined(MFC_OpenMP)
478# 88 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
479
480# 88 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
481#endif
482# 89 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
483 do i = 1, num_fluids
484 ! Mixture density
485 rho = rho + q_cons_vf(i + eqn_idx%cont%beg - 1)%sf(j, k, l)
486
487 ! Total Volume Fraction
488 tvf = tvf + q_cons_vf(i + eqn_idx%adv%beg - 1)%sf(j, k, l)
489 end do
490
491 ! calculating the total reacting mass for the phase change process. By hypothesis, this should not change
492 ! throughout the phase-change process.
493 rm = q_cons_vf(lp + eqn_idx%cont%beg - 1)%sf(j, k, l) + q_cons_vf(vp + eqn_idx%cont%beg - 1)%sf(j, k, l)
494
495 ! correcting negative (reacting) mass fraction values in case they happen
496 call s_correct_partial_densities(mct, q_cons_vf, rm, j, k, l)
497
498 ! fixing m1 and m2 AFTER correcting the partial densities. Note that these values must be stored for the phase
499 ! change process that will happen a posteriori
500 m1 = q_cons_vf(lp + eqn_idx%cont%beg - 1)%sf(j, k, l)
501
502 m2 = q_cons_vf(vp + eqn_idx%cont%beg - 1)%sf(j, k, l)
503
504 ! kinetic energy as an auxiliary variable to the calculation of the total internal energy
505 dyne = 0.0_wp
506
507# 112 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
508#if defined(MFC_OpenACC)
509# 112 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
510!$acc loop seq
511# 112 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
512#elif defined(MFC_OpenMP)
513# 112 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
514
515# 112 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
516#endif
517# 113 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
518 do i = eqn_idx%mom%beg, eqn_idx%mom%end
519 dyne = dyne + 5.0e-1_wp*q_cons_vf(i)%sf(j, k, l)**2/rho
520 end do
521
522 ! calculating the total energy that MUST be preserved throughout the pT- and pTg-relaxation procedures at each
523 ! of the cells. The internal energy is calculated as the total energy minus the kinetic energy to preserved its
524 ! value at sharp interfaces
525 rhoe = q_cons_vf(eqn_idx%E)%sf(j, k, l) - dyne
526
527 ! Calling pT-equilibrium for either finishing phase-change module, or as an IC for the pTg-equilibrium for this
528 ! case, MFL cannot be either 0 or 1, so I chose it to be 2
529 call s_infinite_pt_relaxation_k(j, k, l, 2, ps, p_infpt, q_cons_vf, rhoe, ts)
530
531 ! Check if pTg-equilibrium needed; only partial densities require updating
532 if ((relax_model == 6) .and. ((q_cons_vf(lp + eqn_idx%cont%beg - 1)%sf(j, k, &
533 & l) > mixm*rm) .and. (q_cons_vf(vp + eqn_idx%cont%beg - 1)%sf(j, k, &
534 & l) > mixm*rm)) .and. (ps < pcr) .and. (ts < tcr)) then
535 ! Solve pTg-equilibrium directly on the actual reacting masses. The Newton solver projects
536 ! the liquid mass onto [0, mT], so it recovers the single-phase limits itself (ml -> 0 for
537 ! all-vapor, ml -> mT for all-liquid). The former overheated-vapor / subcooled-liquid pT
538 ! shortcuts were removed: their pT states differ O(1) from the pTg equilibrium, so the
539 ! sub-ULP shortcut/pTg branch decision flipped across backends (CPU vs GPU) near a phase
540 ! boundary and destroyed cross-backend reproducibility.
541 q_cons_vf(lp + eqn_idx%cont%beg - 1)%sf(j, k, l) = m1
542 q_cons_vf(vp + eqn_idx%cont%beg - 1)%sf(j, k, l) = m2
543
544 call s_infinite_ptg_relaxation_k(j, k, l, ps, rhoe, q_cons_vf, ts, ptg_conv)
545
546 ! Unconverged pTg; solve pT equilibrium again for the final masses
547 if (.not. ptg_conv) call s_infinite_pt_relaxation_k(j, k, l, 2, ps, p_infpt, q_cons_vf, rhoe, ts)
548 end if
549
550 ! Calculations AFTER equilibrium
551
552
553# 147 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
554#if defined(MFC_OpenACC)
555# 147 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
556!$acc loop seq
557# 147 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
558#elif defined(MFC_OpenMP)
559# 147 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
560
561# 147 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
562#endif
563# 148 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
564 do i = 1, num_fluids
565 ! entropy
566 sk(i) = cvs(i)*log((ts**isentrope_n(i))/((ps + isentrope_b(i))**(isentrope_n(i) - 1.0_wp))) + qvps(i)
567
568 ! enthalpy
569 hk(i) = isentrope_n(i)*cvs(i)*ts + qvs(i)
570
571 ! Gibbs-free energy
572 gk(i) = hk(i) - ts*sk(i)
573
574 ! densities
575 rhok(i) = f_sg_thermal(ps, ts, isentrope_n(i), isentrope_b(i), cvs(i))
576
577 ! internal energy
578 ek(i) = (ps + isentrope_n(i)*isentrope_b(i))/(ps + isentrope_b(i))*cvs(i)*ts + qvs(i)
579 end do
580
581 ! calculating volume fractions, internal energies, and total entropy
582 rhos = 0.0_wp
583
584# 167 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
585#if defined(MFC_OpenACC)
586# 167 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
587!$acc loop seq
588# 167 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
589#elif defined(MFC_OpenMP)
590# 167 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
591
592# 167 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
593#endif
594# 168 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
595 do i = 1, num_fluids
596 ! volume fractions
597 q_cons_vf(i + eqn_idx%adv%beg - 1)%sf(j, k, l) = q_cons_vf(i + eqn_idx%cont%beg - 1)%sf(j, k, l)/rhok(i)
598
599 ! alpha*rho*e
600 if (model_eqns == model_eqns_6eq) then
601 q_cons_vf(i + eqn_idx%int_en%beg - 1)%sf(j, k, l) = q_cons_vf(i + eqn_idx%cont%beg - 1)%sf(j, k, &
602 & l)*ek(i)
603 end if
604
605 ! Total entropy
606 rhos = rhos + q_cons_vf(i + eqn_idx%cont%beg - 1)%sf(j, k, l)*sk(i)
607 end do
608 end do
609 end do
610 end do
611
612# 184 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
613#if defined(MFC_OpenACC)
614# 184 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
615!$acc end parallel loop
616# 184 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
617#elif defined(MFC_OpenMP)
618# 184 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
619
620# 184 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
621!$omp end target teams loop
622# 184 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
623#endif
624# 185 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
625
626 end subroutine s_infinite_relaxation_k
627
628 !> Apply pT-equilibrium relaxation for N fluids
629 !! @param MFL flag: 0=gas, 1=liquid, 2=mixture
630 subroutine s_infinite_pt_relaxation_k(j, k, l, MFL, pS, p_infpT, q_cons_vf, rhoe, TS)
631
632
633# 192 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
634#ifdef _CRAYFTN
635# 192 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
636#if MFC_OpenACC
637# 192 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
638!$acc routine seq
639# 192 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
640#elif MFC_OpenMP
641# 192 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
642
643# 192 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
644
645# 192 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
646!$omp declare target device_type(any)
647# 192 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
648#else
649# 192 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
650!DIR$ NOINLINE s_infinite_pt_relaxation_k
651# 192 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
652#endif
653# 192 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
654#elif MFC_OpenACC
655# 192 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
656!$acc routine seq
657# 192 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
658#elif MFC_OpenMP
659# 192 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
660
661# 192 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
662
663# 192 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
664!$omp declare target device_type(any)
665# 192 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
666#endif
667# 193 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
668
669 ! initializing variables
670 integer, intent(in) :: j, k, l, MFL
671 real(wp), intent(out) :: pS
672 real(wp), dimension(1:), intent(out) :: p_infpT
673 type(scalar_field), dimension(sys_size), intent(in) :: q_cons_vf
674 real(wp), intent(in) :: rhoe
675 real(wp), intent(out) :: TS
676 real(wp) :: gp, gpp, hp, pO, mCP, mQ !< variables for the Newton Solver
677 real(wp) :: p_infpT_sum
678 integer :: i, ns !< generic loop iterators
679 ! auxiliary variables for the pT-equilibrium solver
680 mcp = 0.0_wp; mq = 0.0_wp; p_infpt_sum = 0._wp
681
682# 206 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
683#if defined(MFC_OpenACC)
684# 206 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
685!$acc loop seq
686# 206 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
687#elif defined(MFC_OpenMP)
688# 206 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
689
690# 206 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
691#endif
692# 207 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
693 do i = 1, num_fluids
694 p_infpt(i) = isentrope_b(i)
695 p_infpt_sum = p_infpt_sum + abs(p_infpt(i))
696 end do
697 ! Performing tests before initializing the pT-equilibrium
698
699# 212 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
700#if defined(MFC_OpenACC)
701# 212 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
702!$acc loop seq
703# 212 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
704#elif defined(MFC_OpenMP)
705# 212 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
706
707# 212 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
708#endif
709# 213 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
710 do i = 1, num_fluids
711 ! sum of the total alpha*rho*cp of the system
712 mcp = mcp + q_cons_vf(i + eqn_idx%cont%beg - 1)%sf(j, k, l)*cvs(i)*isentrope_n(i)
713
714 ! sum of the total alpha*rho*q of the system
715 mq = mq + q_cons_vf(i + eqn_idx%cont%beg - 1)%sf(j, k, l)*qvs(i)
716 end do
717
718# 229 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
719
720 ! Checking energy constraint
721 if ((rhoe - mq - minval(p_infpt)) < 0.0_wp) then
722 if ((mfl == 0) .or. (mfl == 1)) then
723 ! Assigning zero values for mass depletion cases pressure
724 ps = 0.0_wp
725
726 ! temperature
727 ts = 0.0_wp
728
729 return
730 end if
731 end if
732
733 ! calculating initial estimate for pressure in the pT-relaxation procedure. I will also use this variable to iterate over
734 ! the Newton's solver
735 po = 0.0_wp
736
737 ! Maybe improve this condition afterwards. As long as the initial guess is in between -min(isentrope_B) and infinity, a
738 ! solution
739 ! should be able to be found.
740 ps = 1.0e4_wp
741
742 ! Newton Solver for the pT-equilibrium
743 ns = 0
744 ! change this relative error metric. 1.e4_wp is just arbitrary
745 ! Relative criterion written in multiply form to avoid dividing by pO (pO = 0 on the first pass).
746 do while ((abs(ps - po) > palpha_eps) .and. (abs(ps - po) > (palpha_eps/1.e4_wp)*abs(po)) .or. (ns == 0))
747 ! increasing counter
748 ns = ns + 1
749 ! guard against non-convergence: accept the last iterate rather than looping forever
750 if (ns >= max_iter) exit
751
752 ! updating old pressure
753 po = ps
754
755 ! updating functions used in the Newton's solver
756 gpp = 0.0_wp; gp = 0.0_wp; hp = 0.0_wp
757
758# 267 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
759#if defined(MFC_OpenACC)
760# 267 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
761!$acc loop seq
762# 267 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
763#elif defined(MFC_OpenMP)
764# 267 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
765
766# 267 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
767#endif
768# 268 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
769 do i = 1, num_fluids
770 gp = gp + (isentrope_n(i) - 1.0_wp)*q_cons_vf(i + eqn_idx%cont%beg - 1)%sf(j, k, &
771 & l)*cvs(i)*(rhoe + ps - mq)/(mcp*(ps + p_infpt(i)))
772
773 gpp = gpp + (isentrope_n(i) - 1.0_wp)*q_cons_vf(i + eqn_idx%cont%beg - 1)%sf(j, k, &
774 & l)*cvs(i)*(p_infpt(i) - rhoe + mq)/(mcp*(ps + p_infpt(i))**2)
775 end do
776
777 hp = 1.0_wp/(rhoe + ps - mq) + 1.0_wp/(ps + minval(p_infpt))
778
779 ! updating common pressure for the newton solver
780 ps = po + ((1.0_wp - gp)/gpp)/(1.0_wp - (1.0_wp - gp + abs(1.0_wp - gp))/(2.0_wp*gpp)*hp)
781 end do
782
783 ! common temperature; same closure as f_mixture_temperature in m_eos, written in conservative variables
784 ts = (rhoe + ps - mq)/mcp
785
786 end subroutine s_infinite_pt_relaxation_k
787
788 !> Evaluate the pTg-equilibrium residual R2D and temperature TS at a trial state (ml, pS) WITHOUT mutating q_cons_vf, so the
789 !! Newton driver can line-search. The total reacting mass mT is conserved, so the reacting masses are (ml, mT - ml) and only the
790 !! inert fluids are read from q_cons_vf. Also returns the mixture sums the Jacobian and the final temperature need.
791 subroutine s_compute_ptg_residual(ml, mT, pS, j, k, l, q_cons_vf, rhoe, R2D, TS, mCP, mQ, mCVGP, mCVGP2, mCPD)
792
793
794# 292 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
795#if MFC_OpenACC
796# 292 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
797!$acc routine seq
798# 292 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
799#elif MFC_OpenMP
800# 292 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
801
802# 292 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
803
804# 292 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
805!$omp declare target device_type(any)
806# 292 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
807#endif
808# 293 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
809
810 real(wp), intent(in) :: ml, mT, pS, rhoe
811 integer, intent(in) :: j, k, l
812 type(scalar_field), dimension(sys_size), intent(in) :: q_cons_vf
813 real(wp), dimension(2), intent(out) :: R2D
814 real(wp), intent(out) :: TS, mCP, mQ, mCVGP, mCVGP2, mCPD
815 real(wp) :: mQD
816 integer :: i
817
818 ! reacting fluids contribute via (ml, mT - ml); inert fluids are summed from q_cons_vf
819 mcp = ml*cvs(lp)*isentrope_n(lp) + (mt - ml)*cvs(vp)*isentrope_n(vp)
820 mq = ml*qvs(lp) + (mt - ml)*qvs(vp)
821 mcvgp = 0.0_wp; mcvgp2 = 0.0_wp; mcpd = 0.0_wp; mqd = 0.0_wp
822
823# 306 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
824#if defined(MFC_OpenACC)
825# 306 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
826!$acc loop seq
827# 306 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
828#elif defined(MFC_OpenMP)
829# 306 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
830
831# 306 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
832#endif
833# 307 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
834 do i = 1, num_fluids
835 if ((i /= lp) .and. (i /= vp)) then
836 mcp = mcp + q_cons_vf(i + eqn_idx%cont%beg - 1)%sf(j, k, l)*cvs(i)*isentrope_n(i)
837 mq = mq + q_cons_vf(i + eqn_idx%cont%beg - 1)%sf(j, k, l)*qvs(i)
838 mcvgp = mcvgp + q_cons_vf(i + eqn_idx%cont%beg - 1)%sf(j, k, l)*cvs(i)*(isentrope_n(i) - 1)/(ps + isentrope_b(i))
839 mcvgp2 = mcvgp2 + q_cons_vf(i + eqn_idx%cont%beg - 1)%sf(j, k, &
840 & l)*cvs(i)*(isentrope_n(i) - 1)/((ps + isentrope_b(i))**2)
841 mqd = mqd + q_cons_vf(i + eqn_idx%cont%beg - 1)%sf(j, k, l)*qvs(i)
842 mcpd = mcpd + q_cons_vf(i + eqn_idx%cont%beg - 1)%sf(j, k, l)*cvs(i)*isentrope_n(i)
843 end if
844 end do
845
846 ts = 1.0_wp/(mt*cvs(vp)*(isentrope_n(vp) - 1)/(ps + isentrope_b(vp)) + ml*(cvs(lp)*(isentrope_n(lp) - 1)/(ps &
847 & + isentrope_b(lp)) - cvs(vp)*(isentrope_n(vp) - 1)/(ps + isentrope_b(vp))) + mcvgp)
848
849 ! (i) Gibbs free-energy equality
850 r2d(1) = ts*((cvs(lp)*isentrope_n(lp) - cvs(vp)*isentrope_n(vp))*(1 - log(ts)) - (qvps(lp) - qvps(vp)) + cvs(lp) &
851 & *(isentrope_n(lp) - 1)*log(ps + isentrope_b(lp)) - cvs(vp)*(isentrope_n(vp) - 1)*log(ps + isentrope_b(vp))) &
852 & + qvs(lp) - qvs(vp)
853
854 ! (ii) constant-energy condition
855 r2d(2) = rhoe + ps + ml*(qvs(vp) - qvs(lp)) - mt*qvs(vp) - mqd + (ml*(isentrope_n(vp)*cvs(vp) - isentrope_n(lp)*cvs(lp)) &
856 & - mt*isentrope_n(vp)*cvs(vp) - mcpd)/(ml*(cvs(lp)*(isentrope_n(lp) - 1)/(ps + isentrope_b(lp)) - cvs(vp) &
857 & *(isentrope_n(vp) - 1)/(ps + isentrope_b(vp))) + mt*cvs(vp)*(isentrope_n(vp) - 1)/(ps + isentrope_b(vp)) + mcvgp)
858
859 end subroutine s_compute_ptg_residual
860
861 !> Apply pTg-equilibrium relaxation: a damped (backtracking line search) Newton solve for the reacting liquid mass ml and
862 !! pressure pS enforcing Gibbs equality and energy conservation, converging on the residual norm (absolute ptgalpha_eps, or the
863 !! rhoe-relative branch). Every step is projected onto the physical bounds 0 <= ml <= mT, pS > pmin. This converges in a handful
864 !! of iterations with a bounded, uniform count (no GPU warp divergence), unlike the former fixed 1e-3 underrelaxation that
865 !! stalled far from the root.
866 subroutine s_infinite_ptg_relaxation_k(j, k, l, pS, rhoe, q_cons_vf, TS, ptg_conv)
867
868
869# 341 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
870#ifdef _CRAYFTN
871# 341 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
872#if MFC_OpenACC
873# 341 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
874!$acc routine seq
875# 341 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
876#elif MFC_OpenMP
877# 341 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
878
879# 341 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
880
881# 341 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
882!$omp declare target device_type(any)
883# 341 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
884#else
885# 341 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
886!DIR$ NOINLINE s_infinite_ptg_relaxation_k
887# 341 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
888#endif
889# 341 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
890#elif MFC_OpenACC
891# 341 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
892!$acc routine seq
893# 341 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
894#elif MFC_OpenMP
895# 341 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
896
897# 341 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
898
899# 341 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
900!$omp declare target device_type(any)
901# 341 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
902#endif
903# 342 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
904
905 integer, intent(in) :: j, k, l
906 real(wp), intent(inout) :: pS
907 real(wp), intent(in) :: rhoe
908 type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf
909 real(wp), intent(inout) :: TS
910 logical, intent(out) :: ptg_conv
911 real(wp), dimension(2, 2) :: Jac, InvJac
912 real(wp), dimension(2) :: R2D, R2D_try, DeltamP
913 real(wp) :: mCP, mCPD, mCVGP, mCVGP2, mQ
914 real(wp) :: ml, ml_try, mT, pS_try, pmin, lambda, resnorm, resnorm_try
915 real(wp) :: dFdT, dTdm, dTdp, detJ
916 integer :: ns, ls
917
918 ! total reacting mass is conserved; the liquid mass ml is the primary unknown, vapor mass = mT - ml
919 mt = q_cons_vf(lp + eqn_idx%cont%beg - 1)%sf(j, k, l) + q_cons_vf(vp + eqn_idx%cont%beg - 1)%sf(j, k, l)
920 ml = q_cons_vf(lp + eqn_idx%cont%beg - 1)%sf(j, k, l)
921
922 ! recover a physical pressure guess when the incoming pS is non-physical
923 if (((ps < 0.0_wp) .and. ((q_cons_vf(lp + eqn_idx%cont%beg - 1)%sf(j, k, l) + q_cons_vf(vp + eqn_idx%cont%beg - 1)%sf(j, &
924 & k, &
925 & l)) > ((rhoe - isentrope_n(lp)*isentrope_b(lp)/(isentrope_n(lp) - 1))/qvs(lp)))) .or. ((ps >= 0.0_wp) &
926 & .and. (ps < 1.0e-1_wp))) then
927 ps = 1.0e4_wp
928 end if
929
930 ! pressure floor (stiffened gas requires pS + isentrope_B > 0 for both phases)
931 pmin = -min(isentrope_b(lp), isentrope_b(vp)) + 1.0_wp
932
933 call s_compute_ptg_residual(ml, mt, ps, j, k, l, q_cons_vf, rhoe, r2d, ts, mcp, mq, mcvgp, mcvgp2, mcpd)
934 resnorm = sqrt(r2d(1)**2 + r2d(2)**2)
935
936 do ns = 1, max_iter
937 ! converged on the absolute residual, or on the rhoe-relative residual (multiply form, rhoe > 0)
938 ptg_conv = (resnorm <= ptgalpha_eps) .or. (resnorm <= (ptgalpha_eps/1.e6_wp)*rhoe)
939 if (ptg_conv .or. (ns == max_iter)) exit
940
941 ! 2x2 Jacobian of (Gibbs equality, energy) with respect to (ml, pS) at the current state
942 dfdt = -(cvs(lp)*isentrope_n(lp) - cvs(vp)*isentrope_n(vp))*log(ts) - (qvps(lp) - qvps(vp)) + cvs(lp)*(isentrope_n(lp) &
943 & - 1)*log(ps + isentrope_b(lp)) - cvs(vp)*(isentrope_n(vp) - 1)*log(ps + isentrope_b(vp))
944 dtdm = -(cvs(lp)*(isentrope_n(lp) - 1)/(ps + isentrope_b(lp)) - cvs(vp)*(isentrope_n(vp) - 1)/(ps + isentrope_b(vp))) &
945 & *ts**2
946 dtdp = (mt*cvs(vp)*(isentrope_n(vp) - 1)/(ps + isentrope_b(vp))**2 + ml*(cvs(lp)*(isentrope_n(lp) - 1)/(ps &
947 & + isentrope_b(lp))**2 - cvs(vp)*(isentrope_n(vp) - 1)/(ps + isentrope_b(vp))**2) + mcvgp2)*ts**2
948
949 jac(1, 1) = dfdt*dtdm
950 jac(1, &
951 & 2) = dfdt*dtdp + ts*(cvs(lp)*(isentrope_n(lp) - 1)/(ps + isentrope_b(lp)) - cvs(vp)*(isentrope_n(vp) - 1)/(ps &
952 & + isentrope_b(vp)))
953 jac(2, &
954 & 1) = qvs(vp) - qvs(lp) + (cvs(vp)*isentrope_n(vp) - cvs(lp)*isentrope_n(lp))/(ml*(cvs(lp)*(isentrope_n(lp) - 1) &
955 & /(ps + isentrope_b(lp)) - cvs(vp)*(isentrope_n(vp) - 1)/(ps + isentrope_b(vp))) + mt*cvs(vp)*(isentrope_n(vp) &
956 & - 1)/(ps + isentrope_b(vp)) + mcvgp) - (ml*(cvs(vp)*isentrope_n(vp) - cvs(lp)*isentrope_n(lp)) - mt*cvs(vp) &
957 & *isentrope_n(vp) - mcpd)*(cvs(lp)*(isentrope_n(lp) - 1)/(ps + isentrope_b(lp)) - cvs(vp)*(isentrope_n(vp) - 1) &
958 & /(ps + isentrope_b(vp)))/((ml*(cvs(lp)*(isentrope_n(lp) - 1)/(ps + isentrope_b(lp)) - cvs(vp)*(isentrope_n(vp) &
959 & - 1)/(ps + isentrope_b(vp))) + mt*cvs(vp)*(isentrope_n(vp) - 1)/(ps + isentrope_b(vp)) + mcvgp)**2)
960 jac(2, &
961 & 2) = 1 + (ml*(cvs(vp)*isentrope_n(vp) - cvs(lp)*isentrope_n(lp)) - mt*cvs(vp)*isentrope_n(vp) - mcpd) &
962 & *(ml*(cvs(lp)*(isentrope_n(lp) - 1)/(ps + isentrope_b(lp))**2 - cvs(vp)*(isentrope_n(vp) - 1)/(ps &
963 & + isentrope_b(vp))**2) + mt*cvs(vp)*(isentrope_n(vp) - 1)/(ps + isentrope_b(vp))**2 + mcvgp2)/(ml*(cvs(lp) &
964 & *(isentrope_n(lp) - 1)/(ps + isentrope_b(lp)) - cvs(vp)*(isentrope_n(vp) - 1)/(ps + isentrope_b(vp))) &
965 & + mt*cvs(vp)*(isentrope_n(vp) - 1)/(ps + isentrope_b(vp)) + mcvgp)**2
966
967 detj = jac(1, 1)*jac(2, 2) - jac(1, 2)*jac(2, 1)
968 ! singular Jacobian: no usable Newton direction, accept the current (best) state
969 if (detj == 0.0_wp) exit
970
971 invjac(1, 1) = jac(2, 2)/detj
972 invjac(1, 2) = -jac(1, 2)/detj
973 invjac(2, 1) = -jac(2, 1)/detj
974 invjac(2, 2) = jac(1, 1)/detj
975
976 deltamp(1) = -(invjac(1, 1)*r2d(1) + invjac(1, 2)*r2d(2))
977 deltamp(2) = -(invjac(2, 1)*r2d(1) + invjac(2, 2)*r2d(2))
978
979 ! backtracking line search: halve the step until the residual decreases, keeping the state
980 ! physical (0 <= ml <= mT, pS above the stiffened-gas floor)
981 lambda = 1.0_wp
982 do ls = 1, ptg_ls_max
983 ml_try = min(max(ml + lambda*deltamp(1), 0.0_wp), mt)
984 ps_try = max(ps + lambda*deltamp(2), pmin)
985 call s_compute_ptg_residual(ml_try, mt, ps_try, j, k, l, q_cons_vf, rhoe, r2d_try, ts, mcp, mq, mcvgp, mcvgp2, mcpd)
986 resnorm_try = sqrt(r2d_try(1)**2 + r2d_try(2)**2)
987 if ((resnorm_try < resnorm) .or. (ls == ptg_ls_max)) exit
988 lambda = 0.5_wp*lambda
989 end do
990
991 ! accept the trial state (TS, mCP, mQ, mCVGP, mCVGP2, mCPD already set to it by the last call)
992 ml = ml_try; ps = ps_try; r2d = r2d_try; resnorm = resnorm_try
993 end do
994
995 ! commit the reacting masses (mT conserved) and set the common temperature
996 q_cons_vf(lp + eqn_idx%cont%beg - 1)%sf(j, k, l) = ml
997 q_cons_vf(vp + eqn_idx%cont%beg - 1)%sf(j, k, l) = mt - ml
998
999 ts = (rhoe + ps - mq)/mcp
1000
1001 end subroutine s_infinite_ptg_relaxation_k
1002
1003 !> Correct the partial densities of the reacting fluids in case one of them is negative but their sum is positive. Inert phases
1004 !! are not corrected at this moment
1005 subroutine s_correct_partial_densities(MCT, q_cons_vf, rM, j, k, l)
1006
1007
1008# 445 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
1009#ifdef _CRAYFTN
1010# 445 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
1011#if MFC_OpenACC
1012# 445 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
1013!$acc routine seq
1014# 445 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
1015#elif MFC_OpenMP
1016# 445 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
1017
1018# 445 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
1019
1020# 445 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
1021!$omp declare target device_type(any)
1022# 445 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
1023#else
1024# 445 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
1025!DIR$ NOINLINE s_correct_partial_densities
1026# 445 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
1027#endif
1028# 445 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
1029#elif MFC_OpenACC
1030# 445 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
1031!$acc routine seq
1032# 445 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
1033#elif MFC_OpenMP
1034# 445 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
1035
1036# 445 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
1037
1038# 445 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
1039!$omp declare target device_type(any)
1040# 445 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
1041#endif
1042# 446 "/home/runner/work/MFC/MFC/src/common/m_phase_change.fpp"
1043
1044 !> @name variables for the correction of the reacting partial densities
1045 !> @{
1046 real(wp), intent(out) :: mct
1047 type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf
1048 real(wp), intent(inout) :: rm
1049 integer, intent(in) :: j, k, l
1050 !> @}
1051 if (rm < 0.0_wp) then
1052 if ((q_cons_vf(lp + eqn_idx%cont%beg - 1)%sf(j, k, &
1053 & l) >= -1.0_wp*mixm) .and. (q_cons_vf(vp + eqn_idx%cont%beg - 1)%sf(j, k, l) >= -1.0_wp*mixm)) then
1054 q_cons_vf(lp + eqn_idx%cont%beg - 1)%sf(j, k, l) = 0.0_wp
1055
1056 q_cons_vf(vp + eqn_idx%cont%beg - 1)%sf(j, k, l) = 0.0_wp
1057
1058 rm = q_cons_vf(lp + eqn_idx%cont%beg - 1)%sf(j, k, l) + q_cons_vf(vp + eqn_idx%cont%beg - 1)%sf(j, k, l)
1059 end if
1060 end if
1061
1062 ! TODO: Consider partitioning partial densities instead of absolute-value correction
1063 mct = 2*mixm
1064
1065 ! correcting the partial densities of the reacting fluids. What to do for the nonreacting ones?
1066 if (q_cons_vf(lp + eqn_idx%cont%beg - 1)%sf(j, k, l) < 0.0_wp) then
1067 q_cons_vf(lp + eqn_idx%cont%beg - 1)%sf(j, k, l) = mct*rm
1068
1069 q_cons_vf(vp + eqn_idx%cont%beg - 1)%sf(j, k, l) = (1.0_wp - mct)*rm
1070 else if (q_cons_vf(vp + eqn_idx%cont%beg - 1)%sf(j, k, l) < 0.0_wp) then
1071 q_cons_vf(lp + eqn_idx%cont%beg - 1)%sf(j, k, l) = (1.0_wp - mct)*rm
1072
1073 q_cons_vf(vp + eqn_idx%cont%beg - 1)%sf(j, k, l) = mct*rm
1074 end if
1075
1076 end subroutine s_correct_partial_densities
1077
1078 !> Finalize the phase change module
1082
1083end module m_phase_change
type(scalar_field), dimension(sys_size), intent(inout) q_cons_vf
real(wp), intent(inout) rm
integer, intent(in) k
real(wp), intent(out) mct
integer, intent(in) j
integer, intent(in) l
Compile-time constant parameters: default values, tolerances, and physical constants.
integer, parameter model_eqns_6eq
Shared derived types for field data, patch geometry, bubble dynamics, and MPI I/O structures.
Equations of state in Gamma/Pi form, rho e = Gamma(rho) p + Pi(rho).
real(wp) function, public f_sg_thermal(pres, rho_or_t, n, b, cv)
Stiffened-gas thermal law p + B = (n - 1)*cv*rho*T. Pass rho to get T, or T to get rho.
Global parameters for the computational domain, fluid properties, and simulation algorithm configurat...
Basic floating-point utilities: approximate equality, default detection, and coordinate bounds.
MPI halo exchange, domain decomposition, and buffer packing/unpacking for the simulation solver.
Phase transition relaxation solvers for liquid-vapor flows with cavitation and boiling.
subroutine s_infinite_ptg_relaxation_k(j, k, l, ps, rhoe, q_cons_vf, ts, ptg_conv)
Apply pTg-equilibrium relaxation: a damped (backtracking line search) Newton solve for the reacting l...
impure subroutine, public s_finalize_relaxation_solver_module
Finalize the phase change module.
subroutine, public s_infinite_relaxation_k(q_cons_vf)
Apply pT- or pTg-equilibrium relaxation with mass depletion based on the incoming state conditions.
integer, parameter vp
index for the vapor phase of the reacting fluid
integer, parameter lp
index for the liquid phase of the reacting fluid
subroutine s_infinite_pt_relaxation_k(j, k, l, mfl, ps, p_infpt, q_cons_vf, rhoe, ts)
Apply pT-equilibrium relaxation for N fluids.
impure subroutine, public s_relaxation_solver(q_cons_vf)
Dispatch to the correct relaxation solver. Replaces the procedure pointer, which CCE is breaking on.
real(wp), parameter tcr
Critical temperature of water [K].
subroutine s_compute_ptg_residual(ml, mt, ps, j, k, l, q_cons_vf, rhoe, r2d, ts, mcp, mq, mcvgp, mcvgp2, mcpd)
Evaluate the pTg-equilibrium residual R2D and temperature TS at a trial state (ml,...
integer, parameter ptg_ls_max
max backtracking-line-search halvings in the pTg solver
integer, parameter max_iter
max Newton iterations before accepting the last iterate
impure subroutine, public s_initialize_phasechange_module
Initialize the phase change module (no module-level state to set up; the pT/pTg relaxation solvers ar...
real(wp), parameter mixm
Mixture mass fraction threshold for triggering phase change.
real(wp), parameter pcr
Critical pressure of water [Pa].
Conservative-to-primitive variable conversion, mixture property evaluation, and pressure computation.
Derived type annexing a scalar field (SF).