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 math_ext,
only: glsc2_mask
57 use field_math,
only: field_rone, field_copy
58 use utils,
only: neko_error
71 real(kind=rp) :: limit
73 real(kind=rp) :: volume_domain
76 class(coef_t),
pointer :: c_xh => null()
81 procedure,
public, pass(this) :: init_json_sim => &
82 volume_constraint_init_json_sim
84 procedure,
public, pass(this) :: init_from_attributes => &
85 volume_constraint_init_attributes
87 procedure,
public, pass(this) :: free => volume_constraint_free
89 procedure,
public, pass(this) :: update_value => &
90 volume_constraint_update_value
92 procedure,
public, pass(this) :: update_sensitivity => &
93 volume_constraint_update_sensitivity
96 procedure,
private, pass(this) :: compute_volume
107 subroutine volume_constraint_init_json_sim(this, json, design, simulation)
109 type(json_file),
intent(inout) :: json
110 class(
design_t),
intent(in) :: design
113 character(len=:),
allocatable :: mask_name
114 character(len=:),
allocatable :: name
116 real(kind=rp) :: limit
118 call json_get_or_default(json,
"mask_name", mask_name,
"")
119 call json_get_or_default(json,
"name", name,
"Volume constraint")
120 call json_get_or_default(json,
"is_max", is_max, .false.)
121 call json_get(json,
"limit", limit)
123 call this%init_from_attributes(
design, simulation, name, mask_name, &
125 end subroutine volume_constraint_init_json_sim
135 subroutine volume_constraint_init_attributes(this, design, simulation, &
136 name, mask_name, is_max, limit)
138 class(
design_t),
intent(in) :: design
140 character(len=*),
intent(in) :: mask_name
141 character(len=*),
intent(in) :: name
142 logical,
intent(in) :: is_max
143 real(kind=rp),
intent(in) :: limit
145 real(kind=rp) :: volume
146 type(field_t),
pointer :: work
147 integer :: temp_indices(1)
150 call this%init_base(name,
design%size(), mask_name)
155 this%c_Xh => simulation%neko_case%fluid%c_Xh
158 if (this%has_mask)
then
161 call neko_scratch_registry%request_field(work, temp_indices(1))
162 call field_rone(work)
164 if (neko_bcknd_device .eq. 1)
then
166 this%volume_domain = device_glsc2(work%x_d, this%c_xh%B_d, &
169 this%volume_domain = glsc2_mask(work%x, this%c_Xh%B, &
170 design%size(), this%mask%mask, this%mask%size)
173 call neko_scratch_registry%relinquish_field(temp_indices)
175 this%volume_domain = this%c_Xh%volume
182 volume = this%compute_volume(
design)
185 this%value = this%limit - volume / this%volume_domain
188 if (this%is_max) this%value = - ( this%value )
193 this%sensitivity = 1.0_rp / this%volume_domain
196 if (.not. this%is_max) this%sensitivity = (-1.0_rp) * this%sensitivity
198 if (this%has_mask)
then
202 end subroutine volume_constraint_init_attributes
205 subroutine volume_constraint_free(this)
208 call this%free_base()
209 end subroutine volume_constraint_free
214 subroutine volume_constraint_update_value(this, design)
216 class(
design_t),
intent(in) :: design
217 real(kind=rp) :: volume
219 volume = this%compute_volume(
design)
222 this%value = this%limit - volume / this%volume_domain
225 if (this%is_max) this%value = - ( this%value )
227 end subroutine volume_constraint_update_value
232 subroutine volume_constraint_update_sensitivity(this, design)
234 class(
design_t),
intent(in) :: design
238 end subroutine volume_constraint_update_sensitivity
250 function compute_volume(this, design)
result(volume)
252 class(
design_t),
intent(in) :: design
253 real(kind=rp) :: volume
258 volume = volume_brinkman_design(this,
design)
261 call neko_error(
'Volume constraint only works with brinkman_design')
264 end function compute_volume
269 function volume_brinkman_design(this, design)
result(volume)
272 real(kind=rp) :: volume
273 type(field_t),
pointer :: work, design_indicator
274 integer :: temp_indices(1)
277 design_indicator => neko_field_registry%get_field(
"design_indicator")
281 if (this%has_mask)
then
283 if (neko_bcknd_device .eq. 1)
then
284 call neko_scratch_registry%request_field(work, temp_indices(1))
285 call field_copy(work, design_indicator)
287 volume = device_glsc2(work%x_d, this%c_xh%B_d,
design%size())
288 call neko_scratch_registry%relinquish_field(temp_indices)
290 volume = glsc2_mask(design_indicator%x, &
291 this%c_Xh%B,
design%size(), this%mask%mask, this%mask%size)
296 if (neko_bcknd_device .eq. 1)
then
297 volume = device_glsc2(design_indicator%x_d, &
298 this%c_xh%B_d,
design%size())
300 volume = glsc2(design_indicator%x, &
301 this%c_Xh%B,
design%size())
306 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.