Neko 0.9.99
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-2024, 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 num_types, only : rp
36 use krylov, only : ksp_monitor_t
38 pnpn_prs_res_factory, pnpn_vel_res_factory, &
39 pnpn_prs_res_stress_factory, pnpn_vel_res_stress_factory
41 rhs_maker_oifs_t, rhs_maker_sumab_fctry, rhs_maker_bdf_fctry, &
42 rhs_maker_ext_fctry, rhs_maker_oifs_fctry
46 use fluid_aux, only : fluid_step_info
48 use projection, only : projection_t
50 use advection, only : advection_t, advection_factory
53 use json_module, only : json_file
54 use ax_product, only : ax_t, ax_helm_factory
55 use field, only : field_t
56 use dirichlet, only : dirichlet_t
58 use non_normal, only : non_normal_t
59 use comm
60 use mesh, only : mesh_t
61 use user_intf, only : user_t
63 use gs_ops, only : gs_op_add
65 use mathops, only : opadd2cm, opcolv
66 use bc_list, only : bc_list_t
67 use utils, only : neko_error
69 use operators, only : ortho
70 implicit none
71 private
72
73
74 type, public, extends(fluid_scheme_t) :: fluid_pnpn_t
75 type(field_t) :: p_res, u_res, v_res, w_res
76
77 type(field_t) :: dp, du, dv, dw
78
79 ! Coupled Helmholz operator for velocity
80 class(ax_t), allocatable :: ax_vel
81 ! Helmholz operator for pressure
82 class(ax_t), allocatable :: ax_prs
83
84 type(projection_t) :: proj_prs
85 type(projection_t) :: proj_u
86 type(projection_t) :: proj_v
87 type(projection_t) :: proj_w
88
89 type(facet_normal_t) :: bc_prs_surface
90 type(facet_normal_t) :: bc_sym_surface
91 type(dirichlet_t) :: bc_vel_res
92 type(dirichlet_t) :: bc_field_dirichlet_p
93 type(dirichlet_t) :: bc_field_dirichlet_u
94 type(dirichlet_t) :: bc_field_dirichlet_v
95 type(dirichlet_t) :: bc_field_dirichlet_w
96 type(non_normal_t) :: bc_vel_res_non_normal
97 type(bc_list_t) :: bclst_vel_res
98 type(bc_list_t) :: bclst_du
99 type(bc_list_t) :: bclst_dv
100 type(bc_list_t) :: bclst_dw
101 type(bc_list_t) :: bclst_dp
102
103 logical :: prs_dirichlet = .false.
104
105 class(advection_t), allocatable :: adv
106
107 ! Time interpolation scheme
108 logical :: oifs
109
110 ! Time variables
111 type(field_t) :: abx1, aby1, abz1
112 type(field_t) :: abx2, aby2, abz2
113 ! Advection terms for the oifs method
114 type(field_t) :: advx, advy, advz
115
117 class(pnpn_prs_res_t), allocatable :: prs_res
118
120 class(pnpn_vel_res_t), allocatable :: vel_res
121
123 class(rhs_maker_sumab_t), allocatable :: sumab
124
126 class(rhs_maker_ext_t), allocatable :: makeabf
127
129 class(rhs_maker_bdf_t), allocatable :: makebdf
130
132 class(rhs_maker_oifs_t), allocatable :: makeoifs
133
135 type(fluid_volflow_t) :: vol_flow
136
137 contains
138 procedure, pass(this) :: init => fluid_pnpn_init
139 procedure, pass(this) :: free => fluid_pnpn_free
140 procedure, pass(this) :: step => fluid_pnpn_step
141 procedure, pass(this) :: restart => fluid_pnpn_restart
142 end type fluid_pnpn_t
143
144contains
145
146 subroutine fluid_pnpn_init(this, msh, lx, params, user, time_scheme)
147 class(fluid_pnpn_t), target, intent(inout) :: this
148 type(mesh_t), target, intent(inout) :: msh
149 integer, intent(in) :: lx
150 type(json_file), target, intent(inout) :: params
151 type(user_t), target, intent(in) :: user
152 type(time_scheme_controller_t), target, intent(in) :: time_scheme
153 character(len=15), parameter :: scheme = 'Modular (Pn/Pn)'
154 logical :: advection
155
156 call this%free()
157
158 ! Initialize base class
159 call this%scheme_init(msh, lx, params, .true., .true., scheme, user)
160
161 if (this%variable_material_properties .eqv. .true.) then
162 ! Setup backend dependent Ax routines
163 call ax_helm_factory(this%Ax_vel, full_formulation = .true.)
164
165 ! Setup backend dependent prs residual routines
166 call pnpn_prs_res_stress_factory(this%prs_res)
167
168 ! Setup backend dependent vel residual routines
169 call pnpn_vel_res_stress_factory(this%vel_res)
170 else
171 ! Setup backend dependent Ax routines
172 call ax_helm_factory(this%Ax_vel, full_formulation = .false.)
173
174 ! Setup backend dependent prs residual routines
175 call pnpn_prs_res_factory(this%prs_res)
176
177 ! Setup backend dependent vel residual routines
178 call pnpn_vel_res_factory(this%vel_res)
179 end if
180
181 ! Setup Ax for the pressure
182 call ax_helm_factory(this%Ax_prs, full_formulation = .false.)
183
184
185 ! Setup backend dependent summation of AB/BDF
186 call rhs_maker_sumab_fctry(this%sumab)
187
188 ! Setup backend dependent summation of extrapolation scheme
189 call rhs_maker_ext_fctry(this%makeabf)
190
191 ! Setup backend depenent contributions to F from lagged BD terms
192 call rhs_maker_bdf_fctry(this%makebdf)
193
194 ! Setup backend dependent summations of the OIFS method
195 call rhs_maker_oifs_fctry(this%makeoifs)
196
197 ! Initialize variables specific to this plan
198 associate(xh_lx => this%Xh%lx, xh_ly => this%Xh%ly, xh_lz => this%Xh%lz, &
199 dm_xh => this%dm_Xh, nelv => this%msh%nelv)
200
201 call this%p_res%init(dm_xh, "p_res")
202 call this%u_res%init(dm_xh, "u_res")
203 call this%v_res%init(dm_xh, "v_res")
204 call this%w_res%init(dm_xh, "w_res")
205 call this%abx1%init(dm_xh, "abx1")
206 call this%aby1%init(dm_xh, "aby1")
207 call this%abz1%init(dm_xh, "abz1")
208 call this%abx2%init(dm_xh, "abx2")
209 call this%aby2%init(dm_xh, "aby2")
210 call this%abz2%init(dm_xh, "abz2")
211 call this%advx%init(dm_xh, "advx")
212 call this%advy%init(dm_xh, "advy")
213 call this%advz%init(dm_xh, "advz")
214 this%abx1 = 0.0_rp
215 this%aby1 = 0.0_rp
216 this%abz1 = 0.0_rp
217 this%abx2 = 0.0_rp
218 this%aby2 = 0.0_rp
219 this%abz2 = 0.0_rp
220 this%advx = 0.0_rp
221 this%advy = 0.0_rp
222 this%advz = 0.0_rp
223
224 call this%du%init(dm_xh, 'du')
225 call this%dv%init(dm_xh, 'dv')
226 call this%dw%init(dm_xh, 'dw')
227 call this%dp%init(dm_xh, 'dp')
228
229 end associate
230
231 ! Initialize velocity surface terms in pressure rhs
232 call this%bc_prs_surface%init_base(this%c_Xh)
233 call this%bc_prs_surface%mark_zone(msh%inlet)
234 call this%bc_prs_surface%mark_zones_from_list(msh%labeled_zones,&
235 'v', this%bc_labels)
236 ! This impacts the rhs of the pressure,
237 ! need to check what is correct to add here
238 call this%bc_prs_surface%mark_zones_from_list(msh%labeled_zones,&
239 'd_vel_u', this%bc_labels)
240 call this%bc_prs_surface%mark_zones_from_list(msh%labeled_zones,&
241 'd_vel_v', this%bc_labels)
242 call this%bc_prs_surface%mark_zones_from_list(msh%labeled_zones,&
243 'd_vel_w', this%bc_labels)
244 call this%bc_prs_surface%finalize()
245 ! Initialize symmetry surface terms in pressure rhs
246 call this%bc_sym_surface%init_base(this%c_Xh)
247 call this%bc_sym_surface%mark_zone(msh%sympln)
248 call this%bc_sym_surface%mark_zones_from_list(msh%labeled_zones,&
249 'sym', this%bc_labels)
250 ! Same here, should du, dv, dw be marked here?
251 call this%bc_sym_surface%finalize()
252 ! Initialize dirichlet bcs for velocity residual
253 call this%bc_vel_res_non_normal%init_base(this%c_Xh)
254 call this%bc_vel_res_non_normal%mark_zone(msh%outlet_normal)
255 call this%bc_vel_res_non_normal%mark_zones_from_list(msh%labeled_zones,&
256 'on', this%bc_labels)
257 call this%bc_vel_res_non_normal%mark_zones_from_list(msh%labeled_zones,&
258 'on+dong', &
259 this%bc_labels)
260 call this%bc_vel_res_non_normal%finalize()
261 call this%bc_vel_res_non_normal%init(this%c_Xh)
262
263 call this%bc_field_dirichlet_p%init_base(this%c_Xh)
264 call this%bc_field_dirichlet_p%mark_zones_from_list(msh%labeled_zones, &
265 'on+dong', this%bc_labels)
266 call this%bc_field_dirichlet_p%mark_zones_from_list(msh%labeled_zones, &
267 'o+dong', this%bc_labels)
268 call this%bc_field_dirichlet_p%mark_zones_from_list(msh%labeled_zones, &
269 'd_pres', this%bc_labels)
270 call this%bc_field_dirichlet_p%finalize()
271 call this%bc_field_dirichlet_p%set_g(0.0_rp)
272 call this%bclst_dp%init()
273 call this%bclst_dp%append(this%bc_field_dirichlet_p)
274 !Add 0 prs bcs
275 call this%bclst_dp%append(this%bc_prs)
276
277 this%prs_dirichlet = .not. this%bclst_dp%is_empty()
278
279 call mpi_allreduce(mpi_in_place, this%prs_dirichlet, 1, &
280 mpi_logical, mpi_lor, neko_comm)
281
282
283 call this%bc_field_dirichlet_u%init_base(this%c_Xh)
284 call this%bc_field_dirichlet_u%mark_zones_from_list( &
285 msh%labeled_zones, 'd_vel_u', this%bc_labels)
286 call this%bc_field_dirichlet_u%finalize()
287 call this%bc_field_dirichlet_u%set_g(0.0_rp)
288
289 call this%bc_field_dirichlet_v%init_base(this%c_Xh)
290 call this%bc_field_dirichlet_v%mark_zones_from_list(msh%labeled_zones, &
291 'd_vel_v', &
292 this%bc_labels)
293 call this%bc_field_dirichlet_v%finalize()
294 call this%bc_field_dirichlet_v%set_g(0.0_rp)
295
296 call this%bc_field_dirichlet_w%init_base(this%c_Xh)
297 call this%bc_field_dirichlet_w%mark_zones_from_list(msh%labeled_zones, &
298 'd_vel_w', &
299 this%bc_labels)
300 call this%bc_field_dirichlet_w%finalize()
301 call this%bc_field_dirichlet_w%set_g(0.0_rp)
302
303 call this%bc_vel_res%init_base(this%c_Xh)
304 call this%bc_vel_res%mark_zone(msh%inlet)
305 call this%bc_vel_res%mark_zone(msh%wall)
306 call this%bc_vel_res%mark_zones_from_list(msh%labeled_zones, &
307 'v', this%bc_labels)
308 call this%bc_vel_res%mark_zones_from_list(msh%labeled_zones, &
309 'w', this%bc_labels)
310 call this%bc_vel_res%finalize()
311 call this%bc_vel_res%set_g(0.0_rp)
312 call this%bclst_vel_res%init()
313 call this%bclst_vel_res%append(this%bc_vel_res)
314 call this%bclst_vel_res%append(this%bc_vel_res_non_normal)
315 call this%bclst_vel_res%append(this%bc_sym)
316 call this%bclst_vel_res%append(this%bc_sh%symmetry)
317 call this%bclst_vel_res%append(this%bc_wallmodel%symmetry)
318
319 !Initialize bcs for u, v, w velocity components
320 call this%bclst_du%init()
321 call this%bclst_du%append(this%bc_sym%bc_x)
322 call this%bclst_du%append(this%bc_sh%symmetry%bc_x)
323 call this%bclst_du%append(this%bc_wallmodel%symmetry%bc_x)
324 call this%bclst_du%append(this%bc_vel_res_non_normal%bc_x)
325 call this%bclst_du%append(this%bc_vel_res)
326 call this%bclst_du%append(this%bc_field_dirichlet_u)
327
328 call this%bclst_dv%init()
329 call this%bclst_dv%append(this%bc_sym%bc_y)
330 call this%bclst_dv%append(this%bc_sh%symmetry%bc_y)
331 call this%bclst_dv%append(this%bc_wallmodel%symmetry%bc_y)
332 call this%bclst_dv%append(this%bc_vel_res_non_normal%bc_y)
333 call this%bclst_dv%append(this%bc_vel_res)
334 call this%bclst_dv%append(this%bc_field_dirichlet_v)
335
336 call this%bclst_dw%init()
337 call this%bclst_dw%append(this%bc_sym%bc_z)
338 call this%bclst_dw%append(this%bc_sh%symmetry%bc_z)
339 call this%bclst_dw%append(this%bc_wallmodel%symmetry%bc_z)
340 call this%bclst_dw%append(this%bc_vel_res_non_normal%bc_z)
341 call this%bclst_dw%append(this%bc_vel_res)
342 call this%bclst_dw%append(this%bc_field_dirichlet_w)
343
344 !Intialize projection space thingy
345
346 if (this%variable_material_properties .and. &
347 this%vel_projection_dim .gt. 0) then
348 call neko_error("Velocity projection not available for full stress &
349 &formulation")
350 end if
351
352
353 call this%proj_prs%init(this%dm_Xh%size(), this%pr_projection_dim, &
354 this%pr_projection_activ_step)
355
356 call this%proj_u%init(this%dm_Xh%size(), this%vel_projection_dim, &
357 this%vel_projection_activ_step)
358 call this%proj_v%init(this%dm_Xh%size(), this%vel_projection_dim, &
359 this%vel_projection_activ_step)
360 call this%proj_w%init(this%dm_Xh%size(), this%vel_projection_dim, &
361 this%vel_projection_activ_step)
362
363
364 ! Add lagged term to checkpoint
365 call this%chkp%add_lag(this%ulag, this%vlag, this%wlag)
366
367 ! Determine the time-interpolation scheme
368 call json_get_or_default(params, 'case.numerics.oifs', this%oifs, .false.)
369
370 ! Initialize the advection factory
371 call json_get_or_default(params, 'case.fluid.advection', advection, .true.)
372 call advection_factory(this%adv, params, this%c_Xh, &
373 this%ulag, this%vlag, this%wlag, &
374 this%chkp%dtlag, this%chkp%tlag, time_scheme, &
375 .not. advection)
376
377 if (params%valid_path('case.fluid.flow_rate_force')) then
378 call this%vol_flow%init(this%dm_Xh, params)
379 end if
380
381 end subroutine fluid_pnpn_init
382
383 subroutine fluid_pnpn_restart(this, dtlag, tlag)
384 class(fluid_pnpn_t), target, intent(inout) :: this
385 real(kind=rp) :: dtlag(10), tlag(10)
386 type(field_t) :: u_temp, v_temp, w_temp
387 integer :: i, j, n
388
389 n = this%u%dof%size()
390 if (allocated(this%chkp%previous_mesh%elements) .or. &
391 this%chkp%previous_Xh%lx .ne. this%Xh%lx) then
392 associate(u => this%u, v => this%v, w => this%w, p => this%p, &
393 c_xh => this%c_Xh, ulag => this%ulag, vlag => this%vlag, &
394 wlag => this%wlag)
395 do concurrent(j=1:n)
396 u%x(j,1,1,1) = u%x(j,1,1,1) * c_xh%mult(j,1,1,1)
397 v%x(j,1,1,1) = v%x(j,1,1,1) * c_xh%mult(j,1,1,1)
398 w%x(j,1,1,1) = w%x(j,1,1,1) * c_xh%mult(j,1,1,1)
399 p%x(j,1,1,1) = p%x(j,1,1,1) * c_xh%mult(j,1,1,1)
400 end do
401 do i = 1, this%ulag%size()
402 do concurrent(j=1:n)
403 ulag%lf(i)%x(j,1,1,1) = ulag%lf(i)%x(j,1,1,1) &
404 * c_xh%mult(j,1,1,1)
405 vlag%lf(i)%x(j,1,1,1) = vlag%lf(i)%x(j,1,1,1) &
406 * c_xh%mult(j,1,1,1)
407 wlag%lf(i)%x(j,1,1,1) = wlag%lf(i)%x(j,1,1,1) &
408 * c_xh%mult(j,1,1,1)
409 end do
410 end do
411 end associate
412 end if
413
414 if (neko_bcknd_device .eq. 1) then
415 associate(u => this%u, v => this%v, w => this%w, &
416 ulag => this%ulag, vlag => this%vlag, wlag => this%wlag,&
417 p => this%p)
418 call device_memcpy(u%x, u%x_d, u%dof%size(), &
419 host_to_device, sync = .false.)
420 call device_memcpy(v%x, v%x_d, v%dof%size(), &
421 host_to_device, sync = .false.)
422 call device_memcpy(w%x, w%x_d, w%dof%size(), &
423 host_to_device, sync = .false.)
424 call device_memcpy(p%x, p%x_d, p%dof%size(), &
425 host_to_device, sync = .false.)
426 call device_memcpy(ulag%lf(1)%x, ulag%lf(1)%x_d, &
427 u%dof%size(), host_to_device, sync = .false.)
428 call device_memcpy(ulag%lf(2)%x, ulag%lf(2)%x_d, &
429 u%dof%size(), host_to_device, sync = .false.)
430
431 call device_memcpy(vlag%lf(1)%x, vlag%lf(1)%x_d, &
432 v%dof%size(), host_to_device, sync = .false.)
433 call device_memcpy(vlag%lf(2)%x, vlag%lf(2)%x_d, &
434 v%dof%size(), host_to_device, sync = .false.)
435
436 call device_memcpy(wlag%lf(1)%x, wlag%lf(1)%x_d, &
437 w%dof%size(), host_to_device, sync = .false.)
438 call device_memcpy(wlag%lf(2)%x, wlag%lf(2)%x_d, &
439 w%dof%size(), host_to_device, sync = .false.)
440 call device_memcpy(this%abx1%x, this%abx1%x_d, &
441 w%dof%size(), host_to_device, sync = .false.)
442 call device_memcpy(this%abx2%x, this%abx2%x_d, &
443 w%dof%size(), host_to_device, sync = .false.)
444 call device_memcpy(this%aby1%x, this%aby1%x_d, &
445 w%dof%size(), host_to_device, sync = .false.)
446 call device_memcpy(this%aby2%x, this%aby2%x_d, &
447 w%dof%size(), host_to_device, sync = .false.)
448 call device_memcpy(this%abz1%x, this%abz1%x_d, &
449 w%dof%size(), host_to_device, sync = .false.)
450 call device_memcpy(this%abz2%x, this%abz2%x_d, &
451 w%dof%size(), host_to_device, sync = .false.)
452 call device_memcpy(this%advx%x, this%advx%x_d, &
453 w%dof%size(), host_to_device, sync = .false.)
454 call device_memcpy(this%advy%x, this%advy%x_d, &
455 w%dof%size(), host_to_device, sync = .false.)
456 call device_memcpy(this%advz%x, this%advz%x_d, &
457 w%dof%size(), host_to_device, sync = .false.)
458 end associate
459 end if
460 ! Make sure that continuity is maintained (important for interpolation)
461 ! Do not do this for lagged rhs
462 ! (derivatives are not necessairly coninous across elements)
463
464 if (allocated(this%chkp%previous_mesh%elements) &
465 .or. this%chkp%previous_Xh%lx .ne. this%Xh%lx) then
466 call this%gs_Xh%op(this%u, gs_op_add)
467 call this%gs_Xh%op(this%v, gs_op_add)
468 call this%gs_Xh%op(this%w, gs_op_add)
469 call this%gs_Xh%op(this%p, gs_op_add)
470
471 do i = 1, this%ulag%size()
472 call this%gs_Xh%op(this%ulag%lf(i), gs_op_add)
473 call this%gs_Xh%op(this%vlag%lf(i), gs_op_add)
474 call this%gs_Xh%op(this%wlag%lf(i), gs_op_add)
475 end do
476 end if
477 !! If we would decide to only restart from lagged fields instead of saving
478 !! abx1, aby1 etc.
479 !! Observe that one also needs to recompute the focing at the old time steps
480 !u_temp = this%ulag%lf(2)
481 !v_temp = this%vlag%lf(2)
482 !w_temp = this%wlag%lf(2)
483 !! Compute the source terms
484 !call this%source_term%compute(tlag(2), -1)
485 !
486 !! Pre-multiply the source terms with the mass matrix.
487 !if (NEKO_BCKND_DEVICE .eq. 1) then
488 ! call device_opcolv(this%f_x%x_d, this%f_y%x_d, this%f_z%x_d, &
489 ! this%c_Xh%B_d, this%msh%gdim, n)
490 !else
491 ! call opcolv(this%f_x%x, this%f_y%x, this%f_z%x, &
492 ! this%c_Xh%B, this%msh%gdim, n)
493 !end if
494
495 !! Add the advection operators to the right-hand-side.
496 !call this%adv%compute(u_temp, v_temp, w_temp, &
497 ! this%f_x%x, this%f_y%x, this%f_z%x, &
498 ! this%Xh, this%c_Xh, this%dm_Xh%size())
499 !this%abx2 = this%f_x
500 !this%aby2 = this%f_y
501 !this%abz2 = this%f_z
502 !
503 !u_temp = this%ulag%lf(1)
504 !v_temp = this%vlag%lf(1)
505 !w_temp = this%wlag%lf(1)
506 !call this%source_term%compute(tlag(1), 0)
507
508 !! Pre-multiply the source terms with the mass matrix.
509 !if (NEKO_BCKND_DEVICE .eq. 1) then
510 ! call device_opcolv(this%f_x%x_d, this%f_y%x_d, this%f_z%x_d, &
511 ! this%c_Xh%B_d, this%msh%gdim, n)
512 !else
513 ! call opcolv(this%f_x%x, this%f_y%x, this%f_z%x, &
514 ! this%c_Xh%B, this%msh%gdim, n)
515 !end if
516
517 !! Pre-multiply the source terms with the mass matrix.
518 !if (NEKO_BCKND_DEVICE .eq. 1) then
519 ! call device_opcolv(this%f_x%x_d, this%f_y%x_d, this%f_z%x_d, &
520 ! this%c_Xh%B_d, this%msh%gdim, n)
521 !else
522 ! call opcolv(this%f_x%x, this%f_y%x, this%f_z%x, &
523 ! this%c_Xh%B, this%msh%gdim, n)
524 !end if
525
526 !call this%adv%compute(u_temp, v_temp, w_temp, &
527 ! this%f_x%x, this%f_y%x, this%f_z%x, &
528 ! this%Xh, this%c_Xh, this%dm_Xh%size())
529 !this%abx1 = this%f_x
530 !this%aby1 = this%f_y
531 !this%abz1 = this%f_z
532
533 end subroutine fluid_pnpn_restart
534
535 subroutine fluid_pnpn_free(this)
536 class(fluid_pnpn_t), intent(inout) :: this
537
538 !Deallocate velocity and pressure fields
539 call this%scheme_free()
540
541 call this%bc_prs_surface%free()
542 call this%bc_sym_surface%free()
543 call this%bclst_vel_res%free()
544 call this%bclst_dp%free()
545 call this%proj_prs%free()
546 call this%proj_u%free()
547 call this%proj_v%free()
548 call this%proj_w%free()
549
550 call this%p_res%free()
551 call this%u_res%free()
552 call this%v_res%free()
553 call this%w_res%free()
554
555 call this%du%free()
556 call this%dv%free()
557 call this%dw%free()
558 call this%dp%free()
559
560 call this%abx1%free()
561 call this%aby1%free()
562 call this%abz1%free()
563
564 call this%abx2%free()
565 call this%aby2%free()
566 call this%abz2%free()
567
568 call this%advx%free()
569 call this%advy%free()
570 call this%advz%free()
571
572 if (allocated(this%Ax_vel)) then
573 deallocate(this%Ax_vel)
574 end if
575
576 if (allocated(this%Ax_prs)) then
577 deallocate(this%Ax_prs)
578 end if
579
580 if (allocated(this%prs_res)) then
581 deallocate(this%prs_res)
582 end if
583
584 if (allocated(this%vel_res)) then
585 deallocate(this%vel_res)
586 end if
587
588 if (allocated(this%sumab)) then
589 deallocate(this%sumab)
590 end if
591
592 if (allocated(this%makeabf)) then
593 deallocate(this%makeabf)
594 end if
595
596 if (allocated(this%makebdf)) then
597 deallocate(this%makebdf)
598 end if
599
600 if (allocated(this%makeoifs)) then
601 deallocate(this%makeoifs)
602 end if
603
604 call this%vol_flow%free()
605
606 end subroutine fluid_pnpn_free
607
614 subroutine fluid_pnpn_step(this, t, tstep, dt, ext_bdf, dt_controller)
615 class(fluid_pnpn_t), target, intent(inout) :: this
616 real(kind=rp), intent(in) :: t
617 integer, intent(in) :: tstep
618 real(kind=rp), intent(in) :: dt
619 type(time_scheme_controller_t), intent(in) :: ext_bdf
620 type(time_step_controller_t), intent(in) :: dt_controller
621 ! number of degrees of freedom
622 integer :: n
623 ! Solver results monitors (pressure + 3 velocity)
624 type(ksp_monitor_t) :: ksp_results(4)
625 ! Extrapolated velocity for the pressure residual
626 type(field_t), pointer :: u_e, v_e, w_e
627 ! Indices for tracking temporary fields
628 integer :: temp_indices(3)
629
630 if (this%freeze) return
631
632 n = this%dm_Xh%size()
633
634 call profiler_start_region('Fluid', 1)
635 associate(u => this%u, v => this%v, w => this%w, p => this%p, &
636 du => this%du, dv => this%dv, dw => this%dw, dp => this%dp, &
637 u_res => this%u_res, v_res => this%v_res, w_res => this%w_res, &
638 p_res => this%p_res, ax_vel => this%Ax_vel, ax_prs => this%Ax_prs, &
639 xh => this%Xh, &
640 c_xh => this%c_Xh, dm_xh => this%dm_Xh, gs_xh => this%gs_Xh, &
641 ulag => this%ulag, vlag => this%vlag, wlag => this%wlag, &
642 msh => this%msh, prs_res => this%prs_res, &
643 source_term => this%source_term, vel_res => this%vel_res, &
644 sumab => this%sumab, makeoifs => this%makeoifs, &
645 makeabf => this%makeabf, makebdf => this%makebdf, &
646 vel_projection_dim => this%vel_projection_dim, &
647 pr_projection_dim => this%pr_projection_dim, &
648 rho => this%rho, mu => this%mu, oifs => this%oifs, &
649 rho_field => this%rho_field, mu_field => this%mu_field, &
650 f_x => this%f_x, f_y => this%f_y, f_z => this%f_z, &
651 if_variable_dt => dt_controller%if_variable_dt, &
652 dt_last_change => dt_controller%dt_last_change)
653
654 ! Get temporary arrays
655 call this%scratch%request_field(u_e, temp_indices(1))
656 call this%scratch%request_field(v_e, temp_indices(2))
657 call this%scratch%request_field(w_e, temp_indices(3))
658 call sumab%compute_fluid(u_e, v_e, w_e, u, v, w, &
659 ulag, vlag, wlag, ext_bdf%advection_coeffs, ext_bdf%nadv)
660
661 ! Compute the source terms
662 call this%source_term%compute(t, tstep)
663
664 ! Add Neumann bc contributions to the RHS
665 call this%bclst_vel_neumann%apply_vector(f_x%x, f_y%x, f_z%x, &
666 this%dm_Xh%size(), t, tstep)
667
668 ! Compute the grandient jump penalty term
669 if (this%if_gradient_jump_penalty .eqv. .true.) then
670 call this%gradient_jump_penalty_u%compute(u, v, w, u)
671 call this%gradient_jump_penalty_v%compute(u, v, w, v)
672 call this%gradient_jump_penalty_w%compute(u, v, w, w)
673 call this%gradient_jump_penalty_u%perform(f_x)
674 call this%gradient_jump_penalty_v%perform(f_y)
675 call this%gradient_jump_penalty_w%perform(f_z)
676 end if
677
678 if (oifs) then
679 ! Add the advection operators to the right-hand-side.
680 call this%adv%compute(u, v, w, &
681 this%advx, this%advy, this%advz, &
682 xh, this%c_Xh, dm_xh%size(), dt)
683
684 ! At this point the RHS contains the sum of the advection operator and
685 ! additional source terms, evaluated using the velocity field from the
686 ! previous time-step. Now, this value is used in the explicit time
687 ! scheme to advance both terms in time.
688 call makeabf%compute_fluid(this%abx1, this%aby1, this%abz1,&
689 this%abx2, this%aby2, this%abz2, &
690 f_x%x, f_y%x, f_z%x, &
691 rho, ext_bdf%advection_coeffs, n)
692
693 ! Now, the source terms from the previous time step are added to the RHS.
694 call makeoifs%compute_fluid(this%advx%x, this%advy%x, this%advz%x, &
695 f_x%x, f_y%x, f_z%x, &
696 rho, dt, n)
697 else
698 ! Add the advection operators to the right-hand-side.
699 call this%adv%compute(u, v, w, &
700 f_x, f_y, f_z, &
701 xh, this%c_Xh, dm_xh%size())
702
703 ! At this point the RHS contains the sum of the advection operator and
704 ! additional source terms, evaluated using the velocity field from the
705 ! previous time-step. Now, this value is used in the explicit time
706 ! scheme to advance both terms in time.
707 call makeabf%compute_fluid(this%abx1, this%aby1, this%abz1,&
708 this%abx2, this%aby2, this%abz2, &
709 f_x%x, f_y%x, f_z%x, &
710 rho, ext_bdf%advection_coeffs, n)
711
712 ! Add the RHS contributions coming from the BDF scheme.
713 call makebdf%compute_fluid(ulag, vlag, wlag, f_x%x, f_y%x, f_z%x, &
714 u, v, w, c_xh%B, rho, dt, &
715 ext_bdf%diffusion_coeffs, ext_bdf%ndiff, n)
716 end if
717
718 call ulag%update()
719 call vlag%update()
720 call wlag%update()
721
725 call this%user_field_bc_vel%update(this%user_field_bc_vel%field_list, &
726 this%user_field_bc_vel%bc_list, this%c_Xh, t, tstep, "fluid")
727
728 call this%bc_apply_vel(t, tstep)
729 call this%bc_apply_prs(t, tstep)
730
731 ! Update material properties if necessary
732 call this%update_material_properties()
733
734 ! Compute pressure.
735 call profiler_start_region('Pressure_residual', 18)
736 call prs_res%compute(p, p_res,&
737 u, v, w, &
738 u_e, v_e, w_e, &
739 f_x, f_y, f_z, &
740 c_xh, gs_xh, &
741 this%bc_prs_surface, this%bc_sym_surface,&
742 ax_prs, ext_bdf%diffusion_coeffs(1), dt, &
743 mu_field, rho_field)
744
745 if (.not. this%prs_dirichlet) call ortho(p_res%x, this%glb_n_points, n)
746 call gs_xh%op(p_res, gs_op_add)
747 call this%bclst_dp%apply_scalar(p_res%x, p%dof%size(), t, tstep)
748 call profiler_end_region('Pressure_residual', 18)
749
750 call this%proj_prs%pre_solving(p_res%x, tstep, c_xh, n, dt_controller, &
751 'Pressure')
752
753 call this%pc_prs%update()
754 call profiler_start_region('Pressure_solve', 3)
755 ksp_results(1) = &
756 this%ksp_prs%solve(ax_prs, dp, p_res%x, n, c_xh, this%bclst_dp, gs_xh)
757
758 call profiler_end_region('Pressure_solve', 3)
759
760 call this%proj_prs%post_solving(dp%x, ax_prs, c_xh, &
761 this%bclst_dp, gs_xh, n, tstep, dt_controller)
762
763 call field_add2(p, dp, n)
764 if (.not. this%prs_dirichlet) call ortho(p%x, this%glb_n_points, n)
765
766 ! Compute velocity.
767 call profiler_start_region('Velocity_residual', 19)
768 call vel_res%compute(ax_vel, u, v, w, &
769 u_res, v_res, w_res, &
770 p, &
771 f_x, f_y, f_z, &
772 c_xh, msh, xh, &
773 mu_field, rho_field, ext_bdf%diffusion_coeffs(1), &
774 dt, dm_xh%size())
775
776 call gs_xh%op(u_res, gs_op_add)
777 call gs_xh%op(v_res, gs_op_add)
778 call gs_xh%op(w_res, gs_op_add)
779
780 call this%bclst_vel_res%apply_vector(u_res%x, v_res%x, w_res%x, &
781 dm_xh%size(), t, tstep)
782
783 ! We should implement a bc that takes three field_bcs and implements
784 ! vector_apply
785 if (neko_bcknd_device .eq. 1) then
786 call this%bc_field_dirichlet_u%apply_scalar_dev(u_res%x_d, t, tstep)
787 call this%bc_field_dirichlet_v%apply_scalar_dev(v_res%x_d, t, tstep)
788 call this%bc_field_dirichlet_w%apply_scalar_dev(w_res%x_d, t, tstep)
789 else
790 call this%bc_field_dirichlet_u%apply_scalar(u_res%x, n, t, tstep)
791 call this%bc_field_dirichlet_v%apply_scalar(v_res%x, n, t, tstep)
792 call this%bc_field_dirichlet_w%apply_scalar(w_res%x, n, t, tstep)
793 end if
794
795 call profiler_end_region('Velocity_residual', 19)
796
797 call this%proj_u%pre_solving(u_res%x, tstep, c_xh, n, dt_controller)
798 call this%proj_v%pre_solving(v_res%x, tstep, c_xh, n, dt_controller)
799 call this%proj_w%pre_solving(w_res%x, tstep, c_xh, n, dt_controller)
800
801 call this%pc_vel%update()
802
803 call profiler_start_region("Velocity_solve", 4)
804 ksp_results(2:4) = this%ksp_vel%solve_coupled(ax_vel, du, dv, dw, &
805 u_res%x, v_res%x, w_res%x, n, c_xh, &
806 this%bclst_du, this%bclst_dv, this%bclst_dw, gs_xh, &
807 this%ksp_vel%max_iter)
808 call profiler_end_region("Velocity_solve", 4)
809
810 call this%proj_u%post_solving(du%x, ax_vel, c_xh, &
811 this%bclst_du, gs_xh, n, tstep, dt_controller)
812 call this%proj_v%post_solving(dv%x, ax_vel, c_xh, &
813 this%bclst_dv, gs_xh, n, tstep, dt_controller)
814 call this%proj_w%post_solving(dw%x, ax_vel, c_xh, &
815 this%bclst_dw, gs_xh, n, tstep, dt_controller)
816
817 if (neko_bcknd_device .eq. 1) then
818 call device_opadd2cm(u%x_d, v%x_d, w%x_d, &
819 du%x_d, dv%x_d, dw%x_d, 1.0_rp, n, msh%gdim)
820 else
821 call opadd2cm(u%x, v%x, w%x, du%x, dv%x, dw%x, 1.0_rp, n, msh%gdim)
822 end if
823
824 if (this%forced_flow_rate) then
825 call this%vol_flow%adjust( u, v, w, p, u_res, v_res, w_res, p_res, &
826 c_xh, gs_xh, ext_bdf, rho, mu, dt, &
827 this%bclst_dp, this%bclst_du, this%bclst_dv, &
828 this%bclst_dw, this%bclst_vel_res, ax_vel, ax_prs, this%ksp_prs, &
829 this%ksp_vel, this%pc_prs, this%pc_vel, this%ksp_prs%max_iter, &
830 this%ksp_vel%max_iter)
831 end if
832
833 call fluid_step_info(tstep, t, dt, ksp_results, this%strict_convergence)
834
835 call this%scratch%relinquish_field(temp_indices)
836
837 end associate
838 call profiler_end_region('Fluid', 1)
839 end subroutine fluid_pnpn_step
840
841
842end module fluid_pnpn
Copy data between host and device (or device and device)
Definition device.F90:51
Retrieves a parameter by name or assigns a provided default value. In the latter case also adds the m...
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
Definition comm.F90:1
type(mpi_comm) neko_comm
MPI communicator.
Definition comm.F90:16
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
integer, parameter, public host_to_device
Definition device.F90:47
Defines a dirichlet boundary condition.
Definition dirichlet.f90:34
Dirichlet condition applied in the facet normal direction.
subroutine, public field_add2(a, b, n)
Vector addition .
subroutine, public field_copy(a, b, n)
Copy a vector .
Defines a field.
Definition field.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_init(this, msh, lx, params, user, time_scheme)
subroutine fluid_pnpn_step(this, t, tstep, dt, ext_bdf, dt_controller)
Advance fluid simulation in time.
subroutine fluid_pnpn_free(this)
subroutine fluid_pnpn_restart(this, dtlag, tlag)
Fluid formulations.
Defines Gather-scatter operations.
Definition gs_ops.f90:34
integer, parameter, public gs_op_add
Definition gs_ops.f90:36
Utilities for retrieving parameters from the case files.
Implements the base abstract type for Krylov solvers plus helper types.
Definition krylov.f90:34
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.
Routines to generate the right-hand sides for the convection-diffusion equation. Employs the EXT/BDF ...
Definition rhs_maker.f90:38
Implements the source_term_t type and a wrapper source_term_wrapper_t.
Compound scheme for the advection and diffusion operators in a transport equation.
Base class for time integration schemes.
Implements type time_step_controller.
Interfaces for user interaction with NEKO.
Definition user_intf.f90:34
Utilities.
Definition utils.f90:35
Base abstract type for computing the advection operator.
Definition advection.f90:46
Base type for a matrix-vector product providing .
Definition ax.f90:43
A list of allocatable `bc_t`. Follows the standard interface of lists.
Definition bc_list.f90:46
Generic Dirichlet boundary condition on .
Definition dirichlet.f90:44
Dirichlet condition in facet normal direction.
Base type of all fluid formulations.
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:47
Abstract type to compute velocity residual.
Definition pnpn_res.f90:53
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
Implements the logic to compute the time coefficients for the advection and diffusion operators in a ...