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