47 use num_types,
only: rp
48 use coefs,
only: coef_t
49 use json_module,
only: json_file
50 use json_utils,
only: json_get, json_get_or_default
51 use field,
only: field_t
52 use scratch_registry,
only: neko_scratch_registry
53 use neko_config,
only: neko_bcknd_device
55 use math,
only: glsc2, copy, cmult
56 use device_math,
only: device_glsc2, device_copy, device_cmult
57 use vector_math,
only: vector_cmult
58 use math_ext,
only: glsc2_mask
59 use field_math,
only: field_rone, field_copy, field_cmult, field_cfill
60 use utils,
only: neko_error
61 use vector,
only: vector_t
75 real(kind=rp) :: limit
77 real(kind=rp) :: volume_domain
79 class(coef_t),
pointer :: c_xh => null()
83 logical :: if_mapping = .false.
88 procedure,
public, pass(this) :: init_json_sim => &
91 procedure,
public, pass(this) :: init_from_components => &
92 volume_constraint_init_from_components
94 procedure,
public, pass(this) :: free => volume_constraint_free
96 procedure,
public, pass(this) :: update_value => &
97 volume_constraint_update_value
99 procedure,
public, pass(this) :: update_sensitivity => &
100 volume_constraint_update_sensitivity
103 procedure,
private, pass(this) :: compute_volume
116 type(json_file),
intent(inout) :: json
117 class(
design_t),
intent(in) :: design
120 character(len=:),
allocatable :: mask_name
121 character(len=:),
allocatable :: name
123 real(kind=rp) :: limit
125 call json_get_or_default(json,
"name", name,
"Volume constraint")
126 call json_get_or_default(json,
"mask_name", mask_name,
"")
127 call json_get_or_default(json,
"is_max", is_max, .false.)
128 call json_get(json,
"limit", limit)
130 call this%init_from_components(
design, simulation, name, mask_name, &
134 if (
'mapping' .in. json)
then
136 call this%mapping%init_base(this%c_Xh)
137 call this%mapping%add(json,
'mapping')
138 this%if_mapping = .true.
140 call this%update_value(
design)
153 subroutine volume_constraint_init_from_components(this, design, simulation, &
154 name, mask_name, is_max, limit)
156 class(
design_t),
intent(in) :: design
158 character(len=*),
intent(in) :: mask_name
159 character(len=*),
intent(in) :: name
160 logical,
intent(in) :: is_max
161 real(kind=rp),
intent(in) :: limit
163 type(field_t),
pointer :: work
164 integer :: temp_indices(1)
167 call this%init_base(name,
design%size(), mask_name)
172 this%c_Xh => simulation%neko_case%fluid%c_Xh
175 if (this%has_mask)
then
178 call neko_scratch_registry%request(work, temp_indices(1), .false.)
179 call field_rone(work)
182 if (neko_bcknd_device .eq. 1)
then
183 this%volume_domain = device_glsc2(work%x_d, this%c_xh%B_d, &
186 this%volume_domain = glsc2_mask(work%x, this%c_Xh%B, &
187 design%size(), this%mask%mask%get(), this%mask%size)
190 call neko_scratch_registry%relinquish(temp_indices)
192 this%volume_domain = this%c_Xh%volume
198 call this%update_value(
design)
203 if (neko_bcknd_device .eq. 1)
then
204 call device_copy(this%sensitivity%x_d, this%c_xh%B_d,
design%size())
205 call device_cmult(this%sensitivity%x_d, -1.0_rp / this%volume_domain, &
208 if (this%is_max)
then
209 call device_cmult(this%sensitivity%x_d, -1.0_rp,
design%size())
212 call copy(this%sensitivity%x, this%c_Xh%B,
design%size())
213 call cmult(this%sensitivity%x, -1.0_rp / this%volume_domain, &
216 if (this%is_max)
then
217 call vector_cmult(this%sensitivity, -1.0_rp)
221 if (this%has_mask)
then
225 end subroutine volume_constraint_init_from_components
228 subroutine volume_constraint_free(this)
231 call this%free_base()
232 end subroutine volume_constraint_free
237 subroutine volume_constraint_update_value(this, design)
239 class(
design_t),
intent(in) :: design
240 real(kind=rp) :: volume
242 volume = this%compute_volume(
design)
245 this%value = this%limit - volume / this%volume_domain
248 if (this%is_max) this%value = -this%value
250 end subroutine volume_constraint_update_value
255 subroutine volume_constraint_update_sensitivity(this, design)
257 class(
design_t),
intent(in) :: design
259 type(field_t),
pointer :: unmapped, mapped
260 integer :: temp_indices(2)
262 if (this%if_mapping)
then
264 call neko_scratch_registry%request(unmapped, temp_indices(1), &
266 call neko_scratch_registry%request(mapped, temp_indices(2), &
269 call field_cfill(unmapped, -1.0_rp / this%volume_domain)
270 if (this%is_max)
then
271 call field_cmult(unmapped, -1.0_rp)
274 if (this%has_mask)
then
278 call this%mapping%apply_backward(mapped, unmapped)
281 call neko_scratch_registry%relinquish(temp_indices)
287 end subroutine volume_constraint_update_sensitivity
297 function compute_volume(this, design)
result(volume)
299 class(
design_t),
intent(in) :: design
300 real(kind=rp) :: volume
305 volume = volume_brinkman_design(this,
design)
308 call neko_error(
'Volume constraint only works with brinkman_design')
311 end function compute_volume
316 function volume_brinkman_design(this, design)
result(volume)
319 real(kind=rp) :: volume
320 type(field_t),
pointer :: work
321 type(vector_t),
pointer :: values, unmapped_values
322 integer :: temp_indices, ind_value, ind_um_value
324 call neko_scratch_registry%request(values, ind_value,
design%size(), &
328 if (this%if_mapping)
then
329 call neko_scratch_registry%request(unmapped_values, ind_um_value, &
331 call design%get_values(unmapped_values)
332 call this%mapping%apply_forward(values, unmapped_values)
333 call neko_scratch_registry%relinquish(ind_um_value)
335 call design%get_values(values)
338 if (this%has_mask)
then
340 if (neko_bcknd_device .eq. 1)
then
341 call neko_scratch_registry%request(work, temp_indices, .false.)
342 call device_copy(work%x_d, values%x_d,
design%size())
345 volume = device_glsc2(work%x_d, this%c_xh%B_d,
design%size())
347 call neko_scratch_registry%relinquish(temp_indices)
349 volume = glsc2_mask(values%x, this%c_Xh%B,
design%size(), &
350 this%mask%mask%get(), this%mask%size)
355 if (neko_bcknd_device .eq. 1)
then
356 volume = device_glsc2(values%x_d, this%c_xh%B_d,
design%size())
358 volume = glsc2(values%x, this%c_Xh%B,
design%size())
363 call neko_scratch_registry%relinquish(ind_value)
365 end function volume_brinkman_design
Implements the constraint_t type.
Implements the mapping_handler_t type.
Mappings to be applied to a scalar field.
Some common Masking operations we may need.
Contains extensions to the neko library required to run the topology optimization code.
subroutine, public field_to_vector(vector, field)
Field to vector.
Implements the steady_problem_t type.
Implements the volume_constraint_t type. Either .
subroutine volume_constraint_init_json_sim(this, json, design, simulation)
The common constructor using a JSON object.
A topology optimization design variable.
The abstract constraint type.
Abstract class for handling mapping_cascade.
A constraint on the volume of the design.