Neko  0.8.1
A portable framework for high-order spectral element flow simulations
fluid_pnpn.f90
Go to the documentation of this file.
1 ! Copyright (c) 2022, 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 !
34 module fluid_pnpn
35  use num_types, only : rp
36  use krylov, only : ksp_monitor_t
39  use ax_helm_fctry, only : ax_helm_factory
43  use fluid_volflow, only : fluid_volflow_t
44  use fluid_scheme, only : fluid_scheme_t
45  use field_series, only : field_series_t
48  use fluid_aux, only : fluid_step_info
50  use projection, only : projection_t
52  use logger, only : neko_log
53  use advection, only : advection_t
55  use json_utils, only : json_get
56  use json_module, only : json_file
59  use ax_product, only : ax_t
60  use field, only : field_t
61  use dirichlet, only : dirichlet_t
62  use facet_normal, only : facet_normal_t
63  use non_normal, only : non_normal_t
64  use mesh, only : mesh_t
65  use user_intf, only : user_t
66  use coefs, only : coef_t
68  use gather_scatter, only : gs_t, gs_op_add
69  use neko_config, only : neko_bcknd_device
70  use math, only : col2, add2
71  use mathops, only : opadd2cm, opcolv
74  implicit none
75  private
76 
77 
78  type, public, extends(fluid_scheme_t) :: fluid_pnpn_t
79  type(field_t) :: p_res, u_res, v_res, w_res
80 
81  type(field_t) :: dp, du, dv, dw
82 
83  class(ax_t), allocatable :: ax
84 
85  type(projection_t) :: proj_prs
86  type(projection_t) :: proj_u
87  type(projection_t) :: proj_v
88  type(projection_t) :: proj_w
89 
90  type(facet_normal_t) :: bc_prs_surface
91  type(facet_normal_t) :: bc_sym_surface
92  type(dirichlet_t) :: bc_vel_res
93  type(dirichlet_t) :: bc_field_dirichlet_p
94  type(dirichlet_t) :: bc_field_dirichlet_u
95  type(dirichlet_t) :: bc_field_dirichlet_v
96  type(dirichlet_t) :: bc_field_dirichlet_w
97  type(non_normal_t) :: bc_vel_res_non_normal
98  type(bc_list_t) :: bclst_vel_res
99  type(bc_list_t) :: bclst_du
100  type(bc_list_t) :: bclst_dv
101  type(bc_list_t) :: bclst_dw
102  type(bc_list_t) :: bclst_dp
103 
104  class(advection_t), allocatable :: adv
105 
106  ! Time variables
107  type(field_t) :: abx1, aby1, abz1
108  type(field_t) :: abx2, aby2, abz2
109 
111  class(pnpn_prs_res_t), allocatable :: prs_res
112 
114  class(pnpn_vel_res_t), allocatable :: vel_res
115 
117  class(rhs_maker_sumab_t), allocatable :: sumab
118 
120  class(rhs_maker_ext_t), allocatable :: makeabf
121 
123  class(rhs_maker_bdf_t), allocatable :: makebdf
124 
126  type(fluid_volflow_t) :: vol_flow
127 
128  contains
129  procedure, pass(this) :: init => fluid_pnpn_init
130  procedure, pass(this) :: free => fluid_pnpn_free
131  procedure, pass(this) :: step => fluid_pnpn_step
132  procedure, pass(this) :: restart => fluid_pnpn_restart
133  end type fluid_pnpn_t
134 
135 contains
136 
137  subroutine fluid_pnpn_init(this, msh, lx, params, user, material_properties)
138  class(fluid_pnpn_t), target, intent(inout) :: this
139  type(mesh_t), target, intent(inout) :: msh
140  integer, intent(inout) :: lx
141  type(json_file), target, intent(inout) :: params
142  type(user_t), intent(in) :: user
143  type(material_properties_t), target, intent(inout) :: material_properties
144  character(len=15), parameter :: scheme = 'Modular (Pn/Pn)'
145  logical :: found, logical_val
146  integer :: integer_val
147  real(kind=rp) :: real_val
148 
149  call this%free()
150 
151  ! Initialize base class
152  call this%scheme_init(msh, lx, params, .true., .true., scheme, user, &
154 
155  ! Setup backend dependent Ax routines
156  call ax_helm_factory(this%ax)
157 
158  ! Setup backend dependent prs residual routines
159  call pnpn_prs_res_factory(this%prs_res)
160 
161  ! Setup backend dependent vel residual routines
162  call pnpn_vel_res_factory(this%vel_res)
163 
164  ! Setup backend dependent summation of AB/BDF
165  call rhs_maker_sumab_fctry(this%sumab)
166 
167  ! Setup backend dependent summation of extrapolation scheme
168  call rhs_maker_ext_fctry(this%makeabf)
169 
170  ! Setup backend depenent contributions to F from lagged BD terms
171  call rhs_maker_bdf_fctry(this%makebdf)
172 
173  ! Initialize variables specific to this plan
174  associate(xh_lx => this%Xh%lx, xh_ly => this%Xh%ly, xh_lz => this%Xh%lz, &
175  dm_xh => this%dm_Xh, nelv => this%msh%nelv)
176 
177  call this%p_res%init(dm_xh, "p_res")
178  call this%u_res%init(dm_xh, "u_res")
179  call this%v_res%init(dm_xh, "v_res")
180  call this%w_res%init(dm_xh, "w_res")
181  call this%abx1%init(dm_xh, "abx1")
182  call this%aby1%init(dm_xh, "aby1")
183  call this%abz1%init(dm_xh, "abz1")
184  call this%abx2%init(dm_xh, "abx2")
185  call this%aby2%init(dm_xh, "aby2")
186  call this%abz2%init(dm_xh, "abz2")
187  this%abx1 = 0.0_rp
188  this%aby1 = 0.0_rp
189  this%abz1 = 0.0_rp
190  this%abx2 = 0.0_rp
191  this%aby2 = 0.0_rp
192  this%abz2 = 0.0_rp
193 
194  call this%du%init(dm_xh, 'du')
195  call this%dv%init(dm_xh, 'dv')
196  call this%dw%init(dm_xh, 'dw')
197  call this%dp%init(dm_xh, 'dp')
198 
199  end associate
200 
201  ! Initialize velocity surface terms in pressure rhs
202  call this%bc_prs_surface%init(this%c_Xh)
203  call this%bc_prs_surface%mark_zone(msh%inlet)
204  call this%bc_prs_surface%mark_zones_from_list(msh%labeled_zones,&
205  'v', this%bc_labels)
206  !This impacts the rhs of the pressure, need to check what is correct to add here
207  call this%bc_prs_surface%mark_zones_from_list(msh%labeled_zones,&
208  'd_vel_u', this%bc_labels)
209  call this%bc_prs_surface%mark_zones_from_list(msh%labeled_zones,&
210  'd_vel_v', this%bc_labels)
211  call this%bc_prs_surface%mark_zones_from_list(msh%labeled_zones,&
212  'd_vel_w', this%bc_labels)
213  call this%bc_prs_surface%finalize()
214  ! Initialize symmetry surface terms in pressure rhs
215  call this%bc_sym_surface%init(this%c_Xh)
216  call this%bc_sym_surface%mark_zone(msh%sympln)
217  call this%bc_sym_surface%mark_zones_from_list(msh%labeled_zones,&
218  'sym', this%bc_labels)
219  ! Same here, should du, dv, dw be marked here?
220  call this%bc_sym_surface%finalize()
221  ! Initialize dirichlet bcs for velocity residual
222  call this%bc_vel_res_non_normal%init(this%c_Xh)
223  call this%bc_vel_res_non_normal%mark_zone(msh%outlet_normal)
224  call this%bc_vel_res_non_normal%mark_zones_from_list(msh%labeled_zones,&
225  'on', this%bc_labels)
226  call this%bc_vel_res_non_normal%mark_zones_from_list(msh%labeled_zones,&
227  'on+dong', &
228  this%bc_labels)
229  call this%bc_vel_res_non_normal%finalize()
230  call this%bc_vel_res_non_normal%init_msk()
231 
232  call this%bc_field_dirichlet_p%init(this%c_Xh)
233  call this%bc_field_dirichlet_p%mark_zones_from_list(msh%labeled_zones, 'on+dong', &
234  this%bc_labels)
235  call this%bc_field_dirichlet_p%mark_zones_from_list(msh%labeled_zones, &
236  'o+dong', this%bc_labels)
237  call this%bc_field_dirichlet_p%mark_zones_from_list(msh%labeled_zones, 'd_pres', &
238  this%bc_labels)
239  call this%bc_field_dirichlet_p%finalize()
240  call this%bc_field_dirichlet_p%set_g(0.0_rp)
241  call bc_list_init(this%bclst_dp)
242  call bc_list_add(this%bclst_dp, this%bc_field_dirichlet_p)
243  !Add 0 prs bcs
244  call bc_list_add(this%bclst_dp, this%bc_prs)
245 
246  call this%bc_field_dirichlet_u%init(this%c_Xh)
247  call this%bc_field_dirichlet_u%mark_zones_from_list(msh%labeled_zones, 'd_vel_u', &
248  this%bc_labels)
249  call this%bc_field_dirichlet_u%finalize()
250  call this%bc_field_dirichlet_u%set_g(0.0_rp)
251 
252  call this%bc_field_dirichlet_v%init(this%c_Xh)
253  call this%bc_field_dirichlet_v%mark_zones_from_list(msh%labeled_zones, 'd_vel_v', &
254  this%bc_labels)
255  call this%bc_field_dirichlet_v%finalize()
256  call this%bc_field_dirichlet_v%set_g(0.0_rp)
257 
258  call this%bc_field_dirichlet_w%init(this%c_Xh)
259  call this%bc_field_dirichlet_w%mark_zones_from_list(msh%labeled_zones, 'd_vel_w', &
260  this%bc_labels)
261  call this%bc_field_dirichlet_w%finalize()
262  call this%bc_field_dirichlet_w%set_g(0.0_rp)
263 
264  call this%bc_vel_res%init(this%c_Xh)
265  call this%bc_vel_res%mark_zone(msh%inlet)
266  call this%bc_vel_res%mark_zone(msh%wall)
267  call this%bc_vel_res%mark_zones_from_list(msh%labeled_zones, &
268  'v', this%bc_labels)
269  call this%bc_vel_res%mark_zones_from_list(msh%labeled_zones, &
270  'w', this%bc_labels)
271  call this%bc_vel_res%finalize()
272  call this%bc_vel_res%set_g(0.0_rp)
273  call bc_list_init(this%bclst_vel_res)
274  call bc_list_add(this%bclst_vel_res, this%bc_vel_res)
275  call bc_list_add(this%bclst_vel_res, this%bc_vel_res_non_normal)
276  call bc_list_add(this%bclst_vel_res, this%bc_sym)
277 
278  !Initialize bcs for u, v, w velocity components
279  call bc_list_init(this%bclst_du)
280  call bc_list_add(this%bclst_du,this%bc_sym%bc_x)
281  call bc_list_add(this%bclst_du,this%bc_vel_res_non_normal%bc_x)
282  call bc_list_add(this%bclst_du, this%bc_vel_res)
283  call bc_list_add(this%bclst_du, this%bc_field_dirichlet_u)
284 
285  call bc_list_init(this%bclst_dv)
286  call bc_list_add(this%bclst_dv,this%bc_sym%bc_y)
287  call bc_list_add(this%bclst_dv,this%bc_vel_res_non_normal%bc_y)
288  call bc_list_add(this%bclst_dv, this%bc_vel_res)
289  call bc_list_add(this%bclst_dv, this%bc_field_dirichlet_v)
290 
291  call bc_list_init(this%bclst_dw)
292  call bc_list_add(this%bclst_dw,this%bc_sym%bc_z)
293  call bc_list_add(this%bclst_dw,this%bc_vel_res_non_normal%bc_z)
294  call bc_list_add(this%bclst_dw, this%bc_vel_res)
295  call bc_list_add(this%bclst_dw, this%bc_field_dirichlet_w)
296 
297  !Intialize projection space thingy
298  call this%proj_prs%init(this%dm_Xh%size(), this%pr_projection_dim, &
299  this%pr_projection_activ_step)
300 
301  call this%proj_u%init(this%dm_Xh%size(), this%vel_projection_dim, &
302  this%vel_projection_activ_step)
303  call this%proj_v%init(this%dm_Xh%size(), this%vel_projection_dim, &
304  this%vel_projection_activ_step)
305  call this%proj_w%init(this%dm_Xh%size(), this%vel_projection_dim, &
306  this%vel_projection_activ_step)
307 
308 
309  ! Add lagged term to checkpoint
310  call this%chkp%add_lag(this%ulag, this%vlag, this%wlag)
311 
312  call advection_factory(this%adv, params, this%c_Xh)
313 
314  if (params%valid_path('case.fluid.flow_rate_force')) then
315  call this%vol_flow%init(this%dm_Xh, params)
316  end if
317 
318  end subroutine fluid_pnpn_init
319 
320  subroutine fluid_pnpn_restart(this,dtlag, tlag)
321  class(fluid_pnpn_t), target, intent(inout) :: this
322  real(kind=rp) :: dtlag(10), tlag(10)
323  type(field_t) :: u_temp, v_temp, w_temp
324  integer :: i, n
325 
326  n = this%u%dof%size()
327  ! Make sure that continuity is maintained (important for interpolation)
328  ! Do not do this for lagged rhs
329  ! (derivatives are not necessairly coninous across elements)
330  call col2(this%u%x,this%c_Xh%mult,this%u%dof%size())
331  call col2(this%v%x,this%c_Xh%mult,this%u%dof%size())
332  call col2(this%w%x,this%c_Xh%mult,this%u%dof%size())
333  call col2(this%p%x,this%c_Xh%mult,this%u%dof%size())
334  do i = 1, this%ulag%size()
335  call col2(this%ulag%lf(i)%x,this%c_Xh%mult,this%u%dof%size())
336  call col2(this%vlag%lf(i)%x,this%c_Xh%mult,this%u%dof%size())
337  call col2(this%wlag%lf(i)%x,this%c_Xh%mult,this%u%dof%size())
338  end do
339 
340 
341  if (neko_bcknd_device .eq. 1) then
342  associate(u=>this%u, v=>this%v, w=>this%w, &
343  ulag=>this%ulag, vlag=>this%vlag, wlag=>this%wlag,&
344  p=>this%p)
345  call device_memcpy(u%x, u%x_d, u%dof%size(), &
346  host_to_device, sync=.false.)
347  call device_memcpy(v%x, v%x_d, v%dof%size(), &
348  host_to_device, sync=.false.)
349  call device_memcpy(w%x, w%x_d, w%dof%size(), &
350  host_to_device, sync=.false.)
351  call device_memcpy(p%x, p%x_d, p%dof%size(), &
352  host_to_device, sync=.false.)
353  call device_memcpy(ulag%lf(1)%x, ulag%lf(1)%x_d, &
354  u%dof%size(), host_to_device, sync=.false.)
355  call device_memcpy(ulag%lf(2)%x, ulag%lf(2)%x_d, &
356  u%dof%size(), host_to_device, sync=.false.)
357 
358  call device_memcpy(vlag%lf(1)%x, vlag%lf(1)%x_d, &
359  v%dof%size(), host_to_device, sync=.false.)
360  call device_memcpy(vlag%lf(2)%x, vlag%lf(2)%x_d, &
361  v%dof%size(), host_to_device, sync=.false.)
362 
363  call device_memcpy(wlag%lf(1)%x, wlag%lf(1)%x_d, &
364  w%dof%size(), host_to_device, sync=.false.)
365  call device_memcpy(wlag%lf(2)%x, wlag%lf(2)%x_d, &
366  w%dof%size(), host_to_device, sync=.false.)
367  call device_memcpy(this%abx1%x, this%abx1%x_d, &
368  w%dof%size(), host_to_device, sync=.false.)
369  call device_memcpy(this%abx2%x, this%abx2%x_d, &
370  w%dof%size(), host_to_device, sync=.false.)
371  call device_memcpy(this%aby1%x, this%aby1%x_d, &
372  w%dof%size(), host_to_device, sync=.false.)
373  call device_memcpy(this%aby2%x, this%aby2%x_d, &
374  w%dof%size(), host_to_device, sync=.false.)
375  call device_memcpy(this%abz1%x, this%abz1%x_d, &
376  w%dof%size(), host_to_device, sync=.false.)
377  call device_memcpy(this%abz2%x, this%abz2%x_d, &
378  w%dof%size(), host_to_device, sync=.false.)
379  end associate
380  end if
381 
382 
383  call this%gs_Xh%op(this%u,gs_op_add)
384  call this%gs_Xh%op(this%v,gs_op_add)
385  call this%gs_Xh%op(this%w,gs_op_add)
386  call this%gs_Xh%op(this%p,gs_op_add)
387 
388  do i = 1, this%ulag%size()
389  call this%gs_Xh%op(this%ulag%lf(i),gs_op_add)
390  call this%gs_Xh%op(this%vlag%lf(i),gs_op_add)
391  call this%gs_Xh%op(this%wlag%lf(i),gs_op_add)
392  end do
393 
394 
395  !! If we would decide to only restart from lagged fields instead of asving abx1, aby1 etc.
396  !! Observe that one also needs to recompute the focing at the old time steps
397  !u_temp = this%ulag%lf(2)
398  !v_temp = this%vlag%lf(2)
399  !w_temp = this%wlag%lf(2)
400  !! Compute the source terms
401  !call this%source_term%compute(tlag(2), -1)
402  !
403  !! Pre-multiply the source terms with the mass matrix.
404  !if (NEKO_BCKND_DEVICE .eq. 1) then
405  ! call device_opcolv(this%f_x%x_d, this%f_y%x_d, this%f_z%x_d, this%c_Xh%B_d, this%msh%gdim, n)
406  !else
407  ! call opcolv(this%f_x%x, this%f_y%x, this%f_z%x, this%c_Xh%B, this%msh%gdim, n)
408  !end if
409 
410  !! Add the advection operators to the right-hand-side.
411  !call this%adv%compute(u_temp, v_temp, w_temp, &
412  ! this%f_x%x, this%f_y%x, this%f_z%x, &
413  ! this%Xh, this%c_Xh, this%dm_Xh%size())
414  !this%abx2 = this%f_x
415  !this%aby2 = this%f_y
416  !this%abz2 = this%f_z
417  !
418  !u_temp = this%ulag%lf(1)
419  !v_temp = this%vlag%lf(1)
420  !w_temp = this%wlag%lf(1)
421  !call this%source_term%compute(tlag(1), 0)
422 
423  !! Pre-multiply the source terms with the mass matrix.
424  !if (NEKO_BCKND_DEVICE .eq. 1) then
425  ! call device_opcolv(this%f_x%x_d, this%f_y%x_d, this%f_z%x_d, this%c_Xh%B_d, this%msh%gdim, n)
426  !else
427  ! call opcolv(this%f_x%x, this%f_y%x, this%f_z%x, this%c_Xh%B, this%msh%gdim, n)
428  !end if
429 
430  !! Pre-multiply the source terms with the mass matrix.
431  !if (NEKO_BCKND_DEVICE .eq. 1) then
432  ! call device_opcolv(this%f_x%x_d, this%f_y%x_d, this%f_z%x_d, this%c_Xh%B_d, this%msh%gdim, n)
433  !else
434  ! call opcolv(this%f_x%x, this%f_y%x, this%f_z%x, this%c_Xh%B, this%msh%gdim, n)
435  !end if
436 
437  !call this%adv%compute(u_temp, v_temp, w_temp, &
438  ! this%f_x%x, this%f_y%x, this%f_z%x, &
439  ! this%Xh, this%c_Xh, this%dm_Xh%size())
440  !this%abx1 = this%f_x
441  !this%aby1 = this%f_y
442  !this%abz1 = this%f_z
443 
444  end subroutine fluid_pnpn_restart
445 
446  subroutine fluid_pnpn_free(this)
447  class(fluid_pnpn_t), intent(inout) :: this
448 
449  !Deallocate velocity and pressure fields
450  call this%scheme_free()
451 
452  call this%bc_prs_surface%free()
453  call this%bc_sym_surface%free()
454  call bc_list_free(this%bclst_vel_res)
455  call bc_list_free(this%bclst_dp)
456  call this%proj_prs%free()
457  call this%proj_u%free()
458  call this%proj_v%free()
459  call this%proj_w%free()
460 
461  call this%p_res%free()
462  call this%u_res%free()
463  call this%v_res%free()
464  call this%w_res%free()
465 
466  call this%du%free()
467  call this%dv%free()
468  call this%dw%free()
469  call this%dp%free()
470 
471  call this%abx1%free()
472  call this%aby1%free()
473  call this%abz1%free()
474 
475  call this%abx2%free()
476  call this%aby2%free()
477  call this%abz2%free()
478 
479  if (allocated(this%Ax)) then
480  deallocate(this%Ax)
481  end if
482 
483  if (allocated(this%prs_res)) then
484  deallocate(this%prs_res)
485  end if
486 
487  if (allocated(this%vel_res)) then
488  deallocate(this%vel_res)
489  end if
490 
491  if (allocated(this%sumab)) then
492  deallocate(this%sumab)
493  end if
494 
495  if (allocated(this%makeabf)) then
496  deallocate(this%makeabf)
497  end if
498 
499  if (allocated(this%makebdf)) then
500  deallocate(this%makebdf)
501  end if
502 
503  call this%vol_flow%free()
504 
505  end subroutine fluid_pnpn_free
506 
513  subroutine fluid_pnpn_step(this, t, tstep, dt, ext_bdf, dt_controller)
514  class(fluid_pnpn_t), target, intent(inout) :: this
515  real(kind=rp), intent(inout) :: t
516  integer, intent(inout) :: tstep
517  real(kind=rp), intent(in) :: dt
518  type(time_scheme_controller_t), intent(inout) :: ext_bdf
519  type(time_step_controller_t), intent(in) :: dt_controller
520  ! number of degrees of freedom
521  integer :: n
522  ! Solver results monitors (pressure + 3 velocity)
523  type(ksp_monitor_t) :: ksp_results(4)
524  ! Extrapolated velocity for the pressure residual
525  type(field_t), pointer :: u_e, v_e, w_e
526  ! Indices for tracking temporary fields
527  integer :: temp_indices(3)
528  ! Counter
529  integer :: i
530 
531  if (this%freeze) return
532 
533  n = this%dm_Xh%size()
534 
535  call profiler_start_region('Fluid', 1)
536  associate(u => this%u, v => this%v, w => this%w, p => this%p, &
537  du => this%du, dv => this%dv, dw => this%dw, dp => this%dp, &
538  u_res =>this%u_res, v_res => this%v_res, w_res => this%w_res, &
539  p_res => this%p_res, ax => this%Ax, xh => this%Xh, &
540  c_xh => this%c_Xh, dm_xh => this%dm_Xh, gs_xh => this%gs_Xh, &
541  ulag => this%ulag, vlag => this%vlag, wlag => this%wlag, &
542  msh => this%msh, prs_res => this%prs_res, &
543  source_term => this%source_term, &
544  vel_res => this%vel_res, sumab => this%sumab, &
545  makeabf => this%makeabf, makebdf => this%makebdf, &
546  vel_projection_dim => this%vel_projection_dim, &
547  pr_projection_dim => this%pr_projection_dim, &
548  rho => this%rho, mu => this%mu, &
549  f_x => this%f_x, f_y => this%f_y, f_z => this%f_z, &
550  if_variable_dt => dt_controller%if_variable_dt, &
551  dt_last_change => dt_controller%dt_last_change)
552 
553  ! Get temporary arrays
554  call this%scratch%request_field(u_e, temp_indices(1))
555  call this%scratch%request_field(v_e, temp_indices(2))
556  call this%scratch%request_field(w_e, temp_indices(3))
557  call sumab%compute_fluid(u_e, v_e, w_e, u, v, w, &
558  ulag, vlag, wlag, ext_bdf%advection_coeffs, ext_bdf%nadv)
559 
560  ! Compute the source terms
561  call this%source_term%compute(t, tstep)
562 
563  ! Pre-multiply the source terms with the mass matrix.
564  if (neko_bcknd_device .eq. 1) then
565  call device_opcolv(f_x%x_d, f_y%x_d, f_z%x_d, c_xh%B_d, msh%gdim, n)
566  else
567  call opcolv(f_x%x, f_y%x, f_z%x, c_xh%B, msh%gdim, n)
568  end if
569 
570  ! Add the advection operators to the right-hand-side.
571  call this%adv%compute(u, v, w, &
572  f_x%x, f_y%x, f_z%x, &
573  xh, this%c_Xh, dm_xh%size())
574 
575  ! At this point the RHS contains the sum of the advection operator and
576  ! additional source terms, evaluated using the velocity field from the
577  ! previous time-step. Now, this value is used in the explicit time
578  ! scheme to advance both terms in time.
579  call makeabf%compute_fluid(this%abx1, this%aby1, this%abz1,&
580  this%abx2, this%aby2, this%abz2, &
581  f_x%x, f_y%x, f_z%x, &
582  rho, ext_bdf%advection_coeffs, n)
583 
584  ! Add the RHS contributions coming from the BDF scheme.
585  call makebdf%compute_fluid(ulag, vlag, wlag, f_x%x, f_y%x, f_z%x, &
586  u, v, w, c_xh%B, rho, dt, &
587  ext_bdf%diffusion_coeffs, ext_bdf%ndiff, n)
588 
589  call ulag%update()
590  call vlag%update()
591  call wlag%update()
592 
596  call this%dirichlet_update_(this%field_dirichlet_fields, &
597  this%field_dirichlet_bcs, this%c_Xh, t, tstep, "fluid")
598 
599  call this%bc_apply_vel(t, tstep)
600  call this%bc_apply_prs(t, tstep)
601 
602  ! Compute pressure.
603  call profiler_start_region('Pressure residual', 18)
604  call prs_res%compute(p, p_res, u, v, w, u_e, v_e, w_e, &
605  f_x, f_y, f_z, c_xh, gs_xh, this%bc_prs_surface, &
606  this%bc_sym_surface, ax, ext_bdf%diffusion_coeffs(1), &
607  dt, mu, rho)
608 
609  call gs_xh%op(p_res, gs_op_add)
610  call bc_list_apply_scalar(this%bclst_dp, p_res%x, p%dof%size(), t, tstep)
611  call profiler_end_region
612 
613  call this%proj_prs%pre_solving(p_res%x, tstep, c_xh, n, dt_controller, 'Pressure')
614 
615  call this%pc_prs%update()
616  call profiler_start_region('Pressure solve', 3)
617  ksp_results(1) = &
618  this%ksp_prs%solve(ax, dp, p_res%x, n, c_xh, this%bclst_dp, gs_xh)
619 
620  call profiler_end_region
621 
622  call this%proj_prs%post_solving(dp%x, ax, c_xh, &
623  this%bclst_dp, gs_xh, n, tstep, dt_controller)
624 
625  if (neko_bcknd_device .eq. 1) then
626  call device_add2(p%x_d, dp%x_d,n)
627  else
628  call add2(p%x, dp%x,n)
629  end if
630 
631 
632  ! Compute velocity.
633  call profiler_start_region('Velocity residual', 19)
634  call vel_res%compute(ax, u, v, w, &
635  u_res, v_res, w_res, &
636  p, &
637  f_x, f_y, f_z, &
638  c_xh, msh, xh, &
639  mu, rho, ext_bdf%diffusion_coeffs(1), &
640  dt, dm_xh%size())
641 
642  call gs_xh%op(u_res, gs_op_add)
643  call gs_xh%op(v_res, gs_op_add)
644  call gs_xh%op(w_res, gs_op_add)
645 
646  call bc_list_apply_vector(this%bclst_vel_res,&
647  u_res%x, v_res%x, w_res%x, dm_xh%size(),&
648  t, tstep)
649 
650  !We should implement a bc that takes three field_bcs and implements vector_apply
651  if (neko_bcknd_device .eq. 1) then
652  call this%bc_field_dirichlet_u%apply_scalar_dev(u_res%x_d, t, tstep)
653  call this%bc_field_dirichlet_v%apply_scalar_dev(v_res%x_d, t, tstep)
654  call this%bc_field_dirichlet_w%apply_scalar_dev(w_res%x_d, t, tstep)
655  else
656  call this%bc_field_dirichlet_u%apply_scalar(u_res%x, this%dm_Xh%size(), t, tstep)
657  call this%bc_field_dirichlet_v%apply_scalar(v_res%x, this%dm_Xh%size(), t, tstep)
658  call this%bc_field_dirichlet_w%apply_scalar(w_res%x, this%dm_Xh%size(), t, tstep)
659  end if
660 
661  call profiler_end_region
662 
663  call this%proj_u%pre_solving(u_res%x, tstep, c_xh, n, dt_controller)
664  call this%proj_v%pre_solving(v_res%x, tstep, c_xh, n, dt_controller)
665  call this%proj_w%pre_solving(w_res%x, tstep, c_xh, n, dt_controller)
666 
667  call this%pc_vel%update()
668 
669  call profiler_start_region("Velocity solve", 4)
670  ksp_results(2) = this%ksp_vel%solve(ax, du, u_res%x, n, &
671  c_xh, this%bclst_du, gs_xh)
672  ksp_results(3) = this%ksp_vel%solve(ax, dv, v_res%x, n, &
673  c_xh, this%bclst_dv, gs_xh)
674  ksp_results(4) = this%ksp_vel%solve(ax, dw, w_res%x, n, &
675  c_xh, this%bclst_dw, gs_xh)
676  call profiler_end_region
677 
678  call this%proj_u%post_solving(du%x, ax, c_xh, &
679  this%bclst_du, gs_xh, n, tstep, dt_controller)
680  call this%proj_v%post_solving(dv%x, ax, c_xh, &
681  this%bclst_dv, gs_xh, n, tstep, dt_controller)
682  call this%proj_w%post_solving(dw%x, ax, c_xh, &
683  this%bclst_dw, gs_xh, n, tstep, dt_controller)
684 
685  if (neko_bcknd_device .eq. 1) then
686  call device_opadd2cm(u%x_d, v%x_d, w%x_d, &
687  du%x_d, dv%x_d, dw%x_d, 1.0_rp, n, msh%gdim)
688  else
689  call opadd2cm(u%x, v%x, w%x, du%x, dv%x, dw%x, 1.0_rp, n, msh%gdim)
690  end if
691 
692  if (this%forced_flow_rate) then
693  call this%vol_flow%adjust( u, v, w, p, u_res, v_res, w_res, p_res, &
694  c_xh, gs_xh, ext_bdf, rho, mu,&
695  dt, this%bclst_dp, this%bclst_du, this%bclst_dv, &
696  this%bclst_dw, this%bclst_vel_res, ax, this%ksp_prs, &
697  this%ksp_vel, this%pc_prs, this%pc_vel, this%ksp_prs%max_iter, &
698  this%ksp_vel%max_iter)
699  end if
700 
701  call fluid_step_info(tstep, t, dt, ksp_results)
702 
703  call this%scratch%relinquish_field(temp_indices)
704 
705  end associate
706  call profiler_end_region
707  end subroutine fluid_pnpn_step
708 
709 
710 
711 end module fluid_pnpn
Copy data between host and device (or device and device)
Definition: device.F90:51
Retrieves a parameter by name or throws an error.
Definition: json_utils.f90:44
Contains the factory routine for advection_t children.
subroutine, public advection_factory(this, json, coef)
A factory for advection_t decendants.
Subroutines to add advection terms to the RHS of a transport equation.
Definition: advection.f90:34
subroutine, public ax_helm_factory(Ax)
Factory routine for the a Helmholtz problem matrix-vector product. The selection is based on the comp...
Defines a Matrix-vector product.
Definition: ax.f90:34
Defines a boundary condition.
Definition: bc.f90:34
subroutine, public bc_list_add(bclst, bc)
Add a condition to a list of boundary conditions.
Definition: bc.f90:490
subroutine, public bc_list_apply_vector(bclst, x, y, z, n, t, tstep)
Apply a list of boundary conditions to a vector field.
Definition: bc.f90:572
subroutine, public bc_list_init(bclst, size)
Constructor for a list of boundary conditions.
Definition: bc.f90:449
subroutine, public bc_list_free(bclst)
Destructor for a list of boundary conditions.
Definition: bc.f90:476
subroutine, public bc_list_apply_scalar(bclst, x, n, t, tstep)
Apply a list of boundary conditions to a scalar field.
Definition: bc.f90:515
Coefficients.
Definition: coef.f90:34
subroutine, public device_add2(a_d, b_d, n)
subroutine, public device_col2(a_d, b_d, n)
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.
Stores a series fields.
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)
Prints for prs, velx, vely, velz the following: Number of iterations, start residual,...
Definition: fluid_aux.f90:17
Modular version of the Classic Nek5000 Pn/Pn formulation for fluids.
Definition: fluid_pnpn.f90:34
subroutine fluid_pnpn_init(this, msh, lx, params, user, material_properties)
Definition: fluid_pnpn.f90:138
subroutine fluid_pnpn_step(this, t, tstep, dt, ext_bdf, dt_controller)
Advance fluid simulation in time.
Definition: fluid_pnpn.f90:514
subroutine fluid_pnpn_free(this)
Definition: fluid_pnpn.f90:447
subroutine fluid_pnpn_restart(this, dtlag, tlag)
Definition: fluid_pnpn.f90:321
Fluid formulations.
Gather-scatter.
Utilities for retrieving parameters from the case files.
Definition: json_utils.f90:34
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:61
Implements material_properties_t type.
Definition: math.f90:60
subroutine, public add2(a, b, n)
Vector addition .
Definition: math.f90:503
subroutine, public col2(a, b, n)
Vector multiplication .
Definition: math.f90:645
Collection of vector field operations operating on and . Note that in general the indices and ....
Definition: mathops.f90:65
subroutine opcolv(a1, a2, a3, c, gdim, n)
Definition: mathops.f90:94
subroutine opadd2cm(a1, a2, a3, b1, b2, b3, c, n, gdim)
Definition: mathops.f90:139
Defines a mesh.
Definition: mesh.f90:34
Build configurations.
Definition: neko_config.f90:34
integer, parameter neko_bcknd_device
Definition: neko_config.f90:44
Dirichlet condition on axis aligned plane in the non normal direction.
Definition: non_normal.f90:34
integer, parameter, public rp
Global precision used in computations.
Definition: num_types.f90:12
Defines Pressure residual factory for the Pn-Pn formulation.
subroutine, public pnpn_prs_res_factory(prs_res)
subroutine, public pnpn_vel_res_factory(vel_res)
Defines Pressure and velocity residuals in the Pn-Pn formulation.
Definition: pnpn_res.f90:34
Profiling interface.
Definition: profiler.F90:34
subroutine, public profiler_end_region
End the most recently started profiler region.
Definition: profiler.F90:95
subroutine, public profiler_start_region(name, region_id)
Started a named (name) profiler region.
Definition: profiler.F90:76
Project x onto X, the space of old solutions and back again.
Definition: projection.f90:63
Fluid abbdf factory for the Pn-Pn formulation.
subroutine, public rhs_maker_ext_fctry(makeabf)
subroutine, public rhs_maker_sumab_fctry(sumab)
subroutine, public rhs_maker_bdf_fctry(makebdf)
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.
Definition: source_term.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
Base abstract type for computing the advection operator.
Definition: advection.f90:53
Base type for a matrix-vector product providing .
Definition: ax.f90:43
A list of boundary conditions.
Definition: bc.f90:102
Coefficients defined on a given (mesh, ) tuple. Arrays use indices (i,j,k,e): element e,...
Definition: coef.f90:54
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:55
Contains all the material properties necessary in the simulation.
Dirichlet condition in non normal direction of a plane.
Definition: non_normal.f90:50
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 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 ...
Provides a tool to set time step dt.