37 use num_types,
only: rp, dp
38 use field,
only: field_t
39 use field_list,
only: field_list_t
40 use json_utils,
only: json_get, json_get_or_default, json_extract_item
41 use field_registry,
only: neko_field_registry
42 use source_term,
only: source_term_t
43 use coefs,
only: coef_t
44 use neko_config,
only: neko_bcknd_device
45 use utils,
only: neko_error
46 use field_math,
only: field_subcol3
47 use file,
only: file_t
48 use tri_mesh,
only: tri_mesh_t
49 use device,
only: device_memcpy, host_to_device
50 use filters,
only: smooth_step_field, step_function_field, permeability_field
51 use signed_distance,
only: signed_distance_field
52 use profiler,
only: profiler_start_region, profiler_end_region
53 use json_module,
only: json_core, json_value, json_file
54 use point_zone,
only: point_zone_t
55 use point_zone_registry,
only: neko_point_zone_registry
56 use aabb,
only: aabb_t, get_aabb
69 type(field_t),
pointer :: indicator => null()
71 type(field_t),
pointer :: brinkman => null()
74 procedure,
public, pass(this) :: init => &
77 procedure,
public, pass(this) :: free => brinkman_source_term_free
79 procedure,
public, pass(this) :: compute_ => brinkman_source_term_compute
85 procedure, pass(this) :: init_boundary_mesh
86 procedure, pass(this) :: init_point_zone
101 type(json_file),
intent(inout) :: json
102 type(field_list_t),
intent(inout),
target :: fields
103 type(coef_t),
target,
intent(inout) :: coef
104 real(kind=rp) :: start_time, end_time
106 character(len=:),
allocatable :: filter_type
107 real(kind=rp),
dimension(:),
allocatable :: brinkman_limits
108 real(kind=rp) :: brinkman_penalty
110 type(json_value),
pointer :: json_object_list
111 type(json_core) :: core
113 character(len=:),
allocatable :: object_type
114 type(json_file) :: object_settings
119 call json_get_or_default(json,
"start_time", start_time, 0.0_rp)
120 call json_get_or_default(json,
"end_time", end_time, huge(0.0_rp))
123 call json_get(json,
'brinkman.limits', brinkman_limits)
124 call json_get(json,
'brinkman.penalty', brinkman_penalty)
126 if (
size(brinkman_limits) .ne. 2)
then
127 call neko_error(
'brinkman_limits must be a 2 element array of reals')
131 call this%init_base(fields, coef, start_time, end_time)
136 if (neko_field_registry%field_exists(
'brinkman_indicator') &
137 .or. neko_field_registry%field_exists(
'brinkman'))
then
138 call neko_error(
'Brinkman field already exists.')
141 call neko_field_registry%add_field(coef%dof,
'brinkman_indicator')
143 neko_field_registry%get_field_by_name(
'brinkman_indicator')
145 call neko_field_registry%add_field(coef%dof,
'brinkman')
146 this%brinkman => neko_field_registry%get_field_by_name(
'brinkman')
151 call json%get(
'objects', json_object_list)
152 call json%info(
'objects', n_children = n_regions)
153 call json%get_core(core)
156 call json_extract_item(core, json_object_list, i, object_settings)
157 call json_get_or_default(object_settings,
'type', object_type,
'none')
159 select case (object_type)
160 case (
'boundary_mesh')
161 call this%init_boundary_mesh(object_settings)
163 call this%init_point_zone(object_settings)
166 call object_settings%print()
167 call neko_error(
'Brinkman source term objects require a region type')
169 call neko_error(
'Brinkman source term unknown region type')
175 call json_get_or_default(json,
'filter.type', filter_type,
'none')
177 select case (filter_type)
181 call neko_error(
'Brinkman source term unknown filter type')
187 call permeability_field(this%brinkman, this%indicator, &
188 brinkman_limits(1), brinkman_limits(2), brinkman_penalty)
191 if (neko_bcknd_device .eq. 1)
then
192 call device_memcpy(this%brinkman%x, this%brinkman%x_d, &
193 this%brinkman%dof%size(), host_to_device, .true.)
200 subroutine brinkman_source_term_free(this)
203 this%brinkman => null()
204 call this%free_base()
205 end subroutine brinkman_source_term_free
211 subroutine brinkman_source_term_compute(this, t, tstep)
213 real(kind=rp),
intent(in) :: t
214 integer,
intent(in) :: tstep
215 type(field_t),
pointer :: u, v, w, fu, fv, fw
218 n = this%fields%item_size(1)
220 u => neko_field_registry%get_field(
'u')
221 v => neko_field_registry%get_field(
'v')
222 w => neko_field_registry%get_field(
'w')
224 fu => this%fields%get(1)
225 fv => this%fields%get(2)
226 fw => this%fields%get(3)
228 call field_subcol3(fu, u, this%brinkman, n)
229 call field_subcol3(fv, v, this%brinkman, n)
230 call field_subcol3(fw, w, this%brinkman, n)
232 end subroutine brinkman_source_term_compute
240 subroutine init_boundary_mesh(this, json)
242 type(json_file),
intent(inout) :: json
245 character(len=:),
allocatable :: mesh_file_name
246 character(len=:),
allocatable :: distance_transform
247 character(len=:),
allocatable :: filter_type
248 character(len=:),
allocatable :: mesh_transform
251 type(file_t) :: mesh_file
252 type(tri_mesh_t) :: boundary_mesh
253 real(kind=rp) :: scalar_r
254 real(kind=dp) :: scalar_d
257 real(kind=dp),
dimension(:),
allocatable :: box_min, box_max
258 logical :: keep_aspect_ratio
259 real(kind=dp),
dimension(3) :: scaling
260 real(kind=dp),
dimension(3) :: translation
261 type(field_t) :: temp_field
262 type(aabb_t) :: mesh_box, target_box
268 call json_get(json,
'name', mesh_file_name)
271 call json_get(json,
'distance_transform.type', distance_transform)
276 mesh_file = file_t(mesh_file_name)
277 call mesh_file%read(boundary_mesh)
279 if (boundary_mesh%nelv .eq. 0)
then
280 call neko_error(
'No elements in the boundary mesh')
286 call json_get_or_default(json,
'mesh_transform.type', &
287 mesh_transform,
'none')
289 select case (mesh_transform)
292 case (
'bounding_box')
293 call json_get(json,
'mesh_transform.box_min', box_min)
294 call json_get(json,
'mesh_transform.box_max', box_max)
295 call json_get_or_default(json,
'mesh_transform.keep_aspect_ratio', &
296 keep_aspect_ratio, .true.)
298 if (
size(box_min) .ne. 3 .or.
size(box_max) .ne. 3)
then
299 call neko_error(
'Case file: mesh_transform. &
300 &box_min and box_max must be 3 element arrays of reals')
303 call target_box%init(box_min, box_max)
305 mesh_box = get_aabb(boundary_mesh)
307 scaling = target_box%get_diagonal() / mesh_box%get_diagonal()
308 if (keep_aspect_ratio)
then
309 scaling = minval(scaling)
312 translation = - scaling * mesh_box%get_min() + target_box%get_min()
314 do idx_p = 1, boundary_mesh%mpts
315 boundary_mesh%points(idx_p)%x = &
316 scaling * boundary_mesh%points(idx_p)%x + translation
320 call neko_error(
'Unknown mesh transform')
331 call temp_field%init(this%indicator%dof)
334 select case (distance_transform)
336 call json_get(json,
'distance_transform.value', scalar_d)
337 scalar_r = real(scalar_d, kind=rp)
339 call signed_distance_field(temp_field, boundary_mesh, scalar_d)
340 call smooth_step_field(temp_field, scalar_r, 0.0_rp)
344 call json_get(json,
'distance_transform.value', scalar_d)
346 call signed_distance_field(temp_field, boundary_mesh, scalar_d)
347 call step_function_field(temp_field, scalar_r, 1.0_rp, 0.0_rp)
350 call neko_error(
'Unknown distance transform')
355 call json_get_or_default(json,
'filter.type', filter_type,
'none')
357 select case (filter_type)
361 call neko_error(
'Unknown filter type')
365 this%indicator%x = max(this%indicator%x, temp_field%x)
367 end subroutine init_boundary_mesh
372 subroutine init_point_zone(this, json)
374 type(json_file),
intent(inout) :: json
377 character(len=:),
allocatable :: zone_name
378 character(len=:),
allocatable :: filter_type
380 type(field_t) :: temp_field
381 class(point_zone_t),
pointer :: my_point_zone
387 call json_get(json,
'name', zone_name)
388 call json_get_or_default(json,
'filter.type', filter_type,
'none')
392 call temp_field%init(this%indicator%dof)
394 my_point_zone => neko_point_zone_registry%get_point_zone(zone_name)
396 do i = 1, my_point_zone%size
397 temp_field%x(my_point_zone%mask(i), 1, 1, 1) = 1.0_rp
402 select case (filter_type)
406 call neko_error(
'Unknown filter type')
410 this%indicator%x = max(this%indicator%x, temp_field%x)
412 end subroutine init_point_zone
Implements the brinkman_source_term_t type.
subroutine brinkman_source_term_init_from_json(this, json, fields, coef)
The common constructor using a JSON object.
A Brinkman source term. The region and strength are controlled by assigning regions types and brinkma...