42 use space,
only :
gll,
operator(.ne.)
58 use json_module,
only : json_file
75 class(
ksp_t),
allocatable :: ksp_vel
76 class(
ksp_t),
allocatable :: ksp_prs
77 class(
pc_t),
allocatable :: pc_vel
78 class(
pc_t),
allocatable :: pc_prs
79 integer :: vel_projection_dim
80 integer :: pr_projection_dim
81 integer :: vel_projection_activ_step
82 integer :: pr_projection_activ_step
83 logical :: pr_projection_reorthogonalize_basis
84 logical :: strict_convergence
85 logical :: allow_stabilization
87 logical :: svv_enabled = .false.
96 logical :: forced_flow_rate = .false.
99 character(len=:),
allocatable :: nut_field_name
105 integer(kind=i8) :: glb_n_points
107 integer(kind=i8) :: glb_unique_points
121 procedure, pass(this) :: set_material_properties => &
135 module subroutine fluid_scheme_factory(object, type_name)
137 character(len=*) :: type_name
138 end subroutine fluid_scheme_factory
141 public :: fluid_scheme_incompressible_t, fluid_scheme_factory
146 subroutine fluid_scheme_init_base(this, msh, lx, params, scheme, user, &
149 class(fluid_scheme_incompressible_t),
target,
intent(inout) :: this
150 type(
mesh_t),
target,
intent(inout) :: msh
151 integer,
intent(in) :: lx
152 character(len=*),
intent(in) :: scheme
153 type(json_file),
target,
intent(inout) :: params
154 type(
user_t),
target,
intent(in) :: user
155 logical,
intent(in) :: kspv_init
157 character(len=LOG_SIZE) :: log_buf
158 real(kind=
rp),
allocatable :: real_vec(:)
159 real(kind=
rp) :: real_val, kappa, b, z0
160 logical :: logical_val, full_stress_formulation
161 integer :: integer_val, ierr
162 type(json_file) :: wm_json
163 character(len=:),
allocatable :: string_val1, string_val2
164 type(json_file) :: json_subdict, solver_params
172 if (msh%gdim .eq. 2)
then
173 call this%Xh%init(
gll, lx, lx)
175 call this%Xh%init(
gll, lx, lx, lx)
178 call this%dm_Xh%init(msh, this%Xh)
180 call this%gs_Xh%init(this%dm_Xh)
182 call this%c_Xh%init(this%gs_Xh)
195 write(log_buf,
'(A, A)')
'Type : ', trim(scheme)
197 write(log_buf,
'(A, A)')
'Name : ', trim(this%name)
211 call this%set_material_properties(params,
user)
215 'case.fluid.velocity_solver.projection_space_size', &
216 this%vel_projection_dim, 0)
218 'case.fluid.pressure_solver.projection_space_size', &
219 this%pr_projection_dim, 0)
221 'case.fluid.velocity_solver.projection_hold_steps', &
222 this%vel_projection_activ_step, 5)
224 'case.fluid.pressure_solver.projection_hold_steps', &
225 this%pr_projection_activ_step, 5)
227 'case.fluid.pressure_solver.projection_reorthogonalize_basis', &
228 this%pr_projection_reorthogonalize_basis, .false.)
232 if (params%valid_path(
"case.fluid.flow_rate_force"))
then
233 this%forced_flow_rate = .true.
238 write(log_buf,
'(A, I1)')
'Poly order : ', lx-1
239 else if (lx .ge. 10)
then
240 write(log_buf,
'(A, I2)')
'Poly order : ', lx-1
242 write(log_buf,
'(A, I3)')
'Poly order : ', lx-1
245 this%glb_n_points = int(this%msh%glb_nelv,
i8)*int(this%Xh%lxyz,
i8)
246 this%glb_unique_points = int(
glsum(this%c_Xh%mult, this%dm_Xh%size()),
i8)
248 write(log_buf,
'(A, I0)')
'GLL points : ', this%glb_n_points
250 write(log_buf,
'(A, I0)')
'Unique pts.: ', this%glb_unique_points
254 call json_get(params,
'case.numerics.dealias', logical_val)
255 write(log_buf,
'(A, L1)')
'Dealias : ', logical_val
261 write(log_buf,
'(A, L1)')
'Save bdry : ', logical_val
265 full_stress_formulation, .false.)
266 write(log_buf,
'(A, L1)')
'Full stress: ', full_stress_formulation
272 'case.numerics.compress_geometric_factors', logical_val, .false.)
273 write(log_buf,
'(A, L1)')
'Compress G : ', logical_val
275 if (logical_val)
then
276 if (params%valid_path( &
277 'case.numerics.compress_geometric_factors_tolerance'))
then
279 'case.numerics.compress_geometric_factors_tolerance', real_val)
280 call this%c_Xh%enable_geo_compression(real_val)
282 call this%c_Xh%enable_geo_compression()
293 call this%f_x%init(this%dm_Xh, fld_name =
"fluid_rhs_x")
294 call this%f_y%init(this%dm_Xh, fld_name =
"fluid_rhs_y")
295 call this%f_z%init(this%dm_Xh, fld_name =
"fluid_rhs_z")
299 call neko_log%section(
"Velocity solver")
300 call json_get(params,
'case.fluid.velocity_solver', solver_params)
301 call json_get(params,
'case.fluid.velocity_solver.type', string_val1)
302 call json_get(params,
'case.fluid.velocity_solver.preconditioner.type', &
305 'case.fluid.velocity_solver.preconditioner', json_subdict)
307 'case.fluid.velocity_solver.absolute_tolerance', &
310 call neko_log%message(
'Type : ('// trim(string_val1) // &
311 ', ' // trim(string_val2) //
')')
313 write(log_buf,
'(A,ES13.6)')
'Abs tol :', real_val
315 call this%solver_factory(this%ksp_vel, this%dm_Xh%size(), &
317 call this%precon_factory_(this%pc_vel, this%ksp_vel, &
318 this%c_Xh, this%bcs_vel, &
319 string_val2, json_subdict)
325 this%strict_convergence, .false.)
328 this%allow_stabilization, .false.)
332 call this%ulag%init(this%u, 2)
333 call this%vlag%init(this%v, 2)
334 call this%wlag%init(this%w, 2)
344 call neko_log%section(
'Fluid Source term')
345 call this%source_term%init(this%f_x, this%f_y, this%f_z, this%c_Xh,
user, &
347 call this%source_term%add(params,
'case.fluid.source_terms')
350 if (params%valid_path(
'case.fluid.svv'))
then
351 call json_get(params,
'case.fluid', json_subdict)
353 this%svv_enabled, .false.)
354 if (this%svv_enabled)
then
355 if (.not. kspv_init)
then
356 call neko_error(
"SVV is only supported by fluid " // &
357 "schemes with an implicit velocity solve")
359 if (full_stress_formulation)
then
360 if (trim(string_val1) .ne.
'coupled_cg' .and. &
361 trim(string_val1) .ne.
'fused_coupled_cg')
then
362 call neko_error(
"Full-stress SVV requires a " // &
363 "coupled velocity solver (`coupled_cg` or " // &
364 "`fused_coupled_cg`)")
368 call this%svv%init(json_subdict, this%c_Xh, this%rho)
372 end subroutine fluid_scheme_init_base
374 subroutine fluid_scheme_free(this)
375 class(fluid_scheme_incompressible_t),
intent(inout) :: this
376 class(
bc_t),
pointer :: bc
380 if (
allocated(this%svv))
then
384 this%svv_enabled = .false.
388 if (
allocated(this%ksp_vel))
then
389 call this%ksp_vel%free()
390 deallocate(this%ksp_vel)
393 if (
allocated(this%ksp_prs))
then
394 call this%ksp_prs%free()
395 deallocate(this%ksp_prs)
398 if (
allocated(this%pc_vel))
then
399 call this%pc_vel%free()
400 deallocate(this%pc_vel)
403 if (
allocated(this%pc_prs))
then
404 call this%pc_prs%free()
405 deallocate(this%pc_prs)
408 do i = 1, this%bcs_vel%size()
409 bc => this%bcs_vel%get(i)
410 if (
associated(
bc))
then
415 call this%bcs_vel%free()
417 do i = 1, this%bcs_prs%size()
418 bc => this%bcs_prs%get(i)
419 if (
associated(
bc))
then
424 call this%bcs_prs%free()
426 call this%source_term%free()
428 call this%gs_Xh%free()
430 call this%c_Xh%free()
441 call this%ulag%free()
442 call this%vlag%free()
443 call this%wlag%free()
446 if (
associated(this%f_x))
then
451 if (
associated(this%f_y))
then
456 if (
associated(this%f_z))
then
468 call this%dm_Xh%free()
472 end subroutine fluid_scheme_free
476 subroutine fluid_scheme_validate(this)
477 class(fluid_scheme_incompressible_t),
target,
intent(inout) :: this
479 logical :: logical_val
481 if ( (.not.
associated(this%u)) .or. &
482 (.not.
associated(this%v)) .or. &
483 (.not.
associated(this%w)) .or. &
484 (.not.
associated(this%p)))
then
488 if ( (.not.
allocated(this%u%x)) .or. &
489 (.not.
allocated(this%v%x)) .or. &
490 (.not.
allocated(this%w%x)) .or. &
491 (.not.
allocated(this%p%x)))
then
495 if (this%u%Xh .ne. this%v%Xh .or. &
496 this%u%Xh .ne. this%w%Xh)
then
497 call neko_error(
'Different function spaces for velocity components')
500 if (this%u%msh%nelv .ne. this%p%msh%nelv)
then
501 call neko_error(
'Velocity and pressure defined on different meshes')
504 if (.not.
allocated(this%ksp_vel))
then
505 call neko_error(
'No Krylov solver for velocity defined')
508 if (.not.
allocated(this%ksp_prs))
then
509 call neko_error(
'No Krylov solver for pressure defined')
512 end subroutine fluid_scheme_validate
518 subroutine fluid_scheme_bc_apply_vel(this, time, strong)
519 class(fluid_scheme_incompressible_t),
intent(inout) :: this
521 logical,
intent(in) :: strong
523 class(
bc_t),
pointer :: b
525 call this%bcs_vel%apply_vector(&
526 this%u%x, this%v%x, this%w%x, this%dm_Xh%size(), time, strong)
528 call rotate_cyc(this%u, this%v, this%w, 1, this%c_Xh)
535 call rotate_cyc(this%u, this%v, this%w, 0, this%c_Xh)
539 do i = 1, this%bcs_vel%size()
540 b => this%bcs_vel%get(i)
542 call b%apply_vector_generic(this%u, this%v, this%w,time, strong)
546 call rotate_cyc(this%u, this%v, this%w, 1, this%c_Xh)
553 call rotate_cyc(this%u, this%v, this%w, 0, this%c_Xh)
555 do i = 1, this%bcs_vel%size()
556 b => this%bcs_vel%get(i)
561 end subroutine fluid_scheme_bc_apply_vel
565 subroutine fluid_scheme_bc_apply_prs(this, time)
566 class(fluid_scheme_incompressible_t),
intent(inout) :: this
570 class(
bc_t),
pointer :: b
573 call this%bcs_prs%apply(this%p, time)
577 call this%bcs_prs%apply(this%p, time)
581 do i = 1, this%bcs_prs%size()
582 b => this%bcs_prs%get(i)
587 end subroutine fluid_scheme_bc_apply_prs
591 subroutine fluid_scheme_solver_factory(ksp, n, params)
592 class(
ksp_t),
allocatable,
target,
intent(inout) :: ksp
593 integer,
intent(in),
value :: n
594 type(json_file),
intent(inout) :: params
598 end subroutine fluid_scheme_solver_factory
601 subroutine fluid_scheme_precon_factory(this, pc, ksp, coef, bclst, &
603 class(fluid_scheme_incompressible_t),
intent(inout) :: this
604 class(
pc_t),
allocatable,
target,
intent(inout) :: pc
605 class(
ksp_t),
target,
intent(inout) :: ksp
606 type(
coef_t),
target,
intent(in) :: coef
607 type(
bc_list_t),
target,
intent(inout) :: bclst
608 character(len=*) :: pctype
609 type(json_file),
intent(inout) :: json
611 call precon_factory(pc, pctype, coef, bclst, json)
615 end subroutine fluid_scheme_precon_factory
618 function fluid_compute_cfl(this, dt)
result(c)
619 class(fluid_scheme_incompressible_t),
intent(in) :: this
620 real(kind=
dp),
intent(in) :: dt
623 c =
cfl(dt, this%u, this%v, this%w, &
624 this%Xh, this%c_Xh, this%msh%nelv, this%msh%gdim)
626 end function fluid_compute_cfl
633 subroutine fluid_scheme_update_material_properties(this, time)
634 class(fluid_scheme_incompressible_t),
intent(inout) :: this
638 call this%user_material_properties(this%name, this%material_properties, &
641 if (len(trim(this%nut_field_name)) > 0)
then
654 call device_memcpy(this%rho%x, this%rho%x_d, this%rho%size(), &
657 end subroutine fluid_scheme_update_material_properties
662 subroutine fluid_scheme_set_material_properties(this, params, user)
663 class(fluid_scheme_incompressible_t),
target,
intent(inout) :: this
664 type(json_file),
intent(inout) :: params
665 type(
user_t),
target,
intent(in) :: user
666 character(len=LOG_SIZE) :: log_buf
669 logical :: nondimensional
670 real(kind=
rp) :: dummy_lambda, dummy_cp
671 real(kind=
rp) :: const_mu, const_rho
678 call neko_registry%add_field(this%dm_Xh, this%name //
"_mu_tot")
679 call neko_registry%add_field(this%dm_Xh, this%name //
"_rho")
681 this%mu_tot =>
neko_registry%get_field(this%name //
"_mu_tot")
684 call this%material_properties%init(2)
685 call this%material_properties%assign(1, this%rho)
686 call this%material_properties%assign(2, this%mu)
688 if (.not.
associated(
user%material_properties, dummy_mp_ptr))
then
690 write(log_buf,
'(A)')
'Material properties must be set in the user' // &
693 this%user_material_properties =>
user%material_properties
695 call user%material_properties(this%name, this%material_properties, &
701 if (params%valid_path(
'case.fluid.Re') .and. &
702 (params%valid_path(
'case.fluid.mu') .or. &
703 params%valid_path(
'case.fluid.rho')))
then
704 call neko_error(
"To set the material properties for the fluid, " // &
705 "either provide Re OR mu and rho in the case file.")
707 else if (params%valid_path(
'case.fluid.Re'))
then
709 write(log_buf,
'(A)')
'Non-dimensional fluid material properties &
712 write(log_buf,
'(A)')
'Density will be set to 1, dynamic viscosity to&
718 write(log_buf,
'(A)')
'Read non-dimensional material properties'
720 write(log_buf,
'(A,ES13.6)')
'Re :', const_mu
726 const_mu = 1.0_rp/const_mu
736 if (
associated(
user%material_properties, dummy_mp_ptr))
then
743 write(log_buf,
'(A,ES13.6)')
'rho :', const_rho
745 write(log_buf,
'(A,ES13.6)')
'mu :', const_mu
757 call device_memcpy(this%rho%x, this%rho%x_d, this%rho%size(), &
761 call device_memcpy(this%mu_tot%x, this%mu_tot%x_d, this%mu%size(), &
764 end subroutine fluid_scheme_set_material_properties
Copy data between host and device (or device and device)
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...
Retrieves a parameter by name or throws an error.
Factory for Krylov solvers. Both creates and initializes the object, either from its parameters or fr...
Apply cyclic boundary condition to a vector field.
Abstract interface for setting material properties.
Defines a boundary condition.
integer, parameter, public bc_dirichlet
Supported boundary condition types. The values are set in order of precedence for global resolution....
Defines format-independent checkpoint registration and restart state.
Device abstraction, common interface for various accelerators.
subroutine, public device_event_sync(event)
Synchronize an event.
integer, parameter, public device_to_host
type(c_ptr), bind(C), public glb_cmd_event
Event for the global command queue.
Defines a dirichlet boundary condition.
Defines a mapping of the degrees of freedom.
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_copy(a, b, n)
Copy a vector .
subroutine fluid_scheme_set_material_properties(this, params, user)
Sets rho and mu.
subroutine fluid_scheme_update_material_properties(this, time)
Call user material properties routine and update the values of mu if necessary.
subroutine fluid_scheme_free(this)
subroutine fluid_scheme_validate(this)
Validate that all fields, solvers etc necessary for performing time-stepping are defined.
real(kind=dp) function fluid_compute_cfl(this, dt)
Compute CFL.
subroutine fluid_scheme_solver_factory(ksp, n, params)
Initialize a linear solver from its JSON solver block.
subroutine fluid_scheme_bc_apply_vel(this, time, strong)
Apply all boundary conditions defined for velocity Here we perform additional gs operations to take c...
subroutine fluid_scheme_bc_apply_prs(this, time)
Apply all boundary conditions defined for pressure.
subroutine fluid_scheme_precon_factory(this, pc, ksp, coef, bclst, pctype, json)
Initialize a Krylov preconditioner.
subroutine fluid_scheme_init_base(this, msh, lx, params, scheme, user, kspv_init)
Initialise a fluid scheme.
Implements the fluid_source_term_t type.
Computes various statistics for the fluid fields. We use the Reynolds decomposition for a field u = ...
Utilities for retrieving parameters from the case files.
Implements the base abstract type for Krylov solvers plus helper types.
integer, parameter, public neko_log_verbose
Verbose.
type(log_t), public neko_log
Global log stream.
integer, parameter, public log_size
real(kind=rp) function, public glsum(a, n)
Sum a vector of length n.
integer, parameter neko_bcknd_device
integer, parameter, public i8
integer, parameter, public dp
integer, parameter, public rp
Global precision used in computations.
Defines a registry for storing solution fields.
type(registry_t), target, public neko_registry
Global field registry.
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.
Implements the source_term_t type and a wrapper source_term_wrapper_t.
Defines a function space.
integer, parameter, public gll
Data and filter construction for spectral vanishing viscosity.
Defines a container for all statistics.
Module with things related to the simulation time.
Interfaces for user interaction with NEKO.
subroutine, public dummy_user_material_properties(scheme_name, properties, time)
Base type for a boundary condition.
A list of allocatable `bc_t`. Follows the standard interface of lists.
Collection of live simulation data registered for checkpointing.
Coefficients defined on a given (mesh, ) tuple. Arrays use indices (i,j,k,e): element e,...
Generic Dirichlet boundary condition on .
Base type of all fluid formulations.
Base type of all fluid formulations.
Wrapper contaning and executing the fluid source terms.
Base abstract type for a canonical Krylov method, solving .
Defines a canonical Krylov preconditioner.
Spectral vanishing viscosity configuration and coefficients.
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...