346 subroutine fluid_pnpn_init(this, msh, lx, params, user, chkp)
347 class(fluid_pnpn_t),
target,
intent(inout) :: this
348 type(
mesh_t),
target,
intent(inout) :: msh
349 integer,
intent(in) :: lx
350 type(json_file),
target,
intent(inout) :: params
351 type(
user_t),
target,
intent(in) :: user
352 type(
chkp_t),
target,
intent(inout) :: chkp
353 character(len=15),
parameter :: scheme =
'Modular (Pn/Pn)'
355 class(
bc_t),
pointer :: bc_i, vel_bc
356 real(kind=
rp) :: abs_tol
357 character(len=LOG_SIZE) :: log_buf
358 integer :: ierr, integer_val, solver_maxiter
359 character(len=:),
allocatable :: solver_type, precon_type
360 logical :: monitor, found
362 type(json_file) :: numerics_params, precon_params
364 real(kind=
dp),
pointer :: tlag(:), dtlag(:)
369 call this%init_base(msh, lx, params, scheme,
user, .true.)
381 allocate(this%ext_bdf)
382 call this%ext_bdf%init(integer_val)
385 this%full_stress_formulation, .false.)
389 call this%c_Xh%generate_cyclic_bc()
392 call fluid_pnpn_ax_vel_factory(this)
394 if (this%full_stress_formulation)
then
396 call pnpn_prs_res_stress_factory(this%prs_res)
399 call pnpn_vel_res_stress_factory(this%vel_res)
405 call pnpn_prs_res_factory(this%prs_res)
408 call pnpn_vel_res_factory(this%vel_res)
415 call this%bcs_vel_projector%init(this%c_Xh)
417 if (params%valid_path(
'case.fluid.nut_field'))
then
418 if (.not. this%full_stress_formulation)
then
419 call neko_error(
"You need to set full_stress_formulation to " // &
420 "true for the fluid to have a spatially varying " // &
423 call json_get(params,
'case.fluid.nut_field', this%nut_field_name)
425 this%nut_field_name =
""
429 if (this%c_Xh%geo_compression)
then
430 call ax_helm_allocator(this%Ax_prs, type_name =
"standard_compr")
432 call ax_helm_allocator(this%Ax_prs, type_name =
"standard")
437 call rhs_maker_sumab_fctry(this%sumab)
440 call rhs_maker_ext_fctry(this%makeabf)
443 call rhs_maker_bdf_fctry(this%makebdf)
446 call rhs_maker_oifs_fctry(this%makeoifs)
449 associate(xh_lx => this%Xh%lx, xh_ly => this%Xh%ly, xh_lz => this%Xh%lz, &
450 dm_xh => this%dm_Xh, nelv => this%msh%nelv)
452 call this%p_res%init(dm_xh,
"p_res")
453 call this%u_res%init(dm_xh,
"u_res")
454 call this%v_res%init(dm_xh,
"v_res")
455 call this%w_res%init(dm_xh,
"w_res")
456 call this%abx1%init(dm_xh,
"abx1")
457 call this%aby1%init(dm_xh,
"aby1")
458 call this%abz1%init(dm_xh,
"abz1")
459 call this%abx2%init(dm_xh,
"abx2")
460 call this%aby2%init(dm_xh,
"aby2")
461 call this%abz2%init(dm_xh,
"abz2")
462 call this%advx%init(dm_xh,
"advx")
463 call this%advy%init(dm_xh,
"advy")
464 call this%advz%init(dm_xh,
"advz")
467 call this%du%init(this%dm_Xh,
'du')
468 call this%dv%init(this%dm_Xh,
'dv')
469 call this%dw%init(this%dm_Xh,
'dw')
470 call this%dp%init(this%dm_Xh,
'dp')
472 call this%ale%init(this%c_Xh, params,
user, chkp)
474 call neko_log%section(
"Fluid boundary conditions")
476 call this%setup_bcs(
user, params)
480 if (found)
call this%write_boundary_conditions()
483 call this%proj_prs%init(this%dm_Xh%size(), this%pr_projection_dim, &
484 this%pr_projection_activ_step, &
485 this%pr_projection_reorthogonalize_basis)
487 call this%proj_vel%init(this%dm_Xh%size(), this%vel_projection_dim, &
488 this%vel_projection_activ_step)
494 if (params%valid_path(
'case.fluid.flow_rate_force'))
then
495 call this%vol_flow%init(this%dm_Xh, params)
499 call neko_log%section(
"Pressure solver")
502 'case.fluid.pressure_solver.max_iterations', &
504 call json_get(params,
'case.fluid.pressure_solver.type', solver_type)
505 call json_get(params,
'case.fluid.pressure_solver.preconditioner.type', &
508 'case.fluid.pressure_solver.preconditioner', precon_params)
510 'case.fluid.pressure_solver.absolute_tolerance', &
514 call neko_log%message(
'Type : ('// trim(solver_type) // &
515 ', ' // trim(precon_type) //
')')
516 write(log_buf,
'(A,ES13.6)')
'Abs tol :', abs_tol
519 call this%solver_factory(this%ksp_prs, this%dm_Xh%size(), &
520 solver_type, solver_maxiter, abs_tol, monitor)
521 call this%precon_factory_(this%pc_prs, this%ksp_prs, &
522 this%c_Xh, this%bcs_prs, &
523 precon_type, precon_params)
531 call json_get(params,
'case.numerics', numerics_params)
532 call chkp%get_time_history(tlag, dtlag)
533 call advection_factory(this%adv, numerics_params, this%c_Xh, &
534 this%ulag, this%vlag, this%wlag, &
535 dtlag, tlag, this%ext_bdf, &
540 payload => this%chkp%add_payload(
"fluid")
541 call payload%add_field(this%u)
542 call payload%add_field(this%v)
543 call payload%add_field(this%w)
544 call payload%add_field(this%p)
545 call payload%add_field(this%abx1)
546 call payload%add_field(this%abx2)
547 call payload%add_field(this%aby1)
548 call payload%add_field(this%aby2)
549 call payload%add_field(this%abz1)
550 call payload%add_field(this%abz2)
551 call payload%add_series(this%ulag)
552 call payload%add_series(this%vlag)
553 call payload%add_series(this%wlag)
557 this%schwarz_iterations, 0)
561 nullify(bc_i, vel_bc)
597 subroutine fluid_pnpn_restart(this, chkp)
598 class(fluid_pnpn_t),
target,
intent(inout) :: this
599 type(chkp_t),
intent(inout) :: chkp
601 class(bc_t),
pointer :: bc_i
603 n = this%u%dof%size()
604 if (
allocated(chkp%previous_mesh%elements) .or. &
605 chkp%previous_Xh%lx .ne. this%Xh%lx)
then
606 associate(u => this%u, v => this%v, w => this%w, p => this%p, &
607 c_xh => this%c_Xh, ulag => this%ulag, vlag => this%vlag, &
609 do concurrent(j = 1:n)
610 u%x(j,1,1,1) = u%x(j,1,1,1) * c_xh%mult(j,1,1,1)
611 v%x(j,1,1,1) = v%x(j,1,1,1) * c_xh%mult(j,1,1,1)
612 w%x(j,1,1,1) = w%x(j,1,1,1) * c_xh%mult(j,1,1,1)
613 p%x(j,1,1,1) = p%x(j,1,1,1) * c_xh%mult(j,1,1,1)
615 do i = 1, this%ulag%size()
616 do concurrent(j = 1:n)
617 ulag%lf(i)%x(j,1,1,1) = ulag%lf(i)%x(j,1,1,1) &
619 vlag%lf(i)%x(j,1,1,1) = vlag%lf(i)%x(j,1,1,1) &
621 wlag%lf(i)%x(j,1,1,1) = wlag%lf(i)%x(j,1,1,1) &
628 if (neko_bcknd_device .eq. 1)
then
629 associate(u => this%u, v => this%v, w => this%w, &
630 ulag => this%ulag, vlag => this%vlag, wlag => this%wlag,&
632 call device_memcpy(u%x, u%x_d, u%dof%size(), &
633 host_to_device, sync = .false.)
634 call device_memcpy(v%x, v%x_d, v%dof%size(), &
635 host_to_device, sync = .false.)
636 call device_memcpy(w%x, w%x_d, w%dof%size(), &
637 host_to_device, sync = .false.)
638 call device_memcpy(p%x, p%x_d, p%dof%size(), &
639 host_to_device, sync = .false.)
640 call device_memcpy(ulag%lf(1)%x, ulag%lf(1)%x_d, &
641 u%dof%size(), host_to_device, sync = .false.)
642 call device_memcpy(ulag%lf(2)%x, ulag%lf(2)%x_d, &
643 u%dof%size(), host_to_device, sync = .false.)
645 call device_memcpy(vlag%lf(1)%x, vlag%lf(1)%x_d, &
646 v%dof%size(), host_to_device, sync = .false.)
647 call device_memcpy(vlag%lf(2)%x, vlag%lf(2)%x_d, &
648 v%dof%size(), host_to_device, sync = .false.)
650 call device_memcpy(wlag%lf(1)%x, wlag%lf(1)%x_d, &
651 w%dof%size(), host_to_device, sync = .false.)
652 call device_memcpy(wlag%lf(2)%x, wlag%lf(2)%x_d, &
653 w%dof%size(), host_to_device, sync = .false.)
654 call device_memcpy(this%abx1%x, this%abx1%x_d, &
655 w%dof%size(), host_to_device, sync = .false.)
656 call device_memcpy(this%abx2%x, this%abx2%x_d, &
657 w%dof%size(), host_to_device, sync = .false.)
658 call device_memcpy(this%aby1%x, this%aby1%x_d, &
659 w%dof%size(), host_to_device, sync = .false.)
660 call device_memcpy(this%aby2%x, this%aby2%x_d, &
661 w%dof%size(), host_to_device, sync = .false.)
662 call device_memcpy(this%abz1%x, this%abz1%x_d, &
663 w%dof%size(), host_to_device, sync = .false.)
664 call device_memcpy(this%abz2%x, this%abz2%x_d, &
665 w%dof%size(), host_to_device, sync = .false.)
666 call device_memcpy(this%advx%x, this%advx%x_d, &
667 w%dof%size(), host_to_device, sync = .false.)
668 call device_memcpy(this%advy%x, this%advy%x_d, &
669 w%dof%size(), host_to_device, sync = .false.)
670 call device_memcpy(this%advz%x, this%advz%x_d, &
671 w%dof%size(), host_to_device, sync = .false.)
678 if (
allocated(chkp%previous_mesh%elements) &
679 .or. chkp%previous_Xh%lx .ne. this%Xh%lx)
then
681 call rotate_cyc(this%u, this%v, this%w, 1, this%c_Xh)
682 call this%gs_Xh%op(this%u, gs_op_add)
683 call this%gs_Xh%op(this%v, gs_op_add)
684 call this%gs_Xh%op(this%w, gs_op_add)
685 call this%gs_Xh%op(this%p, gs_op_add)
686 call rotate_cyc(this%u, this%v, this%w, 0, this%c_Xh)
688 do i = 1, this%ulag%size()
689 call rotate_cyc(this%ulag%lf(i), this%vlag%lf(i), &
690 this%wlag%lf(i), 1, this%c_Xh)
691 call this%gs_Xh%op(this%ulag%lf(i), gs_op_add)
692 call this%gs_Xh%op(this%vlag%lf(i), gs_op_add)
693 call this%gs_Xh%op(this%wlag%lf(i), gs_op_add)
694 call rotate_cyc(this%ulag%lf(i), this%vlag%lf(i), &
695 this%wlag%lf(i), 0, this%c_Xh)
699 call this%ale%sync_chkp(this%c_Xh, this%Xh, this%adv, chkp, this%gs_Xh)
700 if (this%ale%active)
then
701 call this%bc_prs_surface%recompute_normals()
702 call this%bc_sym_surface%recompute_normals()
706 do i = 1, this%bcs_vel%size()
707 bc_i => this%bcs_vel%get(i)
708 call bc_i%restart(this%u, this%v, this%w, &
709 this%ulag, this%vlag, this%wlag)
713 do i = 1, this%bcs_prs%size()
714 bc_i => this%bcs_prs%get(i)
715 call bc_i%restart(this%p)
820 subroutine fluid_pnpn_step(this, time, dt_controller)
821 class(fluid_pnpn_t),
target,
intent(inout) :: this
822 type(time_state_t),
intent(in) :: time
823 type(time_step_controller_t),
intent(in) :: dt_controller
827 type(ksp_monitor_t) :: ksp_results(4)
830 type(file_t) :: dump_file
831 class(bc_t),
pointer :: bc_i
833 if (this%freeze)
return
835 n = this%dm_Xh%size()
837 call profiler_start_region(
'Fluid', 1)
838 associate(u => this%u, v => this%v, w => this%w, p => this%p, &
839 u_e => this%u_e, v_e => this%v_e, w_e => this%w_e, &
840 du => this%du, dv => this%dv, dw => this%dw, dp => this%dp, &
841 u_res => this%u_res, v_res => this%v_res, w_res => this%w_res, &
842 p_res => this%p_res, ax_vel => this%Ax_vel, ax_prs => this%Ax_prs, &
844 c_xh => this%c_Xh, dm_xh => this%dm_Xh, gs_xh => this%gs_Xh, &
845 ulag => this%ulag, vlag => this%vlag, wlag => this%wlag, &
846 msh => this%msh, prs_res => this%prs_res, &
847 source_term => this%source_term, vel_res => this%vel_res, &
848 sumab => this%sumab, makeoifs => this%makeoifs, &
849 makeabf => this%makeabf, makebdf => this%makebdf, &
850 vel_projection_dim => this%vel_projection_dim, &
851 pr_projection_dim => this%pr_projection_dim, &
853 rho => this%rho, mu_tot => this%mu_tot, &
854 f_x => this%f_x, f_y => this%f_y, f_z => this%f_z, &
855 t => time%t, tstep => time%tstep, dt => time%dt, &
856 ext_bdf => this%ext_bdf, event => glb_cmd_event, &
860 call sumab%compute_fluid(u_e, v_e, w_e, u, v, w, &
861 ulag, vlag, wlag, ext_bdf%advection_coeffs%x, ext_bdf%nadv)
864 call this%source_term%compute(time, extrapolate = .true.)
867 call this%bcs_vel%apply_vector(f_x%x, f_y%x, f_z%x, &
868 this%dm_Xh%size(), time, strong = .false.)
870 if (this%ale%active)
then
872 call neko_error(
"ALE is not yet supported " // &
873 "with OIFS time integration.")
876 call this%adv%compute_ale(u, v, w, &
877 ale%wm_x, ale%wm_y, ale%wm_z, &
879 xh, c_xh, dm_xh%size())
885 call this%adv%compute(u, v, w, &
886 this%advx, this%advy, this%advz, &
887 xh, this%c_Xh, dm_xh%size(),
real(dt, kind=rp))
894 call makeabf%compute_fluid(this%abx1, this%aby1, this%abz1,&
895 this%abx2, this%aby2, this%abz2, &
896 f_x%x, f_y%x, f_z%x, &
897 rho%x(1,1,1,1), ext_bdf%advection_coeffs%x, n)
901 call makeoifs%compute_fluid(this%advx%x, this%advy%x, this%advz%x, &
902 f_x%x, f_y%x, f_z%x, &
903 rho%x(1,1,1,1),
real(dt, kind=rp), n)
906 call this%adv%compute(u, v, w, &
908 xh, this%c_Xh, dm_xh%size())
915 call makeabf%compute_fluid(this%abx1, this%aby1, this%abz1,&
916 this%abx2, this%aby2, this%abz2, &
917 f_x%x, f_y%x, f_z%x, &
918 rho%x(1,1,1,1), ext_bdf%advection_coeffs%x, n)
924 call makebdf%compute_fluid(ulag, vlag, wlag, f_x%x, f_y%x, f_z%x, &
925 u, v, w, c_xh%B, c_xh%Blag, c_xh%Blaglag, rho%x(1,1,1,1), &
927 ext_bdf%diffusion_coeffs%x, ext_bdf%ndiff, n)
934 call this%source_term%compute(time, extrapolate = .false., scale = rho)
936 if (this%ale%active)
then
938 call this%ale%advance_mesh(c_xh, time, ext_bdf%nadv)
940 call profiler_start_region(
'ALE recompute metrics')
942 call c_xh%recompute_metrics()
945 call this%adv%recompute_metrics(c_xh, .true.)
947 call this%bc_prs_surface%recompute_normals()
948 call this%bc_sym_surface%recompute_normals()
949 call profiler_end_region(
'ALE recompute metrics')
957 call this%update_material_properties(time)
960 if (this%svv_enabled)
then
961 call this%svv%update(rho, tstep)
964 do iter = 1, 1 + this%schwarz_iterations
966 call this%bc_apply_vel(time, strong = .true.)
967 call this%bc_apply_prs(time)
970 call profiler_start_region(
'Pressure_residual', 18)
971 call prs_res%compute(p, p_res,&
976 this%bc_prs_surface, this%bc_sym_surface,&
977 ax_prs, ext_bdf%diffusion_coeffs%x(1),
real(dt, kind=rp), &
982 if (.not. this%prs_dirichlet .and. neko_bcknd_device .eq. 1)
then
983 call device_ortho(p_res%x_d, this%glb_n_points, n)
984 else if (.not. this%prs_dirichlet)
then
985 call ortho(p_res%x, this%glb_n_points, n)
988 call gs_xh%op(p_res, gs_op_add, event)
989 call device_event_sync(event)
992 call this%bcs_prs_projector%apply(p_res%x, p%dof%size())
995 call profiler_end_region(
'Pressure_residual', 18)
999 if (iter .eq. 1)
then
1000 call this%proj_prs%pre_solving(p_res%x, tstep, c_xh, n, &
1001 dt_controller, ax = ax_prs, gs_h = gs_xh, &
1002 bclst = this%bcs_prs_projector, string =
'Pressure')
1005 call this%pc_prs%update()
1007 call profiler_start_region(
'Pressure_solve', 3)
1011 this%ksp_prs%solve(ax_prs, dp, p_res%x, n, c_xh, &
1012 this%bcs_prs_projector, gs_xh)
1013 ksp_results(1)%name =
'Pressure'
1016 call profiler_end_region(
'Pressure_solve', 3)
1018 if (iter .eq. 1)
then
1019 call this%proj_prs%post_solving(dp%x, ax_prs, c_xh, &
1020 this%bcs_prs_projector, gs_xh, n, tstep, dt_controller)
1024 call field_add2(p, dp, n)
1025 if (.not. this%prs_dirichlet .and. neko_bcknd_device .eq. 1)
then
1026 call device_ortho(p%x_d, this%glb_n_points, n)
1027 else if (.not. this%prs_dirichlet)
then
1028 call ortho(p%x, this%glb_n_points, n)
1032 call profiler_start_region(
'Velocity_residual', 19)
1033 call vel_res%compute(ax_vel, u, v, w, &
1034 u_res, v_res, w_res, &
1038 mu_tot, rho, ext_bdf%diffusion_coeffs%x(1), &
1039 real(dt, kind=rp), dm_xh%size())
1041 call rotate_cyc(u_res, v_res, w_res, 1, c_xh)
1042 call gs_xh%op(u_res%x, v_res%x, w_res%x, dm_xh%size(), &
1044 call device_event_sync(event)
1045 call rotate_cyc(u_res, v_res, w_res, 0, c_xh)
1048 call this%bcs_vel_projector%apply(u_res%x, v_res%x, w_res%x, &
1052 call profiler_end_region(
'Velocity_residual', 19)
1054 if (iter .eq. 1)
then
1055 call this%proj_vel%pre_solving(u_res%x, v_res%x, w_res%x, &
1056 tstep, c_xh, n, dt_controller,
'Velocity')
1059 call this%pc_vel%update()
1061 call profiler_start_region(
"Velocity_solve", 4)
1062 ksp_results(2:4) = this%ksp_vel%solve_coupled(ax_vel, du, dv, dw, &
1063 u_res%x, v_res%x, w_res%x, n, c_xh, &
1064 this%bcs_vel_projector, gs_xh, &
1065 this%ksp_vel%max_iter)
1066 call profiler_end_region(
"Velocity_solve", 4)
1067 if (this%full_stress_formulation)
then
1068 ksp_results(2)%name =
'Momentum'
1070 ksp_results(2)%name =
'X-Velocity'
1071 ksp_results(3)%name =
'Y-Velocity'
1072 ksp_results(4)%name =
'Z-Velocity'
1075 if (iter .eq. 1)
then
1076 call this%proj_vel%post_solving(du%x, dv%x, dw%x, ax_vel, c_xh, &
1077 this%bcs_vel_projector, gs_xh, n, tstep, &
1081 if (neko_bcknd_device .eq. 1)
then
1082 call device_opadd2cm(u%x_d, v%x_d, w%x_d, &
1083 du%x_d, dv%x_d, dw%x_d, 1.0_rp, n, msh%gdim)
1085 call opadd2cm(u%x, v%x, w%x, du%x, dv%x, dw%x, 1.0_rp, n, msh%gdim)
1088 call fluid_step_info(time, ksp_results, &
1089 this%full_stress_formulation, this%strict_convergence, &
1090 this%allow_stabilization, iter)
1094 if (this%forced_flow_rate)
then
1096 call this%vol_flow%adjust( u, v, w, p, u_res, v_res, w_res, p_res, &
1097 c_xh, gs_xh, ext_bdf, rho%x(1,1,1,1), mu_tot, &
1098 real(dt, kind=rp), time, this%bcs_prs_projector, &
1099 this%bcs_vel_projector, ax_vel, ax_prs, this%ksp_prs, &
1100 this%ksp_vel, this%pc_prs, this%pc_vel, this%ksp_prs%max_iter, &
1101 this%ksp_vel%max_iter)
1107 call this%ale%update_mesh_velocity(c_xh, time)
1113 call profiler_end_region(
'Fluid', 1)
1126 subroutine fluid_pnpn_setup_bcs(this, user, params)
1127 class(fluid_pnpn_t),
target,
intent(inout) :: this
1128 type(user_t),
target,
intent(in) :: user
1129 type(json_file),
intent(inout) :: params
1130 integer :: i, n_bcs, j, k, l, zone_size, global_zone_size, ierr
1131 integer :: facet_value
1132 class(bc_t),
pointer :: bc_i
1133 type(json_core) :: core
1134 type(json_value),
pointer :: bc_object
1135 type(json_file) :: bc_subdict, velocity_subdict, pressure_subdict
1136 logical :: moving_, has_velocity, has_pressure, pressure_dirichlet
1139 logical,
allocatable :: marked_zones(:)
1140 integer,
allocatable :: zone_indices(:)
1141 character(len=256) :: error_msg
1142 character(len=:),
allocatable :: bc_type_str
1144 this%ale%has_moving_boundary = .false.
1147 call this%bc_prs_surface%init_from_components(this%c_Xh)
1148 call this%bc_sym_surface%init_from_components(this%c_Xh)
1151 if (params%valid_path(
'case.fluid.boundary_conditions'))
then
1152 call params%info(
'case.fluid.boundary_conditions', n_children = n_bcs)
1153 call params%get_core(core)
1154 call params%get(
'case.fluid.boundary_conditions', bc_object, found)
1156 call this%bcs_vel%init(n_bcs)
1157 call this%bcs_prs%init(n_bcs)
1159 allocate(marked_zones(
size(this%msh%labeled_zones)))
1160 marked_zones = .false.
1164 call json_extract_item(core, bc_object, i, bc_subdict)
1166 call json_get_or_lookup(bc_subdict,
"zone_indices", zone_indices)
1171 do j = 1,
size(zone_indices)
1172 zone_size = this%msh%labeled_zones(zone_indices(j))%size
1173 call mpi_allreduce(zone_size, global_zone_size, 1, &
1174 mpi_integer, mpi_max, neko_comm, ierr)
1176 if (global_zone_size .eq. 0)
then
1177 write(error_msg,
'(A, I0, A, A, I0, A)') &
1178 "Zone index ", zone_indices(j), &
1179 " is invalid as this zone has 0 size, meaning it ", &
1180 "is not in the mesh. Check fluid boundary condition ", &
1182 call neko_error(error_msg)
1185 if (marked_zones(zone_indices(j)))
then
1186 write(error_msg,
'(A, I0, A, A, A, A)') &
1187 "Zone with index ", zone_indices(j), &
1188 " has already been assigned a boundary condition. ", &
1189 "Please check your boundary_conditions entry for the ", &
1190 "fluid and make sure that each zone index appears only ", &
1191 "in a single boundary condition."
1192 call neko_error(error_msg)
1194 marked_zones(zone_indices(j)) = .true.
1198 call fluid_pnpn_bc_split(bc_subdict, velocity_subdict, &
1199 pressure_subdict, has_velocity, has_pressure)
1205 if (has_velocity)
then
1207 call json_get(velocity_subdict,
"type", bc_type_str)
1208 if (trim(bc_type_str) .eq.
"no_slip")
then
1209 call json_get_or_default(velocity_subdict,
"moving", moving_, &
1211 if (moving_) this%ale%has_moving_boundary = .true.
1214 call velocity_bc_factory(bc_i, this, velocity_subdict, &
1220 if (
associated(bc_i))
then
1223 type is (symmetry_aligned_t)
1228 call this%bcs_vel_projector%mark(bc_i%bc_x, component =
'x')
1229 call this%bcs_vel_projector%mark(bc_i%bc_y, component =
'y')
1230 call this%bcs_vel_projector%mark(bc_i%bc_z, component =
'z')
1231 call this%bcs_vel%append(bc_i)
1232 call this%bc_sym_surface%mark_facets(bc_i%marked_facet)
1233 type is (symmetry_t)
1236 if (.not. this%full_stress_formulation)
then
1237 call neko_error(
"The symmetry boundary condition " // &
1238 "requires the full stress formulation to be enabled.")
1240 call this%bcs_vel_projector%mark(bc_i)
1241 call this%bcs_vel%append(bc_i)
1242 call this%bc_sym_surface%mark_facets(bc_i%marked_facet)
1243 type is (non_normal_aligned_t)
1245 call this%bcs_vel_projector%mark(bc_i%bc_x, component =
'x')
1246 call this%bcs_vel_projector%mark(bc_i%bc_y, component =
'y')
1247 call this%bcs_vel_projector%mark(bc_i%bc_z, component =
'z')
1248 call this%bcs_vel%append(bc_i)
1249 type is (non_normal_t)
1250 call this%bcs_vel_projector%mark(bc_i)
1251 call this%bcs_vel%append(bc_i)
1252 type is (shear_stress_t)
1253 if (.not. this%full_stress_formulation)
then
1254 call neko_error(
"The shear_stress boundary condition " // &
1255 "requires the full stress formulation to be enabled.")
1257 call this%bcs_vel_projector%mark(bc_i)
1258 call this%bcs_vel%append(bc_i)
1259 type is (wall_model_bc_t)
1260 if (.not. this%full_stress_formulation)
then
1261 call neko_error(
"The wall_model boundary condition " // &
1262 "requires the full stress formulation to be enabled.")
1264 call this%bcs_vel_projector%mark(bc_i)
1265 call this%bcs_vel%append(bc_i)
1266 class is (mixed_bc_t)
1269 if (.not. this%full_stress_formulation)
then
1270 call neko_error(
"The " // trim(bc_i%name) // &
1271 " boundary condition is a mixed condition and " // &
1272 "requires the full stress formulation to be enabled.")
1274 call this%bcs_vel_projector%mark(bc_i)
1275 call this%bcs_vel%append(bc_i)
1279 if (bc_i%bc_type .eq. bc_dirichlet)
then
1280 call this%bc_prs_surface%mark_labeled_zones( &
1282 if (this%full_stress_formulation)
then
1283 call this%bcs_vel_projector%mark(bc_i)
1285 call this%bcs_vel_projector%mark(bc_i, component =
'x')
1286 call this%bcs_vel_projector%mark(bc_i, component =
'y')
1287 call this%bcs_vel_projector%mark(bc_i, component =
'z')
1291 call this%bcs_vel%append(bc_i)
1299 pressure_dirichlet = .false.
1300 if (has_pressure)
then
1301 call pressure_bc_factory(bc_i, this, pressure_subdict, &
1307 if (
associated(bc_i))
then
1308 call this%bcs_prs%append(bc_i)
1311 if (bc_i%bc_type .eq. bc_dirichlet)
then
1312 call this%bcs_prs_projector%mark(bc_i)
1313 pressure_dirichlet = .true.
1319 if (pressure_dirichlet)
then
1325 do j = 1,
size(zone_indices)
1326 do k = 1, this%msh%nelv
1327 do l = 1, 2 * this%msh%gdim
1328 if (this%msh%facet_type(l, k) .eq. -zone_indices(j))
then
1329 this%msh%facet_type(l, k) = facet_value
1336 call velocity_subdict%destroy()
1337 call pressure_subdict%destroy()
1339 if (this%ale%active .and. (.not. this%ale%has_moving_boundary))
then
1340 call neko_error(
"Case file error: ALE is active, " // &
1341 "but no moving wall was found. " // &
1342 "Use type = 'no_slip' with 'moving': true in case file.")
1346 do i = 1,
size(this%msh%labeled_zones)
1347 if ((this%msh%labeled_zones(i)%size .gt. 0) .and. &
1348 (.not. marked_zones(i)))
then
1349 write(error_msg,
'(A, I0)') &
1350 "No fluid boundary condition assigned to zone ", i
1351 call neko_error(error_msg)
1356 do i = 1,
size(this%msh%labeled_zones)
1357 if (this%msh%labeled_zones(i)%size .gt. 0)
then
1358 call neko_error(
"No boundary_conditions entry in the case file!")
1364 call this%bcs_vel%init()
1365 call this%bcs_prs%init()
1369 call this%bc_prs_surface%finalize()
1370 call this%bc_sym_surface%finalize()
1371 call this%bcs_vel_projector%finalize(rebuild_mask = .true.)
1374 this%prs_dirichlet = this%bcs_prs_projector%dof_mask%is_set()
1375 call mpi_allreduce(mpi_in_place, this%prs_dirichlet, 1, &
1376 mpi_logical, mpi_lor, neko_comm)
1378 if (
allocated(marked_zones))
then
1379 deallocate(marked_zones)
1382 if (
allocated(zone_indices))
then
1383 deallocate(zone_indices)
1386 nullify(bc_i, bc_object)
1391 subroutine fluid_pnpn_write_boundary_conditions(this)
1398 class(fluid_pnpn_t),
target,
intent(inout) :: this
1399 type(dirichlet_t) :: bdry_mask
1400 type(field_t),
pointer :: bdry_field
1401 type(file_t) :: bdry_file
1402 integer :: temp_index, i
1403 class(bc_t),
pointer :: bci
1404 character(len=LOG_SIZE) :: log_buf
1406 write(log_buf,
'(A)')
'Marking using integer keys in bdry0.f00000'
1407 call neko_log%message(log_buf)
1408 write(log_buf,
'(A)')
'Condition-value pairs: '
1409 call neko_log%message(log_buf)
1410 write(log_buf,
'(A)')
' no_slip (stationary wall) = 1'
1411 call neko_log%message(log_buf)
1412 write(log_buf,
'(A)')
' velocity_value = 2'
1413 call neko_log%message(log_buf)
1414 write(log_buf,
'(A)')
' outflow, normal_outflow (+dong) = 3'
1415 call neko_log%message(log_buf)
1416 write(log_buf,
'(A)')
' symmetry = 4'
1417 call neko_log%message(log_buf)
1418 write(log_buf,
'(A)')
' periodic = 6'
1419 call neko_log%message(log_buf)
1420 write(log_buf,
'(A)')
' user_velocity = 7'
1421 call neko_log%message(log_buf)
1422 write(log_buf,
'(A)')
' user_pressure = 8'
1423 call neko_log%message(log_buf)
1424 write(log_buf,
'(A)')
' shear_stress = 9'
1425 call neko_log%message(log_buf)
1426 write(log_buf,
'(A)')
' wall_modelling = 10'
1427 call neko_log%message(log_buf)
1428 write(log_buf,
'(A)')
' blasius_profile = 11'
1429 call neko_log%message(log_buf)
1430 write(log_buf,
'(A)')
' no_slip (moving wall) = 12'
1431 call neko_log%message(log_buf)
1433 call neko_scratch_registry%request_field(bdry_field, temp_index, .true.)
1437 call bdry_mask%init_from_components(this%c_Xh, 6.0_rp)
1438 call bdry_mask%mark_zone(this%msh%periodic)
1439 call bdry_mask%finalize()
1440 call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
1441 call bdry_mask%free()
1443 do i = 1, this%bcs_prs%size()
1444 bci => this%bcs_prs%get(i)
1445 select type (
bc => bci)
1446 type is (zero_dirichlet_t)
1447 call bdry_mask%init_from_components(this%c_Xh, 3.0_rp)
1448 call bdry_mask%mark_facets(bci%marked_facet)
1449 call bdry_mask%finalize()
1450 call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
1451 call bdry_mask%free()
1453 call bdry_mask%init_from_components(this%c_Xh, 3.0_rp)
1454 call bdry_mask%mark_facets(bci%marked_facet)
1455 call bdry_mask%finalize()
1456 call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
1457 call bdry_mask%free()
1459 call bdry_mask%init_from_components(this%c_Xh, 8.0_rp)
1460 call bdry_mask%mark_facets(bci%marked_facet)
1461 call bdry_mask%finalize()
1462 call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
1463 call bdry_mask%free()
1467 do i = 1, this%bcs_vel%size()
1468 bci => this%bcs_vel%get(i)
1469 select type (
bc => bci)
1471 if (
bc%is_moving)
then
1473 call bdry_mask%init_from_components(this%c_Xh, 12.0_rp)
1476 call bdry_mask%init_from_components(this%c_Xh, 1.0_rp)
1478 call bdry_mask%mark_facets(bci%marked_facet)
1479 call bdry_mask%finalize()
1480 call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
1481 call bdry_mask%free()
1483 call bdry_mask%init_from_components(this%c_Xh, 2.0_rp)
1484 call bdry_mask%mark_facets(bci%marked_facet)
1485 call bdry_mask%finalize()
1486 call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
1487 call bdry_mask%free()
1488 type is (symmetry_aligned_t)
1489 call bdry_mask%init_from_components(this%c_Xh, 4.0_rp)
1490 call bdry_mask%mark_facets(bci%marked_facet)
1491 call bdry_mask%finalize()
1492 call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
1493 call bdry_mask%free()
1494 type is (symmetry_t)
1495 call bdry_mask%init_from_components(this%c_Xh, 4.0_rp)
1496 call bdry_mask%mark_facets(bci%marked_facet)
1497 call bdry_mask%finalize()
1498 call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
1499 call bdry_mask%free()
1501 call bdry_mask%init_from_components(this%c_Xh, 7.0_rp)
1502 call bdry_mask%mark_facets(bci%marked_facet)
1503 call bdry_mask%finalize()
1504 call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
1505 call bdry_mask%free()
1506 type is (shear_stress_t)
1507 call bdry_mask%init_from_components(this%c_Xh, 9.0_rp)
1508 call bdry_mask%mark_facets(bci%marked_facet)
1509 call bdry_mask%finalize()
1510 call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
1511 call bdry_mask%free()
1512 type is (wall_model_bc_t)
1513 call bdry_mask%init_from_components(this%c_Xh, 10.0_rp)
1514 call bdry_mask%mark_facets(bci%marked_facet)
1515 call bdry_mask%finalize()
1516 call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
1517 call bdry_mask%free()
1519 call bdry_mask%init_from_components(this%c_Xh, 11.0_rp)
1520 call bdry_mask%mark_facets(bci%marked_facet)
1521 call bdry_mask%finalize()
1522 call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
1523 call bdry_mask%free()
1528 call bdry_file%init(
'bdry.fld')
1529 call bdry_file%write(bdry_field)
1531 call neko_scratch_registry%relinquish_field(temp_index)
1533 nullify(bdry_field, bci)