35 use num_types,
only: rp, dp
36 use field,
only: field_t
37 use field_list,
only: field_list_t
38 use json_utils,
only: json_get, json_get_or_default, json_extract_item
39 use field_registry,
only: neko_field_registry
40 use source_term,
only: source_term_t
41 use coefs,
only: coef_t
42 use neko_config,
only: neko_bcknd_device
43 use utils,
only: neko_error
44 use field_math,
only: field_subcol3
45 use file,
only: file_t
46 use tri_mesh,
only: tri_mesh_t
47 use device,
only: device_memcpy, host_to_device
48 use filters,
only: smooth_step_field, step_function_field, permeability_field
49 use signed_distance,
only: signed_distance_field
50 use profiler,
only: profiler_start_region, profiler_end_region
51 use json_module,
only: json_core, json_value, json_file
52 use point_zone,
only: point_zone_t
53 use point_zone_registry,
only: neko_point_zone_registry
54 use aabb,
only: aabb_t, get_aabb
67 type(field_t),
pointer :: indicator => null()
69 type(field_t),
pointer :: brinkman => null()
72 procedure,
public, pass(this) :: init => &
73 brinkman_source_term_init_from_json
75 procedure,
public, pass(this) :: free => brinkman_source_term_free
77 procedure,
public, pass(this) :: compute_ => brinkman_source_term_compute
83 procedure, pass(this) :: init_boundary_mesh
84 procedure, pass(this) :: init_point_zone
97 subroutine brinkman_source_term_init_from_json(this, json, fields, coef)
99 type(json_file),
intent(inout) :: json
100 type(field_list_t),
intent(inout),
target :: fields
101 type(coef_t),
target,
intent(inout) :: coef
102 real(kind=rp) :: start_time, end_time
104 character(len=:),
allocatable :: filter_type
105 real(kind=rp),
dimension(:),
allocatable :: brinkman_limits
106 real(kind=rp) :: brinkman_penalty
108 type(json_value),
pointer :: json_object_list
109 type(json_core) :: core
111 character(len=:),
allocatable :: object_type
112 type(json_file) :: object_settings
117 call json_get_or_default(json,
"start_time", start_time, 0.0_rp)
118 call json_get_or_default(json,
"end_time", end_time, huge(0.0_rp))
121 call json_get(json,
'brinkman.limits', brinkman_limits)
122 call json_get(json,
'brinkman.penalty', brinkman_penalty)
124 if (
size(brinkman_limits) .ne. 2)
then
125 call neko_error(
'brinkman_limits must be a 2 element array of reals')
129 call this%init_base(fields, coef, start_time, end_time)
134 if (neko_field_registry%field_exists(
'brinkman_indicator') &
135 .or. neko_field_registry%field_exists(
'brinkman'))
then
136 call neko_error(
'Brinkman field already exists.')
139 call neko_field_registry%add_field(coef%dof,
'brinkman_indicator')
141 neko_field_registry%get_field_by_name(
'brinkman_indicator')
143 call neko_field_registry%add_field(coef%dof,
'brinkman')
144 this%brinkman => neko_field_registry%get_field_by_name(
'brinkman')
149 call json%get(
'objects', json_object_list)
150 call json%info(
'objects', n_children = n_regions)
151 call json%get_core(core)
154 call json_extract_item(core, json_object_list, i, object_settings)
155 call json_get_or_default(object_settings,
'type', object_type,
'none')
157 select case (object_type)
158 case (
'boundary_mesh')
159 call this%init_boundary_mesh(object_settings)
161 call this%init_point_zone(object_settings)
164 call object_settings%print()
165 call neko_error(
'Brinkman source term objects require a region type')
167 call neko_error(
'Brinkman source term unknown region type')
173 call json_get_or_default(json,
'filter.type', filter_type,
'none')
175 select case (filter_type)
179 call neko_error(
'Brinkman source term unknown filter type')
185 call permeability_field(this%brinkman, this%indicator, &
186 brinkman_limits(1), brinkman_limits(2), brinkman_penalty)
189 if (neko_bcknd_device .eq. 1)
then
190 call device_memcpy(this%brinkman%x, this%brinkman%x_d, &
191 this%brinkman%dof%size(), host_to_device, .true.)
194 end subroutine brinkman_source_term_init_from_json
198 subroutine brinkman_source_term_free(this)
201 this%brinkman => null()
202 call this%free_base()
203 end subroutine brinkman_source_term_free
209 subroutine brinkman_source_term_compute(this, t, tstep)
211 real(kind=rp),
intent(in) :: t
212 integer,
intent(in) :: tstep
213 type(field_t),
pointer :: u, v, w, fu, fv, fw
216 n = this%fields%item_size(1)
218 u => neko_field_registry%get_field(
'u')
219 v => neko_field_registry%get_field(
'v')
220 w => neko_field_registry%get_field(
'w')
222 fu => this%fields%get(1)
223 fv => this%fields%get(2)
224 fw => this%fields%get(3)
226 call field_subcol3(fu, u, this%brinkman, n)
227 call field_subcol3(fv, v, this%brinkman, n)
228 call field_subcol3(fw, w, this%brinkman, n)
230 end subroutine brinkman_source_term_compute
238 subroutine init_boundary_mesh(this, json)
240 type(json_file),
intent(inout) :: json
243 character(len=:),
allocatable :: mesh_file_name
244 character(len=:),
allocatable :: distance_transform
245 character(len=:),
allocatable :: filter_type
246 character(len=:),
allocatable :: mesh_transform
249 type(file_t) :: mesh_file
250 type(tri_mesh_t) :: boundary_mesh
251 real(kind=rp) :: scalar_r
252 real(kind=dp) :: scalar_d
255 real(kind=dp),
dimension(:),
allocatable :: box_min, box_max
256 logical :: keep_aspect_ratio
257 real(kind=dp),
dimension(3) :: scaling
258 real(kind=dp),
dimension(3) :: translation
259 type(field_t) :: temp_field
260 type(aabb_t) :: mesh_box, target_box
266 call json_get(json,
'name', mesh_file_name)
269 call json_get(json,
'distance_transform.type', distance_transform)
274 mesh_file = file_t(mesh_file_name)
275 call mesh_file%read(boundary_mesh)
277 if (boundary_mesh%nelv .eq. 0)
then
278 call neko_error(
'No elements in the boundary mesh')
284 call json_get_or_default(json,
'mesh_transform.type', &
285 mesh_transform,
'none')
287 select case (mesh_transform)
290 case (
'bounding_box')
291 call json_get(json,
'mesh_transform.box_min', box_min)
292 call json_get(json,
'mesh_transform.box_max', box_max)
293 call json_get_or_default(json,
'mesh_transform.keep_aspect_ratio', &
294 keep_aspect_ratio, .true.)
296 if (
size(box_min) .ne. 3 .or.
size(box_max) .ne. 3)
then
297 call neko_error(
'Case file: mesh_transform. &
298 &box_min and box_max must be 3 element arrays of reals')
301 call target_box%init(box_min, box_max)
303 mesh_box = get_aabb(boundary_mesh)
305 scaling = target_box%get_diagonal() / mesh_box%get_diagonal()
306 if (keep_aspect_ratio)
then
307 scaling = minval(scaling)
310 translation = - scaling * mesh_box%get_min() + target_box%get_min()
312 do idx_p = 1, boundary_mesh%mpts
313 boundary_mesh%points(idx_p)%x = &
314 scaling * boundary_mesh%points(idx_p)%x + translation
318 call neko_error(
'Unknown mesh transform')
329 call temp_field%init(this%indicator%dof)
332 select case (distance_transform)
334 call json_get(json,
'distance_transform.value', scalar_d)
335 scalar_r = real(scalar_d, kind=rp)
337 call signed_distance_field(temp_field, boundary_mesh, scalar_d)
338 call smooth_step_field(temp_field, scalar_r, 0.0_rp)
342 call json_get(json,
'distance_transform.value', scalar_d)
344 call signed_distance_field(temp_field, boundary_mesh, scalar_d)
345 call step_function_field(temp_field, scalar_r, 1.0_rp, 0.0_rp)
348 call neko_error(
'Unknown distance transform')
353 call json_get_or_default(json,
'filter.type', filter_type,
'none')
355 select case (filter_type)
359 call neko_error(
'Unknown filter type')
363 this%indicator%x = max(this%indicator%x, temp_field%x)
365 end subroutine init_boundary_mesh
370 subroutine init_point_zone(this, json)
372 type(json_file),
intent(inout) :: json
375 character(len=:),
allocatable :: zone_name
376 character(len=:),
allocatable :: filter_type
378 type(field_t) :: temp_field
379 class(point_zone_t),
pointer :: my_point_zone
385 call json_get(json,
'name', zone_name)
386 call json_get_or_default(json,
'filter.type', filter_type,
'none')
390 call temp_field%init(this%indicator%dof)
392 my_point_zone => neko_point_zone_registry%get_point_zone(zone_name)
394 do i = 1, my_point_zone%size
395 temp_field%x(my_point_zone%mask(i), 1, 1, 1) = 1.0_rp
400 select case (filter_type)
404 call neko_error(
'Unknown filter type')
408 this%indicator%x = max(this%indicator%x, temp_field%x)
410 end subroutine init_point_zone
Implements the brinkman_source_term_t type.
A Brinkman source term. The region and strength are controlled by assigning regions types and brinkma...