64  use num_types, 
only: rp
 
   65  use field, 
only: field_t
 
   66  use field_math, 
only: field_col3, field_addcol3, field_cmult, field_add2s2, &
 
   68  use operators, 
only: grad
 
   70  use scratch_registry, 
only: neko_scratch_registry
 
   76  use coefs, 
only: coef_t
 
   77  use field_registry, 
only: neko_field_registry
 
   78  use neko_config, 
only: neko_bcknd_device
 
   79  use math, 
only: glsc2, copy
 
   80  use device_math, 
only: device_copy, device_glsc2
 
   83  use point_zone, 
only: point_zone_t
 
   85  use math_ext, 
only: glsc2_mask
 
   86  use utils, 
only: neko_error
 
   87  use json_module, 
only: json_file
 
   88  use json_utils, 
only: json_get_or_default
 
   99     type(field_t), 
pointer :: u => null()
 
  101     type(field_t), 
pointer :: v => null()
 
  103     type(field_t), 
pointer :: w => null()
 
  105     type(coef_t), 
pointer :: c_xh => null()
 
  108     type(field_t), 
pointer :: adjoint_u => null()
 
  110     type(field_t), 
pointer :: adjoint_v => null()
 
  112     type(field_t), 
pointer :: adjoint_w => null()
 
  116     procedure, 
public, pass(this) :: init_json_sim => &
 
  117          minimum_dissipation_init_json_sim
 
  119     procedure, 
public, pass(this) :: init_from_attributes => &
 
  120          minimum_dissipation_init_attributes
 
  122     procedure, 
public, pass(this) :: free => minimum_dissipation_free
 
  124     procedure, 
public, pass(this) :: update_value => &
 
  125          minimum_dissipation_update_value
 
  127     procedure, 
public, pass(this) :: update_sensitivity => &
 
  128          minimum_dissipation_update_sensitivity
 
 
  139  subroutine minimum_dissipation_init_json_sim(this, json, design, simulation)
 
  141    type(json_file), 
intent(inout) :: json
 
  142    class(
design_t), 
intent(in) :: design
 
  145    character(len=:), 
allocatable :: name
 
  146    character(len=:), 
allocatable :: mask_name
 
  147    real(kind=rp) :: weight
 
  149    call json_get_or_default(json, 
"weight", weight, 1.0_rp)
 
  150    call json_get_or_default(json, 
"mask_name", mask_name, 
"")
 
  151    call json_get_or_default(json, 
"name", name, 
"Dissipation")
 
  153    call this%init_from_attributes(
design, simulation, weight, name, mask_name)
 
 
  154  end subroutine minimum_dissipation_init_json_sim
 
  163  subroutine minimum_dissipation_init_attributes(this, design, simulation, &
 
  164       weight, name, mask_name)
 
  166    class(
design_t), 
intent(in) :: design
 
  168    real(kind=rp), 
intent(in) :: weight
 
  169    character(len=*), 
intent(in) :: name
 
  170    character(len=*), 
intent(in) :: mask_name
 
  174    call this%init_base(name, 
design%size(), weight, mask_name)
 
  177    this%u => neko_field_registry%get_field(
'u')
 
  178    this%v => neko_field_registry%get_field(
'v')
 
  179    this%w => neko_field_registry%get_field(
'w')
 
  180    this%c_Xh => simulation%fluid%c_Xh
 
  181    this%adjoint_u => neko_field_registry%get_field(
'u_adj')
 
  182    this%adjoint_v => neko_field_registry%get_field(
'v_adj')
 
  183    this%adjoint_w => neko_field_registry%get_field(
'w_adj')
 
  188    call adjoint_forcing%init_from_components( &
 
  189         simulation%adjoint_fluid%f_adj_x, &
 
  190         simulation%adjoint_fluid%f_adj_y, &
 
  191         simulation%adjoint_fluid%f_adj_z, &
 
  192         this%u, this%v, this%w, this%weight, &
 
  193         this%mask, this%has_mask, &
 
  197    select type (f => simulation%adjoint_fluid)
 
  199       call f%source_term%add_source_term(adjoint_forcing)
 
  202  end subroutine minimum_dissipation_init_attributes
 
  205  subroutine minimum_dissipation_free(this)
 
  207    call this%free_base()
 
  209    if (
associated(this%u)) 
nullify(this%u)
 
  210    if (
associated(this%v)) 
nullify(this%v)
 
  211    if (
associated(this%w)) 
nullify(this%w)
 
  212    if (
associated(this%c_Xh)) 
nullify(this%c_Xh)
 
  214    if (
associated(this%adjoint_u)) 
nullify(this%adjoint_u)
 
  215    if (
associated(this%adjoint_v)) 
nullify(this%adjoint_v)
 
  216    if (
associated(this%adjoint_w)) 
nullify(this%adjoint_w)
 
  218  end subroutine minimum_dissipation_free
 
  223  subroutine minimum_dissipation_update_value(this, design)
 
  225    class(
design_t), 
intent(in) :: design
 
  226    type(field_t), 
pointer :: wo1, wo2, wo3, work
 
  227    type(field_t), 
pointer :: objective_field
 
  228    integer :: temp_indices(5)
 
  231    call neko_scratch_registry%request_field(wo1, temp_indices(1))
 
  232    call neko_scratch_registry%request_field(wo2, temp_indices(2))
 
  233    call neko_scratch_registry%request_field(wo3, temp_indices(3))
 
  234    call neko_scratch_registry%request_field(objective_field, temp_indices(4))
 
  235    call neko_scratch_registry%request_field(work, temp_indices(5))
 
  238    call grad(wo1%x, wo2%x, wo3%x, this%u%x, this%c_Xh)
 
  239    call field_col3(objective_field, wo1, wo1)
 
  240    call field_addcol3(objective_field, wo2, wo2)
 
  241    call field_addcol3(objective_field, wo3, wo3)
 
  243    call grad(wo1%x, wo2%x, wo3%x, this%v%x, this%c_Xh)
 
  244    call field_addcol3(objective_field, wo1, wo1)
 
  245    call field_addcol3(objective_field, wo2, wo2)
 
  246    call field_addcol3(objective_field, wo3, wo3)
 
  248    call grad(wo1%x, wo2%x, wo3%x, this%w%x, this%c_Xh)
 
  249    call field_addcol3(objective_field, wo1, wo1)
 
  250    call field_addcol3(objective_field, wo2, wo2)
 
  251    call field_addcol3(objective_field, wo3, wo3)
 
  255    if (this%has_mask) 
then 
  256       if (neko_bcknd_device .eq. 1) 
then 
  259          call field_copy(work, objective_field)
 
  261          this%value = device_glsc2(work%x_d, this%c_xh%B_d, n)
 
  263          this%value = glsc2_mask(objective_field%x, this%C_Xh%b, &
 
  264               n, this%mask%mask%get(), this%mask%size)
 
  267       if (neko_bcknd_device .eq. 1) 
then 
  268          this%value = device_glsc2(objective_field%x_d, &
 
  271          this%value = glsc2(objective_field%x, this%C_Xh%b, n)
 
  275    this%value = this%value * 0.5_rp
 
  277    call neko_scratch_registry%relinquish_field(temp_indices)
 
  279  end subroutine minimum_dissipation_update_value
 
  284  subroutine minimum_dissipation_update_sensitivity(this, design)
 
  286    class(
design_t), 
intent(in) :: design
 
  287    type(field_t), 
pointer :: work
 
  288    integer :: temp_indices(1)
 
  290    call neko_scratch_registry%request_field(work, temp_indices(1))
 
  293    call field_col3(work, this%u, this%adjoint_u)
 
  294    call field_addcol3(work, this%v, this%adjoint_v)
 
  295    call field_addcol3(work, this%w, this%adjoint_w)
 
  297    call field_cmult(work, -1.0_rp)
 
  299    if (neko_bcknd_device .eq. 1) 
then 
  300       call device_copy(this%sensitivity%x_d, work%x_d, this%sensitivity%size())
 
  302       call copy(this%sensitivity%x, work%x, this%sensitivity%size())
 
  305    call neko_scratch_registry%relinquish_field(temp_indices)
 
  307  end subroutine minimum_dissipation_update_sensitivity
 
Adjoint Pn/Pn formulation.
 
Implements the adjoint_minimum_dissipation_source_term_t type.
 
Some common Masking operations we may need.
 
Implements the minimum_dissipation_objective_t type.
 
Implements the objective_t type.
 
Implements the steady_problem_t type.
 
Base type of all fluid formulations.
 
An adjoint source term for objectives of minimum dissipation.
 
A topology optimization design variable.
 
An objective function corresponding to minimum dissipation  .
 
The abstract objective type.