9 use fluid_user_source_term,
only: fluid_user_source_term_t
11 use field,
only: field_t
12 use field_registry,
only: neko_field_registry
13 use num_types,
only: rp
14 use point_zone,
only: point_zone_t
15 use device,
only: device_map, device_memcpy, host_to_device
16 use logger,
only: neko_log
17 use point_zone_registry,
only: neko_point_zone_registry
18 use json_utils,
only: json_get, json_get_or_default
19 use neko_config,
only: neko_bcknd_device
20 use math,
only: col3, rzero, col2, cmult, invcol1, cadd, add2, cfill
21 use device_math,
only: device_col3, device_rzero, device_col2, device_cmult, &
22 device_invcol1, device_cadd, device_add2, device_cfill
25 use simulation_component,
only: simulation_component_t
26 use json_module,
only: json_file
27 use utils,
only: neko_error
28 use,
intrinsic :: iso_c_binding, only: c_ptr, c_null_ptr
59 type,
extends(simulation_component_t) ::
design_t
63 class(field_t),
public,
pointer :: chi
65 class(field_t),
public,
pointer :: design_field
67 class(point_zone_t),
private,
pointer :: design_domain => null()
70 real(kind=rp),
private :: perm_0, perm_1, perm_penalty
73 integer :: total_size, design_size
76 logical :: converged = .false.
78 logical :: design_changed = .false.
110 class(
design_t),
intent(inout) :: this
111 type(json_file),
intent(inout) :: json
112 class(case_t),
intent(inout),
target :: case
118 call this%init_base(json, case)
124 call json_get_or_default(json,
"topopt.perm_penalty", &
125 this%perm_penalty, 1.0_rp)
126 call json_get_or_default(json,
"topopt.perm_0", &
127 this%perm_0, 1000.0_rp)
128 call json_get_or_default(json,
"topopt.perm_1", &
135 if (neko_point_zone_registry%point_zone_exists(
"design_domain") )
then
136 this%design_domain => &
137 neko_point_zone_registry%get_point_zone(
"design_domain")
139 call neko_log%error(
"design_domain point zone does not exist")
145 if (neko_bcknd_device .eq. 1)
then
146 call neko_log%warning(
"We assume that NEKO is using the old design " // &
147 "domain masks. Please check the status of PR " // &
148 "on masks if results seem wonky.")
152 this%design_domain%size, host_to_device, &
162 if (.not. neko_field_registry%field_exists(
"design"))
then
163 call neko_field_registry%add_field(case%fluid%dm_Xh,
"design")
166 this%design_field => neko_field_registry%get_field_by_name(
"design")
168 call case%f_out%fluid%append(this%design_field)
171 call rzero(this%design_field%x, this%design_field%dof%size())
172 if (neko_bcknd_device .eq. 1)
then
173 call device_rzero(this%design_field%x_d, this%design_field%dof%size())
183 this%total_size = this%design_field%dof%size()
184 this%design_size = this%design_domain%size
189 if (neko_bcknd_device .eq. 1)
then
199 if (
associated(this%case%usr%fluid_user_f_vector))
then
200 nullify(this%case%usr%fluid_user_f_vector)
208 use device,
only: device_free
211 class(
design_t),
intent(inout) :: this
215 nullify(this%design_field)
216 nullify(this%design_domain)
225 class(
design_t),
intent(inout) :: this
226 real(kind=rp),
intent(in) :: t
227 integer,
intent(in) :: tstep
228 real(kind=rp) :: max_norm
234 associate(x => this%design_field%x, &
235 x_d => this%design_field%x_d, &
236 mask => this%design_domain%mask, &
237 mask_d => this%design_domain%mask_d &
240 if (.not. neko_bcknd_device .eq. 1)
then
241 call cadd_mask(x, 0.3_rp, this%total_size, mask, this%design_size)
244 mask_d, this%design_size)
254 this%converged = max_norm < 0.01_rp
267 class(fluid_user_source_term_t),
intent(inout) :: f
268 real(kind=rp),
intent(in) :: t
269 type(field_t),
pointer :: u, v, w
270 integer :: total_size, design_size
272 u => neko_field_registry%get_field(
'u')
273 v => neko_field_registry%get_field(
'v')
274 w => neko_field_registry%get_field(
'w')
277 total_size = f%dm%size()
279 if (neko_bcknd_device .eq. 1)
then
280 call device_col3_mask(f%u_d, u%x_d,
resistance_d, total_size, &
282 call device_col3_mask(f%v_d, v%x_d,
resistance_d, total_size, &
284 call device_col3_mask(f%w_d, w%x_d,
resistance_d, total_size, &
287 call col3_mask(f%u, u%x,
resistance, total_size, &
289 call col3_mask(f%v, v%x,
resistance, total_size, &
291 call col3_mask(f%w, w%x,
resistance, total_size, &
317 class(
design_t),
intent(inout) :: this
318 real(kind=rp),
intent(in) :: t
319 integer,
intent(in) :: tstep
322 real(kind=rp) :: constant
324 constant = (this%perm_0 - this%perm_1) * (this%perm_penalty + 1.0_rp)
326 if (neko_bcknd_device .eq. 1)
then
327 call device_cfill(
resistance_d, this%perm_penalty, this%total_size)
328 call device_add2(
resistance_d, this%design_field%x_d, this%total_size)
330 call device_col2(
resistance_d, this%design_field%x_d, this%total_size)
331 call device_cmult(
resistance_d, constant, this%total_size)
332 call device_cadd(
resistance_d, this%perm_1, this%total_size)
335 call device_cmult(
resistance_d, -1.0_rp, this%total_size)
337 call cfill(
resistance, this%perm_penalty, this%total_size)
338 call add2(
resistance, this%design_field%x, this%total_size)
340 call col2(
resistance, this%design_field%x, this%total_size)
341 call cmult(
resistance, constant, this%total_size)
342 call cadd(
resistance, this%perm_1, this%total_size)
345 call cmult(
resistance, -1.0_rp, this%total_size)
type(c_ptr) design_domain_mask_d
Pointer to the design domain mask on the device.
subroutine update_permeability(this, t, tstep)
Update the permeability.
integer, dimension(:), pointer design_domain_mask
Pointer to the design domain mask.
subroutine free_design(this)
Free the topology.
subroutine init_design(this, json, case)
Initialize the topology.
subroutine, public topopt_permeability_force(f, t)
Compute the permeability force term.
real(kind=rp), dimension(:), allocatable resistance
The resistance array.
type(c_ptr) resistance_d
Pointer to the resistance array on the device.
subroutine update_design(this, t, tstep)
Update the topology.
subroutine device_cadd_mask(a_d, c, size, mask_d, mask_size)
subroutine device_col3_mask(a_d, b_d, c_d, size, mask_d, mask_size)
subroutine col3_mask(a, b, c, size, mask, mask_size)
Multiply 2 masked vectors. Save the result in a new vector. .
subroutine cadd_mask(a, c, size, mask, mask_size)
Add a constant to a masked vector. .
The topology type, which is used to describe the designs in topology optimization.