35  use, 
intrinsic :: iso_fortran_env, only: error_unit
 
   36  use coefs, 
only: coef_t
 
   37  use symmetry, 
only: symmetry_t
 
   38  use field_registry, 
only: neko_field_registry
 
   39  use logger, 
only: neko_log, log_size, neko_log_debug
 
   40  use num_types, 
only: rp
 
   41  use krylov, 
only: ksp_monitor_t
 
   42  use pnpn_residual, 
only: pnpn_prs_res_t, pnpn_vel_res_t, &
 
   43       pnpn_prs_res_factory, pnpn_vel_res_factory, &
 
   44       pnpn_prs_res_stress_factory, pnpn_vel_res_stress_factory
 
   45  use rhs_maker, 
only: rhs_maker_sumab_t, rhs_maker_bdf_t, rhs_maker_ext_t, &
 
   46       rhs_maker_oifs_t, rhs_maker_sumab_fctry, rhs_maker_bdf_fctry, &
 
   47       rhs_maker_ext_fctry, rhs_maker_oifs_fctry
 
   51  use device_mathops, 
only: device_opcolv, device_opadd2cm
 
   52  use fluid_aux, 
only: fluid_step_info
 
   53  use time_scheme_controller, 
only: time_scheme_controller_t
 
   54  use projection, 
only: projection_t
 
   55  use projection_vel, 
only: projection_vel_t
 
   56  use device, 
only: device_memcpy, host_to_device, device_event_sync, &
 
   59  use profiler, 
only: profiler_start_region, profiler_end_region
 
   60  use json_module, 
only: json_file, json_core, json_value
 
   61  use json_utils, 
only: json_get, json_get_or_default, json_extract_item
 
   62  use json_module, 
only: json_file
 
   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, opcolv
 
   77  use bc_list, 
only: bc_list_t
 
   78  use zero_dirichlet, 
only: zero_dirichlet_t
 
   79  use utils, 
only: neko_error, neko_type_error
 
   80  use field_math, 
only: field_add2, field_copy
 
   82  use file, 
only: file_t
 
   83  use operators, 
only: ortho
 
   84  use inflow, 
only: inflow_t
 
   85  use field_dirichlet, 
only: field_dirichlet_t
 
   86  use blasius, 
only: blasius_t
 
   87  use field_dirichlet_vector, 
only: field_dirichlet_vector_t
 
   88  use dong_outflow, 
only: dong_outflow_t
 
   89  use time_state, 
only: time_state_t
 
   90  use vector, 
only: vector_t
 
   91  use device_math, 
only: device_vlsc3, device_cmult
 
   92  use math, 
only: vlsc3, cmult
 
   94  use, 
intrinsic :: iso_c_binding, only: c_ptr, c_null_ptr, c_associated
 
   95  use comm, 
only: neko_comm, mpi_real_precision
 
   96  use mpi_f08, 
only: mpi_sum, mpi_max, mpi_allreduce, mpi_comm_world, &
 
   97       mpi_integer, mpi_logical, mpi_lor
 
  105     type(field_t) :: p_res, u_res, v_res, w_res
 
  109     type(field_t) :: dp, du, dv, dw
 
  116     class(ax_t), 
allocatable :: ax_vel
 
  118     class(ax_t), 
allocatable :: ax_prs
 
  125     type(projection_t) :: proj_prs
 
  126     type(projection_vel_t) :: proj_vel
 
  133     type(facet_normal_t) :: bc_prs_surface
 
  136     type(facet_normal_t) :: bc_sym_surface
 
  143     type(zero_dirichlet_t) :: bc_vel_res
 
  145     type(zero_dirichlet_t) :: bc_du
 
  147     type(zero_dirichlet_t) :: bc_dv
 
  149     type(zero_dirichlet_t) :: bc_dw
 
  151     type(zero_dirichlet_t) :: bc_dp
 
  154     type(bc_list_t) :: bclst_vel_res
 
  155     type(bc_list_t) :: bclst_du
 
  156     type(bc_list_t) :: bclst_dv
 
  157     type(bc_list_t) :: bclst_dw
 
  158     type(bc_list_t) :: bclst_dp
 
  163     logical :: prs_dirichlet = .false.
 
  173     type(field_t) :: abx1, aby1, abz1
 
  174     type(field_t) :: abx2, aby2, abz2
 
  177     type(field_t) :: advx, advy, advz
 
  180     class(pnpn_prs_res_t), 
allocatable :: prs_res
 
  183     class(pnpn_vel_res_t), 
allocatable :: vel_res
 
  186     class(rhs_maker_sumab_t), 
allocatable :: sumab
 
  189     class(rhs_maker_ext_t), 
allocatable :: makeabf
 
  192     class(rhs_maker_bdf_t), 
allocatable :: makebdf
 
  195     class(rhs_maker_oifs_t), 
allocatable :: makeoifs
 
  201     logical :: full_stress_formulation = .false.
 
  206     real(kind=rp) :: norm_scaling 
 
  207     real(kind=rp) :: norm_target 
 
  208     real(kind=rp) :: norm_tolerance 
 
  214     real(kind=rp) :: norm_l2_base
 
  217     real(kind=rp) :: norm_l2_upper
 
  219     real(kind=rp) :: norm_l2_lower
 
  222     type(file_t) :: file_output
 
  226     procedure, pass(this) :: init => adjoint_fluid_pnpn_init
 
  228     procedure, pass(this) :: free => adjoint_fluid_pnpn_free
 
  230     procedure, pass(this) :: step => adjoint_fluid_pnpn_step
 
  232     procedure, pass(this) :: restart => adjoint_fluid_pnpn_restart
 
  234     procedure, pass(this) :: setup_bcs => adjoint_fluid_pnpn_setup_bcs
 
  236     procedure, pass(this) :: write_boundary_conditions => &
 
  237          adjoint_fluid_pnpn_write_boundary_conditions
 
  240     procedure, 
public, pass(this) :: pw_compute_ => power_iterations_compute
 
 
  252     module subroutine pressure_bc_factory(object, scheme, json, coef, user)
 
  253       class(bc_t), 
pointer, 
intent(inout) :: object
 
  254       type(adjoint_fluid_pnpn_t), 
intent(in) :: scheme
 
  255       type(json_file), 
intent(inout) :: json
 
  256       type(coef_t), 
intent(in) :: coef
 
  257       type(user_t), 
intent(in) :: user
 
  258     end subroutine pressure_bc_factory
 
  259  end interface pressure_bc_factory
 
  268  interface velocity_bc_factory
 
  269     module subroutine velocity_bc_factory(object, scheme, json, coef, user)
 
  270       class(bc_t), 
pointer, 
intent(inout) :: object
 
  271       type(adjoint_fluid_pnpn_t), 
intent(in) :: scheme
 
  272       type(json_file), 
intent(inout) :: json
 
  273       type(coef_t), 
intent(in) :: coef
 
  274       type(user_t), 
intent(in) :: user
 
  275     end subroutine velocity_bc_factory
 
 
  276  end interface velocity_bc_factory
 
  280  subroutine adjoint_fluid_pnpn_init(this, msh, lx, params, user, chkp)
 
  281    class(adjoint_fluid_pnpn_t), 
target, 
intent(inout) :: this
 
  282    type(mesh_t), 
target, 
intent(inout) :: msh
 
  283    integer, 
intent(in) :: lx
 
  284    type(json_file), 
target, 
intent(inout) :: params
 
  285    type(user_t), 
target, 
intent(in) :: user
 
  286    type(chkp_t), 
target, 
intent(inout) :: chkp
 
  287    character(len=15), 
parameter :: scheme = 
'Adjoint (Pn/Pn)' 
  288    real(kind=rp) :: abs_tol
 
  289    character(len=LOG_SIZE) :: log_buf
 
  290    integer :: integer_val, solver_maxiter
 
  291    character(len=:), 
allocatable :: solver_type, precon_type
 
  292    logical :: monitor, found
 
  294    type(json_file) :: numerics_params, precon_params
 
  297    character(len=:), 
allocatable :: file_name
 
  298    character(len=256) :: header_line
 
  303    call this%init_base(msh, lx, params, scheme, user, .true.)
 
  307    call neko_field_registry%add_field(this%dm_Xh, 
'p_adj')
 
  308    this%p_adj => neko_field_registry%get_field(
'p_adj')
 
  314    call json_get(params, 
'case.numerics.time_order', integer_val)
 
  315    allocate(this%ext_bdf)
 
  316    call this%ext_bdf%init(integer_val)
 
  318    call json_get_or_default(params, 
"case.fluid.full_stress_formulation", &
 
  319         this%full_stress_formulation, .false.)
 
  321    if (this%full_stress_formulation .eqv. .true.) 
then 
  323            "Full stress formulation is not supported in the adjoint module.")
 
  334       call ax_helm_factory(this%Ax_vel, full_formulation = .false.)
 
  337       call pnpn_prs_res_factory(this%prs_res)
 
  340       call pnpn_vel_res_factory(this%vel_res)
 
  343    if (params%valid_path(
'case.fluid.nut_field')) 
then 
  344       if (this%full_stress_formulation .eqv. .false.) 
then 
  345          call neko_error(
"You need to set full_stress_formulation to " // &
 
  346               "true for the fluid to have a spatially varying " // &
 
  349       call json_get(params, 
'case.fluid.nut_field', this%nut_field_name)
 
  351       this%nut_field_name = 
"" 
  355    call ax_helm_factory(this%Ax_prs, full_formulation = .false.)
 
  359    call rhs_maker_sumab_fctry(this%sumab)
 
  362    call rhs_maker_ext_fctry(this%makeabf)
 
  365    call rhs_maker_bdf_fctry(this%makebdf)
 
  368    call rhs_maker_oifs_fctry(this%makeoifs)
 
  371    associate(xh_lx => this%Xh%lx, xh_ly => this%Xh%ly, xh_lz => this%Xh%lz, &
 
  372         dm_xh => this%dm_Xh, nelv => this%msh%nelv)
 
  374      call this%p_res%init(dm_xh, 
"p_res")
 
  375      call this%u_res%init(dm_xh, 
"u_res")
 
  376      call this%v_res%init(dm_xh, 
"v_res")
 
  377      call this%w_res%init(dm_xh, 
"w_res")
 
  378      call this%abx1%init(dm_xh, 
"abx1")
 
  379      call this%aby1%init(dm_xh, 
"aby1")
 
  380      call this%abz1%init(dm_xh, 
"abz1")
 
  381      call this%abx2%init(dm_xh, 
"abx2")
 
  382      call this%aby2%init(dm_xh, 
"aby2")
 
  383      call this%abz2%init(dm_xh, 
"abz2")
 
  384      call this%advx%init(dm_xh, 
"advx")
 
  385      call this%advy%init(dm_xh, 
"advy")
 
  386      call this%advz%init(dm_xh, 
"advz")
 
  389    call this%du%init(this%dm_Xh, 
'du')
 
  390    call this%dv%init(this%dm_Xh, 
'dv')
 
  391    call this%dw%init(this%dm_Xh, 
'dw')
 
  392    call this%dp%init(this%dm_Xh, 
'dp')
 
  395    call this%setup_bcs(user, params)
 
  398    call json_get_or_default(params, 
'case.output_boundary', found, .false.)
 
  399    if (found) 
call this%write_boundary_conditions()
 
  401    call this%proj_prs%init(this%dm_Xh%size(), this%pr_projection_dim, &
 
  402         this%pr_projection_activ_step)
 
  404    call this%proj_vel%init(this%dm_Xh%size(), this%vel_projection_dim, &
 
  405         this%vel_projection_activ_step)
 
  408    call json_get_or_default(params, 
'case.numerics.oifs', this%oifs, .false.)
 
  409    if (params%valid_path(
'case.fluid.flow_rate_force')) 
then 
  410       call neko_error(
"Flow rate forcing not available for adjoint_fluid_pnpn")
 
  414    call neko_log%section(
"Pressure solver")
 
  416    call json_get_or_default(params, &
 
  417         'case.fluid.pressure_solver.max_iterations', &
 
  419    call json_get(params, 
'case.fluid.pressure_solver.type', solver_type)
 
  420    call json_get(params, 
'case.fluid.pressure_solver.preconditioner.type', &
 
  422    call json_get(params, &
 
  423         'case.fluid.pressure_solver.preconditioner', precon_params)
 
  424    call json_get(params, 
'case.fluid.pressure_solver.absolute_tolerance', &
 
  426    call json_get_or_default(params, 
'case.fluid.pressure_solver.monitor', &
 
  428    call neko_log%message(
'Type       : ('// trim(solver_type) // &
 
  429         ', ' // trim(precon_type) // 
')')
 
  430    write(log_buf, 
'(A,ES13.6)') 
'Abs tol    :', abs_tol
 
  431    call neko_log%message(log_buf)
 
  433    call this%solver_factory(this%ksp_prs, this%dm_Xh%size(), &
 
  434         solver_type, solver_maxiter, abs_tol, monitor)
 
  435    call this%precon_factory_(this%pc_prs, this%ksp_prs, &
 
  436         this%c_Xh, this%dm_Xh, this%gs_Xh, this%bcs_prs, &
 
  437         precon_type, precon_params)
 
  438    call neko_log%end_section()
 
  441    call neko_log%section(
"Advection factory")
 
  442    call json_get_or_default(params, 
'case.fluid.advection', advection, .true.)
 
  443    call json_get(params, 
'case.numerics', numerics_params)
 
  444    call advection_adjoint_factory(this%adv, numerics_params, this%c_Xh, &
 
  445         this%ulag, this%vlag, this%wlag, &
 
  446         chkp%dtlag, chkp%tlag, this%ext_bdf, &
 
  452    call this%chkp%init(this%u_adj, this%v_adj, this%w_adj, this%p_adj)
 
  454    this%chkp%abx1 => this%abx1
 
  455    this%chkp%abx2 => this%abx2
 
  456    this%chkp%aby1 => this%aby1
 
  457    this%chkp%aby2 => this%aby2
 
  458    this%chkp%abz1 => this%abz1
 
  459    this%chkp%abz2 => this%abz2
 
  460    call this%chkp%add_lag(this%ulag, this%vlag, this%wlag)
 
  462    call neko_log%end_section()
 
  468    call json_get_or_default(params, 
'norm_scaling', &
 
  469         this%norm_scaling, 0.5_rp)
 
  477    this%u_b => neko_field_registry%get_field(
'u')
 
  478    this%v_b => neko_field_registry%get_field(
'v')
 
  479    this%w_b => neko_field_registry%get_field(
'w')
 
  480    this%p_b => neko_field_registry%get_field(
'p')
 
  483    call json_get_or_default(params, 
'norm_target', &
 
  484         this%norm_target, -1.0_rp)
 
  485    call json_get_or_default(params, 
'norm_tolerance', &
 
  486         this%norm_tolerance, 10.0_rp)
 
  489    call json_get_or_default(params, 
'output_file', &
 
  490         file_name, 
'power_iterations.csv')
 
  491    call this%file_output%init(trim(file_name))
 
  492    write(header_line, 
'(A)') 
'Time, Norm, Scaling' 
  493    call this%file_output%set_header(header_line)
 
  495  end subroutine adjoint_fluid_pnpn_init
 
  497  subroutine adjoint_fluid_pnpn_restart(this, chkp)
 
  498    class(adjoint_fluid_pnpn_t), 
target, 
intent(inout) :: this
 
  499    type(chkp_t), 
intent(inout) :: chkp
 
  500    real(kind=rp) :: dtlag(10), tlag(10)
 
  506    n = this%u_adj%dof%size()
 
  507    if (
allocated(this%chkp%previous_mesh%elements) .or. &
 
  508         chkp%previous_Xh%lx .ne. this%Xh%lx) 
then 
  509       associate(u => this%u_adj, v => this%v_adj, w => this%w_adj, &
 
  510            p => this%p_adj, c_xh => this%c_Xh, ulag => this%ulag, &
 
  511            vlag => this%vlag, wlag => this%wlag)
 
  512         do concurrent(j = 1:n)
 
  513            u%x(j,1,1,1) = u%x(j,1,1,1) * c_xh%mult(j,1,1,1)
 
  514            v%x(j,1,1,1) = v%x(j,1,1,1) * c_xh%mult(j,1,1,1)
 
  515            w%x(j,1,1,1) = w%x(j,1,1,1) * c_xh%mult(j,1,1,1)
 
  516            p%x(j,1,1,1) = p%x(j,1,1,1) * c_xh%mult(j,1,1,1)
 
  518         do i = 1, this%ulag%size()
 
  519            do concurrent(j = 1:n)
 
  520               ulag%lf(i)%x(j,1,1,1) = ulag%lf(i)%x(j,1,1,1) &
 
  522               vlag%lf(i)%x(j,1,1,1) = vlag%lf(i)%x(j,1,1,1) &
 
  524               wlag%lf(i)%x(j,1,1,1) = wlag%lf(i)%x(j,1,1,1) &
 
  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%bclst_vel_res%free()
 
  606    call this%bclst_dp%free()
 
  607    call this%proj_prs%free()
 
  608    call this%proj_vel%free()
 
  610    call this%p_res%free()
 
  611    call this%u_res%free()
 
  612    call this%v_res%free()
 
  613    call this%w_res%free()
 
  620    call this%abx1%free()
 
  621    call this%aby1%free()
 
  622    call this%abz1%free()
 
  624    call this%abx2%free()
 
  625    call this%aby2%free()
 
  626    call this%abz2%free()
 
  628    call this%advx%free()
 
  629    call this%advy%free()
 
  630    call this%advz%free()
 
  632    if (
allocated(this%Ax_vel)) 
then 
  633       deallocate(this%Ax_vel)
 
  636    if (
allocated(this%Ax_prs)) 
then 
  637       deallocate(this%Ax_prs)
 
  640    if (
allocated(this%prs_res)) 
then 
  641       deallocate(this%prs_res)
 
  644    if (
allocated(this%vel_res)) 
then 
  645       deallocate(this%vel_res)
 
  648    if (
allocated(this%sumab)) 
then 
  649       deallocate(this%sumab)
 
  652    if (
allocated(this%makeabf)) 
then 
  653       deallocate(this%makeabf)
 
  656    if (
allocated(this%makebdf)) 
then 
  657       deallocate(this%makebdf)
 
  660    if (
allocated(this%makeoifs)) 
then 
  661       deallocate(this%makeoifs)
 
  664    if (
allocated(this%ext_bdf)) 
then 
  665       deallocate(this%ext_bdf)
 
  670  end subroutine adjoint_fluid_pnpn_free
 
  676  subroutine adjoint_fluid_pnpn_step(this, time, dt_controller)
 
  677    class(adjoint_fluid_pnpn_t), 
target, 
intent(inout) :: this
 
  678    type(time_state_t), 
intent(in) :: time
 
  679    type(time_step_controller_t), 
intent(in) :: dt_controller
 
  683    type(ksp_monitor_t) :: ksp_results(4)
 
  685    if (this%freeze) 
return 
  687    n = this%dm_Xh%size()
 
  689    call profiler_start_region(
'Adjoint')
 
  690    associate(u => this%u_adj, v => this%v_adj, w => this%w_adj, &
 
  692         u_e => this%u_adj_e, v_e => this%v_adj_e, w_e => this%w_adj_e, &
 
  693         du => this%du, dv => this%dv, dw => this%dw, dp => this%dp, &
 
  694         u_b => this%u_b, v_b => this%v_b, w_b => this%w_b, &
 
  695         u_res => this%u_res, v_res => this%v_res, w_res => this%w_res, &
 
  696         p_res => this%p_res, ax_vel => this%Ax_vel, ax_prs => this%Ax_prs, &
 
  698         c_xh => this%c_Xh, dm_xh => this%dm_Xh, gs_xh => this%gs_Xh, &
 
  699         ulag => this%ulag, vlag => this%vlag, wlag => this%wlag, &
 
  700         msh => this%msh, prs_res => this%prs_res, &
 
  701         source_term => this%source_term, vel_res => this%vel_res, &
 
  702         sumab => this%sumab, &
 
  703         makeabf => this%makeabf, makebdf => this%makebdf, &
 
  704         vel_projection_dim => this%vel_projection_dim, &
 
  705         pr_projection_dim => this%pr_projection_dim, &
 
  707         rho => this%rho, mu => this%mu, &
 
  708         f_x => this%f_adj_x, f_y => this%f_adj_y, f_z => this%f_adj_z, &
 
  709         t => time%t, tstep => time%tstep, dt => time%dt, &
 
  710         ext_bdf => this%ext_bdf, event => glb_cmd_event)
 
  713      call sumab%compute_fluid(u_e, v_e, w_e, u, v, w, &
 
  714           ulag, vlag, wlag, ext_bdf%advection_coeffs, ext_bdf%nadv)
 
  717      call this%source_term%compute(time)
 
  720      call this%bcs_vel%apply_vector(f_x%x, f_y%x, f_z%x, &
 
  721           this%dm_Xh%size(), time, strong = .false.)
 
  724         call neko_error(
"OIFS not implemented for adjoint")
 
  728         call this%adv%compute_adjoint(u, v, w, u_b, v_b, w_b, &
 
  730              xh, this%c_Xh, dm_xh%size())
 
  736         call makeabf%compute_fluid(this%abx1, this%aby1, this%abz1,&
 
  737              this%abx2, this%aby2, this%abz2, &
 
  738              f_x%x, f_y%x, f_z%x, &
 
  739              rho%x(1,1,1,1), ext_bdf%advection_coeffs, n)
 
  742         call makebdf%compute_fluid(ulag, vlag, wlag, f_x%x, f_y%x, f_z%x, &
 
  743              u, v, w, c_xh%B, rho%x(1,1,1,1), dt, &
 
  744              ext_bdf%diffusion_coeffs, ext_bdf%ndiff, n)
 
  751      call this%bc_apply_vel(time, strong = .true.)
 
  752      call this%bc_apply_prs(time)
 
  755      call this%update_material_properties(time)
 
  758      call profiler_start_region(
'Adjoint_pressure_residual')
 
  760      call prs_res%compute(p, p_res, &
 
  765           this%bc_prs_surface, this%bc_sym_surface, &
 
  766           ax_prs, ext_bdf%diffusion_coeffs(1), dt, &
 
  770      if (.not. this%prs_dirichlet) 
call ortho(p_res%x, this%glb_n_points, n)
 
  772      call gs_xh%op(p_res, gs_op_add, event)
 
  773      call device_event_sync(event)
 
  776      call this%bclst_dp%apply_scalar(p_res%x, p%dof%size(), time)
 
  779      call profiler_end_region(
'Adjoint_pressure_residual')
 
  782      call this%proj_prs%pre_solving(p_res%x, tstep, c_xh, n, dt_controller, &
 
  785      call this%pc_prs%update()
 
  787      call profiler_start_region(
'Adjoint_pressure_solve')
 
  791           this%ksp_prs%solve(ax_prs, dp, p_res%x, n, c_xh, &
 
  792           this%bclst_dp, gs_xh)
 
  795      call profiler_end_region(
'Adjoint_pressure_solve')
 
  797      call this%proj_prs%post_solving(dp%x, ax_prs, c_xh, &
 
  798           this%bclst_dp, gs_xh, n, tstep, dt_controller)
 
  801      call field_add2(p, dp, n)
 
  802      if (.not. this%prs_dirichlet) 
call ortho(p%x, this%glb_n_points, n)
 
  805      call profiler_start_region(
'Adjoint_velocity_residual')
 
  806      call vel_res%compute(ax_vel, u, v, w, &
 
  807           u_res, v_res, w_res, &
 
  811           mu, rho, ext_bdf%diffusion_coeffs(1), &
 
  814      call gs_xh%op(u_res, gs_op_add, event)
 
  815      call device_event_sync(event)
 
  816      call gs_xh%op(v_res, gs_op_add, event)
 
  817      call device_event_sync(event)
 
  818      call gs_xh%op(w_res, gs_op_add, event)
 
  819      call device_event_sync(event)
 
  822      call this%bclst_vel_res%apply(u_res, v_res, w_res, time)
 
  825      call profiler_end_region(
'Adjoint_velocity_residual')
 
  827      call this%proj_vel%pre_solving(u_res%x, v_res%x, w_res%x, &
 
  828           tstep, c_xh, n, dt_controller, 
'Velocity')
 
  830      call this%pc_vel%update()
 
  832      call profiler_start_region(
"Adjoint_velocity_solve")
 
  833      ksp_results(2:4) = this%ksp_vel%solve_coupled(ax_vel, du, dv, dw, &
 
  834           u_res%x, v_res%x, w_res%x, n, c_xh, &
 
  835           this%bclst_du, this%bclst_dv, this%bclst_dw, gs_xh, &
 
  836           this%ksp_vel%max_iter)
 
  837      call profiler_end_region(
"Adjoint_velocity_solve")
 
  839      ksp_results(1)%name = 
'Adjoint Pressure' 
  840      ksp_results(2)%name = 
'Adjoint Velocity U' 
  841      ksp_results(3)%name = 
'Adjoint Velocity V' 
  842      ksp_results(4)%name = 
'Adjoint Velocity W' 
  844      call this%proj_vel%post_solving(du%x, dv%x, dw%x, ax_vel, c_xh, &
 
  845           this%bclst_du, this%bclst_dv, this%bclst_dw, gs_xh, n, tstep, &
 
  848      if (neko_bcknd_device .eq. 1) 
then 
  849         call device_opadd2cm(u%x_d, v%x_d, w%x_d, &
 
  850              du%x_d, dv%x_d, dw%x_d, 1.0_rp, n, msh%gdim)
 
  852         call opadd2cm(u%x, v%x, w%x, du%x, dv%x, dw%x, 1.0_rp, n, msh%gdim)
 
  855      if (this%forced_flow_rate) 
then 
  856         call neko_error(
'Forced flow rate is not implemented for the adjoint')
 
  860      call fluid_step_info(time, ksp_results, &
 
  861           this%full_stress_formulation, this%strict_convergence)
 
  864    call profiler_end_region(
'Adjoint')
 
  866  end subroutine adjoint_fluid_pnpn_step
 
  872  subroutine adjoint_fluid_pnpn_setup_bcs(this, user, params)
 
  873    use mpi_f08, 
only: mpi_in_place
 
  874    class(adjoint_fluid_pnpn_t), 
intent(inout) :: this
 
  875    type(user_t), 
target, 
intent(in) :: user
 
  876    type(json_file), 
intent(inout) :: params
 
  877    integer :: i, n_bcs, j, zone_size, global_zone_size, ierr
 
  878    class(bc_t), 
pointer :: bc_i
 
  879    type(json_core) :: core
 
  880    type(json_value), 
pointer :: bc_object
 
  881    type(json_file) :: bc_subdict
 
  884    logical, 
allocatable :: marked_zones(:)
 
  885    integer, 
allocatable :: zone_indices(:)
 
  886    character(len=:), 
allocatable :: json_key
 
  889    call this%bclst_vel_res%init()
 
  890    call this%bclst_du%init()
 
  891    call this%bclst_dv%init()
 
  892    call this%bclst_dw%init()
 
  893    call this%bclst_dp%init()
 
  895    call this%bc_vel_res%init_from_components(this%c_Xh)
 
  896    call this%bc_du%init_from_components(this%c_Xh)
 
  897    call this%bc_dv%init_from_components(this%c_Xh)
 
  898    call this%bc_dw%init_from_components(this%c_Xh)
 
  899    call this%bc_dp%init_from_components(this%c_Xh)
 
  902    call this%bc_prs_surface%init_from_components(this%c_Xh)
 
  903    call this%bc_sym_surface%init_from_components(this%c_Xh)
 
  905    json_key = 
'case.adjoint_fluid.boundary_conditions' 
  908    if (params%valid_path(json_key)) 
then 
  909       call params%info(json_key, n_children = n_bcs)
 
  910       call params%get_core(core)
 
  911       call params%get(json_key, bc_object, found)
 
  916       call this%bcs_vel%init(n_bcs)
 
  918       allocate(marked_zones(
size(this%msh%labeled_zones)))
 
  919       marked_zones = .false.
 
  923          call json_extract_item(core, bc_object, i, bc_subdict)
 
  925          call json_get(bc_subdict, 
"zone_indices", zone_indices)
 
  930          do j = 1, 
size(zone_indices)
 
  931             zone_size = this%msh%labeled_zones(zone_indices(j))%size
 
  932             call mpi_allreduce(zone_size, global_zone_size, 1, &
 
  933                  mpi_integer, mpi_max, neko_comm, ierr)
 
  935             if (global_zone_size .eq. 0) 
then 
  936                write(error_unit, 
'(A, A, I0, A, A, I0, A)') 
"*** ERROR ***: ",&
 
  937                     "Zone index ", zone_indices(j), &
 
  938                     " is invalid as this zone has 0 size, meaning it does ", &
 
  939                     "not in the mesh. Check adjoint boundary condition ", &
 
  944             if (marked_zones(zone_indices(j)) .eqv. .true.) 
then 
  945                write(error_unit, 
'(A, A, I0, A, A, A, A)') 
"*** ERROR ***: ", &
 
  946                     "Zone with index ", zone_indices(j), &
 
  947                     " has already been assigned a boundary condition. ", &
 
  948                     "Please check your boundary_conditions entry for the ", &
 
  949                     "adjoint and make sure that each zone index appears ", &
 
  950                     "only in a single boundary condition." 
  953                marked_zones(zone_indices(j)) = .true.
 
  958          call velocity_bc_factory(bc_i, this, bc_subdict, this%c_Xh, user)
 
  962          if (
associated(bc_i)) 
then 
  976                call this%bclst_vel_res%append(bc_i)
 
  977                call this%bc_du%mark_facets(bc_i%bc_x%marked_facet)
 
  978                call this%bc_dv%mark_facets(bc_i%bc_y%marked_facet)
 
  979                call this%bc_dw%mark_facets(bc_i%bc_z%marked_facet)
 
  981                call this%bcs_vel%append(bc_i)
 
  983                call this%bc_sym_surface%mark_facets(bc_i%marked_facet)
 
  984             type is (non_normal_t)
 
  987                call this%bclst_vel_res%append(bc_i)
 
  988                call this%bc_du%mark_facets(bc_i%bc_x%marked_facet)
 
  989                call this%bc_dv%mark_facets(bc_i%bc_y%marked_facet)
 
  990                call this%bc_dw%mark_facets(bc_i%bc_z%marked_facet)
 
  991             type is (shear_stress_t)
 
  993                call this%bclst_vel_res%append(bc_i%symmetry)
 
  994                call this%bclst_du%append(bc_i%symmetry%bc_x)
 
  995                call this%bclst_dv%append(bc_i%symmetry%bc_y)
 
  996                call this%bclst_dw%append(bc_i%symmetry%bc_z)
 
  998                call this%bcs_vel%append(bc_i)
 
  999             type is (wall_model_bc_t)
 
 1001                call this%bclst_vel_res%append(bc_i%symmetry)
 
 1002                call this%bclst_du%append(bc_i%symmetry%bc_x)
 
 1003                call this%bclst_dv%append(bc_i%symmetry%bc_y)
 
 1004                call this%bclst_dw%append(bc_i%symmetry%bc_z)
 
 1006                call this%bcs_vel%append(bc_i)
 
 1013                if (bc_i%strong .eqv. .true.) 
then 
 1014                   call this%bc_vel_res%mark_facets(bc_i%marked_facet)
 
 1015                   call this%bc_du%mark_facets(bc_i%marked_facet)
 
 1016                   call this%bc_dv%mark_facets(bc_i%marked_facet)
 
 1017                   call this%bc_dw%mark_facets(bc_i%marked_facet)
 
 1019                   call this%bc_prs_surface%mark_facets(bc_i%marked_facet)
 
 1022                call this%bcs_vel%append(bc_i)
 
 1028       do i = 1, 
size(this%msh%labeled_zones)
 
 1029          if ((this%msh%labeled_zones(i)%size .gt. 0) .and. &
 
 1030               (marked_zones(i) .eqv. .false.)) 
then 
 1031             write(error_unit, 
'(A, A, I0)') 
"*** ERROR ***: ", &
 
 1032                  "No adjoint boundary condition assigned to zone ", i
 
 1040       call this%bcs_prs%init(n_bcs)
 
 1044          call json_extract_item(core, bc_object, i, bc_subdict)
 
 1046          call pressure_bc_factory(bc_i, this, bc_subdict, this%c_Xh, user)
 
 1050          if (
associated(bc_i)) 
then 
 1051             call this%bcs_prs%append(bc_i)
 
 1054             if (bc_i%strong .eqv. .true.) 
then 
 1055                call this%bc_dp%mark_facets(bc_i%marked_facet)
 
 1063       do i = 1, 
size(this%msh%labeled_zones)
 
 1064          if (this%msh%labeled_zones(i)%size .gt. 0) 
then 
 1065             call neko_error(
"No boundary_conditions entry in the case file!")
 
 1071    call this%bc_prs_surface%finalize()
 
 1072    call this%bc_sym_surface%finalize()
 
 1074    call this%bc_vel_res%finalize()
 
 1075    call this%bc_du%finalize()
 
 1076    call this%bc_dv%finalize()
 
 1077    call this%bc_dw%finalize()
 
 1078    call this%bc_dp%finalize()
 
 1080    call this%bclst_vel_res%append(this%bc_vel_res)
 
 1081    call this%bclst_du%append(this%bc_du)
 
 1082    call this%bclst_dv%append(this%bc_dv)
 
 1083    call this%bclst_dw%append(this%bc_dw)
 
 1084    call this%bclst_dp%append(this%bc_dp)
 
 1087    this%prs_dirichlet = .not. this%bclst_dp%is_empty()
 
 1088    call mpi_allreduce(mpi_in_place, this%prs_dirichlet, 1, &
 
 1089         mpi_logical, mpi_lor, neko_comm)
 
 1091  end subroutine adjoint_fluid_pnpn_setup_bcs
 
 1094  subroutine adjoint_fluid_pnpn_write_boundary_conditions(this)
 
 1095    class(adjoint_fluid_pnpn_t), 
target, 
intent(inout) :: this
 
 1096    type(dirichlet_t) :: bdry_mask
 
 1097    type(field_t), 
pointer :: bdry_field
 
 1098    type(file_t) :: bdry_file
 
 1099    integer :: temp_index, i
 
 1100    class(bc_t), 
pointer :: bci
 
 1101    character(len=LOG_SIZE) :: log_buf
 
 1103    call neko_log%section(
"Adjoint boundary conditions")
 
 1104    write(log_buf, 
'(A)') &
 
 1105         'Marking using integer keys in boundary_adjoint0.f00000' 
 1106    call neko_log%message(log_buf)
 
 1107    write(log_buf, 
'(A)') 
'Condition-value pairs: ' 
 1108    call neko_log%message(log_buf)
 
 1109    write(log_buf, 
'(A)') 
'  no_slip                         = 1' 
 1110    call neko_log%message(log_buf)
 
 1111    write(log_buf, 
'(A)') 
'  velocity_value                  = 2' 
 1112    call neko_log%message(log_buf)
 
 1113    write(log_buf, 
'(A)') 
'  outflow, normal_outflow (+dong) = 3' 
 1114    call neko_log%message(log_buf)
 
 1115    write(log_buf, 
'(A)') 
'  symmetry                        = 4' 
 1116    call neko_log%message(log_buf)
 
 1117    write(log_buf, 
'(A)') 
'  user_velocity_pointwise         = 5' 
 1118    call neko_log%message(log_buf)
 
 1119    write(log_buf, 
'(A)') 
'  periodic                        = 6' 
 1120    call neko_log%message(log_buf)
 
 1121    write(log_buf, 
'(A)') 
'  user_velocity                   = 7' 
 1122    call neko_log%message(log_buf)
 
 1123    write(log_buf, 
'(A)') 
'  user_pressure                   = 8' 
 1124    call neko_log%message(log_buf)
 
 1125    write(log_buf, 
'(A)') 
'  shear_stress                    = 9' 
 1126    call neko_log%message(log_buf)
 
 1127    write(log_buf, 
'(A)') 
'  wall_modelling                  = 10' 
 1128    call neko_log%message(log_buf)
 
 1129    write(log_buf, 
'(A)') 
'  blasius_profile                 = 11' 
 1130    call neko_log%message(log_buf)
 
 1131    call neko_log%end_section()
 
 1133    call this%scratch%request_field(bdry_field, temp_index)
 
 1138    call bdry_mask%init_from_components(this%c_Xh, 6.0_rp)
 
 1139    call bdry_mask%mark_zone(this%msh%periodic)
 
 1140    call bdry_mask%finalize()
 
 1141    call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
 
 1142    call bdry_mask%free()
 
 1144    do i = 1, this%bcs_prs%size()
 
 1145       bci => this%bcs_prs%get(i)
 
 1146       select type (bc => bci)
 
 1147       type is (zero_dirichlet_t)
 
 1148          call bdry_mask%init_from_components(this%c_Xh, 3.0_rp)
 
 1149          call bdry_mask%mark_facets(bci%marked_facet)
 
 1150          call bdry_mask%finalize()
 
 1151          call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
 
 1152          call bdry_mask%free()
 
 1153       type is (dong_outflow_t)
 
 1154          call bdry_mask%init_from_components(this%c_Xh, 3.0_rp)
 
 1155          call bdry_mask%mark_facets(bci%marked_facet)
 
 1156          call bdry_mask%finalize()
 
 1157          call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
 
 1158          call bdry_mask%free()
 
 1159       type is (field_dirichlet_t)
 
 1160          call bdry_mask%init_from_components(this%c_Xh, 8.0_rp)
 
 1161          call bdry_mask%mark_facets(bci%marked_facet)
 
 1162          call bdry_mask%finalize()
 
 1163          call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
 
 1164          call bdry_mask%free()
 
 1168    do i = 1, this%bcs_vel%size()
 
 1169       bci => this%bcs_vel%get(i)
 
 1170       select type (bc => bci)
 
 1171       type is (zero_dirichlet_t)
 
 1172          call bdry_mask%init_from_components(this%c_Xh, 1.0_rp)
 
 1173          call bdry_mask%mark_facets(bci%marked_facet)
 
 1174          call bdry_mask%finalize()
 
 1175          call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
 
 1176          call bdry_mask%free()
 
 1178          call bdry_mask%init_from_components(this%c_Xh, 2.0_rp)
 
 1179          call bdry_mask%mark_facets(bci%marked_facet)
 
 1180          call bdry_mask%finalize()
 
 1181          call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
 
 1182          call bdry_mask%free()
 
 1183       type is (symmetry_t)
 
 1184          call bdry_mask%init_from_components(this%c_Xh, 4.0_rp)
 
 1185          call bdry_mask%mark_facets(bci%marked_facet)
 
 1186          call bdry_mask%finalize()
 
 1187          call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
 
 1188          call bdry_mask%free()
 
 1189       type is (field_dirichlet_vector_t)
 
 1190          call bdry_mask%init_from_components(this%c_Xh, 7.0_rp)
 
 1191          call bdry_mask%mark_facets(bci%marked_facet)
 
 1192          call bdry_mask%finalize()
 
 1193          call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
 
 1194          call bdry_mask%free()
 
 1195       type is (shear_stress_t)
 
 1196          call bdry_mask%init_from_components(this%c_Xh, 9.0_rp)
 
 1197          call bdry_mask%mark_facets(bci%marked_facet)
 
 1198          call bdry_mask%finalize()
 
 1199          call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
 
 1200          call bdry_mask%free()
 
 1201       type is (wall_model_bc_t)
 
 1202          call bdry_mask%init_from_components(this%c_Xh, 10.0_rp)
 
 1203          call bdry_mask%mark_facets(bci%marked_facet)
 
 1204          call bdry_mask%finalize()
 
 1205          call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
 
 1206          call bdry_mask%free()
 
 1208          call bdry_mask%init_from_components(this%c_Xh, 11.0_rp)
 
 1209          call bdry_mask%mark_facets(bci%marked_facet)
 
 1210          call bdry_mask%finalize()
 
 1211          call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
 
 1212          call bdry_mask%free()
 
 1217    call bdry_file%init(
'boundary_adjoint.fld')
 
 1218    call bdry_file%write(bdry_field)
 
 1220    call this%scratch%relinquish_field(temp_index)
 
 1221  end subroutine adjoint_fluid_pnpn_write_boundary_conditions
 
 1226  subroutine rescale_fluid(fluid_data, scale)
 
 1228    class(adjoint_fluid_pnpn_t), 
intent(inout) :: fluid_data
 
 1230    real(kind=rp), 
intent(in) :: scale
 
 1236    if (neko_bcknd_device .eq. 1) 
then 
 1237       call device_cmult(fluid_data%u_adj%x_d, scale, fluid_data%u_adj%size())
 
 1238       call device_cmult(fluid_data%v_adj%x_d, scale, fluid_data%v_adj%size())
 
 1239       call device_cmult(fluid_data%w_adj%x_d, scale, fluid_data%w_adj%size())
 
 1241       call cmult(fluid_data%u_adj%x, scale, fluid_data%u_adj%size())
 
 1242       call cmult(fluid_data%v_adj%x, scale, fluid_data%v_adj%size())
 
 1243       call cmult(fluid_data%w_adj%x, scale, fluid_data%w_adj%size())
 
 1247    if (neko_bcknd_device .eq. 1) 
then 
 1248       call device_cmult(fluid_data%f_adj_x%x_d, scale, &
 
 1249            fluid_data%f_adj_x%size())
 
 1250       call device_cmult(fluid_data%f_adj_y%x_d, scale, &
 
 1251            fluid_data%f_adj_y%size())
 
 1252       call device_cmult(fluid_data%f_adj_z%x_d, scale, &
 
 1253            fluid_data%f_adj_z%size())
 
 1256       call device_cmult(fluid_data%abx1%x_d, scale, fluid_data%abx1%size())
 
 1257       call device_cmult(fluid_data%aby1%x_d, scale, fluid_data%aby1%size())
 
 1258       call device_cmult(fluid_data%abz1%x_d, scale, fluid_data%abz1%size())
 
 1259       call device_cmult(fluid_data%abx2%x_d, scale, fluid_data%abx2%size())
 
 1260       call device_cmult(fluid_data%aby2%x_d, scale, fluid_data%aby2%size())
 
 1261       call device_cmult(fluid_data%abz2%x_d, scale, fluid_data%abz2%size())
 
 1264       call cmult(fluid_data%f_adj_x%x, scale, fluid_data%f_adj_x%size())
 
 1265       call cmult(fluid_data%f_adj_y%x, scale, fluid_data%f_adj_y%size())
 
 1266       call cmult(fluid_data%f_adj_z%x, scale, fluid_data%f_adj_z%size())
 
 1268       call cmult(fluid_data%abx1%x, scale, fluid_data%abx1%size())
 
 1269       call cmult(fluid_data%aby1%x, scale, fluid_data%aby1%size())
 
 1270       call cmult(fluid_data%abz1%x, scale, fluid_data%abz1%size())
 
 1272       call cmult(fluid_data%abx2%x, scale, fluid_data%abx2%size())
 
 1273       call cmult(fluid_data%aby2%x, scale, fluid_data%aby2%size())
 
 1274       call cmult(fluid_data%abz2%x, scale, fluid_data%abz2%size())
 
 1278    if (neko_bcknd_device .eq. 1) 
then 
 1279       do i = 1, fluid_data%ulag%size()
 
 1280          call device_cmult(fluid_data%ulag%lf(i)%x_d, &
 
 1281               scale, fluid_data%ulag%lf(i)%size())
 
 1284       do i = 1, fluid_data%vlag%size()
 
 1285          call device_cmult(fluid_data%vlag%lf(i)%x_d, &
 
 1286               scale, fluid_data%vlag%lf(i)%size())
 
 1289       do i = 1, fluid_data%wlag%size()
 
 1290          call device_cmult(fluid_data%wlag%lf(i)%x_d, &
 
 1291               scale, fluid_data%wlag%lf(i)%size())
 
 1294       do i = 1, fluid_data%ulag%size()
 
 1295          call cmult(fluid_data%ulag%lf(i)%x, &
 
 1296               scale, fluid_data%ulag%lf(i)%size())
 
 1299       do i = 1, fluid_data%vlag%size()
 
 1300          call cmult(fluid_data%vlag%lf(i)%x, &
 
 1301               scale, fluid_data%vlag%lf(i)%size())
 
 1304       do i = 1, fluid_data%wlag%size()
 
 1305          call cmult(fluid_data%wlag%lf(i)%x, &
 
 1306               scale, fluid_data%wlag%lf(i)%size())
 
 1310  end subroutine rescale_fluid
 
 1312  function norm(x, y, z, B, volume, n)
 
 1313    use mpi_f08, 
only: mpi_in_place
 
 1315    integer, 
intent(in) :: n
 
 1316    real(kind=rp), 
dimension(n), 
intent(in) :: x, y, z
 
 1317    real(kind=rp), 
dimension(n), 
intent(in) :: b
 
 1318    real(kind=rp), 
intent(in) :: volume
 
 1320    real(kind=rp) :: norm
 
 1322    norm = vlsc3(x, x, b, n) + vlsc3(y, y, b, n) + vlsc3(z, z, b, n)
 
 1324    call mpi_allreduce(mpi_in_place, norm, 1, &
 
 1325         mpi_real_precision, mpi_sum, mpi_comm_world)
 
 1327    norm = sqrt(norm / volume)
 
 1330  function device_norm(x_d, y_d, z_d, B_d, volume, n)
 
 1331    use mpi_f08, 
only: mpi_in_place
 
 1333    type(c_ptr), 
intent(in) :: x_d, y_d, z_d
 
 1334    type(c_ptr), 
intent(in) :: B_d
 
 1335    real(kind=rp), 
intent(in) :: volume
 
 1336    integer, 
intent(in) :: n
 
 1338    real(kind=rp) :: device_norm
 
 1340    device_norm = device_vlsc3(x_d, x_d, b_d, n) + &
 
 1341         device_vlsc3(y_d, y_d, b_d, n) + &
 
 1342         device_vlsc3(z_d, z_d, b_d, n)
 
 1344    call mpi_allreduce(mpi_in_place, device_norm, 1, &
 
 1345         mpi_real_precision, mpi_sum, mpi_comm_world)
 
 1347    device_norm = sqrt(device_norm / volume)
 
 1349  end function device_norm
 
 1355  subroutine power_iterations_compute(this, t, tstep)
 
 1356    class(adjoint_fluid_pnpn_t), 
target, 
intent(inout) :: this
 
 1357    real(kind=rp), 
intent(in) :: t
 
 1358    integer, 
intent(in) :: tstep
 
 1361    real(kind=rp) :: scaling_factor
 
 1362    real(kind=rp) :: norm_l2, norm_l2_base
 
 1363    character(len=256) :: log_message
 
 1364    type(vector_t) :: data_line
 
 1367    n = this%c_Xh%dof%size()
 
 1368    if (tstep .eq. 1) 
then 
 1369       if (neko_bcknd_device .eq. 1) 
then 
 1370          norm_l2_base = device_norm(this%u_adj%x_d, this%v_adj%x_d, &
 
 1372               this%c_Xh%B_d, this%c_Xh%volume, n)
 
 1374          norm_l2_base = this%norm_scaling * norm(this%u_adj%x, this%v_adj%x, &
 
 1376               this%c_Xh%B, this%c_Xh%volume, n)
 
 1378       if (this%norm_target .lt. 0.0_rp) 
then 
 1379          this%norm_target = norm_l2_base
 
 1382       this%norm_l2_upper = this%norm_tolerance * this%norm_target
 
 1383       this%norm_l2_lower = this%norm_target / this%norm_tolerance
 
 1388    if (neko_bcknd_device .eq. 1) 
then 
 1389       norm_l2 = device_norm(this%u_adj%x_d, this%v_adj%x_d, this%w_adj%x_d, &
 
 1390            this%c_Xh%B_d, this%c_Xh%volume, n)
 
 1392       norm_l2 = norm(this%u_adj%x, this%v_adj%x, this%w_adj%x, &
 
 1393            this%c_Xh%B, this%c_Xh%volume, n)
 
 1395    norm_l2 = sqrt(this%norm_scaling) * norm_l2
 
 1396    scaling_factor = 1.0_rp
 
 1399    if (norm_l2 .gt. this%norm_l2_upper &
 
 1400         .or. norm_l2 .lt. this%norm_l2_lower) 
then 
 1401       scaling_factor = this%norm_target / norm_l2
 
 1402       call rescale_fluid(this, scaling_factor)
 
 1403       norm_l2 = this%norm_target
 
 1405       if (tstep .eq. 1) 
then 
 1406          scaling_factor = 1.0_rp
 
 1412    call neko_log%section(
'Power Iterations')
 
 1414    write (log_message, 
'(A7,E20.14)') 
'Norm: ', norm_l2
 
 1415    call neko_log%message(log_message, lvl = neko_log_debug)
 
 1416    write (log_message, 
'(A7,E20.14)') 
'Scaling: ', scaling_factor
 
 1417    call neko_log%message(log_message, lvl = neko_log_debug)
 
 1420    call data_line%init(2)
 
 1421    data_line%x = [norm_l2, scaling_factor]
 
 1422    call this%file_output%write(data_line, t)
 
 1425    call neko_log%end_section(
'Power Iterations')
 
 1426  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.
 
Base type of all fluid formulations.
 
Base abstract type for computing the advection operator.