36 use json_module,
only : json_file
68 type(
coef_t),
pointer :: coef => null()
72 integer,
allocatable :: zone_indices(:)
74 character(len=80),
allocatable :: field_names(:)
76 logical :: log = .true.
78 logical :: csv_output_enabled = .false.
96 real(kind=
rp) :: flux = 0.0_rp
101 generic :: init_from_components => &
102 init_from_controllers, init_from_controllers_properties
104 procedure, pass(this) :: init_from_controllers => &
107 procedure, pass(this) :: init_from_controllers_properties => &
110 procedure,
private, pass(this) :: init_common => &
125 type(json_file),
intent(inout) :: json
126 class(
case_t),
intent(inout),
target :: case
127 character(len=:),
allocatable :: name
128 integer,
allocatable :: zone_indices(:)
129 character(len=80),
allocatable :: field_names(:)
131 character(len=:),
allocatable :: output_filename
137 call this%init_base(json,
case)
139 call json_get(json,
"zone_indices", zone_indices)
140 call json_get(json,
"field_names", field_names)
142 if (json%valid_path(
"output_filename"))
then
143 call json_get(json,
"output_filename", output_filename)
144 call this%init_common(name,
case%fluid%c_Xh, zone_indices, &
145 field_names, log, output_filename)
147 call this%init_common(name,
case%fluid%c_Xh, zone_indices, &
160 field_names, log, output_filename)
162 character(len=*),
intent(in) :: name
163 type(
coef_t),
intent(inout),
target :: coef
164 integer,
intent(in) :: zone_indices(:)
165 character(len=*),
intent(in) :: field_names(:)
166 logical,
intent(in) :: log
167 character(len=*),
intent(in),
optional :: output_filename
168 character(len=LOG_SIZE) :: log_buf
174 this%csv_output_enabled = .false.
179 if (
size(zone_indices) .eq. 0)
then
180 call neko_error(
"boundary_flux requires at least one zone index")
183 if (
size(field_names) .ne. 3)
then
184 call neko_error(
"boundary_flux requires exactly three field names")
187 allocate(this%zone_indices(
size(zone_indices)))
188 this%zone_indices = zone_indices
189 allocate(this%field_names(
size(field_names)))
190 this%field_names = field_names
192 this%u =>
neko_registry%get_field_by_name(trim(this%field_names(1)))
193 this%v =>
neko_registry%get_field_by_name(trim(this%field_names(2)))
194 this%w =>
neko_registry%get_field_by_name(trim(this%field_names(3)))
196 call this%bc%init_from_components(this%coef, 0.0_rp)
197 this%bc%zone_indices = this%zone_indices
198 do i = 1,
size(this%zone_indices)
199 call this%bc%mark_zone(this%bc%msh%labeled_zones(this%zone_indices(i)))
201 call this%bc%finalize()
203 n_pts = this%bc%msk(0)
204 if (n_pts .gt. 0)
then
205 call this%n1%init(n_pts)
206 call this%n2%init(n_pts)
207 call this%n3%init(n_pts)
208 call this%surface_u%init(n_pts)
209 call this%surface_v%init(n_pts)
210 call this%surface_w%init(n_pts)
212 this%n1%x, this%n2%x, this%n3%x, n_pts)
226 if (
present(output_filename))
then
227 call this%csv_output%init(trim(output_filename), &
228 header =
"tstep,time,flux", overwrite = .true.)
229 call this%csv_row%init(3)
230 this%csv_output_enabled = .true.
233 call neko_log%section(
"Boundary flux")
234 write(log_buf,
'(A,A)')
"Name: ", trim(this%name)
236 write(log_buf,
'(A,A,", ",A,", ",A)')
"Fields: ", &
237 trim(this%field_names(1)), trim(this%field_names(2)), &
238 trim(this%field_names(3))
240 write(log_buf,
'(A,*(I0,:,", "))')
"Zone indices: ", this%zone_indices
242 write(log_buf,
'(A,I0)')
"Marked boundary quadrature points: ", &
260 preprocess_controller, compute_controller, output_controller, &
261 zone_indices, field_names, log, output_filename)
263 character(len=*),
intent(in) :: name
264 class(
case_t),
intent(inout),
target :: case
265 integer,
intent(in) :: order
269 integer,
intent(in) :: zone_indices(:)
270 character(len=*),
intent(in) :: field_names(:)
271 logical,
intent(in),
optional :: log
272 character(len=*),
intent(in),
optional :: output_filename
273 logical :: log_enabled
278 if (
present(log)) log_enabled = log
280 call this%init_base_from_components(
case, order, preprocess_controller, &
283 if (
present(output_filename))
then
284 call this%init_common(name,
case%fluid%c_Xh, zone_indices, &
285 field_names, log_enabled, output_filename)
287 call this%init_common(name,
case%fluid%c_Xh, zone_indices, &
288 field_names, log_enabled)
307 order, preprocess_control, preprocess_value, compute_control, &
308 compute_value, output_control, output_value, zone_indices, field_names, &
309 log, output_filename)
311 character(len=*),
intent(in) :: name
312 class(
case_t),
intent(inout),
target :: case
313 integer,
intent(in) :: order
314 character(len=*),
intent(in) :: preprocess_control
315 real(kind=
rp),
intent(in) :: preprocess_value
316 character(len=*),
intent(in) :: compute_control
317 real(kind=
rp),
intent(in) :: compute_value
318 character(len=*),
intent(in) :: output_control
319 real(kind=
rp),
intent(in) :: output_value
320 integer,
intent(in) :: zone_indices(:)
321 character(len=*),
intent(in) :: field_names(:)
322 logical,
intent(in),
optional :: log
323 character(len=*),
intent(in),
optional :: output_filename
324 logical :: log_enabled
329 if (
present(log)) log_enabled = log
331 call this%init_base_from_components(
case, order, preprocess_control, &
332 preprocess_value, compute_control, compute_value, output_control, &
335 if (
present(output_filename))
then
336 call this%init_common(name,
case%fluid%c_Xh, zone_indices, &
337 field_names, log_enabled, output_filename)
339 call this%init_common(name,
case%fluid%c_Xh, zone_indices, &
340 field_names, log_enabled)
349 call this%csv_output%free()
350 call this%csv_row%free()
354 call this%surface_u%free()
355 call this%surface_v%free()
356 call this%surface_w%free()
357 if (
allocated(this%zone_indices))
deallocate(this%zone_indices)
358 if (
allocated(this%field_names))
deallocate(this%field_names)
365 call this%free_base()
374 character(len=18) :: value_buf
375 character(len=12) :: step_str
376 character(len=:),
allocatable :: header_line, value_line
378 n_pts = this%bc%msk(0)
382 this%bc%msk, this%u%size(), n_pts)
384 this%bc%msk, this%v%size(), n_pts)
386 this%bc%msk, this%w%size(), n_pts)
388 this%flux =
vector_glsc2(this%surface_u, this%n1, n_pts) + &
393 call neko_log%section(trim(this%name))
395 header_line = repeat(
' ', 12) //
' |' //
left_pad(
'Flux:', 18)
396 write(step_str,
'(I12)') time%tstep
397 step_str = adjustl(step_str)
398 write(value_buf,
'(ES18.9)') this%flux
399 value_line = step_str //
' |' // value_buf
406 if (this%csv_output_enabled)
then
407 if (this%output_controller%check(time))
then
408 this%csv_row%x(1) =
real(time%tstep,
rp)
409 this%csv_row%x(2) = time%t
410 this%csv_row%x(3) = this%flux
411 call this%csv_output%write(this%csv_row)
412 call this%output_controller%register_execution()
421 character(len=*),
intent(in) :: text
422 integer,
intent(in) :: width
423 character(len=:),
allocatable :: padded
426 pad_width =
max(0, width - len_trim(text))
427 padded = repeat(
' ', pad_width) // trim(text)
Copy data between host and device (or device and device)
Retrieves a parameter by name or assigns a provided default value. In the latter case also adds the m...
Retrieves a parameter by name or throws an error.
Defines a boundary condition.
Implements boundary_flux_t.
subroutine boundary_flux_init_common(this, name, coef, zone_indices, field_names, log, output_filename)
Common constructor shared by all public constructors.
subroutine boundary_flux_init_from_controllers(this, name, case, order, preprocess_controller, compute_controller, output_controller, zone_indices, field_names, log, output_filename)
Construct from explicit time-based controllers.
subroutine boundary_flux_compute(this, time)
Compute and optionally output the total boundary flux.
subroutine boundary_flux_init_from_json(this, json, case)
Construct from JSON.
subroutine boundary_flux_init_from_controllers_properties(this, name, case, order, preprocess_control, preprocess_value, compute_control, compute_value, output_control, output_value, zone_indices, field_names, log, output_filename)
Construct from time-based controller properties.
subroutine boundary_flux_free(this)
Free all resources owned by the component.
pure character(len=:) function, allocatable left_pad(text, width)
Left-pad a string to a fixed width.
Defines a simulation case.
Device abstraction, common interface for various accelerators.
integer, parameter, public host_to_device
subroutine, public setup_normals(coef, mask, facets, n1, n2, n3, n_pts)
Computes the normals for a given set of boundary points accessed by the mask.
Module for file I/O operations.
Utilities for retrieving parameters from the case files.
type(log_t), public neko_log
Global log stream.
integer, parameter, public log_size
integer, parameter neko_bcknd_device
Defines a Neumann boundary condition.
integer, parameter, public rp
Global precision used in computations.
Implements output_controller_t
Defines a registry for storing solution fields.
type(registry_t), target, public neko_registry
Global field registry.
Simulation components are objects that encapsulate functionality that can be fit to a particular comp...
subroutine compute_(this, time)
Dummy compute function.
Contains the time_based_controller_t type.
Module with things related to the simulation time.
subroutine, public vector_masked_gather_copy_0(a, b, mask, n, n_mask)
Gather a vector to reduced contigous array .
subroutine, public vector_cmult(a, c, n)
Multiplication by constant c .
real(kind=rp) function, public vector_glsc2(a, b, n)
A simulation component for total vector flux through labelled zones.
Coefficients defined on a given (mesh, ) tuple. Arrays use indices (i,j,k,e): element e,...
A wrapper around a polymorphic generic_file_t that handles its init. This is essentially a factory fo...
A Neumann boundary condition. Sets the flux of the field to the chosen values.
Base abstract class for simulation components.
A utility type for determining whether an action should be executed based on the current time value....
A struct that contains all info about the time, expand as needed.