35 use num_types,
only: rp, sp
36 use field,
only: field_t
37 use json_module,
only: json_file
39 use coefs,
only: coef_t
41 use scratch_registry,
only: neko_scratch_registry
42 use fld_file_output,
only: fld_file_output_t
43 use point_zone_registry,
only: neko_point_zone_registry
44 use point_zone,
only: point_zone_t
46 use neko_config,
only: neko_bcknd_device
47 use device,
only: device_memcpy, host_to_device
51 use json_module,
only: json_file
53 use vector,
only: vector_t
55 use device_math,
only: device_copy
56 use field_registry,
only: neko_field_registry
59 use field_math,
only: field_rzero
60 use json_utils,
only: json_get, json_get_or_default, json_get
61 use utils,
only: neko_error
73 type(field_t),
pointer :: design_indicator
83 type(field_t),
pointer :: brinkman_amplitude
115 type(field_t),
pointer :: sensitivity
171 class(point_zone_t),
pointer :: optimization_domain
180 type(fld_file_output_t),
private :: output
188 generic,
public :: init => init_from_json_sim, init_from_components
190 procedure, pass(this),
public :: init_from_json_sim => &
191 brinkman_design_init_from_json_sim
193 procedure, pass(this),
public :: init_from_components => &
194 brinkman_design_init_from_components
197 procedure, pass(this) :: get_values => brinkman_design_get_design
199 procedure, pass(this) :: get_sensitivity => brinkman_design_get_sensitivity
202 procedure, pass(this) :: design_get_x => brinkman_design_get_x
204 procedure, pass(this) :: design_get_x_i => brinkman_design_get_x_i
206 procedure, pass(this) :: design_get_y => brinkman_design_get_y
208 procedure, pass(this) :: design_get_y_i => brinkman_design_get_y_i
210 procedure, pass(this) :: design_get_z => brinkman_design_get_z
212 procedure, pass(this) :: design_get_z_i => brinkman_design_get_z_i
215 procedure, pass(this) :: update_design => brinkman_design_update_design
220 procedure, pass(this) :: map_forward => brinkman_design_map_forward
224 procedure, pass(this) :: map_backward => brinkman_design_map_backward
232 procedure, pass(this) :: write => brinkman_design_write
235 procedure, pass(this) :: free => brinkman_design_free
246 subroutine brinkman_design_init_from_json_sim(this, parameters, simulation)
248 type(json_file),
intent(inout) :: parameters
250 type(json_file) :: json_subdict
251 character(len=:),
allocatable :: domain_name, domain_type, name
254 call json_get_or_default(parameters,
'name', name,
'Brinkman Design')
255 call json_get_or_default(parameters,
'domain.type', domain_type,
'full')
256 call json_get_or_default(parameters,
'dealias', dealias, .true.)
258 select case (trim(domain_type))
260 this%has_mask = .false.
262 this%has_mask = .true.
263 call json_get(parameters,
'domain.zone_name', domain_name)
264 this%optimization_domain => &
265 neko_point_zone_registry%get_point_zone(domain_name)
268 call neko_error(
'brinkman design only supports point_zones for ' // &
269 'optimization domain types')
274 call this%init_from_components(name, simulation, dealias)
277 associate(coef => simulation%neko_case%fluid%c_Xh, &
278 gs => simulation%neko_case%fluid%gs_Xh)
280 if (
'mapping' .in. parameters)
then
281 call this%mapping%init_base(coef)
282 call this%mapping%add(parameters,
'mapping')
285 if (
'initial_distribution' .in. parameters)
then
286 call json_get(parameters,
'initial_distribution', json_subdict)
290 call field_rzero(this%design_indicator)
295 call this%map_forward()
297 end subroutine brinkman_design_init_from_json_sim
300 subroutine brinkman_design_free(this)
303 call this%free_base()
304 call this%brinkman_amplitude%free()
305 call this%design_indicator%free()
306 call this%sensitivity%free()
308 end subroutine brinkman_design_free
310 subroutine brinkman_design_init_from_components(this, name, simulation, &
313 character(len=*),
intent(in) :: name
314 type(simulation_t),
intent(inout) :: simulation
315 logical,
intent(in) :: dealias
317 type(simple_brinkman_source_term_t) :: forward_brinkman, adjoint_brinkman
319 associate(dof => simulation%neko_case%fluid%dm_Xh)
321 call neko_field_registry%add_field(dof,
"design_indicator", .true.)
322 call neko_field_registry%add_field(dof,
"brinkman_amplitude", .true.)
323 call neko_field_registry%add_field(dof,
"sensitivity", .true.)
327 this%design_indicator => &
328 neko_field_registry%get_field(
"design_indicator")
329 this%brinkman_amplitude => &
330 neko_field_registry%get_field(
"brinkman_amplitude")
331 this%sensitivity => &
332 neko_field_registry%get_field(
"sensitivity")
338 this%design_indicator = 0.0_rp
339 this%brinkman_amplitude = 0.0_rp
340 this%design_indicator%x = 0.0_rp
342 n = this%design_indicator%dof%size()
345 this%design_indicator%x(i,1,1,1) = 0.0_rp
349 if (neko_bcknd_device .eq. 1)
then
350 call device_memcpy(this%design_indicator%x, &
351 this%design_indicator%x_d, n, &
352 host_to_device, sync = .false.)
383 if (this%has_mask)
then
384 call mask_exterior_const(this%design_indicator, &
385 this%optimization_domain, 0.0_rp)
397 call this%output%init(sp,
'design', 3)
398 call this%output%fields%assign_to_field(1, this%design_indicator)
399 call this%output%fields%assign_to_field(2, this%brinkman_amplitude)
400 call this%output%fields%assign_to_field(3, this%sensitivity)
402 call this%init_base(name, n)
405 call forward_brinkman%init_from_components( &
406 simulation%fluid%f_x, &
407 simulation%fluid%f_y, &
408 simulation%fluid%f_z, &
409 this%brinkman_amplitude, &
410 simulation%fluid%u, &
411 simulation%fluid%v, &
412 simulation%fluid%w, &
413 simulation%fluid%c_Xh, &
414 simulation%adjoint_fluid%c_Xh_GL, &
415 simulation%adjoint_fluid%GLL_to_GL, &
416 dealias, simulation%adjoint_fluid%scratch_GL)
418 call simulation%fluid%source_term%add(forward_brinkman)
421 call adjoint_brinkman%init_from_components( &
422 simulation%adjoint_fluid%f_adj_x, &
423 simulation%adjoint_fluid%f_adj_y, &
424 simulation%adjoint_fluid%f_adj_z, &
425 this%brinkman_amplitude, &
426 simulation%adjoint_fluid%u_adj, &
427 simulation%adjoint_fluid%v_adj, &
428 simulation%adjoint_fluid%w_adj, &
429 simulation%adjoint_fluid%c_Xh, &
430 simulation%adjoint_fluid%c_Xh_GL, &
431 simulation%adjoint_fluid%GLL_to_GL, &
432 dealias, simulation%adjoint_fluid%scratch_GL)
435 select type (f => simulation%adjoint_fluid)
436 type is (adjoint_fluid_pnpn_t)
437 call f%source_term%add(adjoint_brinkman)
441 end subroutine brinkman_design_init_from_components
444 subroutine brinkman_design_map_forward(this)
448 if (this%has_mask)
then
449 call mask_exterior_const(this%design_indicator, &
450 this%optimization_domain, 0.0_rp)
453 call this%mapping%apply_forward(this%brinkman_amplitude, &
454 this%design_indicator)
456 end subroutine brinkman_design_map_forward
458 subroutine brinkman_design_get_design(this, values)
460 type(vector_t),
intent(inout) :: values
464 call copy(values%x, this%design_indicator%x, n)
465 if (neko_bcknd_device .eq. 1)
then
466 call device_copy(values%x_d, this%design_indicator%x_d, n)
469 end subroutine brinkman_design_get_design
471 subroutine brinkman_design_get_sensitivity(this, values)
473 type(vector_t),
intent(inout) :: values
477 call copy(values%x, this%sensitivity%x, n)
478 if (neko_bcknd_device .eq. 1)
then
479 call device_copy(values%x_d, this%sensitivity%x_d, n)
482 end subroutine brinkman_design_get_sensitivity
484 subroutine brinkman_design_get_x(this, x)
486 type(vector_t),
intent(inout) :: x
490 call copy(x%x, this%design_indicator%dof%x, n)
491 if (neko_bcknd_device .eq. 1)
then
492 call device_copy(x%x_d, this%design_indicator%dof%x_d, n)
495 end subroutine brinkman_design_get_x
497 function brinkman_design_get_x_i(this, i)
result(x_i)
499 integer,
intent(in) :: i
504 if (i .lt. 1 .or. i .gt. n)
then
505 call neko_error(
'brinkman_design_get_x_i: index out of bounds')
508 x_i = this%design_indicator%dof%x(i,1,1,1)
510 end function brinkman_design_get_x_i
512 subroutine brinkman_design_get_y(this, y)
514 type(vector_t),
intent(inout) :: y
518 call copy(y%x, this%design_indicator%dof%y, n)
519 if (neko_bcknd_device .eq. 1)
then
520 call device_copy(y%x_d, this%design_indicator%dof%y_d, n)
523 end subroutine brinkman_design_get_y
525 function brinkman_design_get_y_i(this, i)
result(y_i)
527 integer,
intent(in) :: i
532 if (i .lt. 1 .or. i .gt. n)
then
533 call neko_error(
'brinkman_design_get_y_i: index out of bounds')
536 y_i = this%design_indicator%dof%y(i,1,1,1)
538 end function brinkman_design_get_y_i
540 subroutine brinkman_design_get_z(this, z)
542 type(vector_t),
intent(inout) :: z
546 call copy(z%x, this%design_indicator%dof%z, n)
547 if (neko_bcknd_device .eq. 1)
then
548 call device_copy(z%x_d, this%design_indicator%dof%z_d, n)
551 end subroutine brinkman_design_get_z
553 function brinkman_design_get_z_i(this, i)
result(z_i)
555 integer,
intent(in) :: i
560 if (i .lt. 1 .or. i .gt. n)
then
561 call neko_error(
'brinkman_design_get_z_i: index out of bounds')
564 z_i = this%design_indicator%dof%z(i,1,1,1)
566 end function brinkman_design_get_z_i
568 subroutine brinkman_design_update_design(this, values)
570 type(vector_t),
intent(inout) :: values
574 call copy(this%design_indicator%x, values%x, n)
575 if (neko_bcknd_device .eq. 1)
then
576 call device_copy(this%design_indicator%x_d, values%x_d, n)
579 call this%map_forward()
581 call copy(values%x, this%design_indicator%x, n)
582 if (neko_bcknd_device .eq. 1)
then
583 call device_copy(values%x_d, this%design_indicator%x_d, n)
586 end subroutine brinkman_design_update_design
588 subroutine brinkman_design_map_backward(this, sensitivity)
590 type(vector_t),
intent(in) :: sensitivity
591 type(field_t),
pointer :: tmp_fld
592 integer :: temp_indices(1)
594 call neko_scratch_registry%request_field(tmp_fld, temp_indices(1))
596 call vector_to_field(tmp_fld, sensitivity)
598 call this%mapping%apply_backward(this%sensitivity, tmp_fld)
600 if (this%has_mask)
then
601 call mask_exterior_const(this%sensitivity, this%optimization_domain, &
605 call neko_scratch_registry%relinquish_field(temp_indices)
607 end subroutine brinkman_design_map_backward
609 subroutine brinkman_design_write(this, idx)
611 integer,
intent(in) :: idx
613 call this%output%sample(real(idx, kind=rp))
615 end subroutine brinkman_design_write
617end 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.