Neko 1.99.5
A portable framework for high-order spectral element flow simulations
Loading...
Searching...
No Matches
fluid_pnpn.f90
Go to the documentation of this file.
1! Copyright (c) 2022-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!
35 use, intrinsic :: iso_fortran_env, only : error_unit
36 use coefs, only : coef_t
37 use symmetry, only : symmetry_t
38 use registry, only : neko_registry
39 use logger, only : neko_log, log_size
40 use num_types, only : rp
41 use krylov, only : ksp_monitor_t
43 pnpn_prs_res_factory, pnpn_vel_res_factory, &
44 pnpn_prs_res_stress_factory, pnpn_vel_res_stress_factory
46 rhs_maker_oifs_t, rhs_maker_sumab_fctry, rhs_maker_bdf_fctry, &
47 rhs_maker_ext_fctry, rhs_maker_oifs_fctry
52 use fluid_aux, only : fluid_step_info
53 use projection, only : projection_t
57 use advection, only : advection_t, advection_factory
59 use json_module, only : json_file, json_core, json_value
62 use ax_product, only : ax_t, ax_helm_factory
63 use field, only : field_t
64 use dirichlet, only : dirichlet_t
68 use non_normal, only : non_normal_t
69 use checkpoint, only : chkp_t
70 use mesh, only : mesh_t
71 use user_intf, only : user_t
73 use gs_ops, only : gs_op_add
75 use mathops, only : opadd2cm, opcolv
76 use bc_list, only : bc_list_t
80 use bc, only : bc_t
81 use file, only : file_t
82 use operators, only : ortho, rotate_cyc
83 use opr_device, only : device_ortho
84 use time_state, only : time_state_t
85 use comm, only : neko_comm
86 use ale_manager, only : ale_manager_t
88 use mpi_f08, only : mpi_allreduce, mpi_in_place, mpi_max, mpi_lor, &
89 mpi_integer, mpi_logical
90 implicit none
91 private
92
93
94
96
99 integer :: schwarz_iterations = 0
100
102 type(field_t) :: p_res, u_res, v_res, w_res
103
106 type(field_t) :: dp, du, dv, dw
107
109 type(ale_manager_t) :: ale
110
111 ! ! Implicit operators, i.e. the left-hand-side of the Helmholz problem.
112 !
113
114 ! Coupled Helmholz operator for velocity
115 class(ax_t), allocatable :: ax_vel
116 ! Helmholz operator for pressure
117 class(ax_t), allocatable :: ax_prs
118
119 !
120 ! Projections for solver speed-up
121 !
122
124 type(projection_t) :: proj_prs
125 type(projection_vel_t) :: proj_vel
126
127 !
128 ! Special Karniadakis scheme boundary conditions in the pressure equation
129 !
130
132 type(facet_normal_t) :: bc_prs_surface
133
135 type(facet_normal_t) :: bc_sym_surface
136
137 !
138 ! Boundary conditions and lists for residuals and solution increments
139 !
140
142 type(zero_dirichlet_t) :: bc_vel_res
144 type(zero_dirichlet_t) :: bc_du
146 type(zero_dirichlet_t) :: bc_dv
148 type(zero_dirichlet_t) :: bc_dw
150 type(zero_dirichlet_t) :: bc_dp
151
153 type(bc_list_t) :: bclst_vel_res
154 type(bc_list_t) :: bclst_du
155 type(bc_list_t) :: bclst_dv
156 type(bc_list_t) :: bclst_dw
157 type(bc_list_t) :: bclst_dp
158
159
160 ! Checker for wether we have a strong pressure bc. If not, the pressure
161 ! is demeaned at every time step.
162 logical :: prs_dirichlet = .false.
163
164
165 ! The advection operator.
166 class(advection_t), allocatable :: adv
167
168 ! Time OIFS interpolation scheme for advection.
169 logical :: oifs
170
171 ! Time variables
172 type(field_t) :: abx1, aby1, abz1
173 type(field_t) :: abx2, aby2, abz2
174
175 ! Advection terms for the oifs method
176 type(field_t) :: advx, advy, advz
177
179 class(pnpn_prs_res_t), allocatable :: prs_res
180
182 class(pnpn_vel_res_t), allocatable :: vel_res
183
185 class(rhs_maker_sumab_t), allocatable :: sumab
186
188 class(rhs_maker_ext_t), allocatable :: makeabf
189
191 class(rhs_maker_bdf_t), allocatable :: makebdf
192
194 class(rhs_maker_oifs_t), allocatable :: makeoifs
195
197 type(fluid_volflow_t) :: vol_flow
198
200 logical :: full_stress_formulation = .false.
201
202 contains
204 procedure, pass(this) :: init => fluid_pnpn_init
206 procedure, pass(this) :: free => fluid_pnpn_free
208 procedure, pass(this) :: step => fluid_pnpn_step
210 procedure, pass(this) :: restart => fluid_pnpn_restart
212 procedure, pass(this) :: setup_bcs => fluid_pnpn_setup_bcs
214 procedure, pass(this) :: write_boundary_conditions => &
216 end type fluid_pnpn_t
217
218 interface
219
226 module subroutine pressure_bc_factory(object, scheme, json, coef, user)
227 class(bc_t), pointer, intent(inout) :: object
228 type(fluid_pnpn_t), intent(in) :: scheme
229 type(json_file), intent(inout) :: json
230 type(coef_t), target, intent(in) :: coef
231 type(user_t), intent(in) :: user
232 end subroutine pressure_bc_factory
233 end interface
234
235 interface
236
243 module subroutine velocity_bc_factory(object, scheme, json, coef, user)
244 class(bc_t), pointer, intent(inout) :: object
245 type(fluid_pnpn_t), intent(inout) :: scheme
246 type(json_file), intent(inout) :: json
247 type(coef_t), target, intent(in) :: coef
248 type(user_t), intent(in) :: user
249 end subroutine velocity_bc_factory
250 end interface
251
252contains
253
254 subroutine fluid_pnpn_init(this, msh, lx, params, user, chkp)
255 class(fluid_pnpn_t), target, intent(inout) :: this
256 type(mesh_t), target, intent(inout) :: msh
257 integer, intent(in) :: lx
258 type(json_file), target, intent(inout) :: params
259 type(user_t), target, intent(in) :: user
260 type(chkp_t), target, intent(inout) :: chkp
261 character(len=15), parameter :: scheme = 'Modular (Pn/Pn)'
262 integer :: i
263 class(bc_t), pointer :: bc_i, vel_bc
264 real(kind=rp) :: abs_tol
265 character(len=LOG_SIZE) :: log_buf
266 integer :: ierr, integer_val, solver_maxiter
267 character(len=:), allocatable :: solver_type, precon_type
268 logical :: monitor, found
269 logical :: advection
270 type(json_file) :: numerics_params, precon_params
271
272 call this%free()
273
274 ! Initialize base class
275 call this%init_base(msh, lx, params, scheme, user, .true.)
276
277 ! Add pressure field to the registry. For this scheme it is in the same
278 ! Xh as the velocity
279 call neko_registry%add_field(this%dm_Xh, 'p')
280 this%p => neko_registry%get_field('p')
281
282 !
283 ! Select governing equations via associated residual and Ax types
284 !
285
286 call json_get_or_lookup(params, 'case.numerics.time_order', integer_val)
287 allocate(this%ext_bdf)
288 call this%ext_bdf%init(integer_val)
289
290 call json_get_or_default(params, "case.fluid.full_stress_formulation", &
291 this%full_stress_formulation, .false.)
292
293 call json_get_or_default(params, "case.fluid.cyclic", this%c_Xh%cyclic, &
294 .false.)
295 call this%c_Xh%generate_cyclic_bc()
296
297 if (this%full_stress_formulation) then
298 ! Setup backend dependent Ax routines
299 call ax_helm_factory(this%Ax_vel, full_formulation = .true.)
300
301 ! Setup backend dependent prs residual routines
302 call pnpn_prs_res_stress_factory(this%prs_res)
303
304 ! Setup backend dependent vel residual routines
305 call pnpn_vel_res_stress_factory(this%vel_res)
306 else
307 ! Setup backend dependent Ax routines
308 call ax_helm_factory(this%Ax_vel, full_formulation = .false.)
309
310 ! Setup backend dependent prs residual routines
311 call pnpn_prs_res_factory(this%prs_res)
312
313 ! Setup backend dependent vel residual routines
314 call pnpn_vel_res_factory(this%vel_res)
315 end if
316
317
318
319 if (params%valid_path('case.fluid.nut_field')) then
320 if (.not. this%full_stress_formulation) then
321 call neko_error("You need to set full_stress_formulation to " // &
322 "true for the fluid to have a spatially varying " // &
323 "viscocity field.")
324 end if
325 call json_get(params, 'case.fluid.nut_field', this%nut_field_name)
326 else
327 this%nut_field_name = ""
328 end if
329
330 ! Setup Ax for the pressure
331 call ax_helm_factory(this%Ax_prs, full_formulation = .false.)
332
333
334 ! Setup backend dependent summation of AB/BDF
335 call rhs_maker_sumab_fctry(this%sumab)
336
337 ! Setup backend dependent summation of extrapolation scheme
338 call rhs_maker_ext_fctry(this%makeabf)
339
340 ! Setup backend depenent contributions to F from lagged BD terms
341 call rhs_maker_bdf_fctry(this%makebdf)
342
343 ! Setup backend dependent summations of the OIFS method
344 call rhs_maker_oifs_fctry(this%makeoifs)
345
346 ! Initialize variables specific to this plan
347 associate(xh_lx => this%Xh%lx, xh_ly => this%Xh%ly, xh_lz => this%Xh%lz, &
348 dm_xh => this%dm_Xh, nelv => this%msh%nelv)
349
350 call this%p_res%init(dm_xh, "p_res")
351 call this%u_res%init(dm_xh, "u_res")
352 call this%v_res%init(dm_xh, "v_res")
353 call this%w_res%init(dm_xh, "w_res")
354 call this%abx1%init(dm_xh, "abx1")
355 call this%aby1%init(dm_xh, "aby1")
356 call this%abz1%init(dm_xh, "abz1")
357 call this%abx2%init(dm_xh, "abx2")
358 call this%aby2%init(dm_xh, "aby2")
359 call this%abz2%init(dm_xh, "abz2")
360 call this%advx%init(dm_xh, "advx")
361 call this%advy%init(dm_xh, "advy")
362 call this%advz%init(dm_xh, "advz")
363 end associate
364
365 call this%du%init(this%dm_Xh, 'du')
366 call this%dv%init(this%dm_Xh, 'dv')
367 call this%dw%init(this%dm_Xh, 'dw')
368 call this%dp%init(this%dm_Xh, 'dp')
369 ! Initialize ALE
370 call this%ale%init(this%c_Xh, params, user, chkp)
371
372 call neko_log%section("Fluid boundary conditions")
373 ! Set up boundary conditions
374 call this%setup_bcs(user, params)
375
376 ! Check if we need to output boundaries
377 call json_get_or_default(params, 'case.output_boundary', found, .false.)
378 if (found) call this%write_boundary_conditions()
379 call neko_log%end_section()
380
381 call this%proj_prs%init(this%dm_Xh%size(), this%pr_projection_dim, &
382 this%pr_projection_activ_step, &
383 this%pr_projection_reorthogonalize_basis)
384
385 call this%proj_vel%init(this%dm_Xh%size(), this%vel_projection_dim, &
386 this%vel_projection_activ_step)
387
388
389
390 ! Determine the time-interpolation scheme
391 call json_get_or_default(params, 'case.numerics.oifs', this%oifs, .false.)
392 if (params%valid_path('case.fluid.flow_rate_force')) then
393 call this%vol_flow%init(this%dm_Xh, params)
394 end if
395
396 ! Setup pressure solver
397 call neko_log%section("Pressure solver")
398
399 call json_get_or_lookup_or_default(params, &
400 'case.fluid.pressure_solver.max_iterations', &
401 solver_maxiter, 800)
402 call json_get(params, 'case.fluid.pressure_solver.type', solver_type)
403 call json_get(params, 'case.fluid.pressure_solver.preconditioner.type', &
404 precon_type)
405 call json_get(params, &
406 'case.fluid.pressure_solver.preconditioner', precon_params)
407 call json_get_or_lookup(params, &
408 'case.fluid.pressure_solver.absolute_tolerance', &
409 abs_tol)
410 call json_get_or_default(params, 'case.fluid.pressure_solver.monitor', &
411 monitor, .false.)
412 call neko_log%message('Type : ('// trim(solver_type) // &
413 ', ' // trim(precon_type) // ')')
414 write(log_buf, '(A,ES13.6)') 'Abs tol :', abs_tol
415 call neko_log%message(log_buf)
416
417 call this%solver_factory(this%ksp_prs, this%dm_Xh%size(), &
418 solver_type, solver_maxiter, abs_tol, monitor)
419 call this%precon_factory_(this%pc_prs, this%ksp_prs, &
420 this%c_Xh, this%dm_Xh, this%gs_Xh, this%bcs_prs, &
421 precon_type, precon_params)
422 call neko_log%end_section()
423
424 ! Initialize the advection factory
425 call json_get_or_default(params, 'case.fluid.advection', advection, .true.)
426 call json_get(params, 'case.numerics', numerics_params)
427 call advection_factory(this%adv, numerics_params, this%c_Xh, &
428 this%ulag, this%vlag, this%wlag, &
429 chkp%dtlag, chkp%tlag, this%ext_bdf, &
430 .not. advection)
431 ! Should be in init_base maybe?
432 this%chkp => chkp
433 ! This is probably scheme specific
434 call this%chkp%add_fluid(this%u, this%v, this%w, this%p)
435
436 this%chkp%abx1 => this%abx1
437 this%chkp%abx2 => this%abx2
438 this%chkp%aby1 => this%aby1
439 this%chkp%aby2 => this%aby2
440 this%chkp%abz1 => this%abz1
441 this%chkp%abz2 => this%abz2
442 call this%chkp%add_lag(this%ulag, this%vlag, this%wlag)
443
445 call json_get_or_default(params, 'case.fluid.schwarz_iterations', &
446 this%schwarz_iterations, 0)
447
448 call neko_log%end_section()
449
450 nullify(bc_i, vel_bc)
451
452 end subroutine fluid_pnpn_init
453
454 subroutine fluid_pnpn_restart(this, chkp)
455 class(fluid_pnpn_t), target, intent(inout) :: this
456 type(chkp_t), intent(inout) :: chkp
457 real(kind=rp) :: dtlag(10), tlag(10)
458 integer :: i, j, n
459
460 dtlag = chkp%dtlag
461 tlag = chkp%tlag
462
463 n = this%u%dof%size()
464 if (allocated(chkp%previous_mesh%elements) .or. &
465 chkp%previous_Xh%lx .ne. this%Xh%lx) then
466 associate(u => this%u, v => this%v, w => this%w, p => this%p, &
467 c_xh => this%c_Xh, ulag => this%ulag, vlag => this%vlag, &
468 wlag => this%wlag)
469 do concurrent(j = 1:n)
470 u%x(j,1,1,1) = u%x(j,1,1,1) * c_xh%mult(j,1,1,1)
471 v%x(j,1,1,1) = v%x(j,1,1,1) * c_xh%mult(j,1,1,1)
472 w%x(j,1,1,1) = w%x(j,1,1,1) * c_xh%mult(j,1,1,1)
473 p%x(j,1,1,1) = p%x(j,1,1,1) * c_xh%mult(j,1,1,1)
474 end do
475 do i = 1, this%ulag%size()
476 do concurrent(j = 1:n)
477 ulag%lf(i)%x(j,1,1,1) = ulag%lf(i)%x(j,1,1,1) &
478 * c_xh%mult(j,1,1,1)
479 vlag%lf(i)%x(j,1,1,1) = vlag%lf(i)%x(j,1,1,1) &
480 * c_xh%mult(j,1,1,1)
481 wlag%lf(i)%x(j,1,1,1) = wlag%lf(i)%x(j,1,1,1) &
482 * c_xh%mult(j,1,1,1)
483 end do
484 end do
485 end associate
486 end if
487
488 if (neko_bcknd_device .eq. 1) then
489 associate(u => this%u, v => this%v, w => this%w, &
490 ulag => this%ulag, vlag => this%vlag, wlag => this%wlag,&
491 p => this%p)
492 call device_memcpy(u%x, u%x_d, u%dof%size(), &
493 host_to_device, sync = .false.)
494 call device_memcpy(v%x, v%x_d, v%dof%size(), &
495 host_to_device, sync = .false.)
496 call device_memcpy(w%x, w%x_d, w%dof%size(), &
497 host_to_device, sync = .false.)
498 call device_memcpy(p%x, p%x_d, p%dof%size(), &
499 host_to_device, sync = .false.)
500 call device_memcpy(ulag%lf(1)%x, ulag%lf(1)%x_d, &
501 u%dof%size(), host_to_device, sync = .false.)
502 call device_memcpy(ulag%lf(2)%x, ulag%lf(2)%x_d, &
503 u%dof%size(), host_to_device, sync = .false.)
504
505 call device_memcpy(vlag%lf(1)%x, vlag%lf(1)%x_d, &
506 v%dof%size(), host_to_device, sync = .false.)
507 call device_memcpy(vlag%lf(2)%x, vlag%lf(2)%x_d, &
508 v%dof%size(), host_to_device, sync = .false.)
509
510 call device_memcpy(wlag%lf(1)%x, wlag%lf(1)%x_d, &
511 w%dof%size(), host_to_device, sync = .false.)
512 call device_memcpy(wlag%lf(2)%x, wlag%lf(2)%x_d, &
513 w%dof%size(), host_to_device, sync = .false.)
514 call device_memcpy(this%abx1%x, this%abx1%x_d, &
515 w%dof%size(), host_to_device, sync = .false.)
516 call device_memcpy(this%abx2%x, this%abx2%x_d, &
517 w%dof%size(), host_to_device, sync = .false.)
518 call device_memcpy(this%aby1%x, this%aby1%x_d, &
519 w%dof%size(), host_to_device, sync = .false.)
520 call device_memcpy(this%aby2%x, this%aby2%x_d, &
521 w%dof%size(), host_to_device, sync = .false.)
522 call device_memcpy(this%abz1%x, this%abz1%x_d, &
523 w%dof%size(), host_to_device, sync = .false.)
524 call device_memcpy(this%abz2%x, this%abz2%x_d, &
525 w%dof%size(), host_to_device, sync = .false.)
526 call device_memcpy(this%advx%x, this%advx%x_d, &
527 w%dof%size(), host_to_device, sync = .false.)
528 call device_memcpy(this%advy%x, this%advy%x_d, &
529 w%dof%size(), host_to_device, sync = .false.)
530 call device_memcpy(this%advz%x, this%advz%x_d, &
531 w%dof%size(), host_to_device, sync = .false.)
532 end associate
533 end if
534 ! Make sure that continuity is maintained (important for interpolation)
535 ! Do not do this for lagged rhs
536 ! (derivatives are not necessairly coninous across elements)
537
538 if (allocated(chkp%previous_mesh%elements) &
539 .or. chkp%previous_Xh%lx .ne. this%Xh%lx) then
540
541 call rotate_cyc(this%u, this%v, this%w, 1, this%c_Xh)
542 call this%gs_Xh%op(this%u, gs_op_add)
543 call this%gs_Xh%op(this%v, gs_op_add)
544 call this%gs_Xh%op(this%w, gs_op_add)
545 call this%gs_Xh%op(this%p, gs_op_add)
546 call rotate_cyc(this%u, this%v, this%w, 0, this%c_Xh)
547
548 do i = 1, this%ulag%size()
549 call rotate_cyc(this%ulag%lf(i), this%vlag%lf(i), &
550 this%wlag%lf(i), 1, this%c_Xh)
551 call this%gs_Xh%op(this%ulag%lf(i), gs_op_add)
552 call this%gs_Xh%op(this%vlag%lf(i), gs_op_add)
553 call this%gs_Xh%op(this%wlag%lf(i), gs_op_add)
554 call rotate_cyc(this%ulag%lf(i), this%vlag%lf(i), &
555 this%wlag%lf(i), 0, this%c_Xh)
556 end do
557 end if
558
559 call this%ale%sync_chkp(this%c_Xh, this%Xh, this%adv, chkp, this%gs_Xh)
560
561
562 end subroutine fluid_pnpn_restart
563
564 subroutine fluid_pnpn_free(this)
565 class(fluid_pnpn_t), intent(inout) :: this
566
567 !Deallocate velocity and pressure fields
568 call this%scheme_free()
569
570 if (allocated(this%ext_bdf)) then
571 call this%ext_bdf%free()
572 deallocate(this%ext_bdf)
573 end if
574
575 call this%bc_vel_res%free()
576 call this%bc_du%free()
577 call this%bc_dv%free()
578 call this%bc_dw%free()
579 call this%bc_dp%free()
580
581 call this%bc_prs_surface%free()
582 call this%bc_sym_surface%free()
583 call this%bclst_vel_res%free()
584 call this%bclst_du%free()
585 call this%bclst_dv%free()
586 call this%bclst_dw%free()
587 call this%bclst_dp%free()
588 call this%proj_prs%free()
589 call this%proj_vel%free()
590
591 call this%p_res%free()
592 call this%u_res%free()
593 call this%v_res%free()
594 call this%w_res%free()
595
596 call this%ale%free()
597
598 call this%du%free()
599 call this%dv%free()
600 call this%dw%free()
601 call this%dp%free()
602
603 call this%abx1%free()
604 call this%aby1%free()
605 call this%abz1%free()
606
607 call this%abx2%free()
608 call this%aby2%free()
609 call this%abz2%free()
610
611 call this%advx%free()
612 call this%advy%free()
613 call this%advz%free()
614
615 if (allocated(this%adv)) then
616 call this%adv%free()
617 deallocate(this%adv)
618 end if
619
620 if (allocated(this%Ax_vel)) then
621 deallocate(this%Ax_vel)
622 end if
623
624 if (allocated(this%Ax_prs)) then
625 deallocate(this%Ax_prs)
626 end if
627
628 if (allocated(this%prs_res)) then
629 deallocate(this%prs_res)
630 end if
631
632 if (allocated(this%vel_res)) then
633 deallocate(this%vel_res)
634 end if
635
636 if (allocated(this%sumab)) then
637 deallocate(this%sumab)
638 end if
639
640 if (allocated(this%makeabf)) then
641 deallocate(this%makeabf)
642 end if
643
644 if (allocated(this%makebdf)) then
645 deallocate(this%makebdf)
646 end if
647
648 if (allocated(this%makeoifs)) then
649 deallocate(this%makeoifs)
650 end if
651
652 if (allocated(this%ext_bdf)) then
653 deallocate(this%ext_bdf)
654 end if
655
656 call this%vol_flow%free()
657
658 end subroutine fluid_pnpn_free
659
666 subroutine fluid_pnpn_step(this, time, dt_controller)
667 class(fluid_pnpn_t), target, intent(inout) :: this
668 type(time_state_t), intent(in) :: time
669 type(time_step_controller_t), intent(in) :: dt_controller
670 ! number of degrees of freedom
671 integer :: n
672 ! Solver results monitors (pressure + 3 velocity)
673 type(ksp_monitor_t) :: ksp_results(4)
674 integer :: iter
675
676 type(file_t) :: dump_file
677 class(bc_t), pointer :: bc_i
678 type(non_normal_t), pointer :: bc_j
679
680 if (this%freeze) return
681
682 n = this%dm_Xh%size()
683
684 call profiler_start_region('Fluid', 1)
685 associate(u => this%u, v => this%v, w => this%w, p => this%p, &
686 u_e => this%u_e, v_e => this%v_e, w_e => this%w_e, &
687 du => this%du, dv => this%dv, dw => this%dw, dp => this%dp, &
688 u_res => this%u_res, v_res => this%v_res, w_res => this%w_res, &
689 p_res => this%p_res, ax_vel => this%Ax_vel, ax_prs => this%Ax_prs, &
690 xh => this%Xh, &
691 c_xh => this%c_Xh, dm_xh => this%dm_Xh, gs_xh => this%gs_Xh, &
692 ulag => this%ulag, vlag => this%vlag, wlag => this%wlag, &
693 msh => this%msh, prs_res => this%prs_res, &
694 source_term => this%source_term, vel_res => this%vel_res, &
695 sumab => this%sumab, makeoifs => this%makeoifs, &
696 makeabf => this%makeabf, makebdf => this%makebdf, &
697 vel_projection_dim => this%vel_projection_dim, &
698 pr_projection_dim => this%pr_projection_dim, &
699 oifs => this%oifs, &
700 rho => this%rho, mu_tot => this%mu_tot, &
701 f_x => this%f_x, f_y => this%f_y, f_z => this%f_z, &
702 t => time%t, tstep => time%tstep, dt => time%dt, &
703 ext_bdf => this%ext_bdf, event => glb_cmd_event, &
704 ale => this%ale)
705
706 ! Extrapolate the velocity if it's not done in nut_field estimation
707 call sumab%compute_fluid(u_e, v_e, w_e, u, v, w, &
708 ulag, vlag, wlag, ext_bdf%advection_coeffs%x, ext_bdf%nadv)
709
710 ! Compute the source terms
711 call this%source_term%compute(time)
712
713 ! Add Neumann bc contributions to the RHS
714 call this%bcs_vel%apply_vector(f_x%x, f_y%x, f_z%x, &
715 this%dm_Xh%size(), time, strong = .false.)
716
717 if (this%ale%active) then
718 if (oifs) then
719 call neko_error("ALE is not yet supported " // &
720 "with OIFS time integration.")
721 end if
723 call this%adv%compute_ale(u, v, w, &
724 ale%wm_x, ale%wm_y, ale%wm_z, &
725 f_x, f_y, f_z, &
726 xh, c_xh, dm_xh%size())
727 end if
728
729
730 if (oifs) then
731 ! Add the advection operators to the right-hand-side.
732 call this%adv%compute(u, v, w, &
733 this%advx, this%advy, this%advz, &
734 xh, this%c_Xh, dm_xh%size(), dt)
735
736 ! At this point the RHS contains the sum of the advection operator and
737 ! additional source terms, evaluated using the velocity field from the
738 ! previous time-step. Now, this value is used in the explicit time
739 ! scheme to advance both terms in time.
740
741 call makeabf%compute_fluid(this%abx1, this%aby1, this%abz1,&
742 this%abx2, this%aby2, this%abz2, &
743 f_x%x, f_y%x, f_z%x, &
744 rho%x(1,1,1,1), ext_bdf%advection_coeffs%x, n)
745
746 ! Now, the source terms from the previous time step are added to the RHS.
747 call makeoifs%compute_fluid(this%advx%x, this%advy%x, this%advz%x, &
748 f_x%x, f_y%x, f_z%x, &
749 rho%x(1,1,1,1), dt, n)
750 else
751 ! Add the advection operators to the right-hand-side.
752 call this%adv%compute(u, v, w, &
753 f_x, f_y, f_z, &
754 xh, this%c_Xh, dm_xh%size())
755
756 ! At this point the RHS contains the sum of the advection operator and
757 ! additional source terms, evaluated using the velocity field from the
758 ! previous time-step. Now, this value is used in the explicit time
759 ! scheme to advance both terms in time.
760
761 call makeabf%compute_fluid(this%abx1, this%aby1, this%abz1,&
762 this%abx2, this%aby2, this%abz2, &
763 f_x%x, f_y%x, f_z%x, &
764 rho%x(1,1,1,1), ext_bdf%advection_coeffs%x, n)
765
766 ! Add the RHS contributions coming from the BDF scheme.
767 ! Blag and Blaglag are history of B matrices, mainly used for ALE.
768 ! For a normal simulation (no moving mesh), Blag and Blaglag
769 ! are just the initial B matrix, filled at initialization.
770 call makebdf%compute_fluid(ulag, vlag, wlag, f_x%x, f_y%x, f_z%x, &
771 u, v, w, c_xh%B, c_xh%Blag, c_xh%Blaglag, rho%x(1,1,1,1), dt, &
772 ext_bdf%diffusion_coeffs%x, ext_bdf%ndiff, n)
773
774 end if
775
776 if (this%ale%active) then
777 ! Advance Mesh (Moves points, updates B history, updates wm_lags)
778 call this%ale%advance_mesh(c_xh, time, ext_bdf%nadv)
779
780 call profiler_start_region('ALE recompute metrics')
781 ! Update Metrics
782 call c_xh%recompute_metrics()
783 ! Update the metrics used by the adv operator for delaiasing (coef_GL)
784 ! Maps the updated coef_GLL to coef_GL.
785 call this%adv%recompute_metrics(c_xh, .true.)
786 call profiler_end_region('ALE recompute metrics')
787 end if
788
789 call ulag%update()
790 call vlag%update()
791 call wlag%update()
792
793 ! Update material properties if necessary
794 call this%update_material_properties(time)
795
796 do iter = 1, 1 + this%schwarz_iterations
797
798 call this%bc_apply_vel(time, strong = .true.)
799 call this%bc_apply_prs(time)
800
801 ! Compute pressure residual.
802 call profiler_start_region('Pressure_residual', 18)
803 call prs_res%compute(p, p_res,&
804 u, v, w, &
805 u_e, v_e, w_e, &
806 f_x, f_y, f_z, &
807 c_xh, gs_xh, &
808 this%bc_prs_surface, this%bc_sym_surface,&
809 ax_prs, ext_bdf%diffusion_coeffs%x(1), dt, &
810 mu_tot, rho, event)
811
812
813 ! De-mean the pressure residual when no strong pressure boundaries present
814 if (.not. this%prs_dirichlet .and. neko_bcknd_device .eq. 1) then
815 call device_ortho(p_res%x_d, this%glb_n_points, n)
816 else if (.not. this%prs_dirichlet) then
817 call ortho(p_res%x, this%glb_n_points, n)
818 end if
819
820 call gs_xh%op(p_res, gs_op_add, event)
821 call device_event_sync(event)
822
823 ! Set the residual to zero at strong pressure boundaries.
824 call this%bclst_dp%apply_scalar(p_res%x, p%dof%size(), time)
825
826
827 call profiler_end_region('Pressure_residual', 18)
828
829 ! Do projections only on the actual solutions of the tstep
830 ! not intermediate solutions from the subiterations.
831 if (iter .eq. 1) then
832 call this%proj_prs%pre_solving(p_res%x, tstep, c_xh, n, dt_controller, &
833 ax = ax_prs, gs_h = gs_xh, bclst = this%bclst_dp, &
834 string = 'Pressure')
835 end if
836
837 call this%pc_prs%update()
838
839 call profiler_start_region('Pressure_solve', 3)
840
841 ! Solve for the pressure increment.
842 ksp_results(1) = &
843 this%ksp_prs%solve(ax_prs, dp, p_res%x, n, c_xh, &
844 this%bclst_dp, gs_xh)
845 ksp_results(1)%name = 'Pressure'
846
847
848 call profiler_end_region('Pressure_solve', 3)
849
850 if (iter .eq. 1) then
851 call this%proj_prs%post_solving(dp%x, ax_prs, c_xh, &
852 this%bclst_dp, gs_xh, n, tstep, dt_controller)
853 end if
854
855 ! Update the pressure with the increment. Demean if necessary.
856 call field_add2(p, dp, n)
857 if (.not. this%prs_dirichlet .and. neko_bcknd_device .eq. 1) then
858 call device_ortho(p%x_d, this%glb_n_points, n)
859 else if (.not. this%prs_dirichlet) then
860 call ortho(p%x, this%glb_n_points, n)
861 end if
862
863 ! Compute velocity residual.
864 call profiler_start_region('Velocity_residual', 19)
865 call vel_res%compute(ax_vel, u, v, w, &
866 u_res, v_res, w_res, &
867 p, &
868 f_x, f_y, f_z, &
869 c_xh, msh, xh, &
870 mu_tot, rho, ext_bdf%diffusion_coeffs%x(1), &
871 dt, dm_xh%size())
872
873 call rotate_cyc(u_res, v_res, w_res, 1, c_xh)
874 call gs_xh%op(u_res%x, v_res%x, w_res%x, dm_xh%size(), &
875 gs_op_add, event)
876 call device_event_sync(event)
877 call rotate_cyc(u_res, v_res, w_res, 0, c_xh)
878
879 ! Set residual to zero at strong velocity boundaries.
880 call this%bclst_vel_res%apply(u_res, v_res, w_res, time)
881
882
883 call profiler_end_region('Velocity_residual', 19)
884
885 if (iter .eq. 1) then
886 call this%proj_vel%pre_solving(u_res%x, v_res%x, w_res%x, &
887 tstep, c_xh, n, dt_controller, 'Velocity')
888 end if
889
890 call this%pc_vel%update()
891
892 call profiler_start_region("Velocity_solve", 4)
893 ksp_results(2:4) = this%ksp_vel%solve_coupled(ax_vel, du, dv, dw, &
894 u_res%x, v_res%x, w_res%x, n, c_xh, &
895 this%bclst_du, this%bclst_dv, this%bclst_dw, gs_xh, &
896 this%ksp_vel%max_iter)
897 call profiler_end_region("Velocity_solve", 4)
898 if (this%full_stress_formulation) then
899 ksp_results(2)%name = 'Momentum'
900 else
901 ksp_results(2)%name = 'X-Velocity'
902 ksp_results(3)%name = 'Y-Velocity'
903 ksp_results(4)%name = 'Z-Velocity'
904 end if
905
906 if (iter .eq. 1) then
907 call this%proj_vel%post_solving(du%x, dv%x, dw%x, ax_vel, c_xh, &
908 this%bclst_du, this%bclst_dv, this%bclst_dw, gs_xh, n, tstep, &
909 dt_controller)
910 end if
911
912 if (neko_bcknd_device .eq. 1) then
913 call device_opadd2cm(u%x_d, v%x_d, w%x_d, &
914 du%x_d, dv%x_d, dw%x_d, 1.0_rp, n, msh%gdim)
915 else
916 call opadd2cm(u%x, v%x, w%x, du%x, dv%x, dw%x, 1.0_rp, n, msh%gdim)
917 end if
918
919 call fluid_step_info(time, ksp_results, &
920 this%full_stress_formulation, this%strict_convergence, &
921 this%allow_stabilization, iter)
922
923 end do
924
925 if (this%forced_flow_rate) then
926 ! Horrible mu hack?!
927 call this%vol_flow%adjust( u, v, w, p, u_res, v_res, w_res, p_res, &
928 c_xh, gs_xh, ext_bdf, rho%x(1,1,1,1), mu_tot, &
929 dt, time, this%bclst_dp, this%bclst_du, this%bclst_dv, &
930 this%bclst_dw, this%bclst_vel_res, ax_vel, ax_prs, this%ksp_prs, &
931 this%ksp_vel, this%pc_prs, this%pc_vel, this%ksp_prs%max_iter, &
932 this%ksp_vel%max_iter)
933 end if
934
935 ! Update mesh velocities for ALE
936 ! We update them here (end of step) for the next step.
937 ! Returns if .not. ale.
938 call this%ale%update_mesh_velocity(c_xh, time)
939
940 end associate
941
942 nullify(bc_i, bc_j)
943
944 call profiler_end_region('Fluid', 1)
945 end subroutine fluid_pnpn_step
946
949 subroutine fluid_pnpn_setup_bcs(this, user, params)
950 class(fluid_pnpn_t), target, intent(inout) :: this
951 type(user_t), target, intent(in) :: user
952 type(json_file), intent(inout) :: params
953 integer :: i, n_bcs, zone_index, j, zone_size, global_zone_size, ierr
954 class(bc_t), pointer :: bc_i
955 type(json_core) :: core
956 type(json_value), pointer :: bc_object
957 type(json_file) :: bc_subdict
958 logical :: ale_active_local, any_moving_wall, moving_
959 logical :: found
960 ! Monitor which boundary zones have been marked
961 logical, allocatable :: marked_zones(:)
962 integer, allocatable :: zone_indices(:)
963
964 ! For ALE, we set a flag while reading the BCs
965 character(len=:), allocatable :: bc_type_str
966 this%ale%has_moving_boundary = .false.
967 any_moving_wall = .false.
968 ale_active_local = .false.
969 call json_get_or_default(params, &
970 'case.fluid.ale.enabled', &
971 ale_active_local, .false.)
972
973 ! Lists for the residuals and solution increments
974 call this%bclst_vel_res%init()
975 call this%bclst_du%init()
976 call this%bclst_dv%init()
977 call this%bclst_dw%init()
978 call this%bclst_dp%init()
979
980 call this%bc_vel_res%init_from_components(this%c_Xh)
981 call this%bc_du%init_from_components(this%c_Xh)
982 call this%bc_dv%init_from_components(this%c_Xh)
983 call this%bc_dw%init_from_components(this%c_Xh)
984 call this%bc_dp%init_from_components(this%c_Xh)
985
986 ! Special PnPn boundary conditions for pressure
987 call this%bc_prs_surface%init_from_components(this%c_Xh)
988 call this%bc_sym_surface%init_from_components(this%c_Xh)
989
990 ! Populate bcs_vel and bcs_prs based on the case file
991 if (params%valid_path('case.fluid.boundary_conditions')) then
992 call params%info('case.fluid.boundary_conditions', n_children = n_bcs)
993 call params%get_core(core)
994 call params%get('case.fluid.boundary_conditions', bc_object, found)
995
996 !
997 ! Velocity bcs
998 !
999 call this%bcs_vel%init(n_bcs)
1000
1001 allocate(marked_zones(size(this%msh%labeled_zones)))
1002 marked_zones = .false.
1003
1004 do i = 1, n_bcs
1005 ! Create a new json containing just the subdict for this bc
1006 call json_extract_item(core, bc_object, i, bc_subdict)
1007
1008 call json_get_or_lookup(bc_subdict, "zone_indices", zone_indices)
1009
1010 ! Set the ALE flag to true if there is any moving no_slip wall
1011 call json_get(bc_subdict, "type", bc_type_str)
1012 moving_ = .false.
1013 if (trim(bc_type_str) .eq. "no_slip") then
1014 call json_get_or_default(bc_subdict, "moving", moving_, .false.)
1015 end if
1016 if (moving_) then
1017 this%ale%has_moving_boundary = .true.
1018 end if
1019
1020 ! Check that we are not trying to assing a bc to zone, for which one
1021 ! has already been assigned and that the zone has more than 0 size
1022 ! in the mesh.
1023 do j = 1, size(zone_indices)
1024 zone_size = this%msh%labeled_zones(zone_indices(j))%size
1025 call mpi_allreduce(zone_size, global_zone_size, 1, &
1026 mpi_integer, mpi_max, neko_comm, ierr)
1027
1028 if (global_zone_size .eq. 0) then
1029 write(error_unit, '(A, A, I0, A, A, I0, A)') "*** ERROR ***: ",&
1030 "Zone index ", zone_indices(j), &
1031 " is invalid as this zone has 0 size, meaning it ", &
1032 "is not in the mesh. Check fluid boundary condition ", &
1033 i, "."
1034 error stop
1035 end if
1036
1037 if (marked_zones(zone_indices(j))) then
1038 write(error_unit, '(A, A, I0, A, A, A, A)') "*** ERROR ***: ", &
1039 "Zone with index ", zone_indices(j), &
1040 " has already been assigned a boundary condition. ", &
1041 "Please check your boundary_conditions entry for the ", &
1042 "fluid and make sure that each zone index appears only ", &
1043 "in a single boundary condition."
1044 error stop
1045 else
1046 marked_zones(zone_indices(j)) = .true.
1047 end if
1048 end do
1049
1050 bc_i => null()
1051 call velocity_bc_factory(bc_i, this, bc_subdict, this%c_Xh, user)
1052
1053 ! Not all bcs require an allocation for velocity in particular,
1054 ! so we check.
1055 if (associated(bc_i)) then
1056
1057 ! We need to treat mixed bcs separately because they are by
1058 ! convention marked weak and currently contain nested
1059 ! bcs, some of which are strong.
1060 select type (bc_i)
1061 type is (symmetry_t)
1062 ! Symmetry has 3 internal bcs, but only one actually contains
1063 ! markings.
1064 ! Symmetry's apply_scalar doesn't do anything, so we need to mark
1065 ! individual nested bcs to the du,dv,dw, whereas the vel_res can
1066 ! just get symmetry as a whole, because on this list we call
1067 ! apply_vector.
1068 ! Additionally we have to mark the special surface bc for p.
1069 call this%bclst_vel_res%append(bc_i)
1070 call this%bc_du%mark_facets(bc_i%bc_x%marked_facet)
1071 call this%bc_dv%mark_facets(bc_i%bc_y%marked_facet)
1072 call this%bc_dw%mark_facets(bc_i%bc_z%marked_facet)
1073
1074 call this%bcs_vel%append(bc_i)
1075
1076 call this%bc_sym_surface%mark_facets(bc_i%marked_facet)
1077 type is (non_normal_t)
1078 ! This is a bc for the residuals and increments, not the
1079 ! velocity itself. So, don't append to bcs_vel
1080 call this%bclst_vel_res%append(bc_i)
1081 call this%bc_du%mark_facets(bc_i%bc_x%marked_facet)
1082 call this%bc_dv%mark_facets(bc_i%bc_y%marked_facet)
1083 call this%bc_dw%mark_facets(bc_i%bc_z%marked_facet)
1084 type is (shear_stress_t)
1085 ! Same as symmetry
1086 call this%bclst_vel_res%append(bc_i%symmetry)
1087 call this%bclst_du%append(bc_i%symmetry%bc_x)
1088 call this%bclst_dv%append(bc_i%symmetry%bc_y)
1089 call this%bclst_dw%append(bc_i%symmetry%bc_z)
1090
1091 call this%bcs_vel%append(bc_i)
1092 type is (wall_model_bc_t)
1093 ! Same as symmetry
1094 call this%bclst_vel_res%append(bc_i%symmetry)
1095 call this%bclst_du%append(bc_i%symmetry%bc_x)
1096 call this%bclst_dv%append(bc_i%symmetry%bc_y)
1097 call this%bclst_dw%append(bc_i%symmetry%bc_z)
1098
1099 call this%bcs_vel%append(bc_i)
1100 class default
1101
1102 ! For the default case we use our dummy zero_dirichlet bcs to
1103 ! mark the same faces as in ordinary velocity dirichlet
1104 ! conditions.
1105 ! Additionally we mark the special PnPn pressure bc.
1106 if (bc_i%strong) then
1107 call this%bc_vel_res%mark_facets(bc_i%marked_facet)
1108 call this%bc_du%mark_facets(bc_i%marked_facet)
1109 call this%bc_dv%mark_facets(bc_i%marked_facet)
1110 call this%bc_dw%mark_facets(bc_i%marked_facet)
1111
1112 call this%bc_prs_surface%mark_facets(bc_i%marked_facet)
1113 end if
1114
1115 call this%bcs_vel%append(bc_i)
1116 end select
1117 end if
1118 end do
1119
1120 if (this%ale%active .and. (.not. this%ale%has_moving_boundary)) then
1121 call neko_error("Case file error: ALE is active, " // &
1122 "but no moving wall was found. " // &
1123 "Use type = 'no_slip' with 'moving': true in case file.")
1124 end if
1125
1126 ! Make sure all labeled zones with non-zero size have been marked
1127 do i = 1, size(this%msh%labeled_zones)
1128 if ((this%msh%labeled_zones(i)%size .gt. 0) .and. &
1129 (.not. marked_zones(i))) then
1130 write(error_unit, '(A, A, I0)') "*** ERROR ***: ", &
1131 "No fluid boundary condition assigned to zone ", i
1132 error stop
1133 end if
1134 end do
1135
1136 !
1137 ! Pressure bcs
1138 !
1139 call this%bcs_prs%init(n_bcs)
1140
1141 do i = 1, n_bcs
1142 ! Create a new json containing just the subdict for this bc
1143 call json_extract_item(core, bc_object, i, bc_subdict)
1144 bc_i => null()
1145 call pressure_bc_factory(bc_i, this, bc_subdict, this%c_Xh, user)
1146
1147 ! Not all bcs require an allocation for pressure in particular,
1148 ! so we check.
1149 if (associated(bc_i)) then
1150 call this%bcs_prs%append(bc_i)
1151
1152 ! Mark strong bcs in the dummy dp bc to force zero change.
1153 if (bc_i%strong) then
1154 call this%bc_dp%mark_facets(bc_i%marked_facet)
1155 end if
1156
1157 end if
1158
1159 end do
1160 else
1161 ! Check that there are no labeled zones, i.e. all are periodic.
1162 do i = 1, size(this%msh%labeled_zones)
1163 if (this%msh%labeled_zones(i)%size .gt. 0) then
1164 call neko_error("No boundary_conditions entry in the case file!")
1165 end if
1166 end do
1167
1168 ! For a pure periodic case, we still need to initilise the bc lists
1169 ! to a zero size to avoid issues with apply() in step()
1170 call this%bcs_vel%init()
1171 call this%bcs_prs%init()
1172
1173 end if
1174
1175 call this%bc_prs_surface%finalize()
1176 call this%bc_sym_surface%finalize()
1177
1178 call this%bc_vel_res%finalize()
1179 call this%bc_du%finalize()
1180 call this%bc_dv%finalize()
1181 call this%bc_dw%finalize()
1182 call this%bc_dp%finalize()
1183
1184 call this%bclst_vel_res%append(this%bc_vel_res)
1185 call this%bclst_du%append(this%bc_du)
1186 call this%bclst_dv%append(this%bc_dv)
1187 call this%bclst_dw%append(this%bc_dw)
1188 call this%bclst_dp%append(this%bc_dp)
1189
1190 ! If we have no strong pressure bcs, we will demean the pressure
1191 this%prs_dirichlet = .not. this%bclst_dp%is_empty()
1192 call mpi_allreduce(mpi_in_place, this%prs_dirichlet, 1, &
1193 mpi_logical, mpi_lor, neko_comm)
1194
1195
1196 if (allocated(marked_zones)) then
1197 deallocate(marked_zones)
1198 end if
1199
1200 if (allocated(zone_indices)) then
1201 deallocate(zone_indices)
1202 end if
1203
1204 nullify(bc_i, bc_object)
1205
1206 end subroutine fluid_pnpn_setup_bcs
1207
1209 subroutine fluid_pnpn_write_boundary_conditions(this)
1210 use inflow, only : inflow_t
1212 use blasius, only : blasius_t
1214 use dong_outflow, only : dong_outflow_t
1215 use no_slip, only : no_slip_t
1216 class(fluid_pnpn_t), target, intent(inout) :: this
1217 type(dirichlet_t) :: bdry_mask
1218 type(field_t), pointer :: bdry_field
1219 type(file_t) :: bdry_file
1220 integer :: temp_index, i
1221 class(bc_t), pointer :: bci
1222 character(len=LOG_SIZE) :: log_buf
1223
1224 write(log_buf, '(A)') 'Marking using integer keys in bdry0.f00000'
1225 call neko_log%message(log_buf)
1226 write(log_buf, '(A)') 'Condition-value pairs: '
1227 call neko_log%message(log_buf)
1228 write(log_buf, '(A)') ' no_slip (stationary wall) = 1'
1229 call neko_log%message(log_buf)
1230 write(log_buf, '(A)') ' velocity_value = 2'
1231 call neko_log%message(log_buf)
1232 write(log_buf, '(A)') ' outflow, normal_outflow (+dong) = 3'
1233 call neko_log%message(log_buf)
1234 write(log_buf, '(A)') ' symmetry = 4'
1235 call neko_log%message(log_buf)
1236 write(log_buf, '(A)') ' periodic = 6'
1237 call neko_log%message(log_buf)
1238 write(log_buf, '(A)') ' user_velocity = 7'
1239 call neko_log%message(log_buf)
1240 write(log_buf, '(A)') ' user_pressure = 8'
1241 call neko_log%message(log_buf)
1242 write(log_buf, '(A)') ' shear_stress = 9'
1243 call neko_log%message(log_buf)
1244 write(log_buf, '(A)') ' wall_modelling = 10'
1245 call neko_log%message(log_buf)
1246 write(log_buf, '(A)') ' blasius_profile = 11'
1247 call neko_log%message(log_buf)
1248 write(log_buf, '(A)') ' no_slip (moving wall) = 12'
1249 call neko_log%message(log_buf)
1250
1251 call neko_scratch_registry%request_field(bdry_field, temp_index, .true.)
1252
1253
1254
1255 call bdry_mask%init_from_components(this%c_Xh, 6.0_rp)
1256 call bdry_mask%mark_zone(this%msh%periodic)
1257 call bdry_mask%finalize()
1258 call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
1259 call bdry_mask%free()
1260
1261 do i = 1, this%bcs_prs%size()
1262 bci => this%bcs_prs%get(i)
1263 select type (bc => bci)
1264 type is (zero_dirichlet_t)
1265 call bdry_mask%init_from_components(this%c_Xh, 3.0_rp)
1266 call bdry_mask%mark_facets(bci%marked_facet)
1267 call bdry_mask%finalize()
1268 call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
1269 call bdry_mask%free()
1270 type is (dong_outflow_t)
1271 call bdry_mask%init_from_components(this%c_Xh, 3.0_rp)
1272 call bdry_mask%mark_facets(bci%marked_facet)
1273 call bdry_mask%finalize()
1274 call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
1275 call bdry_mask%free()
1276 type is (field_dirichlet_t)
1277 call bdry_mask%init_from_components(this%c_Xh, 8.0_rp)
1278 call bdry_mask%mark_facets(bci%marked_facet)
1279 call bdry_mask%finalize()
1280 call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
1281 call bdry_mask%free()
1282 end select
1283 end do
1284
1285 do i = 1, this%bcs_vel%size()
1286 bci => this%bcs_vel%get(i)
1287 select type (bc => bci)
1288 type is (no_slip_t)
1289 if (bc%is_moving) then
1290 ! moving wall
1291 call bdry_mask%init_from_components(this%c_Xh, 12.0_rp)
1292 else
1293 ! stationary wall
1294 call bdry_mask%init_from_components(this%c_Xh, 1.0_rp)
1295 end if
1296 call bdry_mask%mark_facets(bci%marked_facet)
1297 call bdry_mask%finalize()
1298 call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
1299 call bdry_mask%free()
1300 type is (inflow_t)
1301 call bdry_mask%init_from_components(this%c_Xh, 2.0_rp)
1302 call bdry_mask%mark_facets(bci%marked_facet)
1303 call bdry_mask%finalize()
1304 call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
1305 call bdry_mask%free()
1306 type is (symmetry_t)
1307 call bdry_mask%init_from_components(this%c_Xh, 4.0_rp)
1308 call bdry_mask%mark_facets(bci%marked_facet)
1309 call bdry_mask%finalize()
1310 call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
1311 call bdry_mask%free()
1312 type is (field_dirichlet_vector_t)
1313 call bdry_mask%init_from_components(this%c_Xh, 7.0_rp)
1314 call bdry_mask%mark_facets(bci%marked_facet)
1315 call bdry_mask%finalize()
1316 call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
1317 call bdry_mask%free()
1318 type is (shear_stress_t)
1319 call bdry_mask%init_from_components(this%c_Xh, 9.0_rp)
1320 call bdry_mask%mark_facets(bci%marked_facet)
1321 call bdry_mask%finalize()
1322 call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
1323 call bdry_mask%free()
1324 type is (wall_model_bc_t)
1325 call bdry_mask%init_from_components(this%c_Xh, 10.0_rp)
1326 call bdry_mask%mark_facets(bci%marked_facet)
1327 call bdry_mask%finalize()
1328 call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
1329 call bdry_mask%free()
1330 type is (blasius_t)
1331 call bdry_mask%init_from_components(this%c_Xh, 11.0_rp)
1332 call bdry_mask%mark_facets(bci%marked_facet)
1333 call bdry_mask%finalize()
1334 call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
1335 call bdry_mask%free()
1336 end select
1337 end do
1338
1339
1340 call bdry_file%init('bdry.fld')
1341 call bdry_file%write(bdry_field)
1342
1343 call neko_scratch_registry%relinquish_field(temp_index)
1344
1345 nullify(bdry_field, bci)
1346
1347 end subroutine fluid_pnpn_write_boundary_conditions
1348
1349end module fluid_pnpn
Copy data between host and device (or device and device)
Definition device.F90:72
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.
Apply cyclic boundary condition to a vector field.
Subroutines to add advection terms to the RHS of a transport equation.
Definition advection.f90:34
ALE Manager: Handles Mesh Motion.
Defines a Matrix-vector product.
Definition ax.f90:34
Defines a list of bc_t.
Definition bc_list.f90:34
Defines a boundary condition.
Definition bc.f90:34
Defines a Blasius profile dirichlet condition.
Definition blasius.f90:34
Defines a checkpoint.
Coefficients.
Definition coef.f90:34
Definition comm.F90:1
type(mpi_comm), public neko_comm
MPI communicator.
Definition comm.F90:45
subroutine, public device_opadd2cm(a1_d, a2_d, a3_d, b1_d, b2_d, b3_d, c, n, gdim)
subroutine, public device_opcolv(a1_d, a2_d, a3_d, c_d, gdim, n)
Device abstraction, common interface for various accelerators.
Definition device.F90:34
subroutine, public device_event_sync(event)
Synchronize an event.
Definition device.F90:1594
integer, parameter, public host_to_device
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 dong outflow condition.
Dirichlet condition applied in the facet normal direction.
Defines inflow dirichlet conditions.
Defines user dirichlet condition for a scalar field.
subroutine, public field_add2(a, b, n)
Vector addition .
subroutine, public field_copy(a, b, n)
Copy a vector .
Contains the field_serties_t type.
Defines a field.
Definition field.f90:34
Module for file I/O operations.
Definition file.f90:34
Auxiliary routines for fluid solvers.
Definition fluid_aux.f90:34
subroutine, public fluid_step_info(time, ksp_results, full_stress_formulation, strict_convergence, allow_stabilization, iteration)
Prints for prs, velx, vely, velz the following: Number of iterations, start residual,...
Definition fluid_aux.f90:54
Modular version of the Classic Nek5000 Pn/Pn formulation for fluids.
subroutine fluid_pnpn_setup_bcs(this, user, params)
Sets up the boundary condition for the scheme.
subroutine fluid_pnpn_restart(this, chkp)
subroutine fluid_pnpn_write_boundary_conditions(this)
Write a field with boundary condition specifications.
subroutine fluid_pnpn_step(this, time, dt_controller)
Advance fluid simulation in time.
subroutine fluid_pnpn_free(this)
subroutine fluid_pnpn_init(this, msh, lx, params, user, chkp)
Boundary condition factory for pressure.
Defines Gather-scatter operations.
Definition gs_ops.f90:34
integer, parameter, public gs_op_add
Definition gs_ops.f90:36
Defines inflow dirichlet conditions.
Definition inflow.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
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
Collection of vector field operations operating on and . Note that in general the indices and ....
Definition mathops.f90:67
subroutine, public opcolv(a1, a2, a3, c, gdim, n)
Definition mathops.f90:103
subroutine, public opadd2cm(a1, a2, a3, b1, b2, b3, c, n, gdim)
Definition mathops.f90:156
Defines a mesh.
Definition mesh.f90:34
Build configurations.
integer, parameter neko_bcknd_device
Defines no-slip boundary condition (extends zero_dirichlet)
Definition no_slip.f90:34
Dirichlet condition on axis aligned plane in the non normal direction.
integer, parameter, public dp
Definition num_types.f90:9
integer, parameter, public rp
Global precision used in computations.
Definition num_types.f90:12
Operators.
Definition operators.f90:34
subroutine, public ortho(x, glb_n_points, n)
Othogonalize with regard to vector (1,1,1,1,1,1...,1)^T.
Operators accelerator backends.
subroutine, public device_ortho(x_d, glb_n_points, n)
Othogonalize with regard to vector (1,1,1,1,1,1...,1)^T.
Defines Pressure and velocity residuals in the Pn-Pn formulation.
Definition pnpn_res.f90:34
Profiling interface.
Definition profiler.F90:34
subroutine, public profiler_start_region(name, region_id)
Started a named (name) profiler region.
Definition profiler.F90:79
subroutine, public profiler_end_region(name, region_id)
End the most recently started profiler region.
Definition profiler.F90:116
Project x onto X , the space of old solutions and back again Couple projections for velocity.
Project x onto X, the space of old solutions and back again.
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
Routines to generate the right-hand sides for the convection-diffusion equation. Employs the EXT/BDF ...
Definition rhs_maker.f90:38
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 shear stress boundary condition for a vector field. Maintainer: Timofey Mukha.
Implements the source_term_t type and a wrapper source_term_wrapper_t.
Mixed Dirichlet-Neumann axis aligned symmetry plane.
Definition symmetry.f90:34
Module with things related to the simulation time.
Implements type time_step_controller.
Interfaces for user interaction with NEKO.
Definition user_intf.f90:34
Utilities.
Definition utils.f90:35
subroutine, public neko_type_error(base_type, wrong_type, known_types)
Reports an error allocating a type for a particular base pointer class.
Definition utils.f90:365
Defines the wall_model_bc_t type. Maintainer: Timofey Mukha.
Defines a zero-valued Dirichlet boundary condition.
Base abstract type for computing the advection operator.
Definition advection.f90:46
Base type for a matrix-vector product providing .
Definition ax.f90:43
Base type for a boundary condition.
Definition bc.f90:62
A list of allocatable `bc_t`. Follows the standard interface of lists.
Definition bc_list.f90:49
Blasius profile for inlet (vector valued).
Definition blasius.f90:55
Coefficients defined on a given (mesh, ) tuple. Arrays use indices (i,j,k,e): element e,...
Definition coef.f90:62
Generic Dirichlet boundary condition on .
Definition dirichlet.f90:49
Dong outflow condition Follows "A Convective-like Energy-Stable Open Boundary Condition for Simulati...
Dirichlet condition in facet normal direction.
User defined dirichlet condition, for which the user can work with an entire field....
Extension of the user defined dirichlet condition field_dirichlet
Stores a series (sequence) of fields, logically connected to a base field, and arranged according to ...
A wrapper around a polymorphic generic_file_t that handles its init. This is essentially a factory fo...
Definition file.f90:56
Dirichlet condition for inlet (vector valued)
Definition inflow.f90:47
Type for storing initial and final residuals in a Krylov solver.
Definition krylov.f90:56
Dirichlet condition in non normal direction of a plane.
Abstract type to compute pressure residual.
Definition pnpn_res.f90:48
Abstract type to compute velocity residual.
Definition pnpn_res.f90:54
Abstract type to add contributions to F from lagged BD terms.
Definition rhs_maker.f90:59
Abstract type to sum up contributions to kth order extrapolation scheme.
Definition rhs_maker.f90:52
Abstract type to add contributions of kth order OIFS scheme.
Definition rhs_maker.f90:66
Abstract type to compute extrapolated velocity field for the pressure equation.
Definition rhs_maker.f90:46
A shear stress boundary condition.
Mixed Dirichlet-Neumann symmetry plane condition.
Definition symmetry.f90:50
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...
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...