Neko 1.99.9
A portable framework for high-order spectral element flow simulations
Loading...
Searching...
No Matches
fluid_scheme_incompressible.f90
Go to the documentation of this file.
1! Copyright (c) 2020-2026, 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!
36 use gather_scatter, only : gs_t, gs_op_min, gs_op_max
38 use checkpoint, only : chkp_t
39 use num_types, only : rp, i8, dp
41 use field, only : field_t
42 use space, only : gll
43 use dofmap, only : dofmap_t
44 use krylov, only : ksp_t, krylov_solver_factory, ksp_max_iter
45 use coefs, only : coef_t
46 use dirichlet, only : dirichlet_t
47 use jacobi, only : jacobi_t
48 use sx_jacobi, only : sx_jacobi_t
50 use hsmg, only : hsmg_t
51 use phmg, only : phmg_t
52 use precon, only : pc_t, precon_allocator, precon_destroy
53 use fluid_stats, only : fluid_stats_t
54 use bc, only : bc_t, bc_dirichlet
55 use bc_list, only : bc_list_t
56 use mesh, only : mesh_t
57 use math, only : glsum
58 use operators, only : cfl, rotate_cyc
60 use registry, only : neko_registry
63 use json_module, only : json_file
67 use utils, only : neko_error
71 use time_state, only : time_state_t
73 implicit none
74 private
75
80 class(ksp_t), allocatable :: ksp_vel
81 class(ksp_t), allocatable :: ksp_prs
82 class(pc_t), allocatable :: pc_vel
83 class(pc_t), allocatable :: pc_prs
84 integer :: vel_projection_dim
85 integer :: pr_projection_dim
86 integer :: vel_projection_activ_step
87 integer :: pr_projection_activ_step
88 logical :: pr_projection_reorthogonalize_basis
89 logical :: strict_convergence
90 logical :: allow_stabilization
92 logical :: svv_enabled = .false.
94 type(svv_t), allocatable :: svv
96 type(field_t), pointer :: u_e => null()
97 type(field_t), pointer :: v_e => null()
98 type(field_t), pointer :: w_e => null()
99
101 logical :: forced_flow_rate = .false.
102
104 character(len=:), allocatable :: nut_field_name
105
106 ! The total viscosity field
107 type(field_t), pointer :: mu_tot => null()
108
110 integer(kind=i8) :: glb_n_points
112 integer(kind=i8) :: glb_unique_points
113 contains
115 procedure, pass(this) :: init_base => fluid_scheme_init_base
116 procedure, pass(this) :: scheme_free => fluid_scheme_free
118 procedure, pass(this) :: validate => fluid_scheme_validate
120 procedure, pass(this) :: bc_apply_vel => fluid_scheme_bc_apply_vel
122 procedure, pass(this) :: bc_apply_prs => fluid_scheme_bc_apply_prs
124 procedure, pass(this) :: compute_cfl => fluid_compute_cfl
126 procedure, pass(this) :: set_material_properties => &
128
130 procedure, pass(this) :: update_material_properties => &
133 procedure, nopass :: solver_factory => fluid_scheme_solver_factory
135 procedure, pass(this) :: precon_factory_ => fluid_scheme_precon_factory
137
138 interface
139
140 module subroutine fluid_scheme_factory(object, type_name)
141 class(fluid_scheme_base_t), intent(inout), allocatable :: object
142 character(len=*) :: type_name
143 end subroutine fluid_scheme_factory
144 end interface
145
146 public :: fluid_scheme_incompressible_t, fluid_scheme_factory
147
148contains
149
151 subroutine fluid_scheme_init_base(this, msh, lx, params, scheme, user, &
152 kspv_init)
153 implicit none
154 class(fluid_scheme_incompressible_t), target, intent(inout) :: this
155 type(mesh_t), target, intent(inout) :: msh
156 integer, intent(in) :: lx
157 character(len=*), intent(in) :: scheme
158 type(json_file), target, intent(inout) :: params
159 type(user_t), target, intent(in) :: user
160 logical, intent(in) :: kspv_init
161 type(dirichlet_t) :: bdry_mask
162 character(len=LOG_SIZE) :: log_buf
163 real(kind=rp), allocatable :: real_vec(:)
164 real(kind=rp) :: real_val, kappa, b, z0
165 logical :: logical_val, full_stress_formulation
166 integer :: integer_val, ierr
167 type(json_file) :: wm_json
168 character(len=:), allocatable :: string_val1, string_val2
169 type(json_file) :: json_subdict
170
171 !
172 ! SEM simulation fundamentals
173 !
174
175 this%msh => msh
176
177 if (msh%gdim .eq. 2) then
178 call this%Xh%init(gll, lx, lx)
179 else
180 call this%Xh%init(gll, lx, lx, lx)
181 end if
182
183 call this%dm_Xh%init(msh, this%Xh)
184
185 call this%gs_Xh%init(this%dm_Xh)
186
187 call this%c_Xh%init(this%gs_Xh)
188
189 ! Assign Dofmap to scratch registry
190 call neko_scratch_registry%set_dofmap(this%dm_Xh)
191
192 ! Assign a name
193 call json_get_or_default(params, 'case.fluid.name', this%name, "fluid")
194
195 !
196 ! First section of fluid log
197 !
198
199 call neko_log%section('Fluid')
200 write(log_buf, '(A, A)') 'Type : ', trim(scheme)
201 call neko_log%message(log_buf)
202 write(log_buf, '(A, A)') 'Name : ', trim(this%name)
203 call neko_log%message(log_buf)
204
205 ! Assign velocity fields
206 call neko_registry%add_field(this%dm_Xh, 'u')
207 call neko_registry%add_field(this%dm_Xh, 'v')
208 call neko_registry%add_field(this%dm_Xh, 'w')
209 this%u => neko_registry%get_field('u')
210 this%v => neko_registry%get_field('v')
211 this%w => neko_registry%get_field('w')
212
213 !
214 ! Material properties
215 !
216 call this%set_material_properties(params, user)
217
218 ! Projection spaces
219 call json_get_or_lookup_or_default(params, &
220 'case.fluid.velocity_solver.projection_space_size', &
221 this%vel_projection_dim, 0)
222 call json_get_or_lookup_or_default(params, &
223 'case.fluid.pressure_solver.projection_space_size', &
224 this%pr_projection_dim, 0)
225 call json_get_or_lookup_or_default(params, &
226 'case.fluid.velocity_solver.projection_hold_steps', &
227 this%vel_projection_activ_step, 5)
228 call json_get_or_lookup_or_default(params, &
229 'case.fluid.pressure_solver.projection_hold_steps', &
230 this%pr_projection_activ_step, 5)
231 call json_get_or_default(params, &
232 'case.fluid.pressure_solver.projection_reorthogonalize_basis', &
233 this%pr_projection_reorthogonalize_basis, .false.)
234
235 call json_get_or_default(params, 'case.fluid.freeze', this%freeze, .false.)
236
237 if (params%valid_path("case.fluid.flow_rate_force")) then
238 this%forced_flow_rate = .true.
239 end if
240
241
242 if (lx .lt. 10) then
243 write(log_buf, '(A, I1)') 'Poly order : ', lx-1
244 else if (lx .ge. 10) then
245 write(log_buf, '(A, I2)') 'Poly order : ', lx-1
246 else
247 write(log_buf, '(A, I3)') 'Poly order : ', lx-1
248 end if
249 call neko_log%message(log_buf)
250 this%glb_n_points = int(this%msh%glb_nelv, i8)*int(this%Xh%lxyz, i8)
251 this%glb_unique_points = int(glsum(this%c_Xh%mult, this%dm_Xh%size()), i8)
252
253 write(log_buf, '(A, I0)') 'GLL points : ', this%glb_n_points
254 call neko_log%message(log_buf)
255 write(log_buf, '(A, I0)') 'Unique pts.: ', this%glb_unique_points
256 call neko_log%message(log_buf)
257
258
259 call json_get(params, 'case.numerics.dealias', logical_val)
260 write(log_buf, '(A, L1)') 'Dealias : ', logical_val
261 call neko_log%message(log_buf)
262
263
264 call json_get_or_default(params, 'case.output_boundary', logical_val, &
265 .false.)
266 write(log_buf, '(A, L1)') 'Save bdry : ', logical_val
267 call neko_log%message(log_buf)
268
269 call json_get_or_default(params, "case.fluid.full_stress_formulation", &
270 full_stress_formulation, .false.)
271 write(log_buf, '(A, L1)') 'Full stress: ', full_stress_formulation
272 call neko_log%message(log_buf)
273
274
275 !
276 ! Setup right-hand side fields.
277 !
278 allocate(this%f_x)
279 allocate(this%f_y)
280 allocate(this%f_z)
281 call this%f_x%init(this%dm_Xh, fld_name = "fluid_rhs_x")
282 call this%f_y%init(this%dm_Xh, fld_name = "fluid_rhs_y")
283 call this%f_z%init(this%dm_Xh, fld_name = "fluid_rhs_z")
284
285 ! Initialize velocity solver
286 if (kspv_init) then
287 call neko_log%section("Velocity solver")
288 call json_get_or_lookup_or_default(params, &
289 'case.fluid.velocity_solver.max_iterations', &
290 integer_val, ksp_max_iter)
291 call json_get(params, 'case.fluid.velocity_solver.type', string_val1)
292 call json_get(params, 'case.fluid.velocity_solver.preconditioner.type', &
293 string_val2)
294 call json_get(params, &
295 'case.fluid.velocity_solver.preconditioner', json_subdict)
296 call json_get_or_lookup(params, &
297 'case.fluid.velocity_solver.absolute_tolerance', &
298 real_val)
299 call json_get_or_default(params, &
300 'case.fluid.velocity_solver.monitor', &
301 logical_val, .false.)
302
303 call neko_log%message('Type : ('// trim(string_val1) // &
304 ', ' // trim(string_val2) // ')')
305
306 write(log_buf, '(A,ES13.6)') 'Abs tol :', real_val
307 call neko_log%message(log_buf)
308 call this%solver_factory(this%ksp_vel, this%dm_Xh%size(), &
309 string_val1, integer_val, real_val, logical_val)
310 call this%precon_factory_(this%pc_vel, this%ksp_vel, &
311 this%c_Xh, this%dm_Xh, this%gs_Xh, this%bcs_vel, &
312 string_val2, json_subdict)
313 call neko_log%end_section()
314 end if
315
316 ! Strict convergence for the velocity solver
317 call json_get_or_default(params, 'case.fluid.strict_convergence', &
318 this%strict_convergence, .false.)
319 ! Allow stabilization period where we do not warn about non-convergence
320 call json_get_or_default(params, 'case.fluid.allow_stabilization', &
321 this%allow_stabilization, .false.)
322
323
324 !! Initialize time-lag fields
325 call this%ulag%init(this%u, 2)
326 call this%vlag%init(this%v, 2)
327 call this%wlag%init(this%w, 2)
328
329 call neko_registry%add_field(this%dm_Xh, 'u_e')
330 call neko_registry%add_field(this%dm_Xh, 'v_e')
331 call neko_registry%add_field(this%dm_Xh, 'w_e')
332 this%u_e => neko_registry%get_field('u_e')
333 this%v_e => neko_registry%get_field('v_e')
334 this%w_e => neko_registry%get_field('w_e')
335
336 ! Initialize the source term
337 call neko_log%section('Fluid Source term')
338 call this%source_term%init(this%f_x, this%f_y, this%f_z, this%c_Xh, user, &
339 this%name)
340 call this%source_term%add(params, 'case.fluid.source_terms')
341 call neko_log%end_section()
342
343 if (params%valid_path('case.fluid.svv')) then
344 call json_get(params, 'case.fluid', json_subdict)
345 call json_get_or_default(json_subdict, 'svv.enabled', &
346 this%svv_enabled, .false.)
347 if (this%svv_enabled) then
348 if (.not. kspv_init) then
349 call neko_error("SVV is only supported by fluid " // &
350 "schemes with an implicit velocity solve")
351 end if
352 if (full_stress_formulation) then
353 if (trim(string_val1) .ne. 'coupled_cg' .and. &
354 trim(string_val1) .ne. 'fused_coupled_cg') then
355 call neko_error("Full-stress SVV requires a " // &
356 "coupled velocity solver (`coupled_cg` or " // &
357 "`fused_coupled_cg`)")
358 end if
359 end if
360 allocate(this%svv)
361 call this%svv%init(json_subdict, this%c_Xh, this%rho)
362 end if
363 end if
364
365 end subroutine fluid_scheme_init_base
366
367 subroutine fluid_scheme_free(this)
368 class(fluid_scheme_incompressible_t), intent(inout) :: this
369 class(bc_t), pointer :: bc
370 integer :: i
371
372
373 if (allocated(this%svv)) then
374 call this%svv%free()
375 deallocate(this%svv)
376 end if
377 this%svv_enabled = .false.
378
379 call this%Xh%free()
380
381 if (allocated(this%ksp_vel)) then
382 call this%ksp_vel%free()
383 deallocate(this%ksp_vel)
384 end if
385
386 if (allocated(this%ksp_prs)) then
387 call this%ksp_prs%free()
388 deallocate(this%ksp_prs)
389 end if
390
391 if (allocated(this%pc_vel)) then
392 call precon_destroy(this%pc_vel)
393 deallocate(this%pc_vel)
394 end if
395
396 if (allocated(this%pc_prs)) then
397 call precon_destroy(this%pc_prs)
398 deallocate(this%pc_prs)
399 end if
400
401 do i = 1, this%bcs_vel%size()
402 bc => this%bcs_vel%get(i)
403 if (associated(bc)) then
404 call bc%free()
405 deallocate(bc)
406 end if
407 end do
408 call this%bcs_vel%free()
409
410 do i = 1, this%bcs_prs%size()
411 bc => this%bcs_prs%get(i)
412 if (associated(bc)) then
413 call bc%free()
414 deallocate(bc)
415 end if
416 end do
417 call this%bcs_prs%free()
418
419 call this%source_term%free()
420
421 call this%gs_Xh%free()
422
423 call this%c_Xh%free()
424
425 nullify(this%u)
426 nullify(this%v)
427 nullify(this%w)
428 nullify(this%p)
429
430 nullify(this%u_e)
431 nullify(this%v_e)
432 nullify(this%w_e)
433
434 call this%ulag%free()
435 call this%vlag%free()
436 call this%wlag%free()
437
438
439 if (associated(this%f_x)) then
440 call this%f_x%free()
441 deallocate(this%f_x)
442 end if
443
444 if (associated(this%f_y)) then
445 call this%f_y%free()
446 deallocate(this%f_y)
447 end if
448
449 if (associated(this%f_z)) then
450 call this%f_z%free()
451 deallocate(this%f_z)
452 end if
453
454 nullify(this%f_x)
455 nullify(this%f_y)
456 nullify(this%f_z)
457 nullify(this%rho)
458 nullify(this%mu)
459 nullify(this%mu_tot)
460
461 call this%dm_Xh%free()
462 call this%Xh%free()
463 nullify(this%msh)
464
465 end subroutine fluid_scheme_free
466
469 subroutine fluid_scheme_validate(this)
470 class(fluid_scheme_incompressible_t), target, intent(inout) :: this
471 ! Variables for retrieving json parameters
472 logical :: logical_val
473
474 if ( (.not. associated(this%u)) .or. &
475 (.not. associated(this%v)) .or. &
476 (.not. associated(this%w)) .or. &
477 (.not. associated(this%p))) then
478 call neko_error('Fields are not registered')
479 end if
480
481 if ( (.not. allocated(this%u%x)) .or. &
482 (.not. allocated(this%v%x)) .or. &
483 (.not. allocated(this%w%x)) .or. &
484 (.not. allocated(this%p%x))) then
485 call neko_error('Fields are not allocated')
486 end if
487
488 if (.not. allocated(this%ksp_vel)) then
489 call neko_error('No Krylov solver for velocity defined')
490 end if
491
492 if (.not. allocated(this%ksp_prs)) then
493 call neko_error('No Krylov solver for pressure defined')
494 end if
495
496 end subroutine fluid_scheme_validate
497
502 subroutine fluid_scheme_bc_apply_vel(this, time, strong)
503 class(fluid_scheme_incompressible_t), intent(inout) :: this
504 type(time_state_t), intent(in) :: time
505 logical, intent(in) :: strong
506 integer :: i
507 class(bc_t), pointer :: b
508
509 call this%bcs_vel%apply_vector(&
510 this%u%x, this%v%x, this%w%x, this%dm_Xh%size(), time, strong)
511
512 call rotate_cyc(this%u, this%v, this%w, 1, this%c_Xh)
513 call this%gs_Xh%op(this%u, gs_op_min, glb_cmd_event)
515 call this%gs_Xh%op(this%v, gs_op_min, glb_cmd_event)
517 call this%gs_Xh%op(this%w, gs_op_min, glb_cmd_event)
519 call rotate_cyc(this%u, this%v, this%w, 0, this%c_Xh)
520
521 ! Double pass for Dirichlet bcs only.
522 b => null()
523 do i = 1, this%bcs_vel%size()
524 b => this%bcs_vel%get(i)
525 if (b%bc_type .eq. bc_dirichlet) then
526 call b%apply_vector_generic(this%u, this%v, this%w,time, strong)
527 end if
528 end do
529
530 call rotate_cyc(this%u, this%v, this%w, 1, this%c_Xh)
531 call this%gs_Xh%op(this%u, gs_op_max, glb_cmd_event)
533 call this%gs_Xh%op(this%v, gs_op_max, glb_cmd_event)
535 call this%gs_Xh%op(this%w, gs_op_max, glb_cmd_event)
537 call rotate_cyc(this%u, this%v, this%w, 0, this%c_Xh)
538
539 do i = 1, this%bcs_vel%size()
540 b => this%bcs_vel%get(i)
541 b%updated = .false.
542 end do
543 nullify(b)
544
545 end subroutine fluid_scheme_bc_apply_vel
546
549 subroutine fluid_scheme_bc_apply_prs(this, time)
550 class(fluid_scheme_incompressible_t), intent(inout) :: this
551 type(time_state_t), intent(in) :: time
552
553 integer :: i
554 class(bc_t), pointer :: b
555 b => null()
556
557 call this%bcs_prs%apply(this%p, time)
558 call this%gs_Xh%op(this%p, gs_op_min, glb_cmd_event)
560
561 call this%bcs_prs%apply(this%p, time)
562 call this%gs_Xh%op(this%p, gs_op_max, glb_cmd_event)
564
565 do i = 1, this%bcs_prs%size()
566 b => this%bcs_prs%get(i)
567 b%updated = .false.
568 end do
569 nullify(b)
570
571 end subroutine fluid_scheme_bc_apply_prs
572
575 subroutine fluid_scheme_solver_factory(ksp, n, solver, &
576 max_iter, abstol, monitor)
577 class(ksp_t), allocatable, target, intent(inout) :: ksp
578 integer, intent(in), value :: n
579 character(len=*), intent(in) :: solver
580 integer, intent(in) :: max_iter
581 real(kind=rp), intent(in) :: abstol
582 logical, intent(in) :: monitor
583
584 call krylov_solver_factory(ksp, n, solver, max_iter, abstol, &
585 monitor = monitor)
586
587 end subroutine fluid_scheme_solver_factory
588
590 subroutine fluid_scheme_precon_factory(this, pc, ksp, coef, dof, gs, bclst, &
591 pctype, pcparams)
592 class(fluid_scheme_incompressible_t), intent(inout) :: this
593 class(pc_t), allocatable, target, intent(inout) :: pc
594 class(ksp_t), target, intent(inout) :: ksp
595 type(coef_t), target, intent(in) :: coef
596 type(dofmap_t), target, intent(in) :: dof
597 type(gs_t), target, intent(inout) :: gs
598 type(bc_list_t), target, intent(inout) :: bclst
599 character(len=*) :: pctype
600 type(json_file), intent(inout) :: pcparams
601
602 call precon_allocator(pc, pctype)
603
604 select type (pcp => pc)
605 type is (jacobi_t)
606 call pcp%init(coef, dof, gs)
607 type is (sx_jacobi_t)
608 call pcp%init(coef, dof, gs)
609 type is (device_jacobi_t)
610 call pcp%init(coef, dof, gs)
611 type is (hsmg_t)
612 call pcp%init(coef, bclst, pcparams)
613 type is (phmg_t)
614 call pcp%init(coef, bclst, pcparams)
615 end select
616
617 call ksp%set_pc(pc)
618
619 end subroutine fluid_scheme_precon_factory
620
622 function fluid_compute_cfl(this, dt) result(c)
623 class(fluid_scheme_incompressible_t), intent(in) :: this
624 real(kind=dp), intent(in) :: dt
625 real(kind=dp) :: c
626
627 c = cfl(dt, this%u, this%v, this%w, &
628 this%Xh, this%c_Xh, this%msh%nelv, this%msh%gdim)
629
630 end function fluid_compute_cfl
631
632
637 subroutine fluid_scheme_update_material_properties(this, time)
638 class(fluid_scheme_incompressible_t), intent(inout) :: this
639 type(time_state_t), intent(in) :: time
640 type(field_t), pointer :: nut
641
642 call this%user_material_properties(this%name, this%material_properties, &
643 time)
644
645 if (len(trim(this%nut_field_name)) > 0) then
646 nut => neko_registry%get_field(this%nut_field_name)
647 ! Copy material property
648 call field_copy(this%mu_tot, this%mu)
649 ! Add turbulent contribution
650 call field_addcol3(this%mu_tot, nut, this%rho)
651 end if
652
653 ! Since mu, rho is a field_t, and we use the %x(1,1,1,1)
654 ! host array data to pass constant density and viscosity
655 ! to some routines, we need to make sure that the host
656 ! values are also filled
657 if (neko_bcknd_device .eq. 1) then
658 call device_memcpy(this%rho%x, this%rho%x_d, this%rho%size(), &
659 device_to_host, sync = .false.)
660 end if
661 end subroutine fluid_scheme_update_material_properties
662
666 subroutine fluid_scheme_set_material_properties(this, params, user)
667 class(fluid_scheme_incompressible_t), target, intent(inout) :: this
668 type(json_file), intent(inout) :: params
669 type(user_t), target, intent(in) :: user
670 character(len=LOG_SIZE) :: log_buf
671 ! A local pointer that is needed to make Intel happy
672 procedure(user_material_properties_intf), pointer :: dummy_mp_ptr
673 logical :: nondimensional
674 real(kind=rp) :: dummy_lambda, dummy_cp
675 real(kind=rp) :: const_mu, const_rho
676 type(time_state_t) :: dummy_time_state
677
678
679 dummy_mp_ptr => dummy_user_material_properties
680
681 call neko_registry%add_field(this%dm_Xh, this%name // "_mu")
682 call neko_registry%add_field(this%dm_Xh, this%name // "_mu_tot")
683 call neko_registry%add_field(this%dm_Xh, this%name // "_rho")
684 this%mu => neko_registry%get_field(this%name // "_mu")
685 this%mu_tot => neko_registry%get_field(this%name // "_mu_tot")
686 this%rho => neko_registry%get_field(this%name // "_rho")
687
688 call this%material_properties%init(2)
689 call this%material_properties%assign(1, this%rho)
690 call this%material_properties%assign(2, this%mu)
691
692 if (.not. associated(user%material_properties, dummy_mp_ptr)) then
693
694 write(log_buf, '(A)') 'Material properties must be set in the user' // &
695 ' file!'
696 call neko_log%message(log_buf)
697 this%user_material_properties => user%material_properties
698
699 call user%material_properties(this%name, this%material_properties, &
700 dummy_time_state)
701
702 else
703 this%user_material_properties => dummy_user_material_properties
704 ! Incorrect user input
705 if (params%valid_path('case.fluid.Re') .and. &
706 (params%valid_path('case.fluid.mu') .or. &
707 params%valid_path('case.fluid.rho'))) then
708 call neko_error("To set the material properties for the fluid, " // &
709 "either provide Re OR mu and rho in the case file.")
710
711 else if (params%valid_path('case.fluid.Re')) then
712 ! Non-dimensional case
713 write(log_buf, '(A)') 'Non-dimensional fluid material properties &
714 & input.'
715 call neko_log%message(log_buf, lvl = neko_log_verbose)
716 write(log_buf, '(A)') 'Density will be set to 1, dynamic viscosity to&
717 & 1/Re.'
718 call neko_log%message(log_buf, lvl = neko_log_verbose)
719
720 ! Read Re into mu for further manipulation.
721 call json_get_or_lookup(params, 'case.fluid.Re', const_mu)
722 write(log_buf, '(A)') 'Read non-dimensional material properties'
723 call neko_log%message(log_buf)
724 write(log_buf, '(A,ES13.6)') 'Re :', const_mu
725 call neko_log%message(log_buf)
726
727 ! Set rho to 1 since the setup is non-dimensional.
728 const_rho = 1.0_rp
729 ! Invert the Re to get viscosity.
730 const_mu = 1.0_rp/const_mu
731 else
732 ! Dimensional case
733 call json_get_or_lookup(params, 'case.fluid.mu', const_mu)
734 call json_get_or_lookup(params, 'case.fluid.rho', const_rho)
735 end if
736 end if
737
738 ! We need to fill the fields based on the parsed const values
739 ! if the user routine is not used.
740 if (associated(user%material_properties, dummy_mp_ptr)) then
741 ! Fill mu and rho field with the physical value
742 call field_cfill(this%mu, const_mu)
743 call field_cfill(this%mu_tot, const_mu)
744 call field_cfill(this%rho, const_rho)
745
746
747 write(log_buf, '(A,ES13.6)') 'rho :', const_rho
748 call neko_log%message(log_buf)
749 write(log_buf, '(A,ES13.6)') 'mu :', const_mu
750 call neko_log%message(log_buf)
751 end if
752
753 ! Copy over material property to the total one
754 call field_copy(this%mu_tot, this%mu)
755
756 ! Since mu, rho is a field_t, and we use the %x(1,1,1,1)
757 ! host array data to pass constant density and viscosity
758 ! to some routines, we need to make sure that the host
759 ! values are also filled
760 if (neko_bcknd_device .eq. 1) then
761 call device_memcpy(this%rho%x, this%rho%x_d, this%rho%size(), &
762 device_to_host, sync = .false.)
763 call device_memcpy(this%mu%x, this%mu%x_d, this%mu%size(), &
764 device_to_host, sync = .false.)
765 call device_memcpy(this%mu_tot%x, this%mu_tot%x_d, this%mu%size(), &
766 device_to_host, sync = .false.)
767 end if
768 end subroutine fluid_scheme_set_material_properties
769
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...
Retrieves a parameter by name or throws an error.
Compute CFL condition.
Definition operators.f90:98
Apply cyclic boundary condition to a vector field.
Abstract interface for setting material properties.
Defines a list of bc_t.
Definition bc_list.f90:34
Defines a boundary condition.
Definition bc.f90:34
integer, parameter, public bc_dirichlet
Supported boundary condition types. The values are set in order of precedence for global resolution....
Definition bc.f90:66
Defines a checkpoint.
Coefficients.
Definition coef.f90:34
Jacobi preconditioner accelerator backend.
Device abstraction, common interface for various accelerators.
Definition device.F90:34
subroutine, public device_event_sync(event)
Synchronize an event.
Definition device.F90:1667
integer, parameter, public device_to_host
Definition device.F90:48
type(c_ptr), bind(C), public glb_cmd_event
Event for the global command queue.
Definition device.F90:63
Defines a dirichlet boundary condition.
Definition dirichlet.f90:34
Defines a mapping of the degrees of freedom.
Definition dofmap.f90:35
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 .
Defines a field.
Definition field.f90:34
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_precon_factory(this, pc, ksp, coef, dof, gs, bclst, pctype, pcparams)
Initialize a Krylov preconditioner.
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_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_solver_factory(ksp, n, solver, max_iter, abstol, monitor)
Initialize a linear solver.
subroutine fluid_scheme_bc_apply_prs(this, time)
Apply all boundary conditions defined for pressure.
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 = ...
Gather-scatter.
Krylov preconditioner.
Definition pc_hsmg.f90:61
Jacobi preconditioner.
Definition pc_jacobi.f90:34
Utilities for retrieving parameters from the case files.
Implements the base abstract type for Krylov solvers plus helper types.
Definition krylov.f90:34
integer, parameter, public ksp_max_iter
Maximum number of iters.
Definition krylov.f90:52
Logging routines.
Definition log.f90:34
integer, parameter, public neko_log_verbose
Verbose.
Definition log.f90:54
type(log_t), public neko_log
Global log stream.
Definition log.f90:91
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:632
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 dp
Definition num_types.f90:10
integer, parameter, public rp
Global precision used in computations.
Definition num_types.f90:14
Operators.
Definition operators.f90:34
Hybrid ph-multigrid preconditioner.
Definition phmg.f90:34
Krylov preconditioner.
Definition precon.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.
Implements the source_term_t type and a wrapper source_term_wrapper_t.
Defines a function space.
Definition space.f90:34
integer, parameter, public gll
Definition space.f90:50
Data and filter construction for spectral vanishing viscosity.
Defines a container for all statistics.
Jacobi preconditioner SX-Aurora backend.
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)
Utilities.
Definition utils.f90:35
Base type for a boundary condition.
Definition bc.f90:72
A list of allocatable `bc_t`. Follows the standard interface of lists.
Definition bc_list.f90:49
Coefficients defined on a given (mesh, ) tuple. Arrays use indices (i,j,k,e): element e,...
Definition coef.f90:93
Defines a jacobi preconditioner.
Generic Dirichlet boundary condition on .
Definition dirichlet.f90:49
Base type of all fluid formulations.
Wrapper contaning and executing the fluid source terms.
Gather-scatter kernel.
Defines a jacobi preconditioner.
Definition pc_jacobi.f90:45
Base abstract type for a canonical Krylov method, solving .
Definition krylov.f90:74
Defines a canonical Krylov preconditioner.
Definition precon.f90:40
Spectral vanishing viscosity configuration and coefficients.
Defines a jacobi preconditioner for SX-Aurora.
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...