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
359 character(len=:),
allocatable :: solver_type, precon_type
362 type(json_file) :: numerics_params, precon_params, solver_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")
501 call json_get(params,
'case.fluid.pressure_solver', solver_params)
502 call json_get(params,
'case.fluid.pressure_solver.type', solver_type)
503 call json_get(params,
'case.fluid.pressure_solver.preconditioner.type', &
506 'case.fluid.pressure_solver.preconditioner', precon_params)
508 'case.fluid.pressure_solver.absolute_tolerance', &
510 call neko_log%message(
'Type : ('// trim(solver_type) // &
511 ', ' // trim(precon_type) //
')')
512 write(log_buf,
'(A,ES13.6)')
'Abs tol :', abs_tol
515 call this%solver_factory(this%ksp_prs, this%dm_Xh%size(), solver_params)
516 call this%precon_factory_(this%pc_prs, this%ksp_prs, &
517 this%c_Xh, this%bcs_prs, &
518 precon_type, precon_params)
526 call json_get(params,
'case.numerics', numerics_params)
527 call chkp%get_time_history(tlag, dtlag)
528 call advection_factory(this%adv, numerics_params, this%c_Xh, &
529 this%ulag, this%vlag, this%wlag, &
530 dtlag, tlag, this%ext_bdf, &
535 payload => this%chkp%add_payload(
"fluid")
536 call payload%add_field(this%u)
537 call payload%add_field(this%v)
538 call payload%add_field(this%w)
539 call payload%add_field(this%p)
540 call payload%add_field(this%abx1)
541 call payload%add_field(this%abx2)
542 call payload%add_field(this%aby1)
543 call payload%add_field(this%aby2)
544 call payload%add_field(this%abz1)
545 call payload%add_field(this%abz2)
546 call payload%add_series(this%ulag)
547 call payload%add_series(this%vlag)
548 call payload%add_series(this%wlag)
552 this%schwarz_iterations, 0)
556 nullify(bc_i, vel_bc)
592 subroutine fluid_pnpn_restart(this, chkp)
593 class(fluid_pnpn_t),
target,
intent(inout) :: this
594 type(chkp_t),
intent(inout) :: chkp
596 class(bc_t),
pointer :: bc_i
598 n = this%u%dof%size()
599 if (
allocated(chkp%previous_mesh%elements) .or. &
600 chkp%previous_Xh%lx .ne. this%Xh%lx)
then
601 associate(u => this%u, v => this%v, w => this%w, p => this%p, &
602 c_xh => this%c_Xh, ulag => this%ulag, vlag => this%vlag, &
604 do concurrent(j = 1:n)
605 u%x(j,1,1,1) = u%x(j,1,1,1) * c_xh%mult(j,1,1,1)
606 v%x(j,1,1,1) = v%x(j,1,1,1) * c_xh%mult(j,1,1,1)
607 w%x(j,1,1,1) = w%x(j,1,1,1) * c_xh%mult(j,1,1,1)
608 p%x(j,1,1,1) = p%x(j,1,1,1) * c_xh%mult(j,1,1,1)
610 do i = 1, this%ulag%size()
611 do concurrent(j = 1:n)
612 ulag%lf(i)%x(j,1,1,1) = ulag%lf(i)%x(j,1,1,1) &
614 vlag%lf(i)%x(j,1,1,1) = vlag%lf(i)%x(j,1,1,1) &
616 wlag%lf(i)%x(j,1,1,1) = wlag%lf(i)%x(j,1,1,1) &
623 if (neko_bcknd_device .eq. 1)
then
624 associate(u => this%u, v => this%v, w => this%w, &
625 ulag => this%ulag, vlag => this%vlag, wlag => this%wlag,&
627 call device_memcpy(u%x, u%x_d, u%dof%size(), &
628 host_to_device, sync = .false.)
629 call device_memcpy(v%x, v%x_d, v%dof%size(), &
630 host_to_device, sync = .false.)
631 call device_memcpy(w%x, w%x_d, w%dof%size(), &
632 host_to_device, sync = .false.)
633 call device_memcpy(p%x, p%x_d, p%dof%size(), &
634 host_to_device, sync = .false.)
635 call device_memcpy(ulag%lf(1)%x, ulag%lf(1)%x_d, &
636 u%dof%size(), host_to_device, sync = .false.)
637 call device_memcpy(ulag%lf(2)%x, ulag%lf(2)%x_d, &
638 u%dof%size(), host_to_device, sync = .false.)
640 call device_memcpy(vlag%lf(1)%x, vlag%lf(1)%x_d, &
641 v%dof%size(), host_to_device, sync = .false.)
642 call device_memcpy(vlag%lf(2)%x, vlag%lf(2)%x_d, &
643 v%dof%size(), host_to_device, sync = .false.)
645 call device_memcpy(wlag%lf(1)%x, wlag%lf(1)%x_d, &
646 w%dof%size(), host_to_device, sync = .false.)
647 call device_memcpy(wlag%lf(2)%x, wlag%lf(2)%x_d, &
648 w%dof%size(), host_to_device, sync = .false.)
649 call device_memcpy(this%abx1%x, this%abx1%x_d, &
650 w%dof%size(), host_to_device, sync = .false.)
651 call device_memcpy(this%abx2%x, this%abx2%x_d, &
652 w%dof%size(), host_to_device, sync = .false.)
653 call device_memcpy(this%aby1%x, this%aby1%x_d, &
654 w%dof%size(), host_to_device, sync = .false.)
655 call device_memcpy(this%aby2%x, this%aby2%x_d, &
656 w%dof%size(), host_to_device, sync = .false.)
657 call device_memcpy(this%abz1%x, this%abz1%x_d, &
658 w%dof%size(), host_to_device, sync = .false.)
659 call device_memcpy(this%abz2%x, this%abz2%x_d, &
660 w%dof%size(), host_to_device, sync = .false.)
661 call device_memcpy(this%advx%x, this%advx%x_d, &
662 w%dof%size(), host_to_device, sync = .false.)
663 call device_memcpy(this%advy%x, this%advy%x_d, &
664 w%dof%size(), host_to_device, sync = .false.)
665 call device_memcpy(this%advz%x, this%advz%x_d, &
666 w%dof%size(), host_to_device, sync = .false.)
673 if (
allocated(chkp%previous_mesh%elements) &
674 .or. chkp%previous_Xh%lx .ne. this%Xh%lx)
then
676 call rotate_cyc(this%u, this%v, this%w, 1, this%c_Xh)
677 call this%gs_Xh%op(this%u, gs_op_add)
678 call this%gs_Xh%op(this%v, gs_op_add)
679 call this%gs_Xh%op(this%w, gs_op_add)
680 call this%gs_Xh%op(this%p, gs_op_add)
681 call rotate_cyc(this%u, this%v, this%w, 0, this%c_Xh)
683 do i = 1, this%ulag%size()
684 call rotate_cyc(this%ulag%lf(i), this%vlag%lf(i), &
685 this%wlag%lf(i), 1, this%c_Xh)
686 call this%gs_Xh%op(this%ulag%lf(i), gs_op_add)
687 call this%gs_Xh%op(this%vlag%lf(i), gs_op_add)
688 call this%gs_Xh%op(this%wlag%lf(i), gs_op_add)
689 call rotate_cyc(this%ulag%lf(i), this%vlag%lf(i), &
690 this%wlag%lf(i), 0, this%c_Xh)
694 call this%ale%sync_chkp(this%c_Xh, this%Xh, this%adv, chkp, this%gs_Xh)
695 if (this%ale%active)
then
696 call this%bc_prs_surface%recompute_normals()
697 call this%bc_sym_surface%recompute_normals()
701 do i = 1, this%bcs_vel%size()
702 bc_i => this%bcs_vel%get(i)
703 call bc_i%restart(this%u, this%v, this%w, &
704 this%ulag, this%vlag, this%wlag)
708 do i = 1, this%bcs_prs%size()
709 bc_i => this%bcs_prs%get(i)
710 call bc_i%restart(this%p)
815 subroutine fluid_pnpn_step(this, time, dt_controller)
816 class(fluid_pnpn_t),
target,
intent(inout) :: this
817 type(time_state_t),
intent(in) :: time
818 type(time_step_controller_t),
intent(in) :: dt_controller
822 type(ksp_monitor_t) :: ksp_results(4)
825 type(file_t) :: dump_file
826 class(bc_t),
pointer :: bc_i
828 if (this%freeze)
return
830 n = this%dm_Xh%size()
832 call profiler_start_region(
'Fluid', 1)
833 associate(u => this%u, v => this%v, w => this%w, p => this%p, &
834 u_e => this%u_e, v_e => this%v_e, w_e => this%w_e, &
835 du => this%du, dv => this%dv, dw => this%dw, dp => this%dp, &
836 u_res => this%u_res, v_res => this%v_res, w_res => this%w_res, &
837 p_res => this%p_res, ax_vel => this%Ax_vel, ax_prs => this%Ax_prs, &
839 c_xh => this%c_Xh, dm_xh => this%dm_Xh, gs_xh => this%gs_Xh, &
840 ulag => this%ulag, vlag => this%vlag, wlag => this%wlag, &
841 msh => this%msh, prs_res => this%prs_res, &
842 source_term => this%source_term, vel_res => this%vel_res, &
843 sumab => this%sumab, makeoifs => this%makeoifs, &
844 makeabf => this%makeabf, makebdf => this%makebdf, &
845 vel_projection_dim => this%vel_projection_dim, &
846 pr_projection_dim => this%pr_projection_dim, &
848 rho => this%rho, mu_tot => this%mu_tot, &
849 f_x => this%f_x, f_y => this%f_y, f_z => this%f_z, &
850 t => time%t, tstep => time%tstep, dt => time%dt, &
851 ext_bdf => this%ext_bdf, event => glb_cmd_event, &
855 call sumab%compute_fluid(u_e, v_e, w_e, u, v, w, &
856 ulag, vlag, wlag, ext_bdf%advection_coeffs%x, ext_bdf%nadv)
859 call this%source_term%compute(time, extrapolate = .true.)
862 call this%bcs_vel%apply_vector(f_x%x, f_y%x, f_z%x, &
863 this%dm_Xh%size(), time, strong = .false.)
865 if (this%ale%active)
then
867 call neko_error(
"ALE is not yet supported " // &
868 "with OIFS time integration.")
871 call this%adv%compute_ale(u, v, w, &
872 ale%wm_x, ale%wm_y, ale%wm_z, &
874 xh, c_xh, dm_xh%size())
880 call this%adv%compute(u, v, w, &
881 this%advx, this%advy, this%advz, &
882 xh, this%c_Xh, dm_xh%size(),
real(dt, kind=rp))
889 call makeabf%compute_fluid(this%abx1, this%aby1, this%abz1,&
890 this%abx2, this%aby2, this%abz2, &
891 f_x%x, f_y%x, f_z%x, &
892 rho%x(1,1,1,1), ext_bdf%advection_coeffs%x, n)
896 call makeoifs%compute_fluid(this%advx%x, this%advy%x, this%advz%x, &
897 f_x%x, f_y%x, f_z%x, &
898 rho%x(1,1,1,1),
real(dt, kind=rp), n)
901 call this%adv%compute(u, v, w, &
903 xh, this%c_Xh, dm_xh%size())
910 call makeabf%compute_fluid(this%abx1, this%aby1, this%abz1,&
911 this%abx2, this%aby2, this%abz2, &
912 f_x%x, f_y%x, f_z%x, &
913 rho%x(1,1,1,1), ext_bdf%advection_coeffs%x, n)
919 call makebdf%compute_fluid(ulag, vlag, wlag, f_x%x, f_y%x, f_z%x, &
920 u, v, w, c_xh%B, c_xh%Blag, c_xh%Blaglag, rho%x(1,1,1,1), &
922 ext_bdf%diffusion_coeffs%x, ext_bdf%ndiff, n)
929 call this%source_term%compute(time, extrapolate = .false., scale = rho)
931 if (this%ale%active)
then
933 call this%ale%advance_mesh(c_xh, time, ext_bdf%nadv)
935 call profiler_start_region(
'ALE recompute metrics')
937 call c_xh%recompute_metrics()
940 call this%adv%recompute_metrics(c_xh, .true.)
942 call this%bc_prs_surface%recompute_normals()
943 call this%bc_sym_surface%recompute_normals()
944 call profiler_end_region(
'ALE recompute metrics')
952 call this%update_material_properties(time)
955 if (this%svv_enabled)
then
956 call this%svv%update(rho, tstep)
959 do iter = 1, 1 + this%schwarz_iterations
961 call this%bc_apply_vel(time, strong = .true.)
962 call this%bc_apply_prs(time)
965 call profiler_start_region(
'Pressure_residual', 18)
966 call prs_res%compute(p, p_res,&
971 this%bc_prs_surface, this%bc_sym_surface,&
972 ax_prs, ext_bdf%diffusion_coeffs%x(1),
real(dt, kind=rp), &
977 if (.not. this%prs_dirichlet .and. neko_bcknd_device .eq. 1)
then
978 call device_ortho(p_res%x_d, this%glb_n_points, n)
979 else if (.not. this%prs_dirichlet)
then
980 call ortho(p_res%x, this%glb_n_points, n)
983 call gs_xh%op(p_res, gs_op_add, event)
984 call device_event_sync(event)
987 call this%bcs_prs_projector%apply(p_res%x, p%dof%size())
990 call profiler_end_region(
'Pressure_residual', 18)
994 if (iter .eq. 1)
then
995 call this%proj_prs%pre_solving(p_res%x, tstep, c_xh, n, &
996 dt_controller, ax = ax_prs, gs_h = gs_xh, &
997 bclst = this%bcs_prs_projector, string =
'Pressure')
1000 call this%pc_prs%update()
1002 call profiler_start_region(
'Pressure_solve', 3)
1006 this%ksp_prs%solve(ax_prs, dp, p_res%x, n, c_xh, &
1007 this%bcs_prs_projector, gs_xh)
1008 ksp_results(1)%name =
'Pressure'
1011 call profiler_end_region(
'Pressure_solve', 3)
1013 if (iter .eq. 1)
then
1014 call this%proj_prs%post_solving(dp%x, ax_prs, c_xh, &
1015 this%bcs_prs_projector, gs_xh, n, tstep, dt_controller)
1019 call field_add2(p, dp, n)
1020 if (.not. this%prs_dirichlet .and. neko_bcknd_device .eq. 1)
then
1021 call device_ortho(p%x_d, this%glb_n_points, n)
1022 else if (.not. this%prs_dirichlet)
then
1023 call ortho(p%x, this%glb_n_points, n)
1027 call profiler_start_region(
'Velocity_residual', 19)
1028 call vel_res%compute(ax_vel, u, v, w, &
1029 u_res, v_res, w_res, &
1033 mu_tot, rho, ext_bdf%diffusion_coeffs%x(1), &
1034 real(dt, kind=rp), dm_xh%size())
1036 call rotate_cyc(u_res, v_res, w_res, 1, c_xh)
1037 call gs_xh%op(u_res%x, v_res%x, w_res%x, dm_xh%size(), &
1039 call device_event_sync(event)
1040 call rotate_cyc(u_res, v_res, w_res, 0, c_xh)
1043 call this%bcs_vel_projector%apply(u_res%x, v_res%x, w_res%x, &
1047 call profiler_end_region(
'Velocity_residual', 19)
1049 if (iter .eq. 1)
then
1050 call this%proj_vel%pre_solving(u_res%x, v_res%x, w_res%x, &
1051 tstep, c_xh, n, dt_controller,
'Velocity')
1054 call this%pc_vel%update()
1056 call profiler_start_region(
"Velocity_solve", 4)
1057 ksp_results(2:4) = this%ksp_vel%solve_coupled(ax_vel, du, dv, dw, &
1058 u_res%x, v_res%x, w_res%x, n, c_xh, &
1059 this%bcs_vel_projector, gs_xh, &
1060 this%ksp_vel%max_iter)
1061 call profiler_end_region(
"Velocity_solve", 4)
1062 if (this%full_stress_formulation)
then
1063 ksp_results(2)%name =
'Momentum'
1065 ksp_results(2)%name =
'X-Velocity'
1066 ksp_results(3)%name =
'Y-Velocity'
1067 ksp_results(4)%name =
'Z-Velocity'
1070 if (iter .eq. 1)
then
1071 call this%proj_vel%post_solving(du%x, dv%x, dw%x, ax_vel, c_xh, &
1072 this%bcs_vel_projector, gs_xh, n, tstep, &
1076 if (neko_bcknd_device .eq. 1)
then
1077 call device_opadd2cm(u%x_d, v%x_d, w%x_d, &
1078 du%x_d, dv%x_d, dw%x_d, 1.0_rp, n, msh%gdim)
1080 call opadd2cm(u%x, v%x, w%x, du%x, dv%x, dw%x, 1.0_rp, n, msh%gdim)
1083 call fluid_step_info(time, ksp_results, &
1084 this%full_stress_formulation, this%strict_convergence, &
1085 this%allow_stabilization, iter)
1089 if (this%forced_flow_rate)
then
1091 call this%vol_flow%adjust( u, v, w, p, u_res, v_res, w_res, p_res, &
1092 c_xh, gs_xh, ext_bdf, rho%x(1,1,1,1), mu_tot, &
1093 real(dt, kind=rp), time, this%bcs_prs_projector, &
1094 this%bcs_vel_projector, ax_vel, ax_prs, this%ksp_prs, &
1095 this%ksp_vel, this%pc_prs, this%pc_vel, this%ksp_prs%max_iter, &
1096 this%ksp_vel%max_iter)
1102 call this%ale%update_mesh_velocity(c_xh, time)
1108 call profiler_end_region(
'Fluid', 1)
1121 subroutine fluid_pnpn_setup_bcs(this, user, params)
1122 class(fluid_pnpn_t),
target,
intent(inout) :: this
1123 type(user_t),
target,
intent(in) :: user
1124 type(json_file),
intent(inout) :: params
1125 integer :: i, n_bcs, j, k, l, zone_size, global_zone_size, ierr
1126 integer :: facet_value
1127 class(bc_t),
pointer :: bc_i
1128 type(json_core) :: core
1129 type(json_value),
pointer :: bc_object
1130 type(json_file) :: bc_subdict, velocity_subdict, pressure_subdict
1131 logical :: moving_, has_velocity, has_pressure, pressure_dirichlet
1134 logical,
allocatable :: marked_zones(:)
1135 integer,
allocatable :: zone_indices(:)
1136 character(len=256) :: error_msg
1137 character(len=:),
allocatable :: bc_type_str
1139 this%ale%has_moving_boundary = .false.
1142 call this%bc_prs_surface%init_from_components(this%c_Xh)
1143 call this%bc_sym_surface%init_from_components(this%c_Xh)
1146 if (params%valid_path(
'case.fluid.boundary_conditions'))
then
1147 call params%info(
'case.fluid.boundary_conditions', n_children = n_bcs)
1148 call params%get_core(core)
1149 call params%get(
'case.fluid.boundary_conditions', bc_object, found)
1151 call this%bcs_vel%init(n_bcs)
1152 call this%bcs_prs%init(n_bcs)
1154 allocate(marked_zones(
size(this%msh%labeled_zones)))
1155 marked_zones = .false.
1159 call json_extract_item(core, bc_object, i, bc_subdict)
1161 call json_get_or_lookup(bc_subdict,
"zone_indices", zone_indices)
1166 do j = 1,
size(zone_indices)
1167 zone_size = this%msh%labeled_zones(zone_indices(j))%size
1168 call mpi_allreduce(zone_size, global_zone_size, 1, &
1169 mpi_integer, mpi_max, neko_comm, ierr)
1171 if (global_zone_size .eq. 0)
then
1172 write(error_msg,
'(A, I0, A, A, I0, A)') &
1173 "Zone index ", zone_indices(j), &
1174 " is invalid as this zone has 0 size, meaning it ", &
1175 "is not in the mesh. Check fluid boundary condition ", &
1177 call neko_error(error_msg)
1180 if (marked_zones(zone_indices(j)))
then
1181 write(error_msg,
'(A, I0, A, A, A, A)') &
1182 "Zone with index ", zone_indices(j), &
1183 " has already been assigned a boundary condition. ", &
1184 "Please check your boundary_conditions entry for the ", &
1185 "fluid and make sure that each zone index appears only ", &
1186 "in a single boundary condition."
1187 call neko_error(error_msg)
1189 marked_zones(zone_indices(j)) = .true.
1193 call fluid_pnpn_bc_split(bc_subdict, velocity_subdict, &
1194 pressure_subdict, has_velocity, has_pressure)
1200 if (has_velocity)
then
1202 call json_get(velocity_subdict,
"type", bc_type_str)
1203 if (trim(bc_type_str) .eq.
"no_slip")
then
1204 call json_get_or_default(velocity_subdict,
"moving", moving_, &
1206 if (moving_) this%ale%has_moving_boundary = .true.
1209 call velocity_bc_factory(bc_i, this, velocity_subdict, &
1215 if (
associated(bc_i))
then
1218 type is (symmetry_aligned_t)
1223 call this%bcs_vel_projector%mark(bc_i%bc_x, component =
'x')
1224 call this%bcs_vel_projector%mark(bc_i%bc_y, component =
'y')
1225 call this%bcs_vel_projector%mark(bc_i%bc_z, component =
'z')
1226 call this%bcs_vel%append(bc_i)
1227 call this%bc_sym_surface%mark_facets(bc_i%marked_facet)
1228 type is (symmetry_t)
1231 if (.not. this%full_stress_formulation)
then
1232 call neko_error(
"The symmetry boundary condition " // &
1233 "requires the full stress formulation to be enabled.")
1235 call this%bcs_vel_projector%mark(bc_i)
1236 call this%bcs_vel%append(bc_i)
1237 call this%bc_sym_surface%mark_facets(bc_i%marked_facet)
1238 type is (non_normal_aligned_t)
1240 call this%bcs_vel_projector%mark(bc_i%bc_x, component =
'x')
1241 call this%bcs_vel_projector%mark(bc_i%bc_y, component =
'y')
1242 call this%bcs_vel_projector%mark(bc_i%bc_z, component =
'z')
1243 call this%bcs_vel%append(bc_i)
1244 type is (non_normal_t)
1245 call this%bcs_vel_projector%mark(bc_i)
1246 call this%bcs_vel%append(bc_i)
1247 type is (shear_stress_t)
1248 if (.not. this%full_stress_formulation)
then
1249 call neko_error(
"The shear_stress boundary condition " // &
1250 "requires the full stress formulation to be enabled.")
1252 call this%bcs_vel_projector%mark(bc_i)
1253 call this%bcs_vel%append(bc_i)
1254 type is (wall_model_bc_t)
1255 if (.not. this%full_stress_formulation)
then
1256 call neko_error(
"The wall_model boundary condition " // &
1257 "requires the full stress formulation to be enabled.")
1259 call this%bcs_vel_projector%mark(bc_i)
1260 call this%bcs_vel%append(bc_i)
1261 class is (mixed_bc_t)
1264 if (.not. this%full_stress_formulation)
then
1265 call neko_error(
"The " // trim(bc_i%name) // &
1266 " boundary condition is a mixed condition and " // &
1267 "requires the full stress formulation to be enabled.")
1269 call this%bcs_vel_projector%mark(bc_i)
1270 call this%bcs_vel%append(bc_i)
1274 if (bc_i%bc_type .eq. bc_dirichlet)
then
1275 call this%bc_prs_surface%mark_labeled_zones( &
1277 if (this%full_stress_formulation)
then
1278 call this%bcs_vel_projector%mark(bc_i)
1280 call this%bcs_vel_projector%mark(bc_i, component =
'x')
1281 call this%bcs_vel_projector%mark(bc_i, component =
'y')
1282 call this%bcs_vel_projector%mark(bc_i, component =
'z')
1286 call this%bcs_vel%append(bc_i)
1294 pressure_dirichlet = .false.
1295 if (has_pressure)
then
1296 call pressure_bc_factory(bc_i, this, pressure_subdict, &
1302 if (
associated(bc_i))
then
1303 call this%bcs_prs%append(bc_i)
1306 if (bc_i%bc_type .eq. bc_dirichlet)
then
1307 call this%bcs_prs_projector%mark(bc_i)
1308 pressure_dirichlet = .true.
1314 if (pressure_dirichlet)
then
1320 do j = 1,
size(zone_indices)
1321 do k = 1, this%msh%nelv
1322 do l = 1, 2 * this%msh%gdim
1323 if (this%msh%facet_type(l, k) .eq. -zone_indices(j))
then
1324 this%msh%facet_type(l, k) = facet_value
1331 call velocity_subdict%destroy()
1332 call pressure_subdict%destroy()
1334 if (this%ale%active .and. (.not. this%ale%has_moving_boundary))
then
1335 call neko_error(
"Case file error: ALE is active, " // &
1336 "but no moving wall was found. " // &
1337 "Use type = 'no_slip' with 'moving': true in case file.")
1341 do i = 1,
size(this%msh%labeled_zones)
1342 if ((this%msh%labeled_zones(i)%size .gt. 0) .and. &
1343 (.not. marked_zones(i)))
then
1344 write(error_msg,
'(A, I0)') &
1345 "No fluid boundary condition assigned to zone ", i
1346 call neko_error(error_msg)
1351 do i = 1,
size(this%msh%labeled_zones)
1352 if (this%msh%labeled_zones(i)%size .gt. 0)
then
1353 call neko_error(
"No boundary_conditions entry in the case file!")
1359 call this%bcs_vel%init()
1360 call this%bcs_prs%init()
1364 call this%bc_prs_surface%finalize()
1365 call this%bc_sym_surface%finalize()
1366 call this%bcs_vel_projector%finalize(rebuild_mask = .true.)
1369 this%prs_dirichlet = this%bcs_prs_projector%dof_mask%is_set()
1370 call mpi_allreduce(mpi_in_place, this%prs_dirichlet, 1, &
1371 mpi_logical, mpi_lor, neko_comm)
1373 if (
allocated(marked_zones))
then
1374 deallocate(marked_zones)
1377 if (
allocated(zone_indices))
then
1378 deallocate(zone_indices)
1381 nullify(bc_i, bc_object)
1386 subroutine fluid_pnpn_write_boundary_conditions(this)
1393 class(fluid_pnpn_t),
target,
intent(inout) :: this
1394 type(dirichlet_t) :: bdry_mask
1395 type(field_t),
pointer :: bdry_field
1396 type(file_t) :: bdry_file
1397 integer :: temp_index, i
1398 class(bc_t),
pointer :: bci
1399 character(len=LOG_SIZE) :: log_buf
1401 write(log_buf,
'(A)')
'Marking using integer keys in bdry0.f00000'
1402 call neko_log%message(log_buf)
1403 write(log_buf,
'(A)')
'Condition-value pairs: '
1404 call neko_log%message(log_buf)
1405 write(log_buf,
'(A)')
' no_slip (stationary wall) = 1'
1406 call neko_log%message(log_buf)
1407 write(log_buf,
'(A)')
' velocity_value = 2'
1408 call neko_log%message(log_buf)
1409 write(log_buf,
'(A)')
' outflow, normal_outflow (+dong) = 3'
1410 call neko_log%message(log_buf)
1411 write(log_buf,
'(A)')
' symmetry = 4'
1412 call neko_log%message(log_buf)
1413 write(log_buf,
'(A)')
' periodic = 6'
1414 call neko_log%message(log_buf)
1415 write(log_buf,
'(A)')
' user_velocity = 7'
1416 call neko_log%message(log_buf)
1417 write(log_buf,
'(A)')
' user_pressure = 8'
1418 call neko_log%message(log_buf)
1419 write(log_buf,
'(A)')
' shear_stress = 9'
1420 call neko_log%message(log_buf)
1421 write(log_buf,
'(A)')
' wall_modelling = 10'
1422 call neko_log%message(log_buf)
1423 write(log_buf,
'(A)')
' blasius_profile = 11'
1424 call neko_log%message(log_buf)
1425 write(log_buf,
'(A)')
' no_slip (moving wall) = 12'
1426 call neko_log%message(log_buf)
1428 call neko_scratch_registry%request_field(bdry_field, temp_index, .true.)
1432 call bdry_mask%init_from_components(this%c_Xh, 6.0_rp)
1433 call bdry_mask%mark_zone(this%msh%periodic)
1434 call bdry_mask%finalize()
1435 call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
1436 call bdry_mask%free()
1438 do i = 1, this%bcs_prs%size()
1439 bci => this%bcs_prs%get(i)
1440 select type (
bc => bci)
1441 type is (zero_dirichlet_t)
1442 call bdry_mask%init_from_components(this%c_Xh, 3.0_rp)
1443 call bdry_mask%mark_facets(bci%marked_facet)
1444 call bdry_mask%finalize()
1445 call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
1446 call bdry_mask%free()
1448 call bdry_mask%init_from_components(this%c_Xh, 3.0_rp)
1449 call bdry_mask%mark_facets(bci%marked_facet)
1450 call bdry_mask%finalize()
1451 call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
1452 call bdry_mask%free()
1454 call bdry_mask%init_from_components(this%c_Xh, 8.0_rp)
1455 call bdry_mask%mark_facets(bci%marked_facet)
1456 call bdry_mask%finalize()
1457 call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
1458 call bdry_mask%free()
1462 do i = 1, this%bcs_vel%size()
1463 bci => this%bcs_vel%get(i)
1464 select type (
bc => bci)
1466 if (
bc%is_moving)
then
1468 call bdry_mask%init_from_components(this%c_Xh, 12.0_rp)
1471 call bdry_mask%init_from_components(this%c_Xh, 1.0_rp)
1473 call bdry_mask%mark_facets(bci%marked_facet)
1474 call bdry_mask%finalize()
1475 call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
1476 call bdry_mask%free()
1478 call bdry_mask%init_from_components(this%c_Xh, 2.0_rp)
1479 call bdry_mask%mark_facets(bci%marked_facet)
1480 call bdry_mask%finalize()
1481 call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
1482 call bdry_mask%free()
1483 type is (symmetry_aligned_t)
1484 call bdry_mask%init_from_components(this%c_Xh, 4.0_rp)
1485 call bdry_mask%mark_facets(bci%marked_facet)
1486 call bdry_mask%finalize()
1487 call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
1488 call bdry_mask%free()
1489 type is (symmetry_t)
1490 call bdry_mask%init_from_components(this%c_Xh, 4.0_rp)
1491 call bdry_mask%mark_facets(bci%marked_facet)
1492 call bdry_mask%finalize()
1493 call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
1494 call bdry_mask%free()
1496 call bdry_mask%init_from_components(this%c_Xh, 7.0_rp)
1497 call bdry_mask%mark_facets(bci%marked_facet)
1498 call bdry_mask%finalize()
1499 call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
1500 call bdry_mask%free()
1501 type is (shear_stress_t)
1502 call bdry_mask%init_from_components(this%c_Xh, 9.0_rp)
1503 call bdry_mask%mark_facets(bci%marked_facet)
1504 call bdry_mask%finalize()
1505 call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
1506 call bdry_mask%free()
1507 type is (wall_model_bc_t)
1508 call bdry_mask%init_from_components(this%c_Xh, 10.0_rp)
1509 call bdry_mask%mark_facets(bci%marked_facet)
1510 call bdry_mask%finalize()
1511 call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
1512 call bdry_mask%free()
1514 call bdry_mask%init_from_components(this%c_Xh, 11.0_rp)
1515 call bdry_mask%mark_facets(bci%marked_facet)
1516 call bdry_mask%finalize()
1517 call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
1518 call bdry_mask%free()
1523 call bdry_file%init(
'bdry.fld')
1524 call bdry_file%write(bdry_field)
1526 call neko_scratch_registry%relinquish_field(temp_index)
1528 nullify(bdry_field, bci)