Neko 1.99.6
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
35 use field_math, only : field_col2, field_col3, &
38
39 use registry, only : neko_registry
40 use bc, only : bc_t
42 use json_module, only : json_file
43 use num_types, only : rp
44 use mesh, only : mesh_t
46 use space, only : gll
50 use mpi_f08
51 use operators, only : cfl_compressible
53 use compressible_ops_cpu, only : &
56 use compressible_ops_device, only : &
60 use time_state, only : time_state_t
61 use logger, only : neko_log, log_size
62 use math, only : glsum
63 use num_types, only : i8
64 implicit none
65 private
66
68 type, public, abstract, extends(fluid_scheme_base_t) :: &
71 type(field_t), pointer :: m_x => null()
72 type(field_t), pointer :: m_y => null()
73 type(field_t), pointer :: m_z => null()
74 type(field_t), pointer :: e => null()
75 type(field_t), pointer :: temperature => null()
76 type(field_t), pointer :: max_wave_speed => null()
77 type(field_t), pointer :: s => null()
78 type(field_t), pointer :: artificial_visc => null()
79 type(field_t), pointer :: kappa => null()
80
81 real(kind=rp) :: gamma
82
84 integer(kind=i8) :: glb_n_points
86 integer(kind=i8) :: glb_unique_points
87
88 contains
90 procedure, pass(this) :: scheme_init => fluid_scheme_compressible_init
92 procedure, pass(this) :: scheme_free => fluid_scheme_compressible_free
93
95 procedure, pass(this) :: validate => fluid_scheme_compressible_validate
97 procedure, pass(this) :: compute_cfl &
100 procedure, pass(this) :: set_material_properties => &
103 procedure, pass(this) :: update_material_properties => &
106 procedure, pass(this) :: compute_entropy => &
109 procedure, pass(this) :: compute_max_wave_speed => &
112 procedure, pass(this) :: log_solver_info => &
114
116
117contains
125 subroutine fluid_scheme_compressible_init(this, msh, lx, params, scheme, user)
126 class(fluid_scheme_compressible_t), target, intent(inout) :: this
127 type(mesh_t), target, intent(inout) :: msh
128 integer, intent(in) :: lx
129 character(len=*), intent(in) :: scheme
130 type(json_file), target, intent(inout) :: params
131 type(user_t), target, intent(in) :: user
132
133 !
134 ! SEM simulation fundamentals
135 !
136
137 this%msh => msh
138
139 if (msh%gdim .eq. 2) then
140 call this%Xh%init(gll, lx, lx)
141 else
142 call this%Xh%init(gll, lx, lx, lx)
143 end if
144
145 call this%dm_Xh%init(msh, this%Xh)
146
147 call this%gs_Xh%init(this%dm_Xh)
148
149 call this%c_Xh%init(this%gs_Xh)
150
151 ! Assign Dofmap to scratch registry
152 call neko_scratch_registry%set_dofmap(this%dm_Xh)
153
154 ! Case parameters
155 this%params => params
156
157 ! Assign a name
158 call json_get_or_default(params, 'case.fluid.name', this%name, "fluid")
159
160 ! Material properties will be set up via set_material_properties
161 call neko_registry%add_field(this%dm_Xh, this%name // "_rho")
162 this%rho => neko_registry%get_field(this%name // "_rho")
163
164 ! Assign momentum fields
165 call neko_registry%add_field(this%dm_Xh, "m_x")
166 call neko_registry%add_field(this%dm_Xh, "m_y")
167 call neko_registry%add_field(this%dm_Xh, "m_z")
168 this%m_x => neko_registry%get_field("m_x")
169 this%m_y => neko_registry%get_field("m_y")
170 this%m_z => neko_registry%get_field("m_z")
171 call this%m_x%init(this%dm_Xh, "m_x")
172 call this%m_y%init(this%dm_Xh, "m_y")
173 call this%m_z%init(this%dm_Xh, "m_z")
174
175 ! Assign energy field
176 call neko_registry%add_field(this%dm_Xh, "E")
177 this%E => neko_registry%get_field("E")
178 call this%E%init(this%dm_Xh, "E")
179
180 ! Assign temperature field
181 call neko_registry%add_field(this%dm_Xh, "temperature")
182 this%temperature => neko_registry%get_field("temperature")
183 call this%temperature%init(this%dm_Xh, "temperature")
184
185 ! Assign maximum wave speed field
186 call neko_registry%add_field(this%dm_Xh, "max_wave_speed")
187 this%max_wave_speed => neko_registry%get_field("max_wave_speed")
188 call this%max_wave_speed%init(this%dm_Xh, "max_wave_speed")
189
190 ! Assign entropy field
191 call neko_registry%add_field(this%dm_Xh, "S")
192 this%S => neko_registry%get_field("S")
193 call this%S%init(this%dm_Xh, "S")
194
195 ! Assign artificial viscosity field (without physical viscosity)
196 call neko_registry%add_field(this%dm_Xh, "artificial_visc")
197 this%artificial_visc => neko_registry%get_field("artificial_visc")
198 call this%artificial_visc%init(this%dm_Xh, "artificial_visc")
199
200 ! ! Assign velocity fields
201 call neko_registry%add_field(this%dm_Xh, "u")
202 call neko_registry%add_field(this%dm_Xh, "v")
203 call neko_registry%add_field(this%dm_Xh, "w")
204 this%u => neko_registry%get_field("u")
205 this%v => neko_registry%get_field("v")
206 this%w => neko_registry%get_field("w")
207 call this%u%init(this%dm_Xh, "u")
208 call this%v%init(this%dm_Xh, "v")
209 call this%w%init(this%dm_Xh, "w")
210 call neko_registry%add_field(this%dm_Xh, 'p')
211 this%p => neko_registry%get_field('p')
212 call this%p%init(this%dm_Xh, "p")
213
214 !
215 ! Setup right-hand side fields.
216 !
217 allocate(this%f_x)
218 allocate(this%f_y)
219 allocate(this%f_z)
220 call this%f_x%init(this%dm_Xh, fld_name = "fluid_rhs_x")
221 call this%f_y%init(this%dm_Xh, fld_name = "fluid_rhs_y")
222 call this%f_z%init(this%dm_Xh, fld_name = "fluid_rhs_z")
223
224 ! Material properties
225 call this%set_material_properties(params, user)
226
227 ! Compressible parameters
228 call json_get_or_default(params, 'case.fluid.gamma', this%gamma, 1.4_rp)
229
230 ! Calculate global points for logging
231 this%glb_n_points = int(this%msh%glb_nelv, i8)*int(this%Xh%lxyz, i8)
232 this%glb_unique_points = int(glsum(this%c_Xh%mult, this%dm_Xh%size()), i8)
233
234 !
235 ! Log solver information
236 !
237 call this%log_solver_info(params, scheme, lx)
238 end subroutine fluid_scheme_compressible_init
239
243 class(fluid_scheme_compressible_t), intent(inout) :: this
244 class(bc_t), pointer :: bc
245 integer :: i
246
247 do i = 1, this%bcs_vel%size()
248 bc => this%bcs_vel%get(i)
249 if (associated(bc)) then
250 call bc%free()
251 deallocate(bc)
252 end if
253 end do
254 call this%bcs_vel%free()
255
256 do i = 1, this%bcs_prs%size()
257 bc => this%bcs_prs%get(i)
258 if (associated(bc)) then
259 call bc%free()
260 deallocate(bc)
261 end if
262 end do
263 call this%bcs_prs%free()
264
265 call this%dm_Xh%free()
266 call this%gs_Xh%free()
267 call this%c_Xh%free()
268 call this%Xh%free()
269
270 if (associated(this%m_x)) then
271 call this%m_x%free()
272 end if
273
274 if (associated(this%m_y)) then
275 call this%m_y%free()
276 end if
277
278 if (associated(this%m_z)) then
279 call this%m_z%free()
280 end if
281
282 if (associated(this%E)) then
283 call this%E%free()
284 end if
285
286 if (associated(this%temperature)) then
287 call this%temperature%free()
288 end if
289
290 if (associated(this%max_wave_speed)) then
291 call this%max_wave_speed%free()
292 end if
293
294 if (associated(this%S)) then
295 call this%S%free()
296 end if
297
298 if (associated(this%f_x)) then
299 call this%f_x%free()
300 deallocate(this%f_x)
301 end if
302
303 if (associated(this%f_y)) then
304 call this%f_y%free()
305 deallocate(this%f_y)
306 end if
307
308 if (associated(this%f_z)) then
309 call this%f_z%free()
310 deallocate(this%f_z)
311 end if
312
313 nullify(this%f_x)
314 nullify(this%f_y)
315 nullify(this%f_z)
316
317 nullify(this%m_x)
318 nullify(this%m_y)
319 nullify(this%m_z)
320 nullify(this%E)
321 nullify(this%temperature)
322 nullify(this%max_wave_speed)
323 nullify(this%S)
324
325 nullify(this%u)
326 nullify(this%v)
327 nullify(this%w)
328 nullify(this%p)
329 nullify(this%rho)
330 nullify(this%mu)
331 nullify(this%kappa)
332
333 call this%material_properties%free()
334
335 end subroutine fluid_scheme_compressible_free
336
340 class(fluid_scheme_compressible_t), target, intent(inout) :: this
341 integer :: n, i
342 type(field_t), pointer :: temp
343 integer :: temp_indices(1)
344
345 n = this%dm_Xh%size()
346 call neko_scratch_registry%request_field(temp, temp_indices(1), .false.)
347
349 call field_col3(this%m_x, this%u, this%rho)
350 call field_col3(this%m_y, this%v, this%rho)
351 call field_col3(this%m_z, this%w, this%rho)
352
355 call field_cmult2(this%E, this%p, 1.0_rp/(this%gamma - 1.0_rp), n)
356 call field_col3(temp, this%u, this%u, n)
357 call field_addcol3(temp, this%v, this%v, n)
358 call field_addcol3(temp, this%w, this%w, n)
359 call field_col2(temp, this%rho, n)
360 call field_cmult(temp, 0.5_rp, n)
361 call field_add2(this%E, temp, n)
362
364 do i = 1, n
365 this%temperature%x(i,1,1,1) = this%p%x(i,1,1,1) / &
366 (this%rho%x(i,1,1,1) * (this%gamma - 1.0_rp))
367 end do
368
369 call neko_scratch_registry%relinquish_field(temp_indices)
370
372 call this%compute_max_wave_speed()
373
375
380 function fluid_scheme_compressible_compute_cfl(this, dt) result(c)
381 class(fluid_scheme_compressible_t), intent(in) :: this
382 real(kind=rp), intent(in) :: dt
383 real(kind=rp) :: c
384 integer :: n
385
386 associate(u => this%u, v => this%v, w => this%w, p => this%p, &
387 rho => this%rho, xh => this%Xh, c_xh => this%c_Xh, &
388 msh => this%msh, gamma => this%gamma, &
389 max_wave_speed => this%max_wave_speed)
390
391 n = xh%lx * xh%ly * xh%lz * msh%nelv
392
393 ! Use the compressible CFL function with precomputed maximum wave speed
394 c = cfl_compressible(dt, max_wave_speed%x, xh, c_xh, msh%nelv, msh%gdim)
395 end associate
396
398
404 params, user)
405 class(fluid_scheme_compressible_t), target, intent(inout) :: this
406 type(json_file), intent(inout) :: params
407 type(user_t), target, intent(in) :: user
408 procedure(user_material_properties_intf), pointer :: dummy_mp_ptr
409 type(time_state_t) :: dummy_time_state
410 character(len=LOG_SIZE) :: log_buf
411 real(kind=rp) :: const_mu, const_kappa
412
413 dummy_mp_ptr => dummy_user_material_properties
414
415 call neko_registry%add_field(this%dm_Xh, this%name // "_mu")
416 this%mu => neko_registry%get_field(this%name // "_mu")
417
418 call neko_registry%add_field(this%dm_Xh, this%name // "_kappa")
419 this%kappa => neko_registry%get_field(this%name // "_kappa")
420
421 call this%material_properties%init(3)
422 call this%material_properties%assign(1, this%rho)
423 call this%material_properties%assign(2, this%mu)
424 call this%material_properties%assign(3, this%kappa)
425
426 if (.not. associated(user%material_properties, dummy_mp_ptr)) then
427 this%user_material_properties => user%material_properties
428 call user%material_properties(this%name, this%material_properties, &
429 dummy_time_state)
430 else
431 this%user_material_properties => dummy_user_material_properties
432 call json_get_or_lookup_or_default(params, 'case.fluid.mu', const_mu, &
433 0.0_rp)
434 call json_get_or_lookup_or_default(params, 'case.fluid.kappa', &
435 const_kappa, 0.0_rp)
436
437 call field_cfill(this%mu, const_mu)
438 call field_cfill(this%kappa, const_kappa)
439
440 write(log_buf, '(A,ES13.6)') 'mu :', const_mu
441 call neko_log%message(log_buf)
442 write(log_buf, '(A,ES13.6)') 'kappa :', const_kappa
443 call neko_log%message(log_buf)
444 end if
445
446 if (neko_bcknd_device .eq. 1) then
447 call device_memcpy(this%mu%x, this%mu%x_d, this%mu%size(), &
448 host_to_device, sync = .false.)
449 call device_memcpy(this%kappa%x, this%kappa%x_d, this%kappa%size(), &
450 host_to_device, sync = .false.)
451 end if
452
454
460 class(fluid_scheme_compressible_t), intent(inout) :: this
461 type(time_state_t), intent(in) :: time
462
463 call this%user_material_properties(this%name, this%material_properties, &
464 time)
465
466 if (neko_bcknd_device .eq. 1) then
467 call device_memcpy(this%mu%x, this%mu%x_d, this%mu%size(), &
468 host_to_device, sync = .false.)
469 call device_memcpy(this%kappa%x, this%kappa%x_d, this%kappa%size(), &
470 host_to_device, sync = .false.)
471 end if
473
477 class(fluid_scheme_compressible_t), intent(inout) :: this
478 integer :: n
479
480 n = this%S%dof%size()
481
483 if (neko_bcknd_device .eq. 1) then
484 call compressible_ops_device_compute_entropy(this%S, this%p, this%rho, &
485 this%gamma, n)
486 else
487 call compressible_ops_cpu_compute_entropy(this%S%x, this%p%x, &
488 this%rho%x, this%gamma, n)
489 end if
490
492
496 class(fluid_scheme_compressible_t), intent(inout) :: this
497 integer :: n
498
499 n = this%u%dof%size()
500
502 if (neko_bcknd_device .eq. 1) then
503 call compressible_ops_device_compute_max_wave_speed( &
504 this%max_wave_speed, this%u, this%v, this%w, this%gamma, this%p, &
505 this%rho, n)
506 else
507 call compressible_ops_cpu_compute_max_wave_speed(this%max_wave_speed%x, &
508 this%u%x, this%v%x, this%w%x, this%gamma, this%p%x, this%rho%x, n)
509 end if
510
512
518 subroutine fluid_scheme_compressible_log_solver_info(this, params, scheme, lx)
519 class(fluid_scheme_compressible_t), intent(inout) :: this
520 type(json_file), intent(inout) :: params
521 character(len=*), intent(in) :: scheme
522 integer, intent(in) :: lx
523 character(len=LOG_SIZE) :: log_buf
524 logical :: logical_val
525 real(kind=rp) :: real_val
526 integer :: integer_val
527
528 call neko_log%section('Fluid')
529 write(log_buf, '(A, A)') 'Type : ', trim(scheme)
530 call neko_log%message(log_buf)
531 write(log_buf, '(A, A)') 'Name : ', trim(this%name)
532 call neko_log%message(log_buf)
533
534 ! Polynomial order
535 if (lx .lt. 10) then
536 write(log_buf, '(A, I1)') 'Poly order : ', lx-1
537 else if (lx .ge. 10) then
538 write(log_buf, '(A, I2)') 'Poly order : ', lx-1
539 else
540 write(log_buf, '(A, I3)') 'Poly order : ', lx-1
541 end if
542 call neko_log%message(log_buf)
543
544 ! Global points information
545 write(log_buf, '(A, I0)') 'GLL points : ', this%glb_n_points
546 call neko_log%message(log_buf)
547 write(log_buf, '(A, I0)') 'Unique pts.: ', this%glb_unique_points
548 call neko_log%message(log_buf)
549
550 ! Material properties
551 write(log_buf, '(A,ES13.6)') 'gamma :', this%gamma
552 call neko_log%message(log_buf)
553
554 ! Compressible-specific parameters
555 call json_get_or_default(params, 'case.numerics.c_avisc_low', real_val, &
556 0.5_rp)
557 write(log_buf, '(A,ES13.6)') 'c_avisc_low:', real_val
558 call neko_log%message(log_buf)
559
560 call json_get_or_default(params, 'case.numerics.time_order', integer_val, 4)
561 write(log_buf, '(A, I0)') 'RK order : ', integer_val
562 call neko_log%message(log_buf)
563 call neko_log%end_section()
564
566
Copy data between host and device (or device and device)
Definition device.F90:72
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...
Compute CFL condition for compressible flow.
Abstract interface for setting material properties.
Defines a boundary condition.
Definition bc.f90:34
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.
Device abstraction, common interface for various accelerators.
Definition device.F90:34
integer, parameter, public host_to_device
Definition device.F90:48
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)
Update variable material properties.
subroutine fluid_scheme_compressible_set_material_properties(this, params, user)
Set material properties mu and rho.
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:80
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:629
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
Defines a registry for storing solution fields.
Definition registry.f90:34
type(registry_t), target, public neko_registry
Global field registry.
Definition registry.f90:144
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:50
Module with things related to the simulation time.
Interfaces for user interaction with NEKO.
Definition user_intf.f90:34
subroutine, public dummy_user_material_properties(scheme_name, properties, time)
Base type for a boundary condition.
Definition bc.f90:62
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...