Loading [MathJax]/extensions/tex2jax.js
Neko 0.9.99
A portable framework for high-order spectral element flow simulations
All Classes Namespaces Files Functions Variables Typedefs Enumerator Macros Pages
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 comm
36 use, intrinsic :: iso_fortran_env, only: error_unit
37 use coefs, only : coef_t
38 use symmetry, only : symmetry_t
40 use logger, only: neko_log, log_size
41 use num_types, only : rp
42 use krylov, only : ksp_monitor_t
44 pnpn_prs_res_factory, pnpn_vel_res_factory, &
45 pnpn_prs_res_stress_factory, pnpn_vel_res_stress_factory
47 rhs_maker_oifs_t, rhs_maker_sumab_fctry, rhs_maker_bdf_fctry, &
48 rhs_maker_ext_fctry, rhs_maker_oifs_fctry
52 use fluid_aux, only : fluid_step_info
54 use projection, only : projection_t
58 use advection, only : advection_t, advection_factory
60 use json_module, only : json_file, json_core, json_value
62 use json_module, only : json_file
63 use ax_product, only : ax_t, ax_helm_factory
64 use field, only : field_t
65 use dirichlet, only : dirichlet_t
69 use non_normal, only : non_normal_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
83 implicit none
84 private
85
86
87
89
91 type(field_t) :: p_res, u_res, v_res, w_res
92
95 type(field_t) :: dp, du, dv, dw
96
97 !
98 ! Implicit operators, i.e. the left-hand-side of the Helmholz problem.
99 !
100
101 ! Coupled Helmholz operator for velocity
102 class(ax_t), allocatable :: ax_vel
103 ! Helmholz operator for pressure
104 class(ax_t), allocatable :: ax_prs
105
106 !
107 ! Projections for solver speed-up
108 !
109
111 type(projection_t) :: proj_prs
112 type(projection_vel_t) :: proj_vel
113
114 !
115 ! Special Karniadakis scheme boundary conditions in the pressure equation
116 !
117
119 type(facet_normal_t) :: bc_prs_surface
120
122 type(facet_normal_t) :: bc_sym_surface
123
124 !
125 ! Boundary conditions and lists for residuals and solution increments
126 !
127
129 type(zero_dirichlet_t) :: bc_vel_res
131 type(zero_dirichlet_t) :: bc_du
133 type(zero_dirichlet_t) :: bc_dv
135 type(zero_dirichlet_t) :: bc_dw
137 type(zero_dirichlet_t) :: bc_dp
138
140 type(bc_list_t) :: bclst_vel_res
141 type(bc_list_t) :: bclst_du
142 type(bc_list_t) :: bclst_dv
143 type(bc_list_t) :: bclst_dw
144 type(bc_list_t) :: bclst_dp
145
146
147 ! Checker for wether we have a strong pressure bc. If not, the pressure
148 ! is demeaned at every time step.
149 logical :: prs_dirichlet = .false.
150
151
152 ! The advection operator.
153 class(advection_t), allocatable :: adv
154
155 ! Time OIFS interpolation scheme for advection.
156 logical :: oifs
157
158 ! Time variables
159 type(field_t) :: abx1, aby1, abz1
160 type(field_t) :: abx2, aby2, abz2
161
162 ! Advection terms for the oifs method
163 type(field_t) :: advx, advy, advz
164
166 class(pnpn_prs_res_t), allocatable :: prs_res
167
169 class(pnpn_vel_res_t), allocatable :: vel_res
170
172 class(rhs_maker_sumab_t), allocatable :: sumab
173
175 class(rhs_maker_ext_t), allocatable :: makeabf
176
178 class(rhs_maker_bdf_t), allocatable :: makebdf
179
181 class(rhs_maker_oifs_t), allocatable :: makeoifs
182
184 type(fluid_volflow_t) :: vol_flow
185
186 contains
188 procedure, pass(this) :: init => fluid_pnpn_init
190 procedure, pass(this) :: free => fluid_pnpn_free
192 procedure, pass(this) :: step => fluid_pnpn_step
194 procedure, pass(this) :: restart => fluid_pnpn_restart
196 procedure, pass(this) :: setup_bcs => fluid_pnpn_setup_bcs
198 procedure, pass(this) :: write_boundary_conditions => &
200 end type fluid_pnpn_t
201
202 interface
203
210 module subroutine pressure_bc_factory(object, scheme, json, coef, user)
211 class(bc_t), pointer, intent(inout) :: object
212 type(fluid_pnpn_t), intent(in) :: scheme
213 type(json_file), intent(inout) :: json
214 type(coef_t), intent(in) :: coef
215 type(user_t), intent(in) :: user
216 end subroutine pressure_bc_factory
217 end interface
218
219 interface
220
227 module subroutine velocity_bc_factory(object, scheme, json, coef, user)
228 class(bc_t), pointer, intent(inout) :: object
229 type(fluid_pnpn_t), intent(in) :: scheme
230 type(json_file), intent(inout) :: json
231 type(coef_t), intent(in) :: coef
232 type(user_t), intent(in) :: user
233 end subroutine velocity_bc_factory
234 end interface
235
236contains
237
238 subroutine fluid_pnpn_init(this, msh, lx, params, user)
239 class(fluid_pnpn_t), target, intent(inout) :: this
240 type(mesh_t), target, intent(inout) :: msh
241 integer, intent(in) :: lx
242 type(json_file), target, intent(inout) :: params
243 type(user_t), target, intent(in) :: user
244 character(len=15), parameter :: scheme = 'Modular (Pn/Pn)'
245 integer :: i
246 class(bc_t), pointer :: bc_i, vel_bc
247 real(kind=rp) :: abs_tol
248 character(len=LOG_SIZE) :: log_buf
249 integer :: ierr, integer_val, solver_maxiter
250 character(len=:), allocatable :: solver_type, precon_type
251 logical :: monitor, found
252 logical :: advection
253
254 call this%free()
255
256 ! Initialize base class
257 call this%init_base(msh, lx, params, scheme, user, .true.)
258
259 ! Add pressure field to the registry. For this scheme it is in the same
260 ! Xh as the velocity
261 call neko_field_registry%add_field(this%dm_Xh, 'p')
262 this%p => neko_field_registry%get_field('p')
263
264 !
265 ! Select governing equations via associated residual and Ax types
266 !
267
268 call json_get(params, 'case.numerics.time_order', integer_val)
269 allocate(this%ext_bdf)
270 call this%ext_bdf%init(integer_val)
271
272 if (this%variable_material_properties .eqv. .true.) then
273 ! Setup backend dependent Ax routines
274 call ax_helm_factory(this%Ax_vel, full_formulation = .true.)
275
276 ! Setup backend dependent prs residual routines
277 call pnpn_prs_res_stress_factory(this%prs_res)
278
279 ! Setup backend dependent vel residual routines
280 call pnpn_vel_res_stress_factory(this%vel_res)
281 else
282 ! Setup backend dependent Ax routines
283 call ax_helm_factory(this%Ax_vel, full_formulation = .false.)
284
285 ! Setup backend dependent prs residual routines
286 call pnpn_prs_res_factory(this%prs_res)
287
288 ! Setup backend dependent vel residual routines
289 call pnpn_vel_res_factory(this%vel_res)
290 end if
291
292 ! Setup Ax for the pressure
293 call ax_helm_factory(this%Ax_prs, full_formulation = .false.)
294
295
296 ! Setup backend dependent summation of AB/BDF
297 call rhs_maker_sumab_fctry(this%sumab)
298
299 ! Setup backend dependent summation of extrapolation scheme
300 call rhs_maker_ext_fctry(this%makeabf)
301
302 ! Setup backend depenent contributions to F from lagged BD terms
303 call rhs_maker_bdf_fctry(this%makebdf)
304
305 ! Setup backend dependent summations of the OIFS method
306 call rhs_maker_oifs_fctry(this%makeoifs)
307
308 ! Initialize variables specific to this plan
309 associate(xh_lx => this%Xh%lx, xh_ly => this%Xh%ly, xh_lz => this%Xh%lz, &
310 dm_xh => this%dm_Xh, nelv => this%msh%nelv)
311
312 call this%p_res%init(dm_xh, "p_res")
313 call this%u_res%init(dm_xh, "u_res")
314 call this%v_res%init(dm_xh, "v_res")
315 call this%w_res%init(dm_xh, "w_res")
316 call this%abx1%init(dm_xh, "abx1")
317 call this%aby1%init(dm_xh, "aby1")
318 call this%abz1%init(dm_xh, "abz1")
319 call this%abx2%init(dm_xh, "abx2")
320 call this%aby2%init(dm_xh, "aby2")
321 call this%abz2%init(dm_xh, "abz2")
322 call this%advx%init(dm_xh, "advx")
323 call this%advy%init(dm_xh, "advy")
324 call this%advz%init(dm_xh, "advz")
325 end associate
326
327 call this%du%init(this%dm_Xh, 'du')
328 call this%dv%init(this%dm_Xh, 'dv')
329 call this%dw%init(this%dm_Xh, 'dw')
330 call this%dp%init(this%dm_Xh, 'dp')
331
332 ! Set up boundary conditions
333 call this%setup_bcs(user, params)
334
335 ! Check if we need to output boundaries
336 call json_get_or_default(params, 'case.output_boundary', found, .false.)
337 if (found) call this%write_boundary_conditions()
338
339 call this%proj_prs%init(this%dm_Xh%size(), this%pr_projection_dim, &
340 this%pr_projection_activ_step)
341
342 call this%proj_vel%init(this%dm_Xh%size(), this%vel_projection_dim, &
343 this%vel_projection_activ_step)
344
345
346 ! Add lagged term to checkpoint
347 call this%chkp%add_lag(this%ulag, this%vlag, this%wlag)
348
349 ! Determine the time-interpolation scheme
350 call json_get_or_default(params, 'case.numerics.oifs', this%oifs, .false.)
351
352 ! Initialize the advection factory
353 call json_get_or_default(params, 'case.fluid.advection', advection, .true.)
354 call advection_factory(this%adv, params, this%c_Xh, &
355 this%ulag, this%vlag, this%wlag, &
356 this%chkp%dtlag, this%chkp%tlag, this%ext_bdf, &
357 .not. advection)
358
359 if (params%valid_path('case.fluid.flow_rate_force')) then
360 call this%vol_flow%init(this%dm_Xh, params)
361 end if
362
363 ! Setup pressure solver
364 call neko_log%section("Pressure solver")
365
366 call json_get_or_default(params, &
367 'case.fluid.pressure_solver.max_iterations', &
368 solver_maxiter, 800)
369 call json_get(params, 'case.fluid.pressure_solver.type', solver_type)
370 call json_get(params, 'case.fluid.pressure_solver.preconditioner', &
371 precon_type)
372 call json_get(params, 'case.fluid.pressure_solver.absolute_tolerance', &
373 abs_tol)
374 call json_get_or_default(params, 'case.fluid.pressure_solver.monitor', &
375 monitor, .false.)
376 call neko_log%message('Type : ('// trim(solver_type) // &
377 ', ' // trim(precon_type) // ')')
378 write(log_buf, '(A,ES13.6)') 'Abs tol :', abs_tol
379 call neko_log%message(log_buf)
380
381 call this%solver_factory(this%ksp_prs, this%dm_Xh%size(), &
382 solver_type, solver_maxiter, abs_tol, monitor)
383 call this%precon_factory_(this%pc_prs, this%ksp_prs, &
384 this%c_Xh, this%dm_Xh, this%gs_Xh, this%bcs_prs, precon_type)
385
386 call neko_log%end_section()
387
388 end subroutine fluid_pnpn_init
389
390 subroutine fluid_pnpn_restart(this, dtlag, tlag)
391 class(fluid_pnpn_t), target, intent(inout) :: this
392 real(kind=rp) :: dtlag(10), tlag(10)
393 type(field_t) :: u_temp, v_temp, w_temp
394 integer :: i, j, n
395
396 n = this%u%dof%size()
397 if (allocated(this%chkp%previous_mesh%elements) .or. &
398 this%chkp%previous_Xh%lx .ne. this%Xh%lx) then
399 associate(u => this%u, v => this%v, w => this%w, p => this%p, &
400 c_xh => this%c_Xh, ulag => this%ulag, vlag => this%vlag, &
401 wlag => this%wlag)
402 do concurrent(j = 1:n)
403 u%x(j,1,1,1) = u%x(j,1,1,1) * c_xh%mult(j,1,1,1)
404 v%x(j,1,1,1) = v%x(j,1,1,1) * c_xh%mult(j,1,1,1)
405 w%x(j,1,1,1) = w%x(j,1,1,1) * c_xh%mult(j,1,1,1)
406 p%x(j,1,1,1) = p%x(j,1,1,1) * c_xh%mult(j,1,1,1)
407 end do
408 do i = 1, this%ulag%size()
409 do concurrent(j = 1:n)
410 ulag%lf(i)%x(j,1,1,1) = ulag%lf(i)%x(j,1,1,1) &
411 * c_xh%mult(j,1,1,1)
412 vlag%lf(i)%x(j,1,1,1) = vlag%lf(i)%x(j,1,1,1) &
413 * c_xh%mult(j,1,1,1)
414 wlag%lf(i)%x(j,1,1,1) = wlag%lf(i)%x(j,1,1,1) &
415 * c_xh%mult(j,1,1,1)
416 end do
417 end do
418 end associate
419 end if
420
421 if (neko_bcknd_device .eq. 1) then
422 associate(u => this%u, v => this%v, w => this%w, &
423 ulag => this%ulag, vlag => this%vlag, wlag => this%wlag,&
424 p => this%p)
425 call device_memcpy(u%x, u%x_d, u%dof%size(), &
426 host_to_device, sync = .false.)
427 call device_memcpy(v%x, v%x_d, v%dof%size(), &
428 host_to_device, sync = .false.)
429 call device_memcpy(w%x, w%x_d, w%dof%size(), &
430 host_to_device, sync = .false.)
431 call device_memcpy(p%x, p%x_d, p%dof%size(), &
432 host_to_device, sync = .false.)
433 call device_memcpy(ulag%lf(1)%x, ulag%lf(1)%x_d, &
434 u%dof%size(), host_to_device, sync = .false.)
435 call device_memcpy(ulag%lf(2)%x, ulag%lf(2)%x_d, &
436 u%dof%size(), host_to_device, sync = .false.)
437
438 call device_memcpy(vlag%lf(1)%x, vlag%lf(1)%x_d, &
439 v%dof%size(), host_to_device, sync = .false.)
440 call device_memcpy(vlag%lf(2)%x, vlag%lf(2)%x_d, &
441 v%dof%size(), host_to_device, sync = .false.)
442
443 call device_memcpy(wlag%lf(1)%x, wlag%lf(1)%x_d, &
444 w%dof%size(), host_to_device, sync = .false.)
445 call device_memcpy(wlag%lf(2)%x, wlag%lf(2)%x_d, &
446 w%dof%size(), host_to_device, sync = .false.)
447 call device_memcpy(this%abx1%x, this%abx1%x_d, &
448 w%dof%size(), host_to_device, sync = .false.)
449 call device_memcpy(this%abx2%x, this%abx2%x_d, &
450 w%dof%size(), host_to_device, sync = .false.)
451 call device_memcpy(this%aby1%x, this%aby1%x_d, &
452 w%dof%size(), host_to_device, sync = .false.)
453 call device_memcpy(this%aby2%x, this%aby2%x_d, &
454 w%dof%size(), host_to_device, sync = .false.)
455 call device_memcpy(this%abz1%x, this%abz1%x_d, &
456 w%dof%size(), host_to_device, sync = .false.)
457 call device_memcpy(this%abz2%x, this%abz2%x_d, &
458 w%dof%size(), host_to_device, sync = .false.)
459 call device_memcpy(this%advx%x, this%advx%x_d, &
460 w%dof%size(), host_to_device, sync = .false.)
461 call device_memcpy(this%advy%x, this%advy%x_d, &
462 w%dof%size(), host_to_device, sync = .false.)
463 call device_memcpy(this%advz%x, this%advz%x_d, &
464 w%dof%size(), host_to_device, sync = .false.)
465 end associate
466 end if
467 ! Make sure that continuity is maintained (important for interpolation)
468 ! Do not do this for lagged rhs
469 ! (derivatives are not necessairly coninous across elements)
470
471 if (allocated(this%chkp%previous_mesh%elements) &
472 .or. this%chkp%previous_Xh%lx .ne. this%Xh%lx) then
473 call this%gs_Xh%op(this%u, gs_op_add)
474 call this%gs_Xh%op(this%v, gs_op_add)
475 call this%gs_Xh%op(this%w, gs_op_add)
476 call this%gs_Xh%op(this%p, gs_op_add)
477
478 do i = 1, this%ulag%size()
479 call this%gs_Xh%op(this%ulag%lf(i), gs_op_add)
480 call this%gs_Xh%op(this%vlag%lf(i), gs_op_add)
481 call this%gs_Xh%op(this%wlag%lf(i), gs_op_add)
482 end do
483 end if
484
485 !! If we would decide to only restart from lagged fields instead of saving
486 !! abx1, aby1 etc.
487 !! Observe that one also needs to recompute the focing at the old time steps
488 !u_temp = this%ulag%lf(2)
489 !v_temp = this%vlag%lf(2)
490 !w_temp = this%wlag%lf(2)
491 !! Compute the source terms
492 !call this%source_term%compute(tlag(2), -1)
493 !
494 !! Pre-multiply the source terms with the mass matrix.
495 !if (NEKO_BCKND_DEVICE .eq. 1) then
496 ! call device_opcolv(this%f_x%x_d, this%f_y%x_d, this%f_z%x_d, &
497 ! this%c_Xh%B_d, this%msh%gdim, n)
498 !else
499 ! call opcolv(this%f_x%x, this%f_y%x, this%f_z%x, &
500 ! this%c_Xh%B, this%msh%gdim, n)
501 !end if
502
503 !! Add the advection operators to the right-hand-side.
504 !call this%adv%compute(u_temp, v_temp, w_temp, &
505 ! this%f_x%x, this%f_y%x, this%f_z%x, &
506 ! this%Xh, this%c_Xh, this%dm_Xh%size())
507 !this%abx2 = this%f_x
508 !this%aby2 = this%f_y
509 !this%abz2 = this%f_z
510 !
511 !u_temp = this%ulag%lf(1)
512 !v_temp = this%vlag%lf(1)
513 !w_temp = this%wlag%lf(1)
514 !call this%source_term%compute(tlag(1), 0)
515
516 !! Pre-multiply the source terms with the mass matrix.
517 !if (NEKO_BCKND_DEVICE .eq. 1) then
518 ! call device_opcolv(this%f_x%x_d, this%f_y%x_d, this%f_z%x_d, &
519 ! this%c_Xh%B_d, this%msh%gdim, n)
520 !else
521 ! call opcolv(this%f_x%x, this%f_y%x, this%f_z%x, &
522 ! this%c_Xh%B, this%msh%gdim, n)
523 !end if
524
525 !! Pre-multiply the source terms with the mass matrix.
526 !if (NEKO_BCKND_DEVICE .eq. 1) then
527 ! call device_opcolv(this%f_x%x_d, this%f_y%x_d, this%f_z%x_d, &
528 ! this%c_Xh%B_d, this%msh%gdim, n)
529 !else
530 ! call opcolv(this%f_x%x, this%f_y%x, this%f_z%x, &
531 ! this%c_Xh%B, this%msh%gdim, n)
532 !end if
533
534 !call this%adv%compute(u_temp, v_temp, w_temp, &
535 ! this%f_x%x, this%f_y%x, this%f_z%x, &
536 ! this%Xh, this%c_Xh, this%dm_Xh%size())
537 !this%abx1 = this%f_x
538 !this%aby1 = this%f_y
539 !this%abz1 = this%f_z
540
541 end subroutine fluid_pnpn_restart
542
543 subroutine fluid_pnpn_free(this)
544 class(fluid_pnpn_t), intent(inout) :: this
545
546 !Deallocate velocity and pressure fields
547 call this%scheme_free()
548
549 call this%bc_prs_surface%free()
550 call this%bc_sym_surface%free()
551 call this%bclst_vel_res%free()
552 call this%bclst_dp%free()
553 call this%proj_prs%free()
554 call this%proj_vel%free()
555
556 call this%p_res%free()
557 call this%u_res%free()
558 call this%v_res%free()
559 call this%w_res%free()
560
561 call this%du%free()
562 call this%dv%free()
563 call this%dw%free()
564 call this%dp%free()
565
566 call this%abx1%free()
567 call this%aby1%free()
568 call this%abz1%free()
569
570 call this%abx2%free()
571 call this%aby2%free()
572 call this%abz2%free()
573
574 call this%advx%free()
575 call this%advy%free()
576 call this%advz%free()
577
578 if (allocated(this%Ax_vel)) then
579 deallocate(this%Ax_vel)
580 end if
581
582 if (allocated(this%Ax_prs)) then
583 deallocate(this%Ax_prs)
584 end if
585
586 if (allocated(this%prs_res)) then
587 deallocate(this%prs_res)
588 end if
589
590 if (allocated(this%vel_res)) then
591 deallocate(this%vel_res)
592 end if
593
594 if (allocated(this%sumab)) then
595 deallocate(this%sumab)
596 end if
597
598 if (allocated(this%makeabf)) then
599 deallocate(this%makeabf)
600 end if
601
602 if (allocated(this%makebdf)) then
603 deallocate(this%makebdf)
604 end if
605
606 if (allocated(this%makeoifs)) then
607 deallocate(this%makeoifs)
608 end if
609
610 if (allocated(this%ext_bdf)) then
611 deallocate(this%ext_bdf)
612 end if
613
614 call this%vol_flow%free()
615
616 end subroutine fluid_pnpn_free
617
624 subroutine fluid_pnpn_step(this, t, tstep, dt, ext_bdf, dt_controller)
625 class(fluid_pnpn_t), target, intent(inout) :: this
626 real(kind=rp), intent(in) :: t
627 integer, intent(in) :: tstep
628 real(kind=rp), intent(in) :: dt
629 type(time_scheme_controller_t), intent(in) :: ext_bdf
630 type(time_step_controller_t), intent(in) :: dt_controller
631 ! number of degrees of freedom
632 integer :: n
633 ! Solver results monitors (pressure + 3 velocity)
634 type(ksp_monitor_t) :: ksp_results(4)
635
636 type(file_t) :: dump_file
637 class(bc_t), pointer :: bc_i
638 type(non_normal_t), pointer :: bc_j
639
640 if (this%freeze) return
641
642 n = this%dm_Xh%size()
643
644 call profiler_start_region('Fluid', 1)
645 associate(u => this%u, v => this%v, w => this%w, p => this%p, &
646 u_e => this%u_e, v_e => this%v_e, w_e => this%w_e, &
647 du => this%du, dv => this%dv, dw => this%dw, dp => this%dp, &
648 u_res => this%u_res, v_res => this%v_res, w_res => this%w_res, &
649 p_res => this%p_res, ax_vel => this%Ax_vel, ax_prs => this%Ax_prs, &
650 xh => this%Xh, &
651 c_xh => this%c_Xh, dm_xh => this%dm_Xh, gs_xh => this%gs_Xh, &
652 ulag => this%ulag, vlag => this%vlag, wlag => this%wlag, &
653 msh => this%msh, prs_res => this%prs_res, &
654 source_term => this%source_term, vel_res => this%vel_res, &
655 sumab => this%sumab, makeoifs => this%makeoifs, &
656 makeabf => this%makeabf, makebdf => this%makebdf, &
657 vel_projection_dim => this%vel_projection_dim, &
658 pr_projection_dim => this%pr_projection_dim, &
659 rho => this%rho, mu => this%mu, oifs => this%oifs, &
660 rho_field => this%rho_field, mu_field => this%mu_field, &
661 f_x => this%f_x, f_y => this%f_y, f_z => this%f_z, &
662 if_variable_dt => dt_controller%if_variable_dt, &
663 dt_last_change => dt_controller%dt_last_change, &
664 event => glb_cmd_event)
665
666 ! Extrapolate the velocity if it's not done in nut_field estimation
667 call sumab%compute_fluid(u_e, v_e, w_e, u, v, w, &
668 ulag, vlag, wlag, ext_bdf%advection_coeffs, ext_bdf%nadv)
669
670 ! Compute the source terms
671 call this%source_term%compute(t, tstep)
672
673 ! Add Neumann bc contributions to the RHS
674 call this%bcs_vel%apply_vector(f_x%x, f_y%x, f_z%x, &
675 this%dm_Xh%size(), t, tstep, strong = .false.)
676
677 ! Compute the gradient jump penalty term
678 if (this%if_gradient_jump_penalty .eqv. .true.) then
679 call this%gradient_jump_penalty_u%compute(u, v, w, u)
680 call this%gradient_jump_penalty_v%compute(u, v, w, v)
681 call this%gradient_jump_penalty_w%compute(u, v, w, w)
682 call this%gradient_jump_penalty_u%perform(f_x)
683 call this%gradient_jump_penalty_v%perform(f_y)
684 call this%gradient_jump_penalty_w%perform(f_z)
685 end if
686
687 if (oifs) then
688 ! Add the advection operators to the right-hand-side.
689 call this%adv%compute(u, v, w, &
690 this%advx, this%advy, this%advz, &
691 xh, this%c_Xh, dm_xh%size(), dt)
692
693 ! At this point the RHS contains the sum of the advection operator and
694 ! additional source terms, evaluated using the velocity field from the
695 ! previous time-step. Now, this value is used in the explicit time
696 ! scheme to advance both terms in time.
697 call makeabf%compute_fluid(this%abx1, this%aby1, this%abz1,&
698 this%abx2, this%aby2, this%abz2, &
699 f_x%x, f_y%x, f_z%x, &
700 rho, ext_bdf%advection_coeffs, n)
701
702 ! Now, the source terms from the previous time step are added to the RHS.
703 call makeoifs%compute_fluid(this%advx%x, this%advy%x, this%advz%x, &
704 f_x%x, f_y%x, f_z%x, &
705 rho, dt, n)
706 else
707 ! Add the advection operators to the right-hand-side.
708 call this%adv%compute(u, v, w, &
709 f_x, f_y, f_z, &
710 xh, this%c_Xh, dm_xh%size())
711
712 ! At this point the RHS contains the sum of the advection operator and
713 ! additional source terms, evaluated using the velocity field from the
714 ! previous time-step. Now, this value is used in the explicit time
715 ! scheme to advance both terms in time.
716 call makeabf%compute_fluid(this%abx1, this%aby1, this%abz1,&
717 this%abx2, this%aby2, this%abz2, &
718 f_x%x, f_y%x, f_z%x, &
719 rho, ext_bdf%advection_coeffs, n)
720
721 ! Add the RHS contributions coming from the BDF scheme.
722 call makebdf%compute_fluid(ulag, vlag, wlag, f_x%x, f_y%x, f_z%x, &
723 u, v, w, c_xh%B, rho, dt, &
724 ext_bdf%diffusion_coeffs, ext_bdf%ndiff, n)
725 end if
726
727 call ulag%update()
728 call vlag%update()
729 call wlag%update()
730
731 call this%bc_apply_vel(t, tstep, strong = .true.)
732 call this%bc_apply_prs(t, tstep)
733
734 ! Update material properties if necessary
735 call this%update_material_properties()
736
737 ! Compute pressure residual.
738 call profiler_start_region('Pressure_residual', 18)
739
740 call prs_res%compute(p, p_res,&
741 u, v, w, &
742 u_e, v_e, w_e, &
743 f_x, f_y, f_z, &
744 c_xh, gs_xh, &
745 this%bc_prs_surface, this%bc_sym_surface,&
746 ax_prs, ext_bdf%diffusion_coeffs(1), dt, &
747 mu_field, rho_field, event)
748
749 ! De-mean the pressure residual when no strong pressure boundaries present
750 if (.not. this%prs_dirichlet) call ortho(p_res%x, this%glb_n_points, n)
751
752 call gs_xh%op(p_res, gs_op_add, event)
753 if (neko_bcknd_device .eq. 1) then
754 call device_stream_wait_event(glb_cmd_queue, event, 0)
755 end if
756
757 ! Set the residual to zero at strong pressure boundaries.
758 call this%bclst_dp%apply_scalar(p_res%x, p%dof%size(), t, tstep)
759
760
761 call profiler_end_region('Pressure_residual', 18)
762
763
764 call this%proj_prs%pre_solving(p_res%x, tstep, c_xh, n, dt_controller, &
765 'Pressure')
766
767 call this%pc_prs%update()
768
769 call profiler_start_region('Pressure_solve', 3)
770
771 ! Solve for the pressure increment.
772 ksp_results(1) = &
773 this%ksp_prs%solve(ax_prs, dp, p_res%x, n, c_xh, this%bclst_dp, gs_xh)
774
775
776 call profiler_end_region('Pressure_solve', 3)
777
778 call this%proj_prs%post_solving(dp%x, ax_prs, c_xh, &
779 this%bclst_dp, gs_xh, n, tstep, dt_controller)
780
781 ! Update the pressure with the increment. Demean if necessary.
782 call field_add2(p, dp, n)
783 if (.not. this%prs_dirichlet) call ortho(p%x, this%glb_n_points, n)
784
785 ! Compute velocity residual.
786 call profiler_start_region('Velocity_residual', 19)
787 call vel_res%compute(ax_vel, u, v, w, &
788 u_res, v_res, w_res, &
789 p, &
790 f_x, f_y, f_z, &
791 c_xh, msh, xh, &
792 mu_field, rho_field, ext_bdf%diffusion_coeffs(1), &
793 dt, dm_xh%size())
794
795 call gs_xh%op(u_res, gs_op_add, event)
796 call gs_xh%op(v_res, gs_op_add, event)
797 call gs_xh%op(w_res, gs_op_add, event)
798 if (neko_bcknd_device .eq. 1) then
799 call device_stream_wait_event(glb_cmd_queue, event, 0)
800 end if
801
802 ! Set residual to zero at strong velocity boundaries.
803 call this%bclst_vel_res%apply(u_res, v_res, w_res, t, tstep)
804
805
806 call profiler_end_region('Velocity_residual', 19)
807
808 call this%proj_vel%pre_solving(u_res%x, v_res%x, w_res%x, &
809 tstep, c_xh, n, dt_controller, 'Velocity')
810
811 call this%pc_vel%update()
812
813 call profiler_start_region("Velocity_solve", 4)
814 ksp_results(2:4) = this%ksp_vel%solve_coupled(ax_vel, du, dv, dw, &
815 u_res%x, v_res%x, w_res%x, n, c_xh, &
816 this%bclst_du, this%bclst_dv, this%bclst_dw, gs_xh, &
817 this%ksp_vel%max_iter)
818 call profiler_end_region("Velocity_solve", 4)
819
820 call this%proj_vel%post_solving(du%x, dv%x, dw%x, ax_vel, c_xh, &
821 this%bclst_du, this%bclst_dv, this%bclst_dw, gs_xh, n, tstep, &
822 dt_controller)
823
824 if (neko_bcknd_device .eq. 1) then
825 call device_opadd2cm(u%x_d, v%x_d, w%x_d, &
826 du%x_d, dv%x_d, dw%x_d, 1.0_rp, n, msh%gdim)
827 else
828 call opadd2cm(u%x, v%x, w%x, du%x, dv%x, dw%x, 1.0_rp, n, msh%gdim)
829 end if
830
831 if (this%forced_flow_rate) then
832 call this%vol_flow%adjust( u, v, w, p, u_res, v_res, w_res, p_res, &
833 c_xh, gs_xh, ext_bdf, rho, mu, dt, &
834 this%bclst_dp, this%bclst_du, this%bclst_dv, &
835 this%bclst_dw, this%bclst_vel_res, ax_vel, ax_prs, this%ksp_prs, &
836 this%ksp_vel, this%pc_prs, this%pc_vel, this%ksp_prs%max_iter, &
837 this%ksp_vel%max_iter)
838 end if
839
840 call fluid_step_info(tstep, t, dt, ksp_results, this%strict_convergence)
841
842 end associate
843 call profiler_end_region('Fluid', 1)
844 end subroutine fluid_pnpn_step
845
848 subroutine fluid_pnpn_setup_bcs(this, user, params)
849 class(fluid_pnpn_t), intent(inout) :: this
850 type(user_t), target, intent(in) :: user
851 type(json_file), intent(inout) :: params
852 integer :: i, n_bcs, zone_index, j, zone_size, global_zone_size, ierr
853 class(bc_t), pointer :: bc_i
854 type(json_core) :: core
855 type(json_value), pointer :: bc_object
856 type(json_file) :: bc_subdict
857 logical :: found
858 ! Monitor which boundary zones have been marked
859 logical, allocatable :: marked_zones(:)
860 integer, allocatable :: zone_indices(:)
861
862 ! Lists for the residuals and solution increments
863 call this%bclst_vel_res%init()
864 call this%bclst_du%init()
865 call this%bclst_dv%init()
866 call this%bclst_dw%init()
867 call this%bclst_dp%init()
868
869 call this%bc_vel_res%init_from_components(this%c_Xh)
870 call this%bc_du%init_from_components(this%c_Xh)
871 call this%bc_dv%init_from_components(this%c_Xh)
872 call this%bc_dw%init_from_components(this%c_Xh)
873 call this%bc_dp%init_from_components(this%c_Xh)
874
875 ! Special PnPn boundary conditions for pressure
876 call this%bc_prs_surface%init_from_components(this%c_Xh)
877 call this%bc_sym_surface%init_from_components(this%c_Xh)
878
879 ! Populate bcs_vel and bcs_prs based on the case file
880 if (params%valid_path('case.fluid.boundary_conditions')) then
881 call params%info('case.fluid.boundary_conditions', n_children = n_bcs)
882 call params%get_core(core)
883 call params%get('case.fluid.boundary_conditions', bc_object, found)
884
885 !
886 ! Velocity bcs
887 !
888 call this%bcs_vel%init(n_bcs)
889
890 allocate(marked_zones(size(this%msh%labeled_zones)))
891 marked_zones = .false.
892
893 do i = 1, n_bcs
894 ! Create a new json containing just the subdict for this bc
895 call json_extract_item(core, bc_object, i, bc_subdict)
896
897 call json_get(bc_subdict, "zone_indices", zone_indices)
898
899 ! Check that we are not trying to assing a bc to zone, for which one
900 ! has already been assigned and that the zone has more than 0 size
901 ! in the mesh.
902 do j = 1, size(zone_indices)
903 zone_size = this%msh%labeled_zones(zone_indices(j))%size
904 call mpi_allreduce(zone_size, global_zone_size, 1, &
905 mpi_integer, mpi_max, neko_comm, ierr)
906
907 if (global_zone_size .eq. 0) then
908 write(error_unit, '(A, A, I0, A, A, I0, A)') "*** ERROR ***: ",&
909 "Zone index ", zone_indices(j), &
910 " is invalid as this zone has 0 size, meaning it ", &
911 "is not in the mesh. Check fluid boundary condition ", &
912 i, "."
913 error stop
914 end if
915
916 if (marked_zones(zone_indices(j)) .eqv. .true.) then
917 write(error_unit, '(A, A, I0, A, A, A, A)') "*** ERROR ***: ", &
918 "Zone with index ", zone_indices(j), &
919 " has already been assigned a boundary condition. ", &
920 "Please check your boundary_conditions entry for the ", &
921 "fluid and make sure that each zone index appears only ", &
922 "in a single boundary condition."
923 error stop
924 else
925 marked_zones(zone_indices(j)) = .true.
926 end if
927 end do
928
929 bc_i => null()
930 call velocity_bc_factory(bc_i, this, bc_subdict, this%c_Xh, user)
931
932 ! Not all bcs require an allocation for velocity in particular,
933 ! so we check.
934 if (associated(bc_i)) then
935
936 ! We need to treat mixed bcs separately because they are by
937 ! convention marked weak and currently contain nested
938 ! bcs, some of which are strong.
939 select type (bc_i)
940 type is (symmetry_t)
941 ! Symmetry has 3 internal bcs, but only one actually contains
942 ! markings.
943 ! Symmetry's apply_scalar doesn't do anything, so we need to mark
944 ! individual nested bcs to the du,dv,dw, whereas the vel_res can
945 ! just get symmetry as a whole, because on this list we call
946 ! apply_vector.
947 ! Additionally we have to mark the special surface bc for p.
948 call this%bclst_vel_res%append(bc_i)
949 call this%bc_du%mark_facets(bc_i%bc_x%marked_facet)
950 call this%bc_dv%mark_facets(bc_i%bc_y%marked_facet)
951 call this%bc_dw%mark_facets(bc_i%bc_z%marked_facet)
952
953 call this%bcs_vel%append(bc_i)
954
955 call this%bc_sym_surface%mark_facets(bc_i%marked_facet)
956 type is (non_normal_t)
957 ! This is a bc for the residuals and increments, not the
958 ! velocity itself. So, don't append to bcs_vel
959 call this%bclst_vel_res%append(bc_i)
960 call this%bc_du%mark_facets(bc_i%bc_x%marked_facet)
961 call this%bc_dv%mark_facets(bc_i%bc_y%marked_facet)
962 call this%bc_dw%mark_facets(bc_i%bc_z%marked_facet)
963 type is (shear_stress_t)
964 ! Same as symmetry
965 call this%bclst_vel_res%append(bc_i%symmetry)
966 call this%bclst_du%append(bc_i%symmetry%bc_x)
967 call this%bclst_dv%append(bc_i%symmetry%bc_y)
968 call this%bclst_dw%append(bc_i%symmetry%bc_z)
969
970 call this%bcs_vel%append(bc_i)
971 type is (wall_model_bc_t)
972 ! Same as symmetry
973 call this%bclst_vel_res%append(bc_i%symmetry)
974 call this%bclst_du%append(bc_i%symmetry%bc_x)
975 call this%bclst_dv%append(bc_i%symmetry%bc_y)
976 call this%bclst_dw%append(bc_i%symmetry%bc_z)
977
978 call this%bcs_vel%append(bc_i)
979 class default
980
981 ! For the default case we use our dummy zero_dirichlet bcs to
982 ! mark the same faces as in ordinary velocity dirichlet
983 ! conditions.
984 ! Additionally we mark the special PnPn pressure bc.
985 if (bc_i%strong .eqv. .true.) then
986 call this%bc_vel_res%mark_facets(bc_i%marked_facet)
987 call this%bc_du%mark_facets(bc_i%marked_facet)
988 call this%bc_dv%mark_facets(bc_i%marked_facet)
989 call this%bc_dw%mark_facets(bc_i%marked_facet)
990
991 call this%bc_prs_surface%mark_facets(bc_i%marked_facet)
992 end if
993
994 call this%bcs_vel%append(bc_i)
995 end select
996 end if
997 end do
998
999 ! Make sure all labeled zones with non-zero size have been marked
1000 do i = 1, size(this%msh%labeled_zones)
1001 if ((this%msh%labeled_zones(i)%size .gt. 0) .and. &
1002 (marked_zones(i) .eqv. .false.)) then
1003 write(error_unit, '(A, A, I0)') "*** ERROR ***: ", &
1004 "No fluid boundary condition assigned to zone ", i
1005 error stop
1006 end if
1007 end do
1008
1009 !
1010 ! Pressure bcs
1011 !
1012 call this%bcs_prs%init(n_bcs)
1013
1014 do i = 1, n_bcs
1015 ! Create a new json containing just the subdict for this bc
1016 call json_extract_item(core, bc_object, i, bc_subdict)
1017 bc_i => null()
1018 call pressure_bc_factory(bc_i, this, bc_subdict, this%c_Xh, user)
1019
1020 ! Not all bcs require an allocation for pressure in particular,
1021 ! so we check.
1022 if (associated(bc_i)) then
1023 call this%bcs_prs%append(bc_i)
1024
1025 ! Mark strong bcs in the dummy dp bc to force zero change.
1026 if (bc_i%strong .eqv. .true.) then
1027 call this%bc_dp%mark_facets(bc_i%marked_facet)
1028 end if
1029
1030 end if
1031
1032 end do
1033 else
1034 ! Check that there are no labeled zones, i.e. all are periodic.
1035 do i = 1, size(this%msh%labeled_zones)
1036 if (this%msh%labeled_zones(i)%size .gt. 0) then
1037 call neko_error("No boundary_conditions entry in the case file!")
1038 end if
1039 end do
1040
1041 end if
1042
1043 call this%bc_prs_surface%finalize()
1044 call this%bc_sym_surface%finalize()
1045
1046 call this%bc_vel_res%finalize()
1047 call this%bc_du%finalize()
1048 call this%bc_dv%finalize()
1049 call this%bc_dw%finalize()
1050 call this%bc_dp%finalize()
1051
1052 call this%bclst_vel_res%append(this%bc_vel_res)
1053 call this%bclst_du%append(this%bc_du)
1054 call this%bclst_dv%append(this%bc_dv)
1055 call this%bclst_dw%append(this%bc_dw)
1056 call this%bclst_dp%append(this%bc_dp)
1057
1058 ! If we have no strong pressure bcs, we will demean the pressure
1059 this%prs_dirichlet = .not. this%bclst_dp%is_empty()
1060 call mpi_allreduce(mpi_in_place, this%prs_dirichlet, 1, &
1061 mpi_logical, mpi_lor, neko_comm)
1062
1063 end subroutine fluid_pnpn_setup_bcs
1064
1066 subroutine fluid_pnpn_write_boundary_conditions(this)
1067 use inflow, only : inflow_t
1069 use blasius, only : blasius_t
1071 use usr_inflow, only : usr_inflow_t
1072 use dong_outflow, only : dong_outflow_t
1073 class(fluid_pnpn_t), target, intent(inout) :: this
1074 type(dirichlet_t) :: bdry_mask
1075 type(field_t), pointer :: bdry_field
1076 type(file_t) :: bdry_file
1077 integer :: temp_index, i
1078 class(bc_t), pointer :: bci
1079 character(len=LOG_SIZE) :: log_buf
1080
1081 call neko_log%section("Fluid boundary conditions")
1082 write(log_buf, '(A)') 'Marking using integer keys in bdry0.f00000'
1083 call neko_log%message(log_buf)
1084 write(log_buf, '(A)') 'Condition-value pairs: '
1085 call neko_log%message(log_buf)
1086 write(log_buf, '(A)') ' no_slip = 1'
1087 call neko_log%message(log_buf)
1088 write(log_buf, '(A)') ' velocity_value = 2'
1089 call neko_log%message(log_buf)
1090 write(log_buf, '(A)') ' outflow, normal_outflow (+dong) = 3'
1091 call neko_log%message(log_buf)
1092 write(log_buf, '(A)') ' symmetry = 4'
1093 call neko_log%message(log_buf)
1094 write(log_buf, '(A)') ' user_velocity_pointwise = 5'
1095 call neko_log%message(log_buf)
1096 write(log_buf, '(A)') ' periodic = 6'
1097 call neko_log%message(log_buf)
1098 write(log_buf, '(A)') ' user_velocity = 7'
1099 call neko_log%message(log_buf)
1100 write(log_buf, '(A)') ' user_pressure = 8'
1101 call neko_log%message(log_buf)
1102 write(log_buf, '(A)') ' shear_stress = 9'
1103 call neko_log%message(log_buf)
1104 write(log_buf, '(A)') ' wall_modelling = 10'
1105 call neko_log%message(log_buf)
1106 write(log_buf, '(A)') ' blasius_profile = 11'
1107 call neko_log%message(log_buf)
1108 call neko_log%end_section()
1109
1110 call this%scratch%request_field(bdry_field, temp_index)
1111 bdry_field = 0.0_rp
1112
1113
1114
1115 call bdry_mask%init_from_components(this%c_Xh, 6.0_rp)
1116 call bdry_mask%mark_zone(this%msh%periodic)
1117 call bdry_mask%finalize()
1118 call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
1119 call bdry_mask%free()
1120
1121 do i = 1, this%bcs_prs%size()
1122 bci => this%bcs_prs%get(i)
1123 select type (bc => bci)
1124 type is (zero_dirichlet_t)
1125 call bdry_mask%init_from_components(this%c_Xh, 3.0_rp)
1126 call bdry_mask%mark_facets(bci%marked_facet)
1127 call bdry_mask%finalize()
1128 call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
1129 call bdry_mask%free()
1130 type is (dong_outflow_t)
1131 call bdry_mask%init_from_components(this%c_Xh, 3.0_rp)
1132 call bdry_mask%mark_facets(bci%marked_facet)
1133 call bdry_mask%finalize()
1134 call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
1135 call bdry_mask%free()
1136 type is (field_dirichlet_t)
1137 call bdry_mask%init_from_components(this%c_Xh, 8.0_rp)
1138 call bdry_mask%mark_facets(bci%marked_facet)
1139 call bdry_mask%finalize()
1140 call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
1141 call bdry_mask%free()
1142 end select
1143 end do
1144
1145 do i = 1, this%bcs_vel%size()
1146 bci => this%bcs_vel%get(i)
1147 select type (bc => bci)
1148 type is (zero_dirichlet_t)
1149 call bdry_mask%init_from_components(this%c_Xh, 1.0_rp)
1150 call bdry_mask%mark_facets(bci%marked_facet)
1151 call bdry_mask%finalize()
1152 call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
1153 call bdry_mask%free()
1154 type is (inflow_t)
1155 call bdry_mask%init_from_components(this%c_Xh, 2.0_rp)
1156 call bdry_mask%mark_facets(bci%marked_facet)
1157 call bdry_mask%finalize()
1158 call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
1159 call bdry_mask%free()
1160 type is (symmetry_t)
1161 call bdry_mask%init_from_components(this%c_Xh, 4.0_rp)
1162 call bdry_mask%mark_facets(bci%marked_facet)
1163 call bdry_mask%finalize()
1164 call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
1165 call bdry_mask%free()
1166 type is (usr_inflow_t)
1167 call bdry_mask%init_from_components(this%c_Xh, 5.0_rp)
1168 call bdry_mask%mark_facets(bci%marked_facet)
1169 call bdry_mask%finalize()
1170 call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
1171 call bdry_mask%free()
1172 type is (field_dirichlet_vector_t)
1173 call bdry_mask%init_from_components(this%c_Xh, 7.0_rp)
1174 call bdry_mask%mark_facets(bci%marked_facet)
1175 call bdry_mask%finalize()
1176 call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
1177 call bdry_mask%free()
1178 type is (shear_stress_t)
1179 call bdry_mask%init_from_components(this%c_Xh, 9.0_rp)
1180 call bdry_mask%mark_facets(bci%marked_facet)
1181 call bdry_mask%finalize()
1182 call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
1183 call bdry_mask%free()
1184 type is (wall_model_bc_t)
1185 call bdry_mask%init_from_components(this%c_Xh, 10.0_rp)
1186 call bdry_mask%mark_facets(bci%marked_facet)
1187 call bdry_mask%finalize()
1188 call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
1189 call bdry_mask%free()
1190 type is (blasius_t)
1191 call bdry_mask%init_from_components(this%c_Xh, 11.0_rp)
1192 call bdry_mask%mark_facets(bci%marked_facet)
1193 call bdry_mask%finalize()
1194 call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
1195 call bdry_mask%free()
1196 end select
1197 end do
1198
1199
1200 bdry_file = file_t('bdry.fld')
1201 call bdry_file%write(bdry_field)
1202
1203 call this%scratch%relinquish_field(temp_index)
1204 end subroutine fluid_pnpn_write_boundary_conditions
1205
1206end module fluid_pnpn
Copy data between host and device (or device and device)
Definition device.F90:65
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.
Subroutines to add advection terms to the RHS of a transport equation.
Definition advection.f90:34
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
Coefficients.
Definition coef.f90:34
Definition comm.F90:1
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:1244
integer, parameter, public host_to_device
Definition device.F90:46
subroutine, public device_stream_wait_event(stream, event, flags)
Synchronize a device stream with an event.
Definition device.F90:1138
type(c_ptr), bind(C), public glb_cmd_queue
Global command queue.
Definition device.F90:50
type(c_ptr), bind(C), public glb_cmd_event
Event for the global command queue.
Definition device.F90:56
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 .
Defines a registry for storing solution fields.
type(field_registry_t), target, public neko_field_registry
Global field registry.
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:2
subroutine, public fluid_step_info(step, t, dt, ksp_results, strict_convergence)
Prints for prs, velx, vely, velz the following: Number of iterations, start residual,...
Definition fluid_aux.f90:18
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_step(this, t, tstep, dt, ext_bdf, dt_controller)
Advance fluid simulation in time.
subroutine fluid_pnpn_write_boundary_conditions(this)
Write a field with boundary condition specifications.
subroutine fluid_pnpn_free(this)
subroutine fluid_pnpn_restart(this, dtlag, tlag)
subroutine fluid_pnpn_init(this, msh, lx, params, user)
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:65
integer, parameter, public log_size
Definition log.f90:42
Collection of vector field operations operating on and . Note that in general the indices and ....
Definition mathops.f90:65
subroutine, public opcolv(a1, a2, a3, c, gdim, n)
Definition mathops.f90:97
subroutine, public opadd2cm(a1, a2, a3, b1, b2, b3, c, n, gdim)
Definition mathops.f90:142
Defines a mesh.
Definition mesh.f90:34
Build configurations.
integer, parameter neko_bcknd_device
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.
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:78
subroutine, public profiler_end_region(name, region_id)
End the most recently started profiler region.
Definition profiler.F90:109
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.
Routines to generate the right-hand sides for the convection-diffusion equation. Employs the EXT/BDF ...
Definition rhs_maker.f90:38
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
Compound scheme for the advection and diffusion operators in a transport equation.
Implements type time_step_controller.
Interfaces for user interaction with NEKO.
Definition user_intf.f90:34
Defines inflow dirichlet conditions.
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:250
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:57
A list of allocatable `bc_t`. Follows the standard interface of lists.
Definition bc_list.f90:47
Blasius profile for inlet (vector valued).
Definition blasius.f90:52
Coefficients defined on a given (mesh, ) tuple. Arrays use indices (i,j,k,e): element e,...
Definition coef.f90:55
Generic Dirichlet boundary condition on .
Definition dirichlet.f90:47
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
A wrapper around a polymorphic generic_file_t that handles its init. This is essentially a factory fo...
Definition file.f90:54
Dirichlet condition for inlet (vector valued)
Definition inflow.f90:46
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:49
Implements the logic to compute the time coefficients for the advection and diffusion operators in a ...
User defined dirichlet condition for velocity.
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...