45  use num_types, 
only: rp
 
   46  use coefs, 
only: coef_t
 
   47  use json_module, 
only: json_file
 
   48  use json_utils, 
only: json_get, json_get_or_default
 
   49  use field, 
only: field_t
 
   50  use field_registry, 
only: neko_field_registry
 
   51  use scratch_registry, 
only: neko_scratch_registry
 
   52  use neko_config, 
only: neko_bcknd_device
 
   55  use device_math, 
only: device_glsc2
 
   56  use vector_math, 
only: vector_cmult
 
   57  use math_ext, 
only: glsc2_mask
 
   58  use field_math, 
only: field_rone, field_copy
 
   59  use utils, 
only: neko_error
 
   72     real(kind=rp) :: limit
 
   74     real(kind=rp) :: volume_domain
 
   77     class(coef_t), 
pointer :: c_xh => null()
 
   82     procedure, 
public, pass(this) :: init_json_sim => &
 
   83          volume_constraint_init_json_sim
 
   85     procedure, 
public, pass(this) :: init_from_attributes => &
 
   86          volume_constraint_init_attributes
 
   88     procedure, 
public, pass(this) :: free => volume_constraint_free
 
   90     procedure, 
public, pass(this) :: update_value => &
 
   91          volume_constraint_update_value
 
   93     procedure, 
public, pass(this) :: update_sensitivity => &
 
   94          volume_constraint_update_sensitivity
 
   97     procedure, 
private, pass(this) :: compute_volume
 
 
  108  subroutine volume_constraint_init_json_sim(this, json, design, simulation)
 
  110    type(json_file), 
intent(inout) :: json
 
  111    class(
design_t), 
intent(in) :: design
 
  114    character(len=:), 
allocatable :: mask_name
 
  115    character(len=:), 
allocatable :: name
 
  117    real(kind=rp) :: limit
 
  119    call json_get_or_default(json, 
"mask_name", mask_name, 
"")
 
  120    call json_get_or_default(json, 
"name", name, 
"Volume constraint")
 
  121    call json_get_or_default(json, 
"is_max", is_max, .false.)
 
  122    call json_get(json, 
"limit", limit)
 
  124    call this%init_from_attributes(
design, simulation, name, mask_name, &
 
 
  126  end subroutine volume_constraint_init_json_sim
 
  136  subroutine volume_constraint_init_attributes(this, design, simulation, &
 
  137       name, mask_name, is_max, limit)
 
  139    class(
design_t), 
intent(in) :: design
 
  141    character(len=*), 
intent(in) :: mask_name
 
  142    character(len=*), 
intent(in) :: name
 
  143    logical, 
intent(in) :: is_max
 
  144    real(kind=rp), 
intent(in) :: limit
 
  146    real(kind=rp) :: volume
 
  147    type(field_t), 
pointer :: work
 
  148    integer :: temp_indices(1)
 
  151    call this%init_base(name, 
design%size(), mask_name)
 
  156    this%c_Xh => simulation%neko_case%fluid%c_Xh
 
  159    if (this%has_mask) 
then 
  162       call neko_scratch_registry%request_field(work, temp_indices(1))
 
  163       call field_rone(work)
 
  165       if (neko_bcknd_device .eq. 1) 
then 
  167          this%volume_domain = device_glsc2(work%x_d, this%c_xh%B_d, &
 
  170          this%volume_domain = glsc2_mask(work%x, this%c_Xh%B, &
 
  171               design%size(), this%mask%mask%get(), this%mask%size)
 
  174       call neko_scratch_registry%relinquish_field(temp_indices)
 
  176       this%volume_domain = this%c_Xh%volume
 
  183    volume = this%compute_volume(
design)
 
  186    this%value = this%limit - volume / this%volume_domain
 
  189    if (this%is_max) this%value = - ( this%value )
 
  194    this%sensitivity = 1.0_rp / this%volume_domain
 
  197    call vector_cmult(this%sensitivity, -1.0_rp)
 
  199    if (this%has_mask) 
then 
  203  end subroutine volume_constraint_init_attributes
 
  206  subroutine volume_constraint_free(this)
 
  209    call this%free_base()
 
  210  end subroutine volume_constraint_free
 
  215  subroutine volume_constraint_update_value(this, design)
 
  217    class(
design_t), 
intent(in) :: design
 
  218    real(kind=rp) :: volume
 
  220    volume = this%compute_volume(
design)
 
  223    this%value = this%limit - volume / this%volume_domain
 
  226    if (this%is_max) this%value = - ( this%value )
 
  228  end subroutine volume_constraint_update_value
 
  233  subroutine volume_constraint_update_sensitivity(this, design)
 
  235    class(
design_t), 
intent(in) :: design
 
  239  end subroutine volume_constraint_update_sensitivity
 
  251  function compute_volume(this, design) 
result(volume)
 
  253    class(
design_t), 
intent(in) :: design
 
  254    real(kind=rp) :: volume
 
  259       volume = volume_brinkman_design(this, 
design)
 
  262       call neko_error(
'Volume constraint only works with brinkman_design')
 
  265  end function compute_volume
 
  270  function volume_brinkman_design(this, design) 
result(volume)
 
  273    real(kind=rp) :: volume
 
  274    type(field_t), 
pointer :: work, design_indicator
 
  275    integer :: temp_indices(1)
 
  278    design_indicator => neko_field_registry%get_field(
"design_indicator")
 
  282    if (this%has_mask) 
then 
  284       if (neko_bcknd_device .eq. 1) 
then 
  285          call neko_scratch_registry%request_field(work, temp_indices(1))
 
  286          call field_copy(work, design_indicator)
 
  288          volume = device_glsc2(work%x_d, this%c_xh%B_d, 
design%size())
 
  289          call neko_scratch_registry%relinquish_field(temp_indices)
 
  291          volume = glsc2_mask(design_indicator%x, &
 
  292               this%c_Xh%B, 
design%size(), this%mask%mask%get(), this%mask%size)
 
  297       if (neko_bcknd_device .eq. 1) 
then 
  298          volume = device_glsc2(design_indicator%x_d, &
 
  299               this%c_xh%B_d, 
design%size())
 
  301          volume = glsc2(design_indicator%x, &
 
  302               this%c_Xh%B, 
design%size())
 
  307  end function volume_brinkman_design
 
Implements the constraint_t type.
Some common Masking operations we may need.
Implements the steady_problem_t type.
Implements the volume_constraint_t type.
A topology optimization design variable.
The abstract constraint type.
A constraint on the volume of the design.