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.