37 use,
intrinsic :: iso_fortran_env, only: error_unit
38 use coefs,
only: coef_t
39 use symmetry,
only: symmetry_t
40 use registry,
only: neko_registry
41 use logger,
only: neko_log, log_size, neko_log_debug
42 use num_types,
only: rp
43 use krylov,
only: ksp_monitor_t
46 adjoint_pnpn_vel_res_factory
47 use rhs_maker,
only: rhs_maker_sumab_t, rhs_maker_bdf_t, rhs_maker_ext_t, &
48 rhs_maker_oifs_t, rhs_maker_sumab_fctry, rhs_maker_bdf_fctry, &
49 rhs_maker_ext_fctry, rhs_maker_oifs_fctry
52 use device_mathops,
only: device_opadd2cm
53 use fluid_aux,
only: fluid_step_info
54 use scratch_registry,
only: neko_scratch_registry
55 use projection,
only: projection_t
56 use projection_vel,
only: projection_vel_t
57 use device,
only: device_memcpy, host_to_device, device_event_sync, &
60 use profiler,
only: profiler_start_region, profiler_end_region
61 use json_module,
only: json_file, json_core, json_value
62 use json_utils,
only: json_get, json_get_or_default, json_extract_item
63 use ax_product,
only: ax_t, ax_helm_factory
64 use field,
only: field_t
65 use dirichlet,
only: dirichlet_t
66 use shear_stress,
only: shear_stress_t
67 use wall_model_bc,
only: wall_model_bc_t
68 use facet_normal,
only: facet_normal_t
69 use non_normal,
only: non_normal_t
70 use checkpoint,
only: chkp_t
71 use mesh,
only: mesh_t
72 use user_intf,
only: user_t
73 use time_step_controller,
only: time_step_controller_t
74 use gs_ops,
only: gs_op_add
75 use neko_config,
only: neko_bcknd_device
76 use mathops,
only: opadd2cm
77 use bc_list,
only: bc_list_t
78 use zero_dirichlet,
only: zero_dirichlet_t
79 use utils,
only: neko_error
80 use field_math,
only: field_add2, field_copy, &
83 use file,
only: file_t
84 use operators,
only: ortho
85 use opr_device,
only: device_ortho
86 use inflow,
only: inflow_t
87 use field_dirichlet,
only: field_dirichlet_t
88 use blasius,
only: blasius_t
89 use field_dirichlet_vector,
only: field_dirichlet_vector_t
90 use dong_outflow,
only: dong_outflow_t
91 use time_state,
only: time_state_t
92 use vector,
only: vector_t
93 use device_math,
only: device_vlsc3, device_cmult, device_col2
94 use math,
only: vlsc3, cmult, col2
95 use,
intrinsic :: iso_c_binding, only: c_ptr, c_null_ptr, c_associated
96 use comm,
only: neko_comm, mpi_real_precision
97 use mpi_f08,
only: mpi_sum, mpi_max, mpi_allreduce, mpi_integer, &
99 use operators,
only : opgrad, curl, grad
109 type(field_t) :: p_res, u_res, v_res, w_res
113 type(field_t) :: dp, du, dv, dw
120 class(ax_t),
allocatable :: ax_vel
122 class(ax_t),
allocatable :: ax_prs
129 type(projection_t) :: proj_prs
130 type(projection_vel_t) :: proj_vel
137 type(facet_normal_t) :: bc_prs_surface
140 type(facet_normal_t) :: bc_sym_surface
150 type(zero_dirichlet_t) :: bc_vel_res
152 type(zero_dirichlet_t) :: bc_du
154 type(zero_dirichlet_t) :: bc_dv
156 type(zero_dirichlet_t) :: bc_dw
158 type(zero_dirichlet_t) :: bc_dp
161 type(bc_list_t) :: bclst_vel_res
162 type(bc_list_t) :: bclst_du
163 type(bc_list_t) :: bclst_dv
164 type(bc_list_t) :: bclst_dw
165 type(bc_list_t) :: bclst_dp
170 logical :: prs_dirichlet = .false.
180 type(field_t) :: abx1, aby1, abz1
181 type(field_t) :: abx2, aby2, abz2
184 type(field_t) :: advx, advy, advz
193 class(rhs_maker_sumab_t),
allocatable :: sumab
196 class(rhs_maker_ext_t),
allocatable :: makeabf
199 class(rhs_maker_bdf_t),
allocatable :: makebdf
202 class(rhs_maker_oifs_t),
allocatable :: makeoifs
208 logical :: full_stress_formulation = .false.
213 real(kind=rp) :: norm_scaling
214 real(kind=rp) :: norm_target
215 real(kind=rp) :: norm_tolerance
221 real(kind=rp) :: norm_l2_base
224 real(kind=rp) :: norm_l2_upper
226 real(kind=rp) :: norm_l2_lower
229 type(file_t) :: file_output
233 procedure, pass(this) :: init => adjoint_fluid_pnpn_init
235 procedure, pass(this) :: free => adjoint_fluid_pnpn_free
237 procedure, pass(this) :: step => adjoint_fluid_pnpn_step
239 procedure, pass(this) :: restart => adjoint_fluid_pnpn_restart
241 procedure, pass(this) :: setup_bcs => adjoint_fluid_pnpn_setup_bcs
243 procedure, pass(this) :: write_boundary_conditions => &
244 adjoint_fluid_pnpn_write_boundary_conditions
247 procedure,
public, pass(this) :: pw_compute_ => power_iterations_compute
259 module subroutine pressure_bc_factory(object, scheme, json, coef, user)
260 class(bc_t),
pointer,
intent(inout) :: object
261 type(adjoint_fluid_pnpn_t),
intent(in) :: scheme
262 type(json_file),
intent(inout) :: json
263 type(coef_t),
intent(in) :: coef
264 type(user_t),
intent(in) :: user
265 end subroutine pressure_bc_factory
266 end interface pressure_bc_factory
275 interface velocity_bc_factory
276 module subroutine velocity_bc_factory(object, scheme, json, coef, user)
277 class(bc_t),
pointer,
intent(inout) :: object
278 type(adjoint_fluid_pnpn_t),
intent(in) :: scheme
279 type(json_file),
intent(inout) :: json
280 type(coef_t),
intent(in) :: coef
281 type(user_t),
intent(in) :: user
282 end subroutine velocity_bc_factory
283 end interface velocity_bc_factory
287 subroutine adjoint_fluid_pnpn_init(this, msh, lx, params, user, chkp)
288 class(adjoint_fluid_pnpn_t),
target,
intent(inout) :: this
289 type(mesh_t),
target,
intent(inout) :: msh
290 integer,
intent(in) :: lx
291 type(json_file),
target,
intent(inout) :: params
292 type(user_t),
target,
intent(in) :: user
293 type(chkp_t),
target,
intent(inout) :: chkp
294 character(len=15),
parameter :: scheme =
'Adjoint (Pn/Pn)'
295 real(kind=rp) :: abs_tol
296 character(len=LOG_SIZE) :: log_buf
297 integer :: integer_val, solver_maxiter
298 character(len=:),
allocatable :: solver_type, precon_type
299 logical :: monitor, found
301 type(json_file) :: numerics_params, precon_params
304 character(len=:),
allocatable :: file_name
305 character(len=256) :: header_line
310 call this%init_base(msh, lx, params, scheme, user, .true.)
314 call neko_registry%add_field(this%dm_Xh,
'p_adj')
315 this%p_adj => neko_registry%get_field(
'p_adj')
321 call json_get(params,
'case.numerics.time_order', integer_val)
322 allocate(this%ext_bdf)
323 call this%ext_bdf%init(integer_val)
325 call json_get_or_default(params,
"case.fluid.full_stress_formulation", &
326 this%full_stress_formulation, .false.)
328 if (this%full_stress_formulation .eqv. .true.)
then
330 "Full stress formulation is not supported in the adjoint module.")
341 call ax_helm_factory(this%Ax_vel, full_formulation = .false.)
344 call adjoint_pnpn_prs_res_factory(this%prs_res)
347 call adjoint_pnpn_vel_res_factory(this%vel_res)
350 if (params%valid_path(
'case.fluid.nut_field'))
then
351 if (this%full_stress_formulation .eqv. .false.)
then
352 call neko_error(
"You need to set full_stress_formulation to " // &
353 "true for the fluid to have a spatially varying " // &
356 call json_get(params,
'case.fluid.nut_field', this%nut_field_name)
358 this%nut_field_name =
""
362 call ax_helm_factory(this%Ax_prs, full_formulation = .false.)
366 call rhs_maker_sumab_fctry(this%sumab)
369 call rhs_maker_ext_fctry(this%makeabf)
372 call rhs_maker_bdf_fctry(this%makebdf)
375 call rhs_maker_oifs_fctry(this%makeoifs)
378 associate(xh_lx => this%Xh%lx, xh_ly => this%Xh%ly, xh_lz => this%Xh%lz, &
379 dm_xh => this%dm_Xh, nelv => this%msh%nelv)
381 call this%p_res%init(dm_xh,
"p_res")
382 call this%u_res%init(dm_xh,
"u_res")
383 call this%v_res%init(dm_xh,
"v_res")
384 call this%w_res%init(dm_xh,
"w_res")
385 call this%abx1%init(dm_xh,
"abx1")
386 call this%aby1%init(dm_xh,
"aby1")
387 call this%abz1%init(dm_xh,
"abz1")
388 call this%abx2%init(dm_xh,
"abx2")
389 call this%aby2%init(dm_xh,
"aby2")
390 call this%abz2%init(dm_xh,
"abz2")
391 call this%advx%init(dm_xh,
"advx")
392 call this%advy%init(dm_xh,
"advy")
393 call this%advz%init(dm_xh,
"advz")
396 call this%du%init(this%dm_Xh,
'du')
397 call this%dv%init(this%dm_Xh,
'dv')
398 call this%dw%init(this%dm_Xh,
'dw')
399 call this%dp%init(this%dm_Xh,
'dp')
402 call this%setup_bcs(user, params)
405 call json_get_or_default(params,
'case.output_boundary', found, .false.)
406 if (found)
call this%write_boundary_conditions()
408 call this%proj_prs%init(this%dm_Xh%size(), this%pr_projection_dim, &
409 this%pr_projection_activ_step)
411 call this%proj_vel%init(this%dm_Xh%size(), this%vel_projection_dim, &
412 this%vel_projection_activ_step)
415 call json_get_or_default(params,
'case.numerics.oifs', this%oifs, .false.)
416 if (params%valid_path(
'case.fluid.flow_rate_force'))
then
417 call neko_error(
"Flow rate forcing not available for adjoint_fluid_pnpn")
421 call neko_log%section(
"Pressure solver")
423 call json_get_or_default(params, &
424 'case.fluid.pressure_solver.max_iterations', &
426 call json_get(params,
'case.fluid.pressure_solver.type', solver_type)
427 call json_get(params,
'case.fluid.pressure_solver.preconditioner.type', &
429 call json_get(params, &
430 'case.fluid.pressure_solver.preconditioner', precon_params)
431 call json_get(params,
'case.fluid.pressure_solver.absolute_tolerance', &
433 call json_get_or_default(params,
'case.fluid.pressure_solver.monitor', &
435 call neko_log%message(
'Type : ('// trim(solver_type) // &
436 ', ' // trim(precon_type) //
')')
437 write(log_buf,
'(A,ES13.6)')
'Abs tol :', abs_tol
438 call neko_log%message(log_buf)
440 call this%solver_factory(this%ksp_prs, this%dm_Xh%size(), &
441 solver_type, solver_maxiter, abs_tol, monitor)
442 call this%precon_factory_(this%pc_prs, this%ksp_prs, &
443 this%c_Xh, this%dm_Xh, this%gs_Xh, this%bcs_prs, &
444 precon_type, precon_params)
445 call neko_log%end_section()
448 call neko_log%section(
"Advection factory")
449 call json_get_or_default(params,
'case.fluid.advection', advection, .true.)
450 call json_get(params,
'case.numerics', numerics_params)
451 call advection_adjoint_factory(this%adv, numerics_params, this%c_Xh, &
452 this%ulag, this%vlag, this%wlag, &
453 chkp%dtlag, chkp%tlag, this%ext_bdf, &
459 call this%chkp%add_fluid(this%u_adj, this%v_adj, this%w_adj, this%p_adj)
461 this%chkp%abx1 => this%abx1
462 this%chkp%abx2 => this%abx2
463 this%chkp%aby1 => this%aby1
464 this%chkp%aby2 => this%aby2
465 this%chkp%abz1 => this%abz1
466 this%chkp%abz2 => this%abz2
467 call this%chkp%add_lag(this%ulag, this%vlag, this%wlag)
469 call neko_log%end_section()
475 call json_get_or_default(params,
'norm_scaling', &
476 this%norm_scaling, 0.5_rp)
484 this%u_b => neko_registry%get_field(
'u')
485 this%v_b => neko_registry%get_field(
'v')
486 this%w_b => neko_registry%get_field(
'w')
487 this%p_b => neko_registry%get_field(
'p')
490 call json_get_or_default(params,
'norm_target', &
491 this%norm_target, -1.0_rp)
492 call json_get_or_default(params,
'norm_tolerance', &
493 this%norm_tolerance, 10.0_rp)
496 call json_get_or_default(params,
'output_file', &
497 file_name,
'power_iterations.csv')
498 call this%file_output%init(trim(file_name))
499 write(header_line,
'(A)')
'Time, Norm, Scaling'
500 call this%file_output%set_header(header_line)
502 end subroutine adjoint_fluid_pnpn_init
504 subroutine adjoint_fluid_pnpn_restart(this, chkp)
505 class(adjoint_fluid_pnpn_t),
target,
intent(inout) :: this
506 type(chkp_t),
intent(inout) :: chkp
507 real(kind=rp) :: dtlag(10), tlag(10)
513 n = this%u_adj%dof%size()
514 if (
allocated(this%chkp%previous_mesh%elements) .or. &
515 chkp%previous_Xh%lx .ne. this%Xh%lx)
then
516 associate(u => this%u_adj, v => this%v_adj, w => this%w_adj, &
517 p => this%p_adj, c_xh => this%c_Xh, ulag => this%ulag, &
518 vlag => this%vlag, wlag => this%wlag)
519 call col2(u%x, c_xh%mult, n)
520 call col2(v%x, c_xh%mult, n)
521 call col2(w%x, c_xh%mult, n)
522 call col2(p%x, c_xh%mult, n)
523 do i = 1, this%ulag%size()
524 call col2(ulag%lf(i)%x, c_xh%mult, n)
525 call col2(vlag%lf(i)%x, c_xh%mult, n)
526 call col2(wlag%lf(i)%x, c_xh%mult, n)
531 if (neko_bcknd_device .eq. 1)
then
532 associate(u => this%u_adj, v => this%v_adj, w => this%w_adj, &
533 ulag => this%ulag, vlag => this%vlag, wlag => this%wlag,&
535 call device_memcpy(u%x, u%x_d, u%dof%size(), &
536 host_to_device, sync = .false.)
537 call device_memcpy(v%x, v%x_d, v%dof%size(), &
538 host_to_device, sync = .false.)
539 call device_memcpy(w%x, w%x_d, w%dof%size(), &
540 host_to_device, sync = .false.)
541 call device_memcpy(p%x, p%x_d, p%dof%size(), &
542 host_to_device, sync = .false.)
543 call device_memcpy(ulag%lf(1)%x, ulag%lf(1)%x_d, &
544 u%dof%size(), host_to_device, sync = .false.)
545 call device_memcpy(ulag%lf(2)%x, ulag%lf(2)%x_d, &
546 u%dof%size(), host_to_device, sync = .false.)
548 call device_memcpy(vlag%lf(1)%x, vlag%lf(1)%x_d, &
549 v%dof%size(), host_to_device, sync = .false.)
550 call device_memcpy(vlag%lf(2)%x, vlag%lf(2)%x_d, &
551 v%dof%size(), host_to_device, sync = .false.)
553 call device_memcpy(wlag%lf(1)%x, wlag%lf(1)%x_d, &
554 w%dof%size(), host_to_device, sync = .false.)
555 call device_memcpy(wlag%lf(2)%x, wlag%lf(2)%x_d, &
556 w%dof%size(), host_to_device, sync = .false.)
557 call device_memcpy(this%abx1%x, this%abx1%x_d, &
558 w%dof%size(), host_to_device, sync = .false.)
559 call device_memcpy(this%abx2%x, this%abx2%x_d, &
560 w%dof%size(), host_to_device, sync = .false.)
561 call device_memcpy(this%aby1%x, this%aby1%x_d, &
562 w%dof%size(), host_to_device, sync = .false.)
563 call device_memcpy(this%aby2%x, this%aby2%x_d, &
564 w%dof%size(), host_to_device, sync = .false.)
565 call device_memcpy(this%abz1%x, this%abz1%x_d, &
566 w%dof%size(), host_to_device, sync = .false.)
567 call device_memcpy(this%abz2%x, this%abz2%x_d, &
568 w%dof%size(), host_to_device, sync = .false.)
569 call device_memcpy(this%advx%x, this%advx%x_d, &
570 w%dof%size(), host_to_device, sync = .false.)
571 call device_memcpy(this%advy%x, this%advy%x_d, &
572 w%dof%size(), host_to_device, sync = .false.)
573 call device_memcpy(this%advz%x, this%advz%x_d, &
574 w%dof%size(), host_to_device, sync = .false.)
581 if (
allocated(this%chkp%previous_mesh%elements) &
582 .or. this%chkp%previous_Xh%lx .ne. this%Xh%lx)
then
583 call this%gs_Xh%op(this%u_adj, gs_op_add)
584 call this%gs_Xh%op(this%v_adj, gs_op_add)
585 call this%gs_Xh%op(this%w_adj, gs_op_add)
586 call this%gs_Xh%op(this%p_adj, gs_op_add)
588 do i = 1, this%ulag%size()
589 call this%gs_Xh%op(this%ulag%lf(i), gs_op_add)
590 call this%gs_Xh%op(this%vlag%lf(i), gs_op_add)
591 call this%gs_Xh%op(this%wlag%lf(i), gs_op_add)
595 end subroutine adjoint_fluid_pnpn_restart
597 subroutine adjoint_fluid_pnpn_free(this)
598 class(adjoint_fluid_pnpn_t),
intent(inout) :: this
601 call this%scheme_free()
603 call this%bc_prs_surface%free()
604 call this%bc_sym_surface%free()
605 call this%bc_curl_curl%free()
607 call this%bc_vel_res%free()
608 call this%bc_du%free()
609 call this%bc_dv%free()
610 call this%bc_dw%free()
611 call this%bc_dp%free()
613 call this%bclst_vel_res%free()
614 call this%bclst_du%free()
615 call this%bclst_dv%free()
616 call this%bclst_dw%free()
617 call this%bclst_dp%free()
618 call this%proj_prs%free()
619 call this%proj_vel%free()
621 call this%p_res%free()
622 call this%u_res%free()
623 call this%v_res%free()
624 call this%w_res%free()
631 call this%abx1%free()
632 call this%aby1%free()
633 call this%abz1%free()
635 call this%abx2%free()
636 call this%aby2%free()
637 call this%abz2%free()
639 call this%advx%free()
640 call this%advy%free()
641 call this%advz%free()
643 if (
allocated(this%Ax_vel))
then
644 deallocate(this%Ax_vel)
647 if (
allocated(this%Ax_prs))
then
648 deallocate(this%Ax_prs)
651 if (
allocated(this%prs_res))
then
652 deallocate(this%prs_res)
655 if (
allocated(this%vel_res))
then
656 deallocate(this%vel_res)
659 if (
allocated(this%sumab))
then
660 deallocate(this%sumab)
663 if (
allocated(this%makeabf))
then
664 deallocate(this%makeabf)
667 if (
allocated(this%makebdf))
then
668 deallocate(this%makebdf)
671 if (
allocated(this%makeoifs))
then
672 deallocate(this%makeoifs)
675 if (
allocated(this%ext_bdf))
then
676 deallocate(this%ext_bdf)
681 end subroutine adjoint_fluid_pnpn_free
687 subroutine adjoint_fluid_pnpn_step(this, time, dt_controller)
688 class(adjoint_fluid_pnpn_t),
target,
intent(inout) :: this
689 type(time_state_t),
intent(in) :: time
690 type(time_step_controller_t),
intent(in) :: dt_controller
694 type(ksp_monitor_t) :: ksp_results(4)
695 type(field_t),
pointer :: dx_p_adj, dy_p_adj, dz_p_adj, nx1, nx2, nx3, &
697 integer :: temp_indices(3)
698 integer :: cc_indices(8)
699 real(kind=rp) :: rho_val, mu_val
701 if (this%freeze)
return
703 n = this%dm_Xh%size()
705 call profiler_start_region(
'Adjoint')
706 associate(u => this%u_adj, v => this%v_adj, w => this%w_adj, &
708 u_e => this%u_adj_e, v_e => this%v_adj_e, w_e => this%w_adj_e, &
709 du => this%du, dv => this%dv, dw => this%dw, dp => this%dp, &
710 u_b => this%u_b, v_b => this%v_b, w_b => this%w_b, &
711 u_res => this%u_res, v_res => this%v_res, w_res => this%w_res, &
712 p_res => this%p_res, ax_vel => this%Ax_vel, ax_prs => this%Ax_prs, &
714 c_xh => this%c_Xh, dm_xh => this%dm_Xh, gs_xh => this%gs_Xh, &
715 ulag => this%ulag, vlag => this%vlag, wlag => this%wlag, &
716 msh => this%msh, prs_res => this%prs_res, &
717 source_term => this%source_term, vel_res => this%vel_res, &
718 sumab => this%sumab, &
719 makeabf => this%makeabf, makebdf => this%makebdf, &
720 vel_projection_dim => this%vel_projection_dim, &
721 pr_projection_dim => this%pr_projection_dim, &
723 rho => this%rho, mu => this%mu, &
724 f_x => this%f_adj_x, f_y => this%f_adj_y, f_z => this%f_adj_z, &
725 t => time%t, tstep => time%tstep, dt => time%dt, &
726 ext_bdf => this%ext_bdf, event => glb_cmd_event)
729 call sumab%compute_fluid(u_e, v_e, w_e, u, v, w, &
730 ulag, vlag, wlag, ext_bdf%advection_coeffs%x, ext_bdf%nadv)
733 call this%source_term%compute(time)
736 call this%bcs_vel%apply_vector(f_x%x, f_y%x, f_z%x, &
737 this%dm_Xh%size(), time, strong = .false.)
740 call neko_error(
"OIFS not implemented for adjoint")
744 call this%adv%compute_adjoint(u, v, w, u_b, v_b, w_b, &
746 xh, this%c_Xh, dm_xh%size())
752 call makeabf%compute_fluid(this%abx1, this%aby1, this%abz1,&
753 this%abx2, this%aby2, this%abz2, &
754 f_x%x, f_y%x, f_z%x, &
755 rho%x(1,1,1,1), ext_bdf%advection_coeffs%x, n)
758 call makebdf%compute_fluid(ulag, vlag, wlag, f_x%x, f_y%x, f_z%x, &
759 u, v, w, c_xh%B, rho%x(1,1,1,1), dt, &
760 ext_bdf%diffusion_coeffs%x, ext_bdf%ndiff, n, &
761 c_xh%Blag, c_xh%Blaglag)
768 call this%bc_apply_vel(time, strong = .true.)
769 call this%bc_apply_prs(time)
772 call neko_scratch_registry%request_field(dx_p_adj, cc_indices(1), .false.)
773 call neko_scratch_registry%request_field(dy_p_adj, cc_indices(2), .false.)
774 call neko_scratch_registry%request_field(dz_p_adj, cc_indices(3), .false.)
777 call neko_scratch_registry%request_field(nx1, cc_indices(4), .true.)
778 call neko_scratch_registry%request_field(nx2, cc_indices(5), .true.)
779 call neko_scratch_registry%request_field(nx3, cc_indices(6), .true.)
781 call neko_scratch_registry%request_field(work1, cc_indices(7), .false.)
782 call neko_scratch_registry%request_field(work2, cc_indices(8), .false.)
785 call grad(dx_p_adj%x, dy_p_adj%x, dz_p_adj%x, this%p_adj%x, c_xh)
788 call this%bc_curl_curl%apply_n_cross(nx1%x, nx2%x, nx3%x, dx_p_adj%x, &
789 dy_p_adj%x, dz_p_adj%x, dx_p_adj%size())
794 call curl(dx_p_adj, dy_p_adj, dz_p_adj, nx1, nx2, nx3, work1, work2, c_xh)
797 call gs_xh%op(dx_p_adj, gs_op_add, event)
798 call device_event_sync(event)
799 call gs_xh%op(dy_p_adj, gs_op_add, event)
800 call device_event_sync(event)
801 call gs_xh%op(dz_p_adj, gs_op_add, event)
802 call device_event_sync(event)
805 if (neko_bcknd_device .eq. 1)
then
806 call device_col2(dx_p_adj%x_d, c_xh%mult_d, dx_p_adj%size())
807 call device_col2(dy_p_adj%x_d, c_xh%mult_d, dx_p_adj%size())
808 call device_col2(dz_p_adj%x_d, c_xh%mult_d, dx_p_adj%size())
810 call col2(dx_p_adj%x, c_xh%mult, dx_p_adj%size())
811 call col2(dy_p_adj%x, c_xh%mult, dx_p_adj%size())
812 call col2(dz_p_adj%x, c_xh%mult, dx_p_adj%size())
815 rho_val = rho%x(1,1,1,1)
816 mu_val = mu%x(1,1,1,1)
817 call field_add2s2(f_x, dx_p_adj, -mu_val / rho_val)
818 call field_add2s2(f_y, dy_p_adj, -mu_val / rho_val)
819 call field_add2s2(f_z, dz_p_adj, -mu_val / rho_val)
821 call neko_scratch_registry%relinquish_field(cc_indices)
824 call this%update_material_properties(time)
828 call profiler_start_region(
'Adjoint_velocity_residual')
830 call vel_res%compute(ax_vel, u, v, w, &
831 u_res, v_res, w_res, &
835 mu, rho, ext_bdf%diffusion_coeffs%x(1), &
838 call gs_xh%op(u_res, gs_op_add, event)
839 call device_event_sync(event)
840 call gs_xh%op(v_res, gs_op_add, event)
841 call device_event_sync(event)
842 call gs_xh%op(w_res, gs_op_add, event)
843 call device_event_sync(event)
846 call this%bclst_vel_res%apply(u_res, v_res, w_res, time)
848 call profiler_end_region(
'Adjoint_velocity_residual')
850 call this%proj_vel%pre_solving(u_res%x, v_res%x, w_res%x, &
851 tstep, c_xh, n, dt_controller,
'Velocity')
853 call this%pc_vel%update()
855 call profiler_start_region(
"Adjoint_velocity_solve")
856 ksp_results(1:3) = this%ksp_vel%solve_coupled(ax_vel, du, dv, dw, &
857 u_res%x, v_res%x, w_res%x, n, c_xh, &
858 this%bclst_du, this%bclst_dv, this%bclst_dw, gs_xh, &
859 this%ksp_vel%max_iter)
861 call this%proj_vel%post_solving(du%x, dv%x, dw%x, ax_vel, c_xh, &
862 this%bclst_du, this%bclst_dv, this%bclst_dw, gs_xh, n, tstep, &
865 if (neko_bcknd_device .eq. 1)
then
866 call device_opadd2cm(u%x_d, v%x_d, w%x_d, &
867 du%x_d, dv%x_d, dw%x_d, 1.0_rp, n, msh%gdim)
869 call opadd2cm(u%x, v%x, w%x, du%x, dv%x, dw%x, 1.0_rp, n, msh%gdim)
871 call profiler_end_region(
"Adjoint_velocity_solve")
877 call field_copy(f_x, u)
878 call field_copy(f_y, v)
879 call field_copy(f_z, w)
881 call profiler_start_region(
'Adjoint_pressure_residual')
883 call prs_res%compute(p, p_res, &
887 this%bc_prs_surface, this%bc_sym_surface, &
888 ax_prs, ext_bdf%diffusion_coeffs%x(1), dt, &
892 if (.not. this%prs_dirichlet .and. neko_bcknd_device .eq. 1)
then
893 call device_ortho(p_res%x_d, this%glb_n_points, n)
894 else if (.not. this%prs_dirichlet)
then
895 call ortho(p_res%x, this%glb_n_points, n)
898 call gs_xh%op(p_res, gs_op_add, event)
899 call device_event_sync(event)
902 call this%bclst_dp%apply_scalar(p_res%x, p%dof%size(), time)
905 call profiler_end_region(
'Adjoint_pressure_residual')
908 call this%proj_prs%pre_solving(p_res%x, tstep, c_xh, n, dt_controller, &
911 call this%pc_prs%update()
913 call profiler_start_region(
'Adjoint_pressure_solve')
917 this%ksp_prs%solve(ax_prs, dp, p_res%x, n, c_xh, &
918 this%bclst_dp, gs_xh)
921 call profiler_end_region(
'Adjoint_pressure_solve')
923 call this%proj_prs%post_solving(dp%x, ax_prs, c_xh, &
924 this%bclst_dp, gs_xh, n, tstep, dt_controller)
927 call field_add2(p, dp, n)
928 if (.not. this%prs_dirichlet .and. neko_bcknd_device .eq. 1)
then
929 call device_ortho(p%x_d, this%glb_n_points, n)
930 else if (.not. this%prs_dirichlet)
then
931 call ortho(p%x, this%glb_n_points, n)
934 ksp_results(4)%name =
'Adjoint Pressure'
935 ksp_results(1)%name =
'Adjoint Velocity U'
936 ksp_results(2)%name =
'Adjoint Velocity V'
937 ksp_results(3)%name =
'Adjoint Velocity W'
939 if (this%forced_flow_rate)
then
940 call neko_error(
'Forced flow rate is not implemented for the adjoint')
946 call neko_scratch_registry%request_field(dx_p_adj, temp_indices(1), &
948 call neko_scratch_registry%request_field(dy_p_adj, temp_indices(2), &
950 call neko_scratch_registry%request_field(dz_p_adj, temp_indices(3), &
954 call opgrad(dx_p_adj%x, dy_p_adj%x, dz_p_adj%x, this%p_adj%x, c_xh)
957 call gs_xh%op(dx_p_adj, gs_op_add, event)
958 call device_event_sync(event)
959 call gs_xh%op(dy_p_adj, gs_op_add, event)
960 call device_event_sync(event)
961 call gs_xh%op(dz_p_adj, gs_op_add, event)
962 call device_event_sync(event)
965 if (neko_bcknd_device .eq. 1)
then
966 call device_col2(dx_p_adj%x_d, c_xh%Binv_d, dx_p_adj%size())
967 call device_col2(dy_p_adj%x_d, c_xh%Binv_d, dx_p_adj%size())
968 call device_col2(dz_p_adj%x_d, c_xh%Binv_d, dx_p_adj%size())
972 call col2(dx_p_adj%x, c_xh%Binv, dx_p_adj%size())
973 call col2(dy_p_adj%x, c_xh%Binv, dx_p_adj%size())
974 call col2(dz_p_adj%x, c_xh%Binv, dx_p_adj%size())
977 if (neko_bcknd_device .eq. 1)
then
978 call device_opadd2cm(u%x_d, v%x_d, w%x_d, dx_p_adj%x_d, &
979 dy_p_adj%x_d, dz_p_adj%x_d, -1.0_rp, n, msh%gdim)
981 call opadd2cm(u%x, v%x, w%x, dx_p_adj%x, dy_p_adj%x, dz_p_adj%x, &
982 -1.0_rp, n, msh%gdim)
985 call neko_scratch_registry%relinquish_field(temp_indices)
988 call fluid_step_info(time, ksp_results, &
989 this%full_stress_formulation, this%strict_convergence)
992 call profiler_end_region(
'Adjoint')
994 end subroutine adjoint_fluid_pnpn_step
1000 subroutine adjoint_fluid_pnpn_setup_bcs(this, user, params)
1001 use mpi_f08,
only: mpi_in_place
1002 class(adjoint_fluid_pnpn_t),
intent(inout) :: this
1003 type(user_t),
target,
intent(in) :: user
1004 type(json_file),
intent(inout) :: params
1005 integer :: i, n_bcs, j, zone_size, global_zone_size, ierr
1006 class(bc_t),
pointer :: bc_i
1007 type(json_core) :: core
1008 type(json_value),
pointer :: bc_object
1009 type(json_file) :: bc_subdict
1012 logical,
allocatable :: marked_zones(:)
1013 integer,
allocatable :: zone_indices(:)
1014 character(len=:),
allocatable :: json_key
1017 call this%bclst_vel_res%init()
1018 call this%bclst_du%init()
1019 call this%bclst_dv%init()
1020 call this%bclst_dw%init()
1021 call this%bclst_dp%init()
1023 call this%bc_vel_res%init_from_components(this%c_Xh)
1024 call this%bc_du%init_from_components(this%c_Xh)
1025 call this%bc_dv%init_from_components(this%c_Xh)
1026 call this%bc_dw%init_from_components(this%c_Xh)
1027 call this%bc_dp%init_from_components(this%c_Xh)
1030 call this%bc_prs_surface%init_from_components(this%c_Xh)
1031 call this%bc_sym_surface%init_from_components(this%c_Xh)
1032 call this%bc_curl_curl%init_from_components(this%c_Xh)
1034 json_key =
'case.adjoint_fluid.boundary_conditions'
1037 if (params%valid_path(json_key))
then
1038 call params%info(json_key, n_children = n_bcs)
1039 call params%get_core(core)
1040 call params%get(json_key, bc_object, found)
1045 call this%bcs_vel%init(n_bcs)
1047 allocate(marked_zones(
size(this%msh%labeled_zones)))
1048 marked_zones = .false.
1052 call json_extract_item(core, bc_object, i, bc_subdict)
1054 call json_get(bc_subdict,
"zone_indices", zone_indices)
1059 do j = 1,
size(zone_indices)
1060 zone_size = this%msh%labeled_zones(zone_indices(j))%size
1061 call mpi_allreduce(zone_size, global_zone_size, 1, &
1062 mpi_integer, mpi_max, neko_comm, ierr)
1064 if (global_zone_size .eq. 0)
then
1065 write(error_unit,
'(A, A, I0, A, A, I0, A)')
"*** ERROR ***: ",&
1066 "Zone index ", zone_indices(j), &
1067 " is invalid as this zone has 0 size, meaning it does ", &
1068 "not in the mesh. Check adjoint boundary condition ", &
1073 if (marked_zones(zone_indices(j)) .eqv. .true.)
then
1074 write(error_unit,
'(A, A, I0, A, A, A, A)')
"*** ERROR ***: ", &
1075 "Zone with index ", zone_indices(j), &
1076 " has already been assigned a boundary condition. ", &
1077 "Please check your boundary_conditions entry for the ", &
1078 "adjoint and make sure that each zone index appears ", &
1079 "only in a single boundary condition."
1082 marked_zones(zone_indices(j)) = .true.
1087 call velocity_bc_factory(bc_i, this, bc_subdict, this%c_Xh, user)
1091 if (
associated(bc_i))
then
1097 type is (symmetry_t)
1105 call this%bclst_vel_res%append(bc_i)
1106 call this%bc_du%mark_facets(bc_i%bc_x%marked_facet)
1107 call this%bc_dv%mark_facets(bc_i%bc_y%marked_facet)
1108 call this%bc_dw%mark_facets(bc_i%bc_z%marked_facet)
1110 call this%bcs_vel%append(bc_i)
1112 call this%bc_sym_surface%mark_facets(bc_i%marked_facet)
1113 type is (non_normal_t)
1116 call this%bclst_vel_res%append(bc_i)
1117 call this%bc_du%mark_facets(bc_i%bc_x%marked_facet)
1118 call this%bc_dv%mark_facets(bc_i%bc_y%marked_facet)
1119 call this%bc_dw%mark_facets(bc_i%bc_z%marked_facet)
1120 type is (shear_stress_t)
1122 call this%bclst_vel_res%append(bc_i%symmetry)
1123 call this%bclst_du%append(bc_i%symmetry%bc_x)
1124 call this%bclst_dv%append(bc_i%symmetry%bc_y)
1125 call this%bclst_dw%append(bc_i%symmetry%bc_z)
1127 call this%bcs_vel%append(bc_i)
1128 type is (wall_model_bc_t)
1130 call this%bclst_vel_res%append(bc_i%symmetry)
1131 call this%bclst_du%append(bc_i%symmetry%bc_x)
1132 call this%bclst_dv%append(bc_i%symmetry%bc_y)
1133 call this%bclst_dw%append(bc_i%symmetry%bc_z)
1135 call this%bcs_vel%append(bc_i)
1142 if (bc_i%strong .eqv. .true.)
then
1143 call this%bc_vel_res%mark_facets(bc_i%marked_facet)
1144 call this%bc_du%mark_facets(bc_i%marked_facet)
1145 call this%bc_dv%mark_facets(bc_i%marked_facet)
1146 call this%bc_dw%mark_facets(bc_i%marked_facet)
1148 call this%bc_prs_surface%mark_facets(bc_i%marked_facet)
1152 call this%bc_curl_curl%mark_facets(bc_i%marked_facet)
1154 call this%bcs_vel%append(bc_i)
1160 do i = 1,
size(this%msh%labeled_zones)
1161 if ((this%msh%labeled_zones(i)%size .gt. 0) .and. &
1162 (marked_zones(i) .eqv. .false.))
then
1163 write(error_unit,
'(A, A, I0)')
"*** ERROR ***: ", &
1164 "No adjoint boundary condition assigned to zone ", i
1172 call this%bcs_prs%init(n_bcs)
1176 call json_extract_item(core, bc_object, i, bc_subdict)
1178 call pressure_bc_factory(bc_i, this, bc_subdict, this%c_Xh, user)
1182 if (
associated(bc_i))
then
1183 call this%bcs_prs%append(bc_i)
1186 if (bc_i%strong .eqv. .true.)
then
1187 call this%bc_dp%mark_facets(bc_i%marked_facet)
1195 do i = 1,
size(this%msh%labeled_zones)
1196 if (this%msh%labeled_zones(i)%size .gt. 0)
then
1197 call neko_error(
"No boundary_conditions entry in the case file!")
1203 call this%bc_prs_surface%finalize()
1204 call this%bc_sym_surface%finalize()
1205 call this%bc_curl_curl%finalize()
1207 call this%bc_vel_res%finalize()
1208 call this%bc_du%finalize()
1209 call this%bc_dv%finalize()
1210 call this%bc_dw%finalize()
1211 call this%bc_dp%finalize()
1213 call this%bclst_vel_res%append(this%bc_vel_res)
1214 call this%bclst_du%append(this%bc_du)
1215 call this%bclst_dv%append(this%bc_dv)
1216 call this%bclst_dw%append(this%bc_dw)
1217 call this%bclst_dp%append(this%bc_dp)
1220 this%prs_dirichlet = .not. this%bclst_dp%is_empty()
1221 call mpi_allreduce(mpi_in_place, this%prs_dirichlet, 1, &
1222 mpi_logical, mpi_lor, neko_comm)
1224 end subroutine adjoint_fluid_pnpn_setup_bcs
1227 subroutine adjoint_fluid_pnpn_write_boundary_conditions(this)
1228 class(adjoint_fluid_pnpn_t),
target,
intent(inout) :: this
1229 type(dirichlet_t) :: bdry_mask
1230 type(field_t),
pointer :: bdry_field
1231 type(file_t) :: bdry_file
1232 integer :: temp_index, i
1233 class(bc_t),
pointer :: bci
1234 character(len=LOG_SIZE) :: log_buf
1236 call neko_log%section(
"Adjoint boundary conditions")
1237 write(log_buf,
'(A)') &
1238 'Marking using integer keys in boundary_adjoint0.f00000'
1239 call neko_log%message(log_buf)
1240 write(log_buf,
'(A)')
'Condition-value pairs: '
1241 call neko_log%message(log_buf)
1242 write(log_buf,
'(A)')
' no_slip = 1'
1243 call neko_log%message(log_buf)
1244 write(log_buf,
'(A)')
' velocity_value = 2'
1245 call neko_log%message(log_buf)
1246 write(log_buf,
'(A)')
' outflow, normal_outflow (+dong) = 3'
1247 call neko_log%message(log_buf)
1248 write(log_buf,
'(A)')
' symmetry = 4'
1249 call neko_log%message(log_buf)
1250 write(log_buf,
'(A)')
' user_velocity_pointwise = 5'
1251 call neko_log%message(log_buf)
1252 write(log_buf,
'(A)')
' periodic = 6'
1253 call neko_log%message(log_buf)
1254 write(log_buf,
'(A)')
' user_velocity = 7'
1255 call neko_log%message(log_buf)
1256 write(log_buf,
'(A)')
' user_pressure = 8'
1257 call neko_log%message(log_buf)
1258 write(log_buf,
'(A)')
' shear_stress = 9'
1259 call neko_log%message(log_buf)
1260 write(log_buf,
'(A)')
' wall_modelling = 10'
1261 call neko_log%message(log_buf)
1262 write(log_buf,
'(A)')
' blasius_profile = 11'
1263 call neko_log%message(log_buf)
1264 call neko_log%end_section()
1266 call neko_scratch_registry%request_field(bdry_field, temp_index, .true.)
1270 call bdry_mask%init_from_components(this%c_Xh, 6.0_rp)
1271 call bdry_mask%mark_zone(this%msh%periodic)
1272 call bdry_mask%finalize()
1273 call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
1274 call bdry_mask%free()
1276 do i = 1, this%bcs_prs%size()
1277 bci => this%bcs_prs%get(i)
1278 select type (bc => bci)
1279 type is (zero_dirichlet_t)
1280 call bdry_mask%init_from_components(this%c_Xh, 3.0_rp)
1281 call bdry_mask%mark_facets(bci%marked_facet)
1282 call bdry_mask%finalize()
1283 call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
1284 call bdry_mask%free()
1285 type is (dong_outflow_t)
1286 call bdry_mask%init_from_components(this%c_Xh, 3.0_rp)
1287 call bdry_mask%mark_facets(bci%marked_facet)
1288 call bdry_mask%finalize()
1289 call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
1290 call bdry_mask%free()
1291 type is (field_dirichlet_t)
1292 call bdry_mask%init_from_components(this%c_Xh, 8.0_rp)
1293 call bdry_mask%mark_facets(bci%marked_facet)
1294 call bdry_mask%finalize()
1295 call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
1296 call bdry_mask%free()
1300 do i = 1, this%bcs_vel%size()
1301 bci => this%bcs_vel%get(i)
1302 select type (bc => bci)
1303 type is (zero_dirichlet_t)
1304 call bdry_mask%init_from_components(this%c_Xh, 1.0_rp)
1305 call bdry_mask%mark_facets(bci%marked_facet)
1306 call bdry_mask%finalize()
1307 call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
1308 call bdry_mask%free()
1310 call bdry_mask%init_from_components(this%c_Xh, 2.0_rp)
1311 call bdry_mask%mark_facets(bci%marked_facet)
1312 call bdry_mask%finalize()
1313 call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
1314 call bdry_mask%free()
1315 type is (symmetry_t)
1316 call bdry_mask%init_from_components(this%c_Xh, 4.0_rp)
1317 call bdry_mask%mark_facets(bci%marked_facet)
1318 call bdry_mask%finalize()
1319 call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
1320 call bdry_mask%free()
1321 type is (field_dirichlet_vector_t)
1322 call bdry_mask%init_from_components(this%c_Xh, 7.0_rp)
1323 call bdry_mask%mark_facets(bci%marked_facet)
1324 call bdry_mask%finalize()
1325 call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
1326 call bdry_mask%free()
1327 type is (shear_stress_t)
1328 call bdry_mask%init_from_components(this%c_Xh, 9.0_rp)
1329 call bdry_mask%mark_facets(bci%marked_facet)
1330 call bdry_mask%finalize()
1331 call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
1332 call bdry_mask%free()
1333 type is (wall_model_bc_t)
1334 call bdry_mask%init_from_components(this%c_Xh, 10.0_rp)
1335 call bdry_mask%mark_facets(bci%marked_facet)
1336 call bdry_mask%finalize()
1337 call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
1338 call bdry_mask%free()
1340 call bdry_mask%init_from_components(this%c_Xh, 11.0_rp)
1341 call bdry_mask%mark_facets(bci%marked_facet)
1342 call bdry_mask%finalize()
1343 call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
1344 call bdry_mask%free()
1349 call bdry_file%init(
'boundary_adjoint.fld')
1350 call bdry_file%write(bdry_field)
1352 call neko_scratch_registry%relinquish_field(temp_index)
1353 end subroutine adjoint_fluid_pnpn_write_boundary_conditions
1358 subroutine rescale_fluid(fluid_data, scale)
1360 class(adjoint_fluid_pnpn_t),
intent(inout) :: fluid_data
1362 real(kind=rp),
intent(in) :: scale
1368 if (neko_bcknd_device .eq. 1)
then
1369 call device_cmult(fluid_data%u_adj%x_d, scale, fluid_data%u_adj%size())
1370 call device_cmult(fluid_data%v_adj%x_d, scale, fluid_data%v_adj%size())
1371 call device_cmult(fluid_data%w_adj%x_d, scale, fluid_data%w_adj%size())
1373 call cmult(fluid_data%u_adj%x, scale, fluid_data%u_adj%size())
1374 call cmult(fluid_data%v_adj%x, scale, fluid_data%v_adj%size())
1375 call cmult(fluid_data%w_adj%x, scale, fluid_data%w_adj%size())
1379 if (neko_bcknd_device .eq. 1)
then
1380 call device_cmult(fluid_data%f_adj_x%x_d, scale, &
1381 fluid_data%f_adj_x%size())
1382 call device_cmult(fluid_data%f_adj_y%x_d, scale, &
1383 fluid_data%f_adj_y%size())
1384 call device_cmult(fluid_data%f_adj_z%x_d, scale, &
1385 fluid_data%f_adj_z%size())
1388 call device_cmult(fluid_data%abx1%x_d, scale, fluid_data%abx1%size())
1389 call device_cmult(fluid_data%aby1%x_d, scale, fluid_data%aby1%size())
1390 call device_cmult(fluid_data%abz1%x_d, scale, fluid_data%abz1%size())
1391 call device_cmult(fluid_data%abx2%x_d, scale, fluid_data%abx2%size())
1392 call device_cmult(fluid_data%aby2%x_d, scale, fluid_data%aby2%size())
1393 call device_cmult(fluid_data%abz2%x_d, scale, fluid_data%abz2%size())
1396 call cmult(fluid_data%f_adj_x%x, scale, fluid_data%f_adj_x%size())
1397 call cmult(fluid_data%f_adj_y%x, scale, fluid_data%f_adj_y%size())
1398 call cmult(fluid_data%f_adj_z%x, scale, fluid_data%f_adj_z%size())
1400 call cmult(fluid_data%abx1%x, scale, fluid_data%abx1%size())
1401 call cmult(fluid_data%aby1%x, scale, fluid_data%aby1%size())
1402 call cmult(fluid_data%abz1%x, scale, fluid_data%abz1%size())
1404 call cmult(fluid_data%abx2%x, scale, fluid_data%abx2%size())
1405 call cmult(fluid_data%aby2%x, scale, fluid_data%aby2%size())
1406 call cmult(fluid_data%abz2%x, scale, fluid_data%abz2%size())
1410 if (neko_bcknd_device .eq. 1)
then
1411 do i = 1, fluid_data%ulag%size()
1412 call device_cmult(fluid_data%ulag%lf(i)%x_d, &
1413 scale, fluid_data%ulag%lf(i)%size())
1416 do i = 1, fluid_data%vlag%size()
1417 call device_cmult(fluid_data%vlag%lf(i)%x_d, &
1418 scale, fluid_data%vlag%lf(i)%size())
1421 do i = 1, fluid_data%wlag%size()
1422 call device_cmult(fluid_data%wlag%lf(i)%x_d, &
1423 scale, fluid_data%wlag%lf(i)%size())
1426 do i = 1, fluid_data%ulag%size()
1427 call cmult(fluid_data%ulag%lf(i)%x, &
1428 scale, fluid_data%ulag%lf(i)%size())
1431 do i = 1, fluid_data%vlag%size()
1432 call cmult(fluid_data%vlag%lf(i)%x, &
1433 scale, fluid_data%vlag%lf(i)%size())
1436 do i = 1, fluid_data%wlag%size()
1437 call cmult(fluid_data%wlag%lf(i)%x, &
1438 scale, fluid_data%wlag%lf(i)%size())
1442 end subroutine rescale_fluid
1444 function norm(x, y, z, B, volume, n)
1445 use mpi_f08,
only: mpi_in_place
1447 integer,
intent(in) :: n
1448 real(kind=rp),
dimension(n),
intent(in) :: x, y, z
1449 real(kind=rp),
dimension(n),
intent(in) :: b
1450 real(kind=rp),
intent(in) :: volume
1452 real(kind=rp) :: norm
1454 norm = vlsc3(x, x, b, n) + vlsc3(y, y, b, n) + vlsc3(z, z, b, n)
1456 call mpi_allreduce(mpi_in_place, norm, 1, &
1457 mpi_real_precision, mpi_sum, neko_comm)
1459 norm = sqrt(norm / volume)
1462 function device_norm(x_d, y_d, z_d, B_d, volume, n)
1463 use mpi_f08,
only: mpi_in_place
1465 type(c_ptr),
intent(in) :: x_d, y_d, z_d
1466 type(c_ptr),
intent(in) :: B_d
1467 real(kind=rp),
intent(in) :: volume
1468 integer,
intent(in) :: n
1470 real(kind=rp) :: device_norm
1472 device_norm = device_vlsc3(x_d, x_d, b_d, n) + &
1473 device_vlsc3(y_d, y_d, b_d, n) + &
1474 device_vlsc3(z_d, z_d, b_d, n)
1476 call mpi_allreduce(mpi_in_place, device_norm, 1, &
1477 mpi_real_precision, mpi_sum, neko_comm)
1479 device_norm = sqrt(device_norm / volume)
1481 end function device_norm
1487 subroutine power_iterations_compute(this, t, tstep)
1488 class(adjoint_fluid_pnpn_t),
target,
intent(inout) :: this
1489 real(kind=rp),
intent(in) :: t
1490 integer,
intent(in) :: tstep
1493 real(kind=rp) :: scaling_factor
1494 real(kind=rp) :: norm_l2, norm_l2_base
1495 character(len=256) :: log_message
1496 type(vector_t) :: data_line
1499 n = this%c_Xh%dof%size()
1500 if (tstep .eq. 1)
then
1501 if (neko_bcknd_device .eq. 1)
then
1502 norm_l2_base = device_norm(this%u_adj%x_d, this%v_adj%x_d, &
1504 this%c_Xh%B_d, this%c_Xh%volume, n)
1506 norm_l2_base = this%norm_scaling * norm(this%u_adj%x, this%v_adj%x, &
1508 this%c_Xh%B, this%c_Xh%volume, n)
1510 if (this%norm_target .lt. 0.0_rp)
then
1511 this%norm_target = norm_l2_base
1514 this%norm_l2_upper = this%norm_tolerance * this%norm_target
1515 this%norm_l2_lower = this%norm_target / this%norm_tolerance
1520 if (neko_bcknd_device .eq. 1)
then
1521 norm_l2 = device_norm(this%u_adj%x_d, this%v_adj%x_d, this%w_adj%x_d, &
1522 this%c_Xh%B_d, this%c_Xh%volume, n)
1524 norm_l2 = norm(this%u_adj%x, this%v_adj%x, this%w_adj%x, &
1525 this%c_Xh%B, this%c_Xh%volume, n)
1527 norm_l2 = sqrt(this%norm_scaling) * norm_l2
1528 scaling_factor = 1.0_rp
1531 if (norm_l2 .gt. this%norm_l2_upper &
1532 .or. norm_l2 .lt. this%norm_l2_lower)
then
1533 scaling_factor = this%norm_target / norm_l2
1534 call rescale_fluid(this, scaling_factor)
1535 norm_l2 = this%norm_target
1537 if (tstep .eq. 1)
then
1538 scaling_factor = 1.0_rp
1544 call neko_log%section(
'Power Iterations')
1546 write (log_message,
'(A7,E20.14)')
'Norm: ', norm_l2
1547 call neko_log%message(log_message, lvl = neko_log_debug)
1548 write (log_message,
'(A7,E20.14)')
'Scaling: ', scaling_factor
1549 call neko_log%message(log_message, lvl = neko_log_debug)
1552 call data_line%init(2)
1553 data_line%x = [norm_l2, scaling_factor]
1554 call this%file_output%write(data_line, t)
1557 call neko_log%end_section(
'Power Iterations')
1558 end subroutine power_iterations_compute
Boundary condition factory for pressure.
Adjoint Pn/Pn formulation.
Subroutines to add advection terms to the RHS of a transport equation.
Base type of all fluid formulations.
Abstract type to compute pressure residual.
Abstract type to compute velocity residual.
Base abstract type for computing the advection operator.
Dirichlet condition in facet normal direction.