37 use,
intrinsic :: iso_fortran_env, only: error_unit
38 use coefs,
only: coef_t
39 use symmetry_aligned,
only: symmetry_aligned_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_allocator
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_aligned,
only: non_normal_aligned_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 scalar_bc_projector,
only: scalar_bc_projector_t
78 use vector_bc_projector,
only: vector_bc_projector_t, &
79 segregated_vector_bc_projector_t
80 use zero_dirichlet,
only: zero_dirichlet_t
81 use utils,
only: neko_error
82 use field_math,
only: field_add2, field_copy, &
84 use bc,
only: bc_t, bc_dirichlet
85 use file,
only: file_t
86 use operators,
only: ortho
87 use opr_device,
only: device_ortho
88 use inflow,
only: inflow_t
89 use field_dirichlet,
only: field_dirichlet_t
90 use blasius,
only: blasius_t
91 use field_dirichlet_vector,
only: field_dirichlet_vector_t
92 use dong_outflow,
only: dong_outflow_t
93 use time_state,
only: time_state_t
94 use vector,
only: vector_t
95 use device_math,
only: device_vlsc3, device_cmult, device_col2
96 use math,
only: vlsc3, cmult, col2
97 use,
intrinsic :: iso_c_binding, only: c_ptr, c_null_ptr, c_associated
98 use comm,
only: neko_comm, mpi_real_precision
99 use mpi_f08,
only: mpi_sum, mpi_max, mpi_allreduce, mpi_integer, &
101 use operators,
only : opgrad, curl, grad
111 type(field_t) :: p_res, u_res, v_res, w_res
115 type(field_t) :: dp, du, dv, dw
122 class(ax_t),
allocatable :: ax_vel
124 class(ax_t),
allocatable :: ax_prs
131 type(projection_t) :: proj_prs
132 type(projection_vel_t) :: proj_vel
139 type(facet_normal_t) :: bc_prs_surface
142 type(facet_normal_t) :: bc_sym_surface
148 class(vector_bc_projector_t),
allocatable :: bcs_vel_projector
150 type(scalar_bc_projector_t) :: bcs_prs_projector
155 logical :: prs_dirichlet = .false.
165 type(field_t) :: abx1, aby1, abz1
166 type(field_t) :: abx2, aby2, abz2
169 type(field_t) :: advx, advy, advz
178 class(rhs_maker_sumab_t),
allocatable :: sumab
181 class(rhs_maker_ext_t),
allocatable :: makeabf
184 class(rhs_maker_bdf_t),
allocatable :: makebdf
187 class(rhs_maker_oifs_t),
allocatable :: makeoifs
193 logical :: full_stress_formulation = .false.
198 real(kind=rp) :: norm_scaling
199 real(kind=rp) :: norm_target
200 real(kind=rp) :: norm_tolerance
206 real(kind=rp) :: norm_l2_base
209 real(kind=rp) :: norm_l2_upper
211 real(kind=rp) :: norm_l2_lower
214 type(file_t) :: file_output
218 procedure, pass(this) :: init => adjoint_fluid_pnpn_init
220 procedure, pass(this) :: free => adjoint_fluid_pnpn_free
222 procedure, pass(this) :: step => adjoint_fluid_pnpn_step
224 procedure, pass(this) :: restart => adjoint_fluid_pnpn_restart
226 procedure, pass(this) :: setup_bcs => adjoint_fluid_pnpn_setup_bcs
228 procedure, pass(this) :: write_boundary_conditions => &
229 adjoint_fluid_pnpn_write_boundary_conditions
232 procedure,
public, pass(this) :: pw_compute_ => power_iterations_compute
244 module subroutine pressure_bc_factory(object, scheme, json, coef, user)
245 class(bc_t),
pointer,
intent(inout) :: object
246 type(adjoint_fluid_pnpn_t),
intent(in) :: scheme
247 type(json_file),
intent(inout) :: json
248 type(coef_t),
target,
intent(in) :: coef
249 type(user_t),
target,
intent(in) :: user
250 end subroutine pressure_bc_factory
251 end interface pressure_bc_factory
260 interface velocity_bc_factory
261 module subroutine velocity_bc_factory(object, scheme, json, coef, user)
262 class(bc_t),
pointer,
intent(inout) :: object
263 type(adjoint_fluid_pnpn_t),
intent(in) :: scheme
264 type(json_file),
intent(inout) :: json
265 type(coef_t),
target,
intent(in) :: coef
266 type(user_t),
target,
intent(in) :: user
267 end subroutine velocity_bc_factory
268 end interface velocity_bc_factory
272 subroutine adjoint_fluid_pnpn_init(this, msh, lx, params, user, chkp)
273 class(adjoint_fluid_pnpn_t),
target,
intent(inout) :: this
274 type(mesh_t),
target,
intent(inout) :: msh
275 integer,
intent(in) :: lx
276 type(json_file),
target,
intent(inout) :: params
277 type(user_t),
target,
intent(in) :: user
278 type(chkp_t),
target,
intent(inout) :: chkp
279 character(len=15),
parameter :: scheme =
'Adjoint (Pn/Pn)'
280 real(kind=rp) :: abs_tol
281 character(len=LOG_SIZE) :: log_buf
282 integer :: integer_val, solver_maxiter
283 character(len=:),
allocatable :: solver_type, precon_type
284 logical :: monitor, found
286 type(json_file) :: numerics_params, precon_params
289 character(len=:),
allocatable :: file_name
290 character(len=256) :: header_line
295 call this%init_base(msh, lx, params, scheme, user, .true.)
299 call neko_registry%add_field(this%dm_Xh,
'p_adj')
300 this%p_adj => neko_registry%get_field(
'p_adj')
306 call json_get(params,
'case.numerics.time_order', integer_val)
307 allocate(this%ext_bdf)
308 call this%ext_bdf%init(integer_val)
310 call json_get_or_default(params,
"case.fluid.full_stress_formulation", &
311 this%full_stress_formulation, .false.)
313 if (this%full_stress_formulation .eqv. .true.)
then
315 "Full stress formulation is not supported in the adjoint module.")
326 call ax_helm_allocator(this%Ax_vel, type_name =
"standard")
329 call adjoint_pnpn_prs_res_factory(this%prs_res)
332 call adjoint_pnpn_vel_res_factory(this%vel_res)
334 allocate(segregated_vector_bc_projector_t :: this%bcs_vel_projector)
335 call this%bcs_vel_projector%init(this%c_Xh)
338 if (params%valid_path(
'case.fluid.nut_field'))
then
339 if (this%full_stress_formulation .eqv. .false.)
then
340 call neko_error(
"You need to set full_stress_formulation to " // &
341 "true for the fluid to have a spatially varying " // &
344 call json_get(params,
'case.fluid.nut_field', this%nut_field_name)
346 this%nut_field_name =
""
350 call ax_helm_allocator(this%Ax_prs, type_name =
"standard")
354 call rhs_maker_sumab_fctry(this%sumab)
357 call rhs_maker_ext_fctry(this%makeabf)
360 call rhs_maker_bdf_fctry(this%makebdf)
363 call rhs_maker_oifs_fctry(this%makeoifs)
366 associate(xh_lx => this%Xh%lx, xh_ly => this%Xh%ly, xh_lz => this%Xh%lz, &
367 dm_xh => this%dm_Xh, nelv => this%msh%nelv)
369 call this%p_res%init(dm_xh,
"p_res")
370 call this%u_res%init(dm_xh,
"u_res")
371 call this%v_res%init(dm_xh,
"v_res")
372 call this%w_res%init(dm_xh,
"w_res")
373 call this%abx1%init(dm_xh,
"abx1")
374 call this%aby1%init(dm_xh,
"aby1")
375 call this%abz1%init(dm_xh,
"abz1")
376 call this%abx2%init(dm_xh,
"abx2")
377 call this%aby2%init(dm_xh,
"aby2")
378 call this%abz2%init(dm_xh,
"abz2")
379 call this%advx%init(dm_xh,
"advx")
380 call this%advy%init(dm_xh,
"advy")
381 call this%advz%init(dm_xh,
"advz")
384 call this%du%init(this%dm_Xh,
'du')
385 call this%dv%init(this%dm_Xh,
'dv')
386 call this%dw%init(this%dm_Xh,
'dw')
387 call this%dp%init(this%dm_Xh,
'dp')
390 call this%setup_bcs(user, params)
393 call json_get_or_default(params,
'case.output_boundary', found, .false.)
394 if (found)
call this%write_boundary_conditions()
396 call this%proj_prs%init(this%dm_Xh%size(), this%pr_projection_dim, &
397 this%pr_projection_activ_step)
399 call this%proj_vel%init(this%dm_Xh%size(), this%vel_projection_dim, &
400 this%vel_projection_activ_step)
403 call json_get_or_default(params,
'case.numerics.oifs', this%oifs, .false.)
404 if (params%valid_path(
'case.fluid.flow_rate_force'))
then
405 call neko_error(
"Flow rate forcing not available for adjoint_fluid_pnpn")
409 call neko_log%section(
"Pressure solver")
411 call json_get_or_default(params, &
412 'case.fluid.pressure_solver.max_iterations', &
414 call json_get(params,
'case.fluid.pressure_solver.type', solver_type)
415 call json_get(params,
'case.fluid.pressure_solver.preconditioner.type', &
417 call json_get(params, &
418 'case.fluid.pressure_solver.preconditioner', precon_params)
419 call json_get(params,
'case.fluid.pressure_solver.absolute_tolerance', &
421 call json_get_or_default(params,
'case.fluid.pressure_solver.monitor', &
423 call neko_log%message(
'Type : ('// trim(solver_type) // &
424 ', ' // trim(precon_type) //
')')
425 write(log_buf,
'(A,ES13.6)')
'Abs tol :', abs_tol
426 call neko_log%message(log_buf)
428 call this%solver_factory(this%ksp_prs, this%dm_Xh%size(), &
429 solver_type, solver_maxiter, abs_tol, monitor)
430 call this%precon_factory_(this%pc_prs, this%ksp_prs, &
431 this%c_Xh, this%dm_Xh, this%gs_Xh, this%bcs_prs, &
432 precon_type, precon_params)
433 call neko_log%end_section()
436 call neko_log%section(
"Advection factory")
437 call json_get_or_default(params,
'case.fluid.advection', advection, .true.)
438 call json_get(params,
'case.numerics', numerics_params)
439 call advection_adjoint_factory(this%adv, numerics_params, this%c_Xh, &
440 this%ulag, this%vlag, this%wlag, &
441 chkp%dtlag, chkp%tlag, this%ext_bdf, &
447 call this%chkp%add_fluid(this%u_adj, this%v_adj, this%w_adj, this%p_adj)
449 this%chkp%abx1 => this%abx1
450 this%chkp%abx2 => this%abx2
451 this%chkp%aby1 => this%aby1
452 this%chkp%aby2 => this%aby2
453 this%chkp%abz1 => this%abz1
454 this%chkp%abz2 => this%abz2
455 call this%chkp%add_lag(this%ulag, this%vlag, this%wlag)
457 call neko_log%end_section()
463 call json_get_or_default(params,
'norm_scaling', &
464 this%norm_scaling, 0.5_rp)
472 this%u_b => neko_registry%get_field(
'u')
473 this%v_b => neko_registry%get_field(
'v')
474 this%w_b => neko_registry%get_field(
'w')
475 this%p_b => neko_registry%get_field(
'p')
478 call json_get_or_default(params,
'norm_target', &
479 this%norm_target, -1.0_rp)
480 call json_get_or_default(params,
'norm_tolerance', &
481 this%norm_tolerance, 10.0_rp)
484 call json_get_or_default(params,
'output_file', &
485 file_name,
'power_iterations.csv')
486 call this%file_output%init(trim(file_name))
487 write(header_line,
'(A)')
'Time, Norm, Scaling'
488 call this%file_output%set_header(header_line)
490 end subroutine adjoint_fluid_pnpn_init
492 subroutine adjoint_fluid_pnpn_restart(this, chkp)
493 class(adjoint_fluid_pnpn_t),
target,
intent(inout) :: this
494 type(chkp_t),
intent(inout) :: chkp
495 real(kind=rp) :: dtlag(10), tlag(10)
501 n = this%u_adj%dof%size()
502 if (
allocated(this%chkp%previous_mesh%elements) .or. &
503 chkp%previous_Xh%lx .ne. this%Xh%lx)
then
504 associate(u => this%u_adj, v => this%v_adj, w => this%w_adj, &
505 p => this%p_adj, c_xh => this%c_Xh, ulag => this%ulag, &
506 vlag => this%vlag, wlag => this%wlag)
507 call col2(u%x, c_xh%mult, n)
508 call col2(v%x, c_xh%mult, n)
509 call col2(w%x, c_xh%mult, n)
510 call col2(p%x, c_xh%mult, n)
511 do i = 1, this%ulag%size()
512 call col2(ulag%lf(i)%x, c_xh%mult, n)
513 call col2(vlag%lf(i)%x, c_xh%mult, n)
514 call col2(wlag%lf(i)%x, c_xh%mult, n)
519 if (neko_bcknd_device .eq. 1)
then
520 associate(u => this%u_adj, v => this%v_adj, w => this%w_adj, &
521 ulag => this%ulag, vlag => this%vlag, wlag => this%wlag,&
523 call device_memcpy(u%x, u%x_d, u%dof%size(), &
524 host_to_device, sync = .false.)
525 call device_memcpy(v%x, v%x_d, v%dof%size(), &
526 host_to_device, sync = .false.)
527 call device_memcpy(w%x, w%x_d, w%dof%size(), &
528 host_to_device, sync = .false.)
529 call device_memcpy(p%x, p%x_d, p%dof%size(), &
530 host_to_device, sync = .false.)
531 call device_memcpy(ulag%lf(1)%x, ulag%lf(1)%x_d, &
532 u%dof%size(), host_to_device, sync = .false.)
533 call device_memcpy(ulag%lf(2)%x, ulag%lf(2)%x_d, &
534 u%dof%size(), host_to_device, sync = .false.)
536 call device_memcpy(vlag%lf(1)%x, vlag%lf(1)%x_d, &
537 v%dof%size(), host_to_device, sync = .false.)
538 call device_memcpy(vlag%lf(2)%x, vlag%lf(2)%x_d, &
539 v%dof%size(), host_to_device, sync = .false.)
541 call device_memcpy(wlag%lf(1)%x, wlag%lf(1)%x_d, &
542 w%dof%size(), host_to_device, sync = .false.)
543 call device_memcpy(wlag%lf(2)%x, wlag%lf(2)%x_d, &
544 w%dof%size(), host_to_device, sync = .false.)
545 call device_memcpy(this%abx1%x, this%abx1%x_d, &
546 w%dof%size(), host_to_device, sync = .false.)
547 call device_memcpy(this%abx2%x, this%abx2%x_d, &
548 w%dof%size(), host_to_device, sync = .false.)
549 call device_memcpy(this%aby1%x, this%aby1%x_d, &
550 w%dof%size(), host_to_device, sync = .false.)
551 call device_memcpy(this%aby2%x, this%aby2%x_d, &
552 w%dof%size(), host_to_device, sync = .false.)
553 call device_memcpy(this%abz1%x, this%abz1%x_d, &
554 w%dof%size(), host_to_device, sync = .false.)
555 call device_memcpy(this%abz2%x, this%abz2%x_d, &
556 w%dof%size(), host_to_device, sync = .false.)
557 call device_memcpy(this%advx%x, this%advx%x_d, &
558 w%dof%size(), host_to_device, sync = .false.)
559 call device_memcpy(this%advy%x, this%advy%x_d, &
560 w%dof%size(), host_to_device, sync = .false.)
561 call device_memcpy(this%advz%x, this%advz%x_d, &
562 w%dof%size(), host_to_device, sync = .false.)
569 if (
allocated(this%chkp%previous_mesh%elements) &
570 .or. this%chkp%previous_Xh%lx .ne. this%Xh%lx)
then
571 call this%gs_Xh%op(this%u_adj, gs_op_add)
572 call this%gs_Xh%op(this%v_adj, gs_op_add)
573 call this%gs_Xh%op(this%w_adj, gs_op_add)
574 call this%gs_Xh%op(this%p_adj, gs_op_add)
576 do i = 1, this%ulag%size()
577 call this%gs_Xh%op(this%ulag%lf(i), gs_op_add)
578 call this%gs_Xh%op(this%vlag%lf(i), gs_op_add)
579 call this%gs_Xh%op(this%wlag%lf(i), gs_op_add)
583 end subroutine adjoint_fluid_pnpn_restart
585 subroutine adjoint_fluid_pnpn_free(this)
586 class(adjoint_fluid_pnpn_t),
intent(inout) :: this
589 call this%scheme_free()
591 call this%bc_prs_surface%free()
592 call this%bc_sym_surface%free()
593 call this%bc_curl_curl%free()
594 if (
allocated(this%bcs_vel_projector))
then
595 call this%bcs_vel_projector%free()
596 deallocate(this%bcs_vel_projector)
598 call this%bcs_prs_projector%free()
599 call this%proj_prs%free()
600 call this%proj_vel%free()
602 call this%p_res%free()
603 call this%u_res%free()
604 call this%v_res%free()
605 call this%w_res%free()
612 call this%abx1%free()
613 call this%aby1%free()
614 call this%abz1%free()
616 call this%abx2%free()
617 call this%aby2%free()
618 call this%abz2%free()
620 call this%advx%free()
621 call this%advy%free()
622 call this%advz%free()
624 if (
allocated(this%Ax_vel))
then
625 deallocate(this%Ax_vel)
628 if (
allocated(this%Ax_prs))
then
629 deallocate(this%Ax_prs)
632 if (
allocated(this%prs_res))
then
633 deallocate(this%prs_res)
636 if (
allocated(this%vel_res))
then
637 deallocate(this%vel_res)
640 if (
allocated(this%sumab))
then
641 deallocate(this%sumab)
644 if (
allocated(this%makeabf))
then
645 deallocate(this%makeabf)
648 if (
allocated(this%makebdf))
then
649 deallocate(this%makebdf)
652 if (
allocated(this%makeoifs))
then
653 deallocate(this%makeoifs)
656 if (
allocated(this%ext_bdf))
then
657 deallocate(this%ext_bdf)
662 end subroutine adjoint_fluid_pnpn_free
668 subroutine adjoint_fluid_pnpn_step(this, time, dt_controller)
669 class(adjoint_fluid_pnpn_t),
target,
intent(inout) :: this
670 type(time_state_t),
intent(in) :: time
671 type(time_step_controller_t),
intent(in) :: dt_controller
675 type(ksp_monitor_t) :: ksp_results(4)
676 type(field_t),
pointer :: dx_p_adj, dy_p_adj, dz_p_adj, nx1, nx2, nx3, &
678 integer :: temp_indices(3)
679 integer :: cc_indices(8)
680 real(kind=rp) :: rho_val, mu_val
682 if (this%freeze)
return
684 n = this%dm_Xh%size()
686 call profiler_start_region(
'Adjoint')
687 associate(u => this%u_adj, v => this%v_adj, w => this%w_adj, &
689 u_e => this%u_adj_e, v_e => this%v_adj_e, w_e => this%w_adj_e, &
690 du => this%du, dv => this%dv, dw => this%dw, dp => this%dp, &
691 u_b => this%u_b, v_b => this%v_b, w_b => this%w_b, &
692 u_res => this%u_res, v_res => this%v_res, w_res => this%w_res, &
693 p_res => this%p_res, ax_vel => this%Ax_vel, ax_prs => this%Ax_prs, &
695 c_xh => this%c_Xh, dm_xh => this%dm_Xh, gs_xh => this%gs_Xh, &
696 ulag => this%ulag, vlag => this%vlag, wlag => this%wlag, &
697 msh => this%msh, prs_res => this%prs_res, &
698 source_term => this%source_term, vel_res => this%vel_res, &
699 sumab => this%sumab, &
700 makeabf => this%makeabf, makebdf => this%makebdf, &
701 vel_projection_dim => this%vel_projection_dim, &
702 pr_projection_dim => this%pr_projection_dim, &
704 rho => this%rho, mu => this%mu, &
705 f_x => this%f_adj_x, f_y => this%f_adj_y, f_z => this%f_adj_z, &
706 t => time%t, tstep => time%tstep, dt => time%dt, &
707 ext_bdf => this%ext_bdf, event => glb_cmd_event)
710 call sumab%compute_fluid(u_e, v_e, w_e, u, v, w, &
711 ulag, vlag, wlag, ext_bdf%advection_coeffs%x, ext_bdf%nadv)
714 call this%source_term%compute(time)
717 call this%bcs_vel%apply_vector(f_x%x, f_y%x, f_z%x, &
718 this%dm_Xh%size(), time, strong = .false.)
721 call neko_error(
"OIFS not implemented for adjoint")
725 call this%adv%compute_adjoint(u, v, w, u_b, v_b, w_b, &
727 xh, this%c_Xh, dm_xh%size())
733 call makeabf%compute_fluid(this%abx1, this%aby1, this%abz1,&
734 this%abx2, this%aby2, this%abz2, &
735 f_x%x, f_y%x, f_z%x, &
736 rho%x(1,1,1,1), ext_bdf%advection_coeffs%x, n)
739 call makebdf%compute_fluid(ulag, vlag, wlag, f_x%x, f_y%x, f_z%x, &
740 u, v, w, c_xh%B, c_xh%Blag, c_xh%Blaglag, rho%x(1,1,1,1), dt, &
741 ext_bdf%diffusion_coeffs%x, ext_bdf%ndiff, n)
748 call this%bc_apply_vel(time, strong = .true.)
749 call this%bc_apply_prs(time)
752 call neko_scratch_registry%request_field(dx_p_adj, cc_indices(1), .false.)
753 call neko_scratch_registry%request_field(dy_p_adj, cc_indices(2), .false.)
754 call neko_scratch_registry%request_field(dz_p_adj, cc_indices(3), .false.)
757 call neko_scratch_registry%request_field(nx1, cc_indices(4), .true.)
758 call neko_scratch_registry%request_field(nx2, cc_indices(5), .true.)
759 call neko_scratch_registry%request_field(nx3, cc_indices(6), .true.)
761 call neko_scratch_registry%request_field(work1, cc_indices(7), .false.)
762 call neko_scratch_registry%request_field(work2, cc_indices(8), .false.)
765 call grad(dx_p_adj%x, dy_p_adj%x, dz_p_adj%x, this%p_adj%x, c_xh)
768 call this%bc_curl_curl%apply_n_cross(nx1%x, nx2%x, nx3%x, dx_p_adj%x, &
769 dy_p_adj%x, dz_p_adj%x, dx_p_adj%size())
774 call curl(dx_p_adj, dy_p_adj, dz_p_adj, nx1, nx2, nx3, work1, work2, c_xh)
777 call gs_xh%op(dx_p_adj, gs_op_add, event)
778 call device_event_sync(event)
779 call gs_xh%op(dy_p_adj, gs_op_add, event)
780 call device_event_sync(event)
781 call gs_xh%op(dz_p_adj, gs_op_add, event)
782 call device_event_sync(event)
785 if (neko_bcknd_device .eq. 1)
then
786 call device_col2(dx_p_adj%x_d, c_xh%mult_d, dx_p_adj%size())
787 call device_col2(dy_p_adj%x_d, c_xh%mult_d, dx_p_adj%size())
788 call device_col2(dz_p_adj%x_d, c_xh%mult_d, dx_p_adj%size())
790 call col2(dx_p_adj%x, c_xh%mult, dx_p_adj%size())
791 call col2(dy_p_adj%x, c_xh%mult, dx_p_adj%size())
792 call col2(dz_p_adj%x, c_xh%mult, dx_p_adj%size())
795 rho_val = rho%x(1,1,1,1)
796 mu_val = mu%x(1,1,1,1)
797 call field_add2s2(f_x, dx_p_adj, -mu_val / rho_val)
798 call field_add2s2(f_y, dy_p_adj, -mu_val / rho_val)
799 call field_add2s2(f_z, dz_p_adj, -mu_val / rho_val)
801 call neko_scratch_registry%relinquish_field(cc_indices)
804 call this%update_material_properties(time)
808 call profiler_start_region(
'Adjoint_velocity_residual')
810 call vel_res%compute(ax_vel, u, v, w, &
811 u_res, v_res, w_res, &
815 mu, rho, ext_bdf%diffusion_coeffs%x(1), &
818 call gs_xh%op(u_res, gs_op_add, event)
819 call device_event_sync(event)
820 call gs_xh%op(v_res, gs_op_add, event)
821 call device_event_sync(event)
822 call gs_xh%op(w_res, gs_op_add, event)
823 call device_event_sync(event)
826 call this%bcs_vel_projector%apply(u_res%x, v_res%x, w_res%x, n)
828 call profiler_end_region(
'Adjoint_velocity_residual')
830 call this%proj_vel%pre_solving(u_res%x, v_res%x, w_res%x, &
831 tstep, c_xh, n, dt_controller,
'Velocity')
833 call this%pc_vel%update()
835 call profiler_start_region(
"Adjoint_velocity_solve")
836 ksp_results(1:3) = this%ksp_vel%solve_coupled(ax_vel, du, dv, dw, &
837 u_res%x, v_res%x, w_res%x, n, c_xh, &
838 this%bcs_vel_projector, gs_xh, &
839 this%ksp_vel%max_iter)
841 call this%proj_vel%post_solving(du%x, dv%x, dw%x, ax_vel, c_xh, &
842 this%bcs_vel_projector, gs_xh, n, tstep, &
845 if (neko_bcknd_device .eq. 1)
then
846 call device_opadd2cm(u%x_d, v%x_d, w%x_d, &
847 du%x_d, dv%x_d, dw%x_d, 1.0_rp, n, msh%gdim)
849 call opadd2cm(u%x, v%x, w%x, du%x, dv%x, dw%x, 1.0_rp, n, msh%gdim)
851 call profiler_end_region(
"Adjoint_velocity_solve")
857 call field_copy(f_x, u)
858 call field_copy(f_y, v)
859 call field_copy(f_z, w)
861 call profiler_start_region(
'Adjoint_pressure_residual')
863 call prs_res%compute(p, p_res, &
867 this%bc_prs_surface, this%bc_sym_surface, &
868 ax_prs, ext_bdf%diffusion_coeffs%x(1), dt, &
872 if (.not. this%prs_dirichlet .and. neko_bcknd_device .eq. 1)
then
873 call device_ortho(p_res%x_d, this%glb_n_points, n)
874 else if (.not. this%prs_dirichlet)
then
875 call ortho(p_res%x, this%glb_n_points, n)
878 call gs_xh%op(p_res, gs_op_add, event)
879 call device_event_sync(event)
882 call this%bcs_prs_projector%apply(p_res%x, p%dof%size())
885 call profiler_end_region(
'Adjoint_pressure_residual')
888 call this%proj_prs%pre_solving(p_res%x, tstep, c_xh, n, dt_controller, &
891 call this%pc_prs%update()
893 call profiler_start_region(
'Adjoint_pressure_solve')
897 this%ksp_prs%solve(ax_prs, dp, p_res%x, n, c_xh, &
898 this%bcs_prs_projector, gs_xh)
901 call profiler_end_region(
'Adjoint_pressure_solve')
903 call this%proj_prs%post_solving(dp%x, ax_prs, c_xh, &
904 this%bcs_prs_projector, gs_xh, n, tstep, dt_controller)
907 call field_add2(p, dp, n)
908 if (.not. this%prs_dirichlet .and. neko_bcknd_device .eq. 1)
then
909 call device_ortho(p%x_d, this%glb_n_points, n)
910 else if (.not. this%prs_dirichlet)
then
911 call ortho(p%x, this%glb_n_points, n)
914 ksp_results(4)%name =
'Adjoint Pressure'
915 ksp_results(1)%name =
'Adjoint Velocity U'
916 ksp_results(2)%name =
'Adjoint Velocity V'
917 ksp_results(3)%name =
'Adjoint Velocity W'
919 if (this%forced_flow_rate)
then
920 call neko_error(
'Forced flow rate is not implemented for the adjoint')
926 call neko_scratch_registry%request_field(dx_p_adj, temp_indices(1), &
928 call neko_scratch_registry%request_field(dy_p_adj, temp_indices(2), &
930 call neko_scratch_registry%request_field(dz_p_adj, temp_indices(3), &
934 call opgrad(dx_p_adj%x, dy_p_adj%x, dz_p_adj%x, this%p_adj%x, c_xh)
937 call gs_xh%op(dx_p_adj, gs_op_add, event)
938 call device_event_sync(event)
939 call gs_xh%op(dy_p_adj, gs_op_add, event)
940 call device_event_sync(event)
941 call gs_xh%op(dz_p_adj, gs_op_add, event)
942 call device_event_sync(event)
945 if (neko_bcknd_device .eq. 1)
then
946 call device_col2(dx_p_adj%x_d, c_xh%Binv_d, dx_p_adj%size())
947 call device_col2(dy_p_adj%x_d, c_xh%Binv_d, dx_p_adj%size())
948 call device_col2(dz_p_adj%x_d, c_xh%Binv_d, dx_p_adj%size())
952 call col2(dx_p_adj%x, c_xh%Binv, dx_p_adj%size())
953 call col2(dy_p_adj%x, c_xh%Binv, dx_p_adj%size())
954 call col2(dz_p_adj%x, c_xh%Binv, dx_p_adj%size())
957 if (neko_bcknd_device .eq. 1)
then
958 call device_opadd2cm(u%x_d, v%x_d, w%x_d, dx_p_adj%x_d, &
959 dy_p_adj%x_d, dz_p_adj%x_d, -1.0_rp, n, msh%gdim)
961 call opadd2cm(u%x, v%x, w%x, dx_p_adj%x, dy_p_adj%x, dz_p_adj%x, &
962 -1.0_rp, n, msh%gdim)
965 call neko_scratch_registry%relinquish_field(temp_indices)
968 call fluid_step_info(time, ksp_results, &
969 this%full_stress_formulation, this%strict_convergence)
972 call profiler_end_region(
'Adjoint')
974 end subroutine adjoint_fluid_pnpn_step
980 subroutine adjoint_fluid_pnpn_setup_bcs(this, user, params)
981 use mpi_f08,
only: mpi_in_place
982 class(adjoint_fluid_pnpn_t),
target,
intent(inout) :: this
983 type(user_t),
target,
intent(in) :: user
984 type(json_file),
intent(inout) :: params
985 integer :: i, n_bcs, j, zone_size, global_zone_size, ierr
986 class(bc_t),
pointer :: bc_i
987 type(json_core) :: core
988 type(json_value),
pointer :: bc_object
989 type(json_file) :: bc_subdict
992 logical,
allocatable :: marked_zones(:)
993 integer,
allocatable :: zone_indices(:)
994 character(len=:),
allocatable :: json_key
997 call this%bc_prs_surface%init_from_components(this%c_Xh)
998 call this%bc_sym_surface%init_from_components(this%c_Xh)
999 call this%bc_curl_curl%init_from_components(this%c_Xh)
1001 json_key =
'case.adjoint_fluid.boundary_conditions'
1004 if (params%valid_path(json_key))
then
1005 call params%info(json_key, n_children = n_bcs)
1006 call params%get_core(core)
1007 call params%get(json_key, bc_object, found)
1012 call this%bcs_vel%init(n_bcs)
1014 allocate(marked_zones(
size(this%msh%labeled_zones)))
1015 marked_zones = .false.
1019 call json_extract_item(core, bc_object, i, bc_subdict)
1021 call json_get(bc_subdict,
"zone_indices", zone_indices)
1026 do j = 1,
size(zone_indices)
1027 zone_size = this%msh%labeled_zones(zone_indices(j))%size
1028 call mpi_allreduce(zone_size, global_zone_size, 1, &
1029 mpi_integer, mpi_max, neko_comm, ierr)
1031 if (global_zone_size .eq. 0)
then
1032 write(error_unit,
'(A, A, I0, A, A, I0, A)')
"*** ERROR ***: ",&
1033 "Zone index ", zone_indices(j), &
1034 " is invalid as this zone has 0 size, meaning it does ", &
1035 "not in the mesh. Check adjoint boundary condition ", &
1040 if (marked_zones(zone_indices(j)) .eqv. .true.)
then
1041 write(error_unit,
'(A, A, I0, A, A, A, A)')
"*** ERROR ***: ", &
1042 "Zone with index ", zone_indices(j), &
1043 " has already been assigned a boundary condition. ", &
1044 "Please check your boundary_conditions entry for the ", &
1045 "adjoint and make sure that each zone index appears ", &
1046 "only in a single boundary condition."
1049 marked_zones(zone_indices(j)) = .true.
1054 call velocity_bc_factory(bc_i, this, bc_subdict, this%c_Xh, user)
1058 if (
associated(bc_i))
then
1061 type is (symmetry_aligned_t)
1062 call this%bcs_vel_projector%mark(bc_i%bc_x, component =
'x')
1063 call this%bcs_vel_projector%mark(bc_i%bc_y, component =
'y')
1064 call this%bcs_vel_projector%mark(bc_i%bc_z, component =
'z')
1065 call this%bcs_vel%append(bc_i)
1066 call this%bc_sym_surface%mark_facets(bc_i%marked_facet)
1067 type is (non_normal_aligned_t)
1068 call this%bcs_vel_projector%mark(bc_i%bc_x, component =
'x')
1069 call this%bcs_vel_projector%mark(bc_i%bc_y, component =
'y')
1070 call this%bcs_vel_projector%mark(bc_i%bc_z, component =
'z')
1071 call this%bcs_vel%append(bc_i)
1072 type is (shear_stress_t)
1073 call neko_error(
"The shear_stress boundary condition " // &
1074 "requires the full stress formulation to be enabled.")
1075 type is (wall_model_bc_t)
1076 call neko_error(
"The wall_model boundary condition " // &
1077 "requires the full stress formulation to be enabled.")
1081 if (bc_i%bc_type .eq. bc_dirichlet)
then
1082 call this%bc_prs_surface%mark_labeled_zones( &
1084 call this%bcs_vel_projector%mark(bc_i, component =
'x')
1085 call this%bcs_vel_projector%mark(bc_i, component =
'y')
1086 call this%bcs_vel_projector%mark(bc_i, component =
'z')
1090 call this%bc_curl_curl%mark_facets(bc_i%marked_facet)
1092 call this%bcs_vel%append(bc_i)
1098 do i = 1,
size(this%msh%labeled_zones)
1099 if ((this%msh%labeled_zones(i)%size .gt. 0) .and. &
1100 (marked_zones(i) .eqv. .false.))
then
1101 write(error_unit,
'(A, A, I0)')
"*** ERROR ***: ", &
1102 "No adjoint boundary condition assigned to zone ", i
1110 call this%bcs_prs%init(n_bcs)
1114 call json_extract_item(core, bc_object, i, bc_subdict)
1116 call pressure_bc_factory(bc_i, this, bc_subdict, this%c_Xh, user)
1120 if (
associated(bc_i))
then
1121 call this%bcs_prs%append(bc_i)
1124 if (bc_i%bc_type .eq. bc_dirichlet)
then
1125 call this%bcs_prs_projector%mark(bc_i)
1133 do i = 1,
size(this%msh%labeled_zones)
1134 if (this%msh%labeled_zones(i)%size .gt. 0)
then
1135 call neko_error(
"No boundary_conditions entry in the case file!")
1139 call this%bcs_vel%init()
1140 call this%bcs_prs%init()
1144 call this%bc_prs_surface%finalize()
1145 call this%bc_sym_surface%finalize()
1146 call this%bc_curl_curl%finalize()
1147 call this%bcs_vel_projector%finalize(rebuild_mask = .true.)
1150 this%prs_dirichlet = this%bcs_prs_projector%dof_mask%is_set()
1151 call mpi_allreduce(mpi_in_place, this%prs_dirichlet, 1, &
1152 mpi_logical, mpi_lor, neko_comm)
1154 end subroutine adjoint_fluid_pnpn_setup_bcs
1157 subroutine adjoint_fluid_pnpn_write_boundary_conditions(this)
1158 class(adjoint_fluid_pnpn_t),
target,
intent(inout) :: this
1159 type(dirichlet_t) :: bdry_mask
1160 type(field_t),
pointer :: bdry_field
1161 type(file_t) :: bdry_file
1162 integer :: temp_index, i
1163 class(bc_t),
pointer :: bci
1164 character(len=LOG_SIZE) :: log_buf
1166 call neko_log%section(
"Adjoint boundary conditions")
1167 write(log_buf,
'(A)') &
1168 'Marking using integer keys in boundary_adjoint0.f00000'
1169 call neko_log%message(log_buf)
1170 write(log_buf,
'(A)')
'Condition-value pairs: '
1171 call neko_log%message(log_buf)
1172 write(log_buf,
'(A)')
' no_slip = 1'
1173 call neko_log%message(log_buf)
1174 write(log_buf,
'(A)')
' velocity_value = 2'
1175 call neko_log%message(log_buf)
1176 write(log_buf,
'(A)')
' outflow, normal_outflow (+dong) = 3'
1177 call neko_log%message(log_buf)
1178 write(log_buf,
'(A)')
' symmetry = 4'
1179 call neko_log%message(log_buf)
1180 write(log_buf,
'(A)')
' user_velocity_pointwise = 5'
1181 call neko_log%message(log_buf)
1182 write(log_buf,
'(A)')
' periodic = 6'
1183 call neko_log%message(log_buf)
1184 write(log_buf,
'(A)')
' user_velocity = 7'
1185 call neko_log%message(log_buf)
1186 write(log_buf,
'(A)')
' user_pressure = 8'
1187 call neko_log%message(log_buf)
1188 write(log_buf,
'(A)')
' shear_stress = 9'
1189 call neko_log%message(log_buf)
1190 write(log_buf,
'(A)')
' wall_modelling = 10'
1191 call neko_log%message(log_buf)
1192 write(log_buf,
'(A)')
' blasius_profile = 11'
1193 call neko_log%message(log_buf)
1194 call neko_log%end_section()
1196 call neko_scratch_registry%request_field(bdry_field, temp_index, .true.)
1200 call bdry_mask%init_from_components(this%c_Xh, 6.0_rp)
1201 call bdry_mask%mark_zone(this%msh%periodic)
1202 call bdry_mask%finalize()
1203 call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
1204 call bdry_mask%free()
1206 do i = 1, this%bcs_prs%size()
1207 bci => this%bcs_prs%get(i)
1208 select type (bc => bci)
1209 type is (zero_dirichlet_t)
1210 call bdry_mask%init_from_components(this%c_Xh, 3.0_rp)
1211 call bdry_mask%mark_facets(bci%marked_facet)
1212 call bdry_mask%finalize()
1213 call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
1214 call bdry_mask%free()
1215 type is (dong_outflow_t)
1216 call bdry_mask%init_from_components(this%c_Xh, 3.0_rp)
1217 call bdry_mask%mark_facets(bci%marked_facet)
1218 call bdry_mask%finalize()
1219 call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
1220 call bdry_mask%free()
1221 type is (field_dirichlet_t)
1222 call bdry_mask%init_from_components(this%c_Xh, 8.0_rp)
1223 call bdry_mask%mark_facets(bci%marked_facet)
1224 call bdry_mask%finalize()
1225 call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
1226 call bdry_mask%free()
1230 do i = 1, this%bcs_vel%size()
1231 bci => this%bcs_vel%get(i)
1232 select type (bc => bci)
1233 type is (zero_dirichlet_t)
1234 call bdry_mask%init_from_components(this%c_Xh, 1.0_rp)
1235 call bdry_mask%mark_facets(bci%marked_facet)
1236 call bdry_mask%finalize()
1237 call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
1238 call bdry_mask%free()
1240 call bdry_mask%init_from_components(this%c_Xh, 2.0_rp)
1241 call bdry_mask%mark_facets(bci%marked_facet)
1242 call bdry_mask%finalize()
1243 call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
1244 call bdry_mask%free()
1245 type is (symmetry_aligned_t)
1246 call bdry_mask%init_from_components(this%c_Xh, 4.0_rp)
1247 call bdry_mask%mark_facets(bci%marked_facet)
1248 call bdry_mask%finalize()
1249 call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
1250 call bdry_mask%free()
1251 type is (field_dirichlet_vector_t)
1252 call bdry_mask%init_from_components(this%c_Xh, 7.0_rp)
1253 call bdry_mask%mark_facets(bci%marked_facet)
1254 call bdry_mask%finalize()
1255 call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
1256 call bdry_mask%free()
1257 type is (shear_stress_t)
1258 call bdry_mask%init_from_components(this%c_Xh, 9.0_rp)
1259 call bdry_mask%mark_facets(bci%marked_facet)
1260 call bdry_mask%finalize()
1261 call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
1262 call bdry_mask%free()
1263 type is (wall_model_bc_t)
1264 call bdry_mask%init_from_components(this%c_Xh, 10.0_rp)
1265 call bdry_mask%mark_facets(bci%marked_facet)
1266 call bdry_mask%finalize()
1267 call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
1268 call bdry_mask%free()
1270 call bdry_mask%init_from_components(this%c_Xh, 11.0_rp)
1271 call bdry_mask%mark_facets(bci%marked_facet)
1272 call bdry_mask%finalize()
1273 call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
1274 call bdry_mask%free()
1279 call bdry_file%init(
'boundary_adjoint.fld')
1280 call bdry_file%write(bdry_field)
1282 call neko_scratch_registry%relinquish_field(temp_index)
1283 end subroutine adjoint_fluid_pnpn_write_boundary_conditions
1288 subroutine rescale_fluid(fluid_data, scale)
1290 class(adjoint_fluid_pnpn_t),
intent(inout) :: fluid_data
1292 real(kind=rp),
intent(in) :: scale
1298 if (neko_bcknd_device .eq. 1)
then
1299 call device_cmult(fluid_data%u_adj%x_d, scale, fluid_data%u_adj%size())
1300 call device_cmult(fluid_data%v_adj%x_d, scale, fluid_data%v_adj%size())
1301 call device_cmult(fluid_data%w_adj%x_d, scale, fluid_data%w_adj%size())
1303 call cmult(fluid_data%u_adj%x, scale, fluid_data%u_adj%size())
1304 call cmult(fluid_data%v_adj%x, scale, fluid_data%v_adj%size())
1305 call cmult(fluid_data%w_adj%x, scale, fluid_data%w_adj%size())
1309 if (neko_bcknd_device .eq. 1)
then
1310 call device_cmult(fluid_data%f_adj_x%x_d, scale, &
1311 fluid_data%f_adj_x%size())
1312 call device_cmult(fluid_data%f_adj_y%x_d, scale, &
1313 fluid_data%f_adj_y%size())
1314 call device_cmult(fluid_data%f_adj_z%x_d, scale, &
1315 fluid_data%f_adj_z%size())
1318 call device_cmult(fluid_data%abx1%x_d, scale, fluid_data%abx1%size())
1319 call device_cmult(fluid_data%aby1%x_d, scale, fluid_data%aby1%size())
1320 call device_cmult(fluid_data%abz1%x_d, scale, fluid_data%abz1%size())
1321 call device_cmult(fluid_data%abx2%x_d, scale, fluid_data%abx2%size())
1322 call device_cmult(fluid_data%aby2%x_d, scale, fluid_data%aby2%size())
1323 call device_cmult(fluid_data%abz2%x_d, scale, fluid_data%abz2%size())
1326 call cmult(fluid_data%f_adj_x%x, scale, fluid_data%f_adj_x%size())
1327 call cmult(fluid_data%f_adj_y%x, scale, fluid_data%f_adj_y%size())
1328 call cmult(fluid_data%f_adj_z%x, scale, fluid_data%f_adj_z%size())
1330 call cmult(fluid_data%abx1%x, scale, fluid_data%abx1%size())
1331 call cmult(fluid_data%aby1%x, scale, fluid_data%aby1%size())
1332 call cmult(fluid_data%abz1%x, scale, fluid_data%abz1%size())
1334 call cmult(fluid_data%abx2%x, scale, fluid_data%abx2%size())
1335 call cmult(fluid_data%aby2%x, scale, fluid_data%aby2%size())
1336 call cmult(fluid_data%abz2%x, scale, fluid_data%abz2%size())
1340 if (neko_bcknd_device .eq. 1)
then
1341 do i = 1, fluid_data%ulag%size()
1342 call device_cmult(fluid_data%ulag%lf(i)%x_d, &
1343 scale, fluid_data%ulag%lf(i)%size())
1346 do i = 1, fluid_data%vlag%size()
1347 call device_cmult(fluid_data%vlag%lf(i)%x_d, &
1348 scale, fluid_data%vlag%lf(i)%size())
1351 do i = 1, fluid_data%wlag%size()
1352 call device_cmult(fluid_data%wlag%lf(i)%x_d, &
1353 scale, fluid_data%wlag%lf(i)%size())
1356 do i = 1, fluid_data%ulag%size()
1357 call cmult(fluid_data%ulag%lf(i)%x, &
1358 scale, fluid_data%ulag%lf(i)%size())
1361 do i = 1, fluid_data%vlag%size()
1362 call cmult(fluid_data%vlag%lf(i)%x, &
1363 scale, fluid_data%vlag%lf(i)%size())
1366 do i = 1, fluid_data%wlag%size()
1367 call cmult(fluid_data%wlag%lf(i)%x, &
1368 scale, fluid_data%wlag%lf(i)%size())
1372 end subroutine rescale_fluid
1374 function norm(x, y, z, B, volume, n)
1375 use mpi_f08,
only: mpi_in_place
1377 integer,
intent(in) :: n
1378 real(kind=rp),
dimension(n),
intent(in) :: x, y, z
1379 real(kind=rp),
dimension(n),
intent(in) :: b
1380 real(kind=rp),
intent(in) :: volume
1382 real(kind=rp) :: norm
1384 norm = vlsc3(x, x, b, n) + vlsc3(y, y, b, n) + vlsc3(z, z, b, n)
1386 call mpi_allreduce(mpi_in_place, norm, 1, &
1387 mpi_real_precision, mpi_sum, neko_comm)
1389 norm = sqrt(norm / volume)
1392 function device_norm(x_d, y_d, z_d, B_d, volume, n)
1393 use mpi_f08,
only: mpi_in_place
1395 type(c_ptr),
intent(in) :: x_d, y_d, z_d
1396 type(c_ptr),
intent(in) :: B_d
1397 real(kind=rp),
intent(in) :: volume
1398 integer,
intent(in) :: n
1400 real(kind=rp) :: device_norm
1402 device_norm = device_vlsc3(x_d, x_d, b_d, n) + &
1403 device_vlsc3(y_d, y_d, b_d, n) + &
1404 device_vlsc3(z_d, z_d, b_d, n)
1406 call mpi_allreduce(mpi_in_place, device_norm, 1, &
1407 mpi_real_precision, mpi_sum, neko_comm)
1409 device_norm = sqrt(device_norm / volume)
1411 end function device_norm
1417 subroutine power_iterations_compute(this, t, tstep)
1418 class(adjoint_fluid_pnpn_t),
target,
intent(inout) :: this
1419 real(kind=rp),
intent(in) :: t
1420 integer,
intent(in) :: tstep
1423 real(kind=rp) :: scaling_factor
1424 real(kind=rp) :: norm_l2, norm_l2_base
1425 character(len=256) :: log_message
1426 type(vector_t) :: data_line
1429 n = this%c_Xh%dof%size()
1430 if (tstep .eq. 1)
then
1431 if (neko_bcknd_device .eq. 1)
then
1432 norm_l2_base = device_norm(this%u_adj%x_d, this%v_adj%x_d, &
1434 this%c_Xh%B_d, this%c_Xh%volume, n)
1436 norm_l2_base = this%norm_scaling * norm(this%u_adj%x, this%v_adj%x, &
1438 this%c_Xh%B, this%c_Xh%volume, n)
1440 if (this%norm_target .lt. 0.0_rp)
then
1441 this%norm_target = norm_l2_base
1444 this%norm_l2_upper = this%norm_tolerance * this%norm_target
1445 this%norm_l2_lower = this%norm_target / this%norm_tolerance
1450 if (neko_bcknd_device .eq. 1)
then
1451 norm_l2 = device_norm(this%u_adj%x_d, this%v_adj%x_d, this%w_adj%x_d, &
1452 this%c_Xh%B_d, this%c_Xh%volume, n)
1454 norm_l2 = norm(this%u_adj%x, this%v_adj%x, this%w_adj%x, &
1455 this%c_Xh%B, this%c_Xh%volume, n)
1457 norm_l2 = sqrt(this%norm_scaling) * norm_l2
1458 scaling_factor = 1.0_rp
1461 if (norm_l2 .gt. this%norm_l2_upper &
1462 .or. norm_l2 .lt. this%norm_l2_lower)
then
1463 scaling_factor = this%norm_target / norm_l2
1464 call rescale_fluid(this, scaling_factor)
1465 norm_l2 = this%norm_target
1467 if (tstep .eq. 1)
then
1468 scaling_factor = 1.0_rp
1474 call neko_log%section(
'Power Iterations')
1476 write (log_message,
'(A7,E20.14)')
'Norm: ', norm_l2
1477 call neko_log%message(log_message, lvl = neko_log_debug)
1478 write (log_message,
'(A7,E20.14)')
'Scaling: ', scaling_factor
1479 call neko_log%message(log_message, lvl = neko_log_debug)
1482 call data_line%init(2)
1483 data_line%x = [norm_l2, scaling_factor]
1484 call this%file_output%write(data_line, t)
1487 call neko_log%end_section(
'Power Iterations')
1488 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.