37 use num_types,
only: rp, sp
38 use field,
only: field_t
39 use json_module,
only: json_file
41 use coefs,
only: coef_t
43 use scratch_registry,
only: neko_scratch_registry
44 use fld_file_output,
only: fld_file_output_t
45 use point_zone_registry,
only: neko_point_zone_registry
46 use point_zone,
only: point_zone_t
48 use neko_config,
only: neko_bcknd_device
49 use device,
only: device_memcpy, host_to_device
53 use json_module,
only: json_file
55 use vector,
only: vector_t
57 use device_math,
only: device_copy
58 use registry,
only: neko_registry
61 use field_math,
only: field_rzero
62 use json_utils,
only: json_get, json_get_or_default, json_get
63 use utils,
only: neko_error
75 type(field_t),
pointer :: design_indicator
85 type(field_t),
pointer :: brinkman_amplitude
117 type(field_t),
pointer :: sensitivity
173 class(point_zone_t),
pointer :: optimization_domain
182 type(fld_file_output_t),
private :: output
190 generic,
public :: init => init_from_json_sim, init_from_components
192 procedure, pass(this),
public :: init_from_json_sim => &
193 brinkman_design_init_from_json_sim
195 procedure, pass(this),
public :: init_from_components => &
196 brinkman_design_init_from_components
199 procedure, pass(this) :: get_values => brinkman_design_get_design
201 procedure, pass(this) :: get_sensitivity => brinkman_design_get_sensitivity
204 procedure, pass(this) :: design_get_x => brinkman_design_get_x
206 procedure, pass(this) :: design_get_x_i => brinkman_design_get_x_i
208 procedure, pass(this) :: design_get_y => brinkman_design_get_y
210 procedure, pass(this) :: design_get_y_i => brinkman_design_get_y_i
212 procedure, pass(this) :: design_get_z => brinkman_design_get_z
214 procedure, pass(this) :: design_get_z_i => brinkman_design_get_z_i
217 procedure, pass(this) :: update_design => brinkman_design_update_design
222 procedure, pass(this) :: map_forward => brinkman_design_map_forward
226 procedure, pass(this) :: map_backward => brinkman_design_map_backward
234 procedure, pass(this) :: write => brinkman_design_write
237 procedure, pass(this) :: free => brinkman_design_free
248 subroutine brinkman_design_init_from_json_sim(this, parameters, simulation)
250 type(json_file),
intent(inout) :: parameters
252 type(json_file) :: json_subdict
253 character(len=:),
allocatable :: domain_name, domain_type, name
256 call json_get_or_default(parameters,
'name', name,
'Brinkman Design')
257 call json_get_or_default(parameters,
'domain.type', domain_type,
'full')
258 call json_get_or_default(parameters,
'dealias', dealias, .true.)
260 select case (trim(domain_type))
262 this%has_mask = .false.
264 this%has_mask = .true.
265 call json_get(parameters,
'domain.zone_name', domain_name)
266 this%optimization_domain => &
267 neko_point_zone_registry%get_point_zone(domain_name)
270 call neko_error(
'brinkman design only supports point_zones for ' // &
271 'optimization domain types')
276 call this%init_from_components(name, simulation, dealias)
279 associate(coef => simulation%neko_case%fluid%c_Xh, &
280 gs => simulation%neko_case%fluid%gs_Xh)
282 if (
'mapping' .in. parameters)
then
283 call this%mapping%init_base(coef)
284 call this%mapping%add(parameters,
'mapping')
287 if (
'initial_distribution' .in. parameters)
then
288 call json_get(parameters,
'initial_distribution', json_subdict)
292 call field_rzero(this%design_indicator)
297 call this%map_forward()
299 end subroutine brinkman_design_init_from_json_sim
302 subroutine brinkman_design_free(this)
305 call this%free_base()
306 nullify(this%brinkman_amplitude)
307 nullify(this%design_indicator)
308 nullify(this%sensitivity)
310 end subroutine brinkman_design_free
312 subroutine brinkman_design_init_from_components(this, name, simulation, &
315 character(len=*),
intent(in) :: name
316 type(simulation_t),
intent(inout) :: simulation
317 logical,
intent(in) :: dealias
319 type(simple_brinkman_source_term_t) :: forward_brinkman, adjoint_brinkman
321 associate(dof => simulation%neko_case%fluid%dm_Xh)
323 call neko_registry%add_field(dof,
"design_indicator", .true.)
324 call neko_registry%add_field(dof,
"brinkman_amplitude", .true.)
325 call neko_registry%add_field(dof,
"sensitivity", .true.)
329 this%design_indicator => neko_registry%get_field(
"design_indicator")
330 this%brinkman_amplitude => neko_registry%get_field(
"brinkman_amplitude")
331 this%sensitivity => neko_registry%get_field(
"sensitivity")
337 this%design_indicator = 0.0_rp
338 this%brinkman_amplitude = 0.0_rp
339 this%design_indicator = 0.0_rp
369 if (this%has_mask)
then
370 call mask_exterior_const(this%design_indicator, &
371 this%optimization_domain, 0.0_rp)
383 call this%output%init(sp,
'design', 3)
384 call this%output%fields%assign_to_field(1, this%design_indicator)
385 call this%output%fields%assign_to_field(2, this%brinkman_amplitude)
386 call this%output%fields%assign_to_field(3, this%sensitivity)
388 n = this%design_indicator%dof%size()
389 call this%init_base(name, n)
392 call forward_brinkman%init_from_components( &
393 simulation%fluid%f_x, &
394 simulation%fluid%f_y, &
395 simulation%fluid%f_z, &
396 this%brinkman_amplitude, &
397 simulation%fluid%u, &
398 simulation%fluid%v, &
399 simulation%fluid%w, &
400 simulation%fluid%c_Xh, &
401 simulation%adjoint_fluid%c_Xh_GL, &
402 simulation%adjoint_fluid%GLL_to_GL, &
403 dealias, simulation%adjoint_fluid%scratch_GL)
405 call simulation%fluid%source_term%add(forward_brinkman)
408 call adjoint_brinkman%init_from_components( &
409 simulation%adjoint_fluid%f_adj_x, &
410 simulation%adjoint_fluid%f_adj_y, &
411 simulation%adjoint_fluid%f_adj_z, &
412 this%brinkman_amplitude, &
413 simulation%adjoint_fluid%u_adj, &
414 simulation%adjoint_fluid%v_adj, &
415 simulation%adjoint_fluid%w_adj, &
416 simulation%adjoint_fluid%c_Xh, &
417 simulation%adjoint_fluid%c_Xh_GL, &
418 simulation%adjoint_fluid%GLL_to_GL, &
419 dealias, simulation%adjoint_fluid%scratch_GL)
422 select type (f => simulation%adjoint_fluid)
423 type is (adjoint_fluid_pnpn_t)
424 call f%source_term%add(adjoint_brinkman)
428 end subroutine brinkman_design_init_from_components
431 subroutine brinkman_design_map_forward(this)
435 if (this%has_mask)
then
436 call mask_exterior_const(this%design_indicator, &
437 this%optimization_domain, 0.0_rp)
440 call this%mapping%apply_forward(this%brinkman_amplitude, &
441 this%design_indicator)
443 end subroutine brinkman_design_map_forward
445 subroutine brinkman_design_get_design(this, values)
447 type(vector_t),
intent(inout) :: values
451 if (n .ne. values%size())
then
452 call neko_error(
'Get design: size mismatch')
455 if (neko_bcknd_device .eq. 1)
then
456 call device_copy(values%x_d, this%design_indicator%x_d, n)
458 call copy(values%x, this%design_indicator%x, n)
461 end subroutine brinkman_design_get_design
463 subroutine brinkman_design_get_sensitivity(this, values)
465 type(vector_t),
intent(inout) :: values
469 if (n .ne. values%size())
then
470 call neko_error(
'Get design: size mismatch')
473 if (neko_bcknd_device .eq. 1)
then
474 call device_copy(values%x_d, this%sensitivity%x_d, n)
476 call copy(values%x, this%sensitivity%x, n)
479 end subroutine brinkman_design_get_sensitivity
481 subroutine brinkman_design_get_x(this, x)
483 type(vector_t),
intent(inout) :: x
487 if (n .ne. x%size())
then
488 call neko_error(
'Get x: size mismatch')
491 if (neko_bcknd_device .eq. 1)
then
492 call device_copy(x%x_d, this%design_indicator%dof%x_d, n)
494 call copy(x%x, this%design_indicator%dof%x, n)
497 end subroutine brinkman_design_get_x
499 function brinkman_design_get_x_i(this, i)
result(x_i)
501 integer,
intent(in) :: i
506 if (i .lt. 1 .or. i .gt. n)
then
507 call neko_error(
'brinkman_design_get_x_i: index out of bounds')
510 x_i = this%design_indicator%dof%x(i,1,1,1)
512 end function brinkman_design_get_x_i
514 subroutine brinkman_design_get_y(this, y)
516 type(vector_t),
intent(inout) :: y
520 if (n .ne. y%size())
then
521 call neko_error(
'Get y: size mismatch')
524 if (neko_bcknd_device .eq. 1)
then
525 call device_copy(y%x_d, this%design_indicator%dof%y_d, n)
527 call copy(y%x, this%design_indicator%dof%y, n)
530 end subroutine brinkman_design_get_y
532 function brinkman_design_get_y_i(this, i)
result(y_i)
534 integer,
intent(in) :: i
539 if (i .lt. 1 .or. i .gt. n)
then
540 call neko_error(
'brinkman_design_get_y_i: index out of bounds')
543 y_i = this%design_indicator%dof%y(i,1,1,1)
545 end function brinkman_design_get_y_i
547 subroutine brinkman_design_get_z(this, z)
549 type(vector_t),
intent(inout) :: z
553 if (n .ne. z%size())
then
554 call neko_error(
'Get z: size mismatch')
557 if (neko_bcknd_device .eq. 1)
then
558 call device_copy(z%x_d, this%design_indicator%dof%z_d, n)
560 call copy(z%x, this%design_indicator%dof%z, n)
563 end subroutine brinkman_design_get_z
565 function brinkman_design_get_z_i(this, i)
result(z_i)
567 integer,
intent(in) :: i
572 if (i .lt. 1 .or. i .gt. n)
then
573 call neko_error(
'brinkman_design_get_z_i: index out of bounds')
576 z_i = this%design_indicator%dof%z(i,1,1,1)
578 end function brinkman_design_get_z_i
580 subroutine brinkman_design_update_design(this, values)
582 type(vector_t),
intent(inout) :: values
586 if (neko_bcknd_device .eq. 1)
then
587 call device_copy(this%design_indicator%x_d, values%x_d, n)
589 call copy(this%design_indicator%x, values%x, n)
592 call this%map_forward()
594 if (neko_bcknd_device .eq. 1)
then
595 call device_copy(values%x_d, this%design_indicator%x_d, n)
597 call copy(values%x, this%design_indicator%x, n)
600 end subroutine brinkman_design_update_design
602 subroutine brinkman_design_map_backward(this, sensitivity)
604 type(vector_t),
intent(in) :: sensitivity
605 type(field_t),
pointer :: tmp_fld
606 integer :: temp_index
608 call neko_scratch_registry%request(tmp_fld, temp_index, .false.)
610 call vector_to_field(tmp_fld, sensitivity)
612 call this%mapping%apply_backward(this%sensitivity, tmp_fld)
614 if (this%has_mask)
then
615 call mask_exterior_const(this%sensitivity, this%optimization_domain, &
619 call neko_scratch_registry%relinquish_field(temp_index)
621 end subroutine brinkman_design_map_backward
623 subroutine brinkman_design_write(this, idx)
625 integer,
intent(in) :: idx
627 call this%output%sample(real(idx, kind=rp))
629 end subroutine brinkman_design_write
631end module brinkman_design
Adjoint Pn/Pn formulation.
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.
subroutine, public vector_to_field(field, vector)
Vector to field.
Optimization initial condition.
Implements the simple_brinkman_source_term_t type.
Implements the steady_problem_t type.
A topology optimization design variable.
Abstract class for handling mapping_cascade.
A simple Brinkman source term.