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
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()
82 procedure,
public, pass(this) :: init_from_attributes => &
87 procedure,
public, pass(this) :: update_value => &
90 procedure,
public, pass(this) :: update_sensitivity => &
106 type(json_file),
intent(inout) :: json
107 class(
design_t),
intent(in) :: design
110 character(len=:),
allocatable :: mask_name
111 character(len=:),
allocatable :: name
113 real(kind=rp) :: limit
115 call json_get_or_default(json,
"mask_name", mask_name,
"")
116 call json_get_or_default(json,
"name", name,
"Volume constraint")
117 call json_get_or_default(json,
"is_max", is_max, .false.)
118 call json_get(json,
"limit", limit)
131 name, mask_name, is_max, limit)
133 class(
design_t),
intent(in) :: design
135 character(len=*),
intent(in) :: mask_name
136 character(len=*),
intent(in) :: name
137 logical,
intent(in) :: is_max
138 real(kind=rp),
intent(in) :: limit
140 real(kind=rp) :: volume
141 type(field_t),
pointer :: work
142 integer :: temp_indices(1)
145 call this%init_base(name,
design%size(), mask_name)
153 if (this%has_mask)
then
156 call neko_scratch_registry%request_field(work, temp_indices(1))
157 call field_rone(work)
159 if (neko_bcknd_device .eq. 1)
then
161 this%volume_domain = device_glsc2(work%x_d, this%c_xh%B_d, &
164 this%volume_domain =
glsc2_mask(work%x, this%c_Xh%B, &
165 design%size(), this%mask%mask, this%mask%size)
168 call neko_scratch_registry%relinquish_field(temp_indices)
170 this%volume_domain = this%c_Xh%volume
177 volume = this%compute_volume(
design)
180 this%value = this%limit - volume / this%volume_domain
183 if (this%is_max) this%value = - ( this%value )
188 this%sensitivity = 1.0_rp / this%volume_domain
191 if (.not. this%is_max) this%sensitivity = (-1.0_rp) * this%sensitivity
193 if (this%has_mask)
then
203 call this%free_base()
211 class(
design_t),
intent(in) :: design
212 real(kind=rp) :: volume
214 volume = this%compute_volume(
design)
217 this%value = this%limit - volume / this%volume_domain
220 if (this%is_max) this%value = - ( this%value )
230 class(
design_t),
intent(in) :: design
248 real(kind=rp) :: volume
256 call neko_error(
'Volume constraint only works with brinkman_design')
266 real(kind=rp) :: volume
267 type(field_t),
pointer :: work, design_indicator
268 integer :: temp_indices(1)
271 design_indicator => neko_field_registry%get_field(
"design_indicator")
275 if (this%has_mask)
then
277 if (neko_bcknd_device .eq. 1)
then
278 call neko_scratch_registry%request_field(work, temp_indices(1))
279 call field_copy(work, design_indicator)
281 volume = device_glsc2(work%x_d, this%c_xh%B_d,
design%size())
282 call neko_scratch_registry%relinquish_field(temp_indices)
285 this%c_Xh%B,
design%size(), this%mask%mask, this%mask%size)
290 if (neko_bcknd_device .eq. 1)
then
291 volume = device_glsc2(design_indicator%x_d, &
292 this%c_xh%B_d,
design%size())
294 volume = glsc2(design_indicator%x, &
295 this%c_Xh%B,
design%size())
Implements the constraint_t type.
Some common Masking operations we may need.
real(kind=rp) function glsc2_mask(a, b, size, mask, mask_size)
Weighted inner product for indices in the mask.
Implements the steady_problem_t type.
Implements the volume_constraint_t type.
real(kind=rp) function compute_volume(this, design)
Computes the volume of the design.
subroutine volume_constraint_init_json(this, json, design, simulation)
The common constructor using a JSON object.
subroutine volume_constraint_init_attributes(this, design, simulation, name, mask_name, is_max, limit)
The direct initializer from attributes.
real(kind=rp) function volume_brinkman_design(this, design)
Computes the volume of the brinkman_design.
subroutine volume_constraint_update_sensitivity(this, design)
The computation of the sensitivity.
subroutine volume_constraint_update_value(this, design)
The computation of the constraint.
subroutine volume_constraint_free(this)
Destructor.
A topology optimization design variable.
The abstract constraint type.
A constraint on the volume of the design.