46 use json_module,
only : json_array
72 type :: fluid_pnpn_bc_preset_t
73 character(len=25) :: name
74 character(len=25) :: velocity
75 character(len=25) :: pressure
76 end type fluid_pnpn_bc_preset_t
82 type(fluid_pnpn_bc_preset_t),
parameter :: FLUID_PNPN_BC_PRESETS(17) = [ &
83 fluid_pnpn_bc_preset_t(
"symmetry",
"symmetry",
""), &
84 fluid_pnpn_bc_preset_t(
"velocity_value",
"dirichlet",
""), &
85 fluid_pnpn_bc_preset_t(
"expression_velocity",
"expression",
""), &
86 fluid_pnpn_bc_preset_t(
"expression_pressure",
"",
"expression"), &
87 fluid_pnpn_bc_preset_t(
"no_slip",
"no_slip",
""), &
88 fluid_pnpn_bc_preset_t(
"outflow",
"",
"zero_dirichlet"), &
89 fluid_pnpn_bc_preset_t(
"normal_outflow",
"non_normal", &
91 fluid_pnpn_bc_preset_t(
"outflow+user",
"",
"user_dirichlet"), &
92 fluid_pnpn_bc_preset_t(
"normal_outflow+user",
"non_normal", &
94 fluid_pnpn_bc_preset_t(
"outflow+dong",
"",
"dong"), &
95 fluid_pnpn_bc_preset_t(
"normal_outflow+dong",
"non_normal",
"dong"), &
96 fluid_pnpn_bc_preset_t(
"shear_stress",
"shear_stress",
""), &
97 fluid_pnpn_bc_preset_t(
"user_velocity",
"user_dirichlet",
""), &
98 fluid_pnpn_bc_preset_t(
"user_pressure",
"",
"user_dirichlet"), &
99 fluid_pnpn_bc_preset_t(
"blasius_profile",
"blasius_profile",
""), &
100 fluid_pnpn_bc_preset_t(
"wall_model",
"wall_model",
""), &
101 fluid_pnpn_bc_preset_t(
"overset_interface",
"overset_interface", &
102 "overset_interface")]
105 character(len=25),
parameter :: FLUID_PNPN_VELOCITY_BCS(11) = [ &
106 character(len=25) :: &
120 character(len=25),
parameter :: FLUID_PNPN_PRESSURE_BCS(7) = [ &
121 character(len=25) :: &
144 module subroutine fluid_pnpn_bc_split(json, velocity_json, pressure_json, &
145 has_velocity, has_pressure)
146 type(json_file),
intent(inout) :: json
147 type(json_file),
intent(inout) :: velocity_json
148 type(json_file),
intent(inout) :: pressure_json
149 logical,
intent(out) :: has_velocity
150 logical,
intent(out) :: has_pressure
151 character(len=:),
allocatable :: type
152 character(len=25) :: velocity_type, pressure_type
153 logical :: couple_pressure
158 has_velocity = json%valid_path(
"velocity")
159 has_pressure = json%valid_path(
"pressure")
161 if (json%valid_path(
"type"))
then
162 if (has_velocity .or. has_pressure)
then
163 call neko_error(
"A fluid boundary condition cannot have both a " // &
164 "'type' keyword and a 'velocity' or 'pressure' object.")
167 call json_get(json,
"type", type)
169 do i = 1,
size(fluid_pnpn_bc_presets)
170 if (trim(type) .eq. trim(fluid_pnpn_bc_presets(i)%name))
exit
173 if (i .gt.
size(fluid_pnpn_bc_presets))
then
175 FLUID_PNPN_BC_PRESETS%name)
178 velocity_type = fluid_pnpn_bc_presets(i)%velocity
179 pressure_type = fluid_pnpn_bc_presets(i)%pressure
182 if (trim(type) .eq.
"overset_interface")
then
183 call json_get_or_default(json,
"couple_pressure", couple_pressure, &
185 if (.not. couple_pressure) pressure_type =
""
188 has_velocity = len_trim(velocity_type) .gt. 0
189 has_pressure = len_trim(pressure_type) .gt. 0
190 else if (.not. (has_velocity .and. has_pressure))
then
191 call neko_error(
"A fluid boundary condition needs either a 'type' " // &
192 "keyword, or both a 'velocity' and a 'pressure' object.")
195 if (has_velocity)
then
196 call fluid_pnpn_bc_extract_part(json,
"velocity", velocity_type, &
200 if (has_pressure)
then
201 call fluid_pnpn_bc_extract_part(json,
"pressure", pressure_type, &
204 end subroutine fluid_pnpn_bc_split
216 subroutine fluid_pnpn_bc_extract_part(entry, key, preset_type, part)
217 type(json_file),
intent(inout) :: entry
218 character(len=*),
intent(in) :: key
219 character(len=*),
intent(in) :: preset_type
220 type(json_file),
intent(inout) :: part
221 type(json_core) :: core
222 type(json_value),
pointer :: root, sub, child, existing, child_clone
223 character(len=:),
allocatable :: buffer, child_name
228 call entry%print_to_string(
buffer)
230 call part%initialize(strict_type_checking = .true.)
231 call part%load_from_string(
buffer)
234 call part%remove(
"type")
235 call part%remove(
"velocity")
236 call part%remove(
"pressure")
238 if (len_trim(preset_type) .gt. 0)
then
239 call part%add(
"type", trim(preset_type))
243 call entry%get(key, sub, found)
245 call part%get_core(core)
249 call core%get_child(sub, i, child, found)
250 call core%info(child, name = child_name)
252 call core%get_child(root, child_name, existing, found)
253 if (found)
call core%remove(existing, destroy = .true.)
256 call core%clone(child, child_clone)
257 call core%add(root, child_clone)
260 end subroutine fluid_pnpn_bc_extract_part
268 module subroutine fluid_pnpn_velocity_bc_allocator(object, type_name, &
269 full_stress_formulation)
270 class(bc_t),
pointer,
intent(inout) :: object
271 character(len=*),
intent(in) :: type_name
272 logical,
intent(in) :: full_stress_formulation
275 if (
associated(object))
then
280 select case (trim(type_name))
290 if (full_stress_formulation)
then
296 if (full_stress_formulation)
then
301 case (
"shear_stress")
305 case (
"blasius_profile")
307 case (
"user_dirichlet")
309 case (
"overset_interface")
312 do i = 1, fluid_pnpn_velocity_bc_registry_size
313 if (trim(type_name) .eq. &
314 trim(fluid_pnpn_velocity_bc_registry(i)%type_name))
then
315 call fluid_pnpn_velocity_bc_registry(i)%allocator(object)
321 type_name, fluid_pnpn_velocity_bcs)
323 end subroutine fluid_pnpn_velocity_bc_allocator
328 module subroutine fluid_pnpn_pressure_bc_allocator(object, type_name)
329 class(bc_t),
pointer,
intent(inout) :: object
330 character(len=*),
intent(in) :: type_name
333 if (
associated(object))
then
338 select case (trim(type_name))
341 case (
"zero_dirichlet")
347 case (
"user_dirichlet")
349 case (
"overset_interface")
352 do i = 1, fluid_pnpn_pressure_bc_registry_size
353 if (trim(type_name) .eq. &
354 trim(fluid_pnpn_pressure_bc_registry(i)%type_name))
then
355 call fluid_pnpn_pressure_bc_registry(i)%allocator(object)
361 type_name, fluid_pnpn_pressure_bcs)
363 end subroutine fluid_pnpn_pressure_bc_allocator
370 module subroutine register_fluid_pnpn_velocity_bc(type_name, allocator)
371 character(len=*),
intent(in) :: type_name
372 procedure(fluid_pnpn_bc_allocate),
pointer,
intent(in) :: allocator
374 call fluid_pnpn_bc_register(fluid_pnpn_velocity_bc_registry, &
375 fluid_pnpn_velocity_bc_registry_size, fluid_pnpn_velocity_bcs, &
376 "fluid_pnpn velocity boundary condition", type_name, allocator)
377 end subroutine register_fluid_pnpn_velocity_bc
384 module subroutine register_fluid_pnpn_pressure_bc(type_name, allocator)
385 character(len=*),
intent(in) :: type_name
386 procedure(fluid_pnpn_bc_allocate),
pointer,
intent(in) :: allocator
388 call fluid_pnpn_bc_register(fluid_pnpn_pressure_bc_registry, &
389 fluid_pnpn_pressure_bc_registry_size, fluid_pnpn_pressure_bcs, &
390 "fluid_pnpn pressure boundary condition", type_name, allocator)
391 end subroutine register_fluid_pnpn_pressure_bc
401 subroutine fluid_pnpn_bc_register(registry, registry_size, known_bcs, &
402 base_type, type_name, allocator)
403 type(fluid_pnpn_bc_allocator_entry),
allocatable,
intent(inout) :: &
405 integer,
intent(inout) :: registry_size
406 character(len=*),
intent(in) :: known_bcs(:)
407 character(len=*),
intent(in) :: base_type
408 character(len=*),
intent(in) :: type_name
409 procedure(fluid_pnpn_bc_allocate),
pointer,
intent(in) :: allocator
410 type(fluid_pnpn_bc_allocator_entry),
allocatable :: temp(:)
413 do i = 1,
size(known_bcs)
414 if (trim(type_name) .eq. trim(known_bcs(i)))
then
419 do i = 1, registry_size
420 if (trim(type_name) .eq. trim(
registry(i)%type_name))
then
425 if (registry_size .eq. 0)
then
428 allocate(temp(registry_size + 1))
433 registry_size = registry_size + 1
434 registry(registry_size)%type_name = type_name
435 registry(registry_size)%allocator => allocator
436 end subroutine fluid_pnpn_bc_register
450 module subroutine pressure_bc_factory(object, scheme, json, coef,
user)
451 class(bc_t),
pointer,
intent(inout) :: object
452 type(fluid_pnpn_t),
intent(in) :: scheme
453 type(json_file),
intent(inout) :: json
454 type(coef_t),
target,
intent(in) :: coef
455 type(user_t),
target,
intent(in) :: user
456 character(len=:),
allocatable :: type
458 integer,
allocatable :: zone_indices(:)
459 character(len=:),
allocatable :: default_name
460 character(len=64) :: buf
462 call json_get(json,
"type", type)
464 if (trim(type) .eq.
"neumann")
then
466 if (json%valid_path(
"flux"))
then
467 call neko_error(
"The 'neumann' pressure boundary condition " // &
468 "does not accept a 'flux' keyword, the flux is set by the " // &
472 if (
associated(object))
then
479 call fluid_pnpn_pressure_bc_allocator(object, type)
481 select case (trim(type))
482 case (
"user_dirichlet")
483 select type (obj => object)
485 obj%update =>
user%dirichlet_conditions
486 call json%add(
"field_name", scheme%p%name)
488 case (
"overset_interface")
489 select type (obj => object)
491 call json%add(
"field_name", scheme%p%name)
492 obj%morph_interface =>
user%morph_interface
496 call json_get_or_lookup(json,
"zone_indices", zone_indices)
497 call object%init(coef, json)
499 do i = 1,
size(zone_indices)
500 call object%mark_labeled_zone(zone_indices(i))
503 write(buf,
'("pressure_bc_", I0)') zone_indices(1)
504 default_name = trim(buf)
505 call json_get_or_default(json,
"name", object%name, default_name)
506 object%zone_indices = zone_indices
507 call object%finalize()
510 deallocate(zone_indices)
511 deallocate(default_name)
512 end subroutine pressure_bc_factory
527 module subroutine velocity_bc_factory(object, scheme, json, coef,
user)
528 class(bc_t),
pointer,
intent(inout) :: object
529 type(fluid_pnpn_t),
intent(in) :: scheme
530 type(json_file),
intent(inout) :: json
531 type(coef_t),
target,
intent(in) :: coef
532 type(user_t),
target,
intent(in) :: user
533 character(len=:),
allocatable :: type
535 integer,
allocatable :: zone_indices(:)
536 character(len=:),
allocatable :: default_name
537 character(len=:),
allocatable :: bc_name
538 character(len=64) :: buf
539 integer :: var_type, n_children
541 call json_get(json,
"type", type)
543 if (trim(type) .eq.
"neumann")
then
544 if (.not. json%valid_path(
"flux"))
then
545 if (
associated(object))
then
554 call json%info(
"flux", var_type = var_type, n_children = n_children)
555 if (var_type .ne. json_array .or. n_children .ne. 3)
then
556 call neko_error(
"The 'flux' of the 'neumann' velocity boundary " // &
557 "condition must be an array of 3 reals.")
561 call fluid_pnpn_velocity_bc_allocator(object,
type, &
562 scheme%full_stress_formulation)
564 select case (trim(type))
567 call json%add(
"scheme_name", scheme%name)
569 select type (wall_bc => object)
573 case (
"user_dirichlet")
574 select type (obj => object)
576 obj%update =>
user%dirichlet_conditions
578 case (
"overset_interface")
579 select type (obj => object)
581 obj%morph_interface =>
user%morph_interface
585 call json_get_or_lookup(json,
"zone_indices", zone_indices)
586 write(buf,
'("velocity_bc_",I0)') zone_indices(1)
587 default_name = trim(buf)
588 call json_get_or_default(json,
"name", bc_name, default_name)
590 call object%init(coef, json)
591 do i = 1,
size(zone_indices)
592 call object%mark_labeled_zone(zone_indices(i))
595 object%name = bc_name
596 object%zone_indices = zone_indices
598 call object%finalize()
601 deallocate(zone_indices)
602 deallocate(default_name)
604 end subroutine velocity_bc_factory
606end submodule fluid_pnpn_bc_fctry
Defines a Blasius profile dirichlet condition.
Generic buffer that is extended with buffers of varying rank.
Defines a dirichlet boundary condition.
Defines a dong outflow condition.
Defines a vector valued Dirichlet condition prescribed by mathematical expressions.
Defines a Dirichlet condition prescribed by a mathematical expression.
Defines inflow dirichlet conditions.
Defines user dirichlet condition for a scalar field.
Modular version of the Classic Nek5000 Pn/Pn formulation for fluids.
Defines inflow dirichlet conditions.
Defines a Neumann boundary condition.
Defines no-slip boundary condition (extends zero_dirichlet)
Implements non_normal_aligned_t.
Defines overset interface vector boundary conditions.
Defines overset interface scalar boundary conditions.
Defines a registry for storing solution fields.
Defines a shear stress boundary condition for a vector field. Maintainer: Timofey Mukha.
Implements symmetry_aligned_t.
Interfaces for user interaction with NEKO.
subroutine, public neko_type_registration_error(base_type, wrong_type, known)
subroutine, public neko_type_error(base_type, wrong_type, known_types)
Reports an error allocating a type for a particular base pointer class.
Implements boundary condition projectors for vector fields. Two types concrete types are provided: se...
Defines the wall_model_bc_t type. Maintainer: Timofey Mukha.
Defines a zero-valued Dirichlet boundary condition.
Blasius profile for inlet (vector valued).
Generic Dirichlet boundary condition on .
Dong outflow condition Follows "A Convective-like Energy-Stable Open Boundary Condition for Simulati...
Dirichlet condition on , where is a mathematical expression given in the case file.
Vector valued Dirichlet condition, with one mathematical expression per component,...
User defined dirichlet condition, for which the user can work with an entire field....
Extension of the user defined dirichlet condition field_dirichlet
Dirichlet condition for inlet (vector valued)
A Neumann boundary condition. Sets the flux of the field to the chosen values.
Mixed Dirichlet condition constraining the tangential vector components.
Axis-aligned mixed Dirichlet condition in the non-normal direction.
Overset interface BC for a scalar field.
Extension of the user defined dirichlet condition overset_interface
A shear stress boundary condition.
Symmetry boundary condition constraining the normal vector component.
Axis-aligned symmetry boundary condition.
A type collecting all the overridable user routines and flag to suppress type injection from custom m...
A coupled projector for vector fields, suitable for mixed boundary conditions.
A projector for vector fields that acts component-wise.
A shear stress boundary condition, computing the stress values using a wall model.
Zero-valued Dirichlet boundary condition. Used for no-slip walls, but also for various auxillary cond...