Neko 1.99.2
A portable framework for high-order spectral element flow simulations
Loading...
Searching...
No Matches
fluid_scheme_compressible.f90
Go to the documentation of this file.
1! Copyright (c) 2025, The Neko Authors
2! All rights reserved.
3!
4! Redistribution and use in source and binary forms, with or without
5! modification, are permitted provided that the following conditions
6! are met:
7!
8! * Redistributions of source code must retain the above copyright
9! notice, this list of conditions and the following disclaimer.
10!
11! * Redistributions in binary form must reproduce the above
12! copyright notice, this list of conditions and the following
13! disclaimer in the documentation and/or other materials provided
14! with the distribution.
15!
16! * Neither the name of the authors nor the names of its
17! contributors may be used to endorse or promote products derived
18! from this software without specific prior written permission.
19!
20! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21! "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22! LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23! FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24! COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25! INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26! BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27! LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28! CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29! LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30! ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31! POSSIBILITY OF SUCH DAMAGE.
32!
34 use field, only : field_t
37
38 use registry, only : neko_registry
40 use json_module, only : json_file
41 use num_types, only : rp
42 use mesh, only : mesh_t
44 use space, only : gll
45 use user_intf, only : user_t
47 use mpi_f08
48 use operators, only : cfl_compressible
49 use compressible_ops_cpu, only : &
52 use compressible_ops_device, only : &
56 use time_state, only : time_state_t
57 use logger, only : neko_log, log_size
58 use math, only : glsum
59 use num_types, only : i8
60 implicit none
61 private
62
64 type, public, abstract, extends(fluid_scheme_base_t) :: &
67 type(field_t), pointer :: m_x => null()
68 type(field_t), pointer :: m_y => null()
69 type(field_t), pointer :: m_z => null()
70 type(field_t), pointer :: e => null()
71 type(field_t), pointer :: max_wave_speed => null()
72 type(field_t), pointer :: s => null()
73 type(field_t), pointer :: effective_visc => null()
74
75 real(kind=rp) :: gamma
76
78 integer(kind=i8) :: glb_n_points
80 integer(kind=i8) :: glb_unique_points
81
82 contains
84 procedure, pass(this) :: scheme_init => fluid_scheme_compressible_init
86 procedure, pass(this) :: scheme_free => fluid_scheme_compressible_free
87
89 procedure, pass(this) :: validate => fluid_scheme_compressible_validate
91 procedure, pass(this) :: compute_cfl &
94 procedure, pass(this) :: update_material_properties => &
97 procedure, pass(this) :: compute_entropy => &
100 procedure, pass(this) :: compute_max_wave_speed => &
103 procedure, pass(this) :: log_solver_info => &
105
107
108contains
116 subroutine fluid_scheme_compressible_init(this, msh, lx, params, scheme, user)
117 class(fluid_scheme_compressible_t), target, intent(inout) :: this
118 type(mesh_t), target, intent(inout) :: msh
119 integer, intent(in) :: lx
120 character(len=*), intent(in) :: scheme
121 type(json_file), target, intent(inout) :: params
122 type(user_t), target, intent(in) :: user
123
124 !
125 ! SEM simulation fundamentals
126 !
127
128 this%msh => msh
129
130 if (msh%gdim .eq. 2) then
131 call this%Xh%init(gll, lx, lx)
132 else
133 call this%Xh%init(gll, lx, lx, lx)
134 end if
135
136 call this%dm_Xh%init(msh, this%Xh)
137
138 call this%gs_Xh%init(this%dm_Xh)
139
140 call this%c_Xh%init(this%gs_Xh)
141
142 ! Assign Dofmap to scratch registry
143 call neko_scratch_registry%set_dofmap(this%dm_Xh)
144
145 ! Case parameters
146 this%params => params
147
148 ! Assign a name
149 call json_get_or_default(params, 'case.fluid.name', this%name, "fluid")
150
151 ! Fill mu and rho field with the physical value
152 call neko_registry%add_field(this%dm_Xh, this%name // "_mu")
153 call neko_registry%add_field(this%dm_Xh, this%name // "_rho")
154 this%mu => neko_registry%get_field(this%name // "_mu")
155 this%rho => neko_registry%get_field(this%name // "_rho")
156 call field_cfill(this%mu, 0.0_rp, this%mu%size())
157
158 ! Assign momentum fields
159 call neko_registry%add_field(this%dm_Xh, "m_x")
160 call neko_registry%add_field(this%dm_Xh, "m_y")
161 call neko_registry%add_field(this%dm_Xh, "m_z")
162 this%m_x => neko_registry%get_field("m_x")
163 this%m_y => neko_registry%get_field("m_y")
164 this%m_z => neko_registry%get_field("m_z")
165 call this%m_x%init(this%dm_Xh, "m_x")
166 call this%m_y%init(this%dm_Xh, "m_y")
167 call this%m_z%init(this%dm_Xh, "m_z")
168
169 ! Assign energy field
170 call neko_registry%add_field(this%dm_Xh, "E")
171 this%E => neko_registry%get_field("E")
172 call this%E%init(this%dm_Xh, "E")
173
174 ! Assign maximum wave speed field
175 call neko_registry%add_field(this%dm_Xh, "max_wave_speed")
176 this%max_wave_speed => neko_registry%get_field("max_wave_speed")
177 call this%max_wave_speed%init(this%dm_Xh, "max_wave_speed")
178
179 ! Assign entropy field
180 call neko_registry%add_field(this%dm_Xh, "S")
181 this%S => neko_registry%get_field("S")
182 call this%S%init(this%dm_Xh, "S")
183
184 ! Assign effective artificial viscosity field
185 call neko_registry%add_field(this%dm_Xh, "effective_visc")
186 this%effective_visc => neko_registry%get_field("effective_visc")
187 call this%effective_visc%init(this%dm_Xh, "effective_visc")
188
189 ! ! Assign velocity fields
190 call neko_registry%add_field(this%dm_Xh, "u")
191 call neko_registry%add_field(this%dm_Xh, "v")
192 call neko_registry%add_field(this%dm_Xh, "w")
193 this%u => neko_registry%get_field("u")
194 this%v => neko_registry%get_field("v")
195 this%w => neko_registry%get_field("w")
196 call this%u%init(this%dm_Xh, "u")
197 call this%v%init(this%dm_Xh, "v")
198 call this%w%init(this%dm_Xh, "w")
199 call neko_registry%add_field(this%dm_Xh, 'p')
200 this%p => neko_registry%get_field('p')
201 call this%p%init(this%dm_Xh, "p")
202
203 !
204 ! Setup right-hand side fields.
205 !
206 allocate(this%f_x)
207 allocate(this%f_y)
208 allocate(this%f_z)
209 call this%f_x%init(this%dm_Xh, fld_name = "fluid_rhs_x")
210 call this%f_y%init(this%dm_Xh, fld_name = "fluid_rhs_y")
211 call this%f_z%init(this%dm_Xh, fld_name = "fluid_rhs_z")
212
213 ! Compressible parameters
214 call json_get_or_default(params, 'case.fluid.gamma', this%gamma, 1.4_rp)
215
216 ! Calculate global points for logging
217 this%glb_n_points = int(this%msh%glb_nelv, i8)*int(this%Xh%lxyz, i8)
218 this%glb_unique_points = int(glsum(this%c_Xh%mult, this%dm_Xh%size()), i8)
219
220 !
221 ! Log solver information
222 !
223 call this%log_solver_info(params, scheme, lx)
224 end subroutine fluid_scheme_compressible_init
225
229 class(fluid_scheme_compressible_t), intent(inout) :: this
230 call this%dm_Xh%free()
231 call this%gs_Xh%free()
232 call this%c_Xh%free()
233 call this%Xh%free()
234
235 if (associated(this%m_x)) then
236 call this%m_x%free()
237 end if
238
239 if (associated(this%m_y)) then
240 call this%m_y%free()
241 end if
242
243 if (associated(this%m_z)) then
244 call this%m_z%free()
245 end if
246
247 if (associated(this%E)) then
248 call this%E%free()
249 end if
250
251 if (associated(this%max_wave_speed)) then
252 call this%max_wave_speed%free()
253 end if
254
255 if (associated(this%S)) then
256 call this%S%free()
257 end if
258
259 if (associated(this%f_x)) then
260 call this%f_x%free()
261 deallocate(this%f_x)
262 end if
263
264 if (associated(this%f_y)) then
265 call this%f_y%free()
266 deallocate(this%f_y)
267 end if
268
269 if (associated(this%f_z)) then
270 call this%f_z%free()
271 deallocate(this%f_z)
272 end if
273
274 nullify(this%f_x)
275 nullify(this%f_y)
276 nullify(this%f_z)
277
278 nullify(this%m_x)
279 nullify(this%m_y)
280 nullify(this%m_z)
281 nullify(this%E)
282 nullify(this%max_wave_speed)
283 nullify(this%S)
284
285 nullify(this%u)
286 nullify(this%v)
287 nullify(this%w)
288 nullify(this%p)
289 nullify(this%rho)
290 nullify(this%mu)
291
292 end subroutine fluid_scheme_compressible_free
293
297 class(fluid_scheme_compressible_t), target, intent(inout) :: this
298 integer :: n
299 type(field_t), pointer :: temp
300 integer :: temp_indices(1)
301
302 n = this%dm_Xh%size()
303 call neko_scratch_registry%request_field(temp, temp_indices(1), .false.)
304
306 call field_col3(this%m_x, this%u, this%rho)
307 call field_col3(this%m_y, this%v, this%rho)
308 call field_col3(this%m_z, this%w, this%rho)
309
312 call field_cmult2(this%E, this%p, 1.0_rp/(this%gamma - 1.0_rp), n)
313 call field_col3(temp, this%u, this%u, n)
314 call field_addcol3(temp, this%v, this%v, n)
315 call field_addcol3(temp, this%w, this%w, n)
316 call field_col2(temp, this%rho, n)
317 call field_cmult(temp, 0.5_rp, n)
318 call field_add2(this%E, temp, n)
319
320 call neko_scratch_registry%relinquish_field(temp_indices)
321
323 call this%compute_max_wave_speed()
324
326
331 function fluid_scheme_compressible_compute_cfl(this, dt) result(c)
332 class(fluid_scheme_compressible_t), intent(in) :: this
333 real(kind=rp), intent(in) :: dt
334 real(kind=rp) :: c
335 integer :: n
336
337 associate(u => this%u, v => this%v, w => this%w, p => this%p, &
338 rho => this%rho, xh => this%Xh, c_xh => this%c_Xh, &
339 msh => this%msh, gamma => this%gamma, &
340 max_wave_speed => this%max_wave_speed)
341
342 n = xh%lx * xh%ly * xh%lz * msh%nelv
343
344 ! Use the compressible CFL function with precomputed maximum wave speed
345 c = cfl_compressible(dt, max_wave_speed%x, xh, c_xh, msh%nelv, msh%gdim)
346 end associate
347
349
353 class(fluid_scheme_compressible_t), intent(inout) :: this
354 type(time_state_t), intent(in) :: time
356
360 class(fluid_scheme_compressible_t), intent(inout) :: this
361 integer :: n
362
363 n = this%S%dof%size()
364
366 if (neko_bcknd_device .eq. 1) then
367 call compressible_ops_device_compute_entropy(this%S, this%p, this%rho, &
368 this%gamma, n)
369 else
370 call compressible_ops_cpu_compute_entropy(this%S%x, this%p%x, &
371 this%rho%x, this%gamma, n)
372 end if
373
375
379 class(fluid_scheme_compressible_t), intent(inout) :: this
380 integer :: n
381
382 n = this%u%dof%size()
383
385 if (neko_bcknd_device .eq. 1) then
386 call compressible_ops_device_compute_max_wave_speed( &
387 this%max_wave_speed, this%u, this%v, this%w, this%gamma, this%p, &
388 this%rho, n)
389 else
390 call compressible_ops_cpu_compute_max_wave_speed(this%max_wave_speed%x, &
391 this%u%x, this%v%x, this%w%x, this%gamma, this%p%x, this%rho%x, n)
392 end if
393
395
401 subroutine fluid_scheme_compressible_log_solver_info(this, params, scheme, lx)
402 class(fluid_scheme_compressible_t), intent(inout) :: this
403 type(json_file), intent(inout) :: params
404 character(len=*), intent(in) :: scheme
405 integer, intent(in) :: lx
406 character(len=LOG_SIZE) :: log_buf
407 logical :: logical_val
408 real(kind=rp) :: real_val
409 integer :: integer_val
410
411 call neko_log%section('Fluid')
412 write(log_buf, '(A, A)') 'Type : ', trim(scheme)
413 call neko_log%message(log_buf)
414 write(log_buf, '(A, A)') 'Name : ', trim(this%name)
415 call neko_log%message(log_buf)
416
417 ! Polynomial order
418 if (lx .lt. 10) then
419 write(log_buf, '(A, I1)') 'Poly order : ', lx-1
420 else if (lx .ge. 10) then
421 write(log_buf, '(A, I2)') 'Poly order : ', lx-1
422 else
423 write(log_buf, '(A, I3)') 'Poly order : ', lx-1
424 end if
425 call neko_log%message(log_buf)
426
427 ! Global points information
428 write(log_buf, '(A, I0)') 'GLL points : ', this%glb_n_points
429 call neko_log%message(log_buf)
430 write(log_buf, '(A, I0)') 'Unique pts.: ', this%glb_unique_points
431 call neko_log%message(log_buf)
432
433 ! Material properties
434 write(log_buf, '(A,ES13.6)') 'gamma :', this%gamma
435 call neko_log%message(log_buf)
436
437 ! Compressible-specific parameters
438 call json_get_or_default(params, 'case.numerics.c_avisc_low', real_val, &
439 0.5_rp)
440 write(log_buf, '(A,ES13.6)') 'c_avisc_low:', real_val
441 call neko_log%message(log_buf)
442
443 call json_get_or_default(params, 'case.numerics.time_order', integer_val, 4)
444 write(log_buf, '(A, I0)') 'RK order : ', integer_val
445 call neko_log%message(log_buf)
446 call neko_log%end_section()
447
449
Abstract interface to sets rho and mu.
Retrieves a parameter by name or assigns a provided default value. In the latter case also adds the m...
CPU implementation of compressible flow operations.
subroutine, public compressible_ops_cpu_compute_entropy(s, p, rho, gamma, n)
Compute entropy field S = 1/(gamma-1) * rho * (log(p) - gamma * log(rho)) on CPU.
subroutine, public compressible_ops_cpu_compute_max_wave_speed(max_wave_speed, u, v, w, gamma, p, rho, n)
Compute maximum wave speed for compressible flows on CPU.
Device implementation of compressible flow operations.
subroutine, public compressible_ops_device_compute_entropy(s, p, rho, gamma, n)
Compute entropy field S = 1/(gamma-1) * rho * (log(p) - gamma * log(rho)) on device.
subroutine, public compressible_ops_device_compute_max_wave_speed(max_wave_speed, u, v, w, gamma, p, rho, n)
Compute maximum wave speed for compressible flows on device.
subroutine, public field_col2(a, b, n)
Vector multiplication .
subroutine, public field_cmult2(a, b, c, n)
Multiplication by constant c .
subroutine, public field_cfill(a, c, n)
Set all elements to a constant c .
subroutine, public field_addcol3(a, b, c, n)
Returns .
subroutine, public field_add2(a, b, n)
Vector addition .
subroutine, public field_col3(a, b, c, n)
Vector multiplication with 3 vectors .
subroutine, public field_cmult(a, c, n)
Multiplication by constant c .
Defines a field.
Definition field.f90:34
subroutine fluid_scheme_compressible_log_solver_info(this, params, scheme, lx)
Log comprehensive solver information.
subroutine fluid_scheme_compressible_free(this)
Free allocated memory and cleanup resources.
subroutine fluid_scheme_compressible_update_material_properties(this, time)
Set rho and mu.
subroutine fluid_scheme_compressible_init(this, msh, lx, params, scheme, user)
Initialize common data for compressible fluid scheme.
real(kind=rp) function fluid_scheme_compressible_compute_cfl(this, dt)
Compute CFL number.
subroutine fluid_scheme_compressible_compute_max_wave_speed(this)
Compute maximum wave speed for compressible flows.
subroutine fluid_scheme_compressible_validate(this)
Validate field initialization and compute derived quantities.
subroutine fluid_scheme_compressible_compute_entropy(this)
Compute entropy field S = 1/(gamma-1) * rho * (log(p) - gamma * log(rho))
Utilities for retrieving parameters from the case files.
Logging routines.
Definition log.f90:34
type(log_t), public neko_log
Global log stream.
Definition log.f90:77
integer, parameter, public log_size
Definition log.f90:46
Definition math.f90:60
real(kind=rp) function, public glsum(a, n)
Sum a vector of length n.
Definition math.f90:499
Defines a mesh.
Definition mesh.f90:34
Build configurations.
integer, parameter neko_bcknd_device
integer, parameter, public i8
Definition num_types.f90:7
integer, parameter, public rp
Global precision used in computations.
Definition num_types.f90:12
Operators.
Definition operators.f90:34
real(kind=rp) function, public cfl_compressible(dt, max_wave_speed, xh, coef, nelv, gdim)
Defines a registry for storing solution fields.
Definition registry.f90:34
type(registry_t), target, public neko_registry
Global field registry.
Definition registry.f90:149
Defines a registry for storing and requesting temporary objects This can be used when you have a func...
type(scratch_registry_t), target, public neko_scratch_registry
Global scratch registry.
Defines a function space.
Definition space.f90:34
integer, parameter, public gll
Definition space.f90:49
Module with things related to the simulation time.
Interfaces for user interaction with NEKO.
Definition user_intf.f90:34
Base type of all fluid formulations.
A struct that contains all info about the time, expand as needed.
A type collecting all the overridable user routines and flag to suppress type injection from custom m...