36 use json_module,
only : json_file
81 type(
field_t),
pointer :: tau_mag => null()
83 type(
coef_t),
pointer :: coef => null()
88 integer,
allocatable :: zone_indices(:)
90 logical :: want_x = .true.
91 logical :: want_y = .true.
92 logical :: want_z = .true.
93 logical :: want_mag = .true.
95 logical :: mesh_has_changed = .false.
97 character(len=:),
allocatable :: computed_field
101 generic :: init_from_components => &
102 init_from_controllers, init_from_controllers_properties
103 procedure, pass(this) :: init_from_controllers => &
105 procedure, pass(this) :: init_from_controllers_properties => &
107 procedure,
private, pass(this) :: init_common => &
122 type(json_file),
intent(inout) :: json
123 class(
case_t),
intent(inout),
target :: case
124 character(len=:),
allocatable :: name, computed_field, fluid_name
125 character(len=:),
allocatable :: viscosity_field
126 integer,
allocatable :: zone_indices(:)
127 character(len=NEKO_VARNAME_LEN),
allocatable :: components(:)
135 trim(fluid_name) //
"_mu_tot")
136 call json_get(json,
"zone_indices", zone_indices)
139 if (json%valid_path(
"components"))
then
140 call json_get(json,
"components", components)
142 allocate(components(1))
143 components(1) =
"all"
146 call this%init_base(json,
case)
148 call this%init_common(name, computed_field, viscosity_field, &
149 zone_indices, components,
case%fluid%c_Xh)
161 want_x, want_y, want_z, want_mag)
162 character(len=*),
intent(in) :: components(:)
163 logical,
intent(out) :: want_x, want_y, want_z, want_mag
165 character(len=:),
allocatable :: c
172 if (
size(components) .eq. 0)
then
173 call neko_error(
"wall_shear_stress: 'components' must not be empty")
176 do i = 1,
size(components)
177 c = trim(components(i))
193 call neko_error(
"wall_shear_stress: unknown component '" // c // &
194 "'. Use x, y, z, mag, or all.")
198 if (.not. (want_x .or. want_y .or. want_z .or. want_mag))
then
199 call neko_error(
"wall_shear_stress: no components selected")
212 want_y, want_z, want_mag, fields)
213 character(len=*),
intent(in) :: computed_field
214 logical,
intent(in) :: want_x, want_y, want_z, want_mag
215 character(len=NEKO_VARNAME_LEN),
allocatable,
intent(out) :: fields(:)
219 if (want_x) n = n + 1
220 if (want_y) n = n + 1
221 if (want_z) n = n + 1
222 if (want_mag) n = n + 1
228 fields(k) = trim(computed_field) //
"_x"
232 fields(k) = trim(computed_field) //
"_y"
236 fields(k) = trim(computed_field) //
"_z"
240 fields(k) = trim(computed_field) //
"_mag"
258 preprocess_controller, compute_controller, output_controller, &
259 computed_field, viscosity_field, zone_indices, components, coef)
261 character(len=*),
intent(in) :: name
262 class(
case_t),
intent(inout),
target :: case
263 integer,
intent(in) :: order
267 character(len=*),
intent(in) :: computed_field
268 character(len=*),
intent(in) :: viscosity_field
269 integer,
intent(in) :: zone_indices(:)
270 character(len=*),
intent(in) :: components(:)
271 type(
coef_t),
intent(inout),
target :: coef
275 call this%init_base_from_components(
case, order, preprocess_controller, &
278 call this%init_common(name, computed_field, viscosity_field, &
279 zone_indices, components, coef)
300 case, order, preprocess_control, preprocess_value, compute_control, &
301 compute_value, output_control, output_value, computed_field, &
302 viscosity_field, zone_indices, components, coef)
304 character(len=*),
intent(in) :: name
305 class(
case_t),
intent(inout),
target :: case
306 integer,
intent(in) :: order
307 character(len=*),
intent(in) :: preprocess_control
308 real(kind=
rp),
intent(in) :: preprocess_value
309 character(len=*),
intent(in) :: compute_control
310 real(kind=
rp),
intent(in) :: compute_value
311 character(len=*),
intent(in) :: output_control
312 real(kind=
rp),
intent(in) :: output_value
313 character(len=*),
intent(in) :: computed_field
314 character(len=*),
intent(in) :: viscosity_field
315 integer,
intent(in) :: zone_indices(:)
316 character(len=*),
intent(in) :: components(:)
317 type(
coef_t),
intent(inout),
target :: coef
321 call this%init_base_from_components(
case, order, preprocess_control, &
322 preprocess_value, compute_control, compute_value, output_control, &
325 call this%init_common(name, computed_field, viscosity_field, &
326 zone_indices, components, coef)
338 viscosity_field, zone_indices, components, coef)
340 character(len=*),
intent(in) :: name
341 character(len=*),
intent(in) :: computed_field
342 character(len=*),
intent(in) :: viscosity_field
343 integer,
intent(in) :: zone_indices(:)
344 character(len=*),
intent(in) :: components(:)
345 type(
coef_t),
intent(inout),
target :: coef
346 character(len=NEKO_VARNAME_LEN),
allocatable :: fields(:)
347 character(len=LOG_SIZE) :: log_buf
348 integer :: i, glb_n_pts
349 logical :: ale_enabled
353 this%computed_field = computed_field
356 this%want_y, this%want_z, this%want_mag)
359 this%want_y, this%want_z, this%want_mag, fields)
362 do i = 1,
size(fields)
364 ignore_existing = .false.)
367 allocate(this%zone_indices(
size(zone_indices)))
368 this%zone_indices = zone_indices
370 ale_enabled = .false.
372 if (
neko_ale%active) ale_enabled = .true.
376 this%mesh_has_changed = .false.
377 if (ale_enabled)
then
378 this%mesh_has_changed = .true.
386 if (.not.
neko_registry%field_exists(trim(viscosity_field)))
then
387 call neko_error(
"wall_shear_stress: the viscosity field '" // &
388 trim(viscosity_field) //
"' is not in the registry")
390 this%mu =>
neko_registry%get_field_by_name(trim(viscosity_field))
392 if (this%want_x) this%tau_x => &
393 neko_registry%get_field_by_name(trim(computed_field) //
"_x")
394 if (this%want_y) this%tau_y => &
395 neko_registry%get_field_by_name(trim(computed_field) //
"_y")
396 if (this%want_z) this%tau_z => &
397 neko_registry%get_field_by_name(trim(computed_field) //
"_z")
398 if (this%want_mag) this%tau_mag => &
399 neko_registry%get_field_by_name(trim(computed_field) //
"_mag")
405 call this%bdata%init(this%coef, this%zone_indices, &
406 outward_normals = .false.)
408 glb_n_pts = this%bdata%n_global
410 call neko_log%section(
"Wall shear stress")
411 write(log_buf,
'(A,A)')
"Name: ", trim(this%name)
413 write(log_buf,
'(A,*(I0,:,", "))')
"Zone indices: ", this%zone_indices
415 write(log_buf,
'(A,I0)')
"Global number of masked points: ", glb_n_pts
417 write(log_buf,
'(A,A)')
"Viscosity field: ", trim(viscosity_field)
419 log_buf =
"Registered fields: "
420 if (this%want_x) log_buf = trim(log_buf) //
" " // &
421 trim(computed_field) //
"_x"
422 if (this%want_y) log_buf = trim(log_buf) //
" " // &
423 trim(computed_field) //
"_y"
424 if (this%want_z) log_buf = trim(log_buf) //
" " // &
425 trim(computed_field) //
"_z"
426 if (this%want_mag) log_buf = trim(log_buf) //
" " // &
427 trim(computed_field) //
"_mag"
429 write(log_buf,
'(A,L1)')
"Moving mesh: ", this%mesh_has_changed
439 call this%bdata%free()
441 if (
allocated(this%zone_indices))
deallocate(this%zone_indices)
442 if (
allocated(this%computed_field))
deallocate(this%computed_field)
452 nullify(this%tau_mag)
455 call this%free_base()
464 type(
field_t),
pointer :: s11, s22, s33, s12, s13, s23
465 type(
vector_t),
pointer :: mu_msk, p_msk
466 type(
vector_t),
pointer :: s11_msk, s22_msk, s33_msk
467 type(
vector_t),
pointer :: s12_msk, s13_msk, s23_msk
468 type(
vector_t),
pointer :: t1, t2, t3, t_mag
469 type(
vector_t),
pointer :: pt1, pt2, pt3
470 integer :: field_indices(6)
471 integer :: vector_indices(15)
473 character(len=LOG_SIZE) :: log_buf
475 n_pts = this%bdata%n_local
478 if (this%mesh_has_changed)
then
479 call this%bdata%update_geometry()
490 call strain_rate(s11, s22, s33, s12, s13, s23, this%u, this%v, &
493 if (n_pts .gt. 0)
then
526 call this%bdata%get(this%mu, mu_msk)
527 call this%bdata%get(this%p, p_msk)
528 call this%bdata%get(s11, s11_msk)
529 call this%bdata%get(s22, s22_msk)
530 call this%bdata%get(s33, s33_msk)
531 call this%bdata%get(s12, s12_msk)
532 call this%bdata%get(s13, s13_msk)
533 call this%bdata%get(s23, s23_msk)
537 t1%x_d, t2%x_d, t3%x_d, &
538 s11_msk%x_d, s22_msk%x_d, s33_msk%x_d, &
539 s12_msk%x_d, s13_msk%x_d, s23_msk%x_d, &
540 p_msk%x_d, this%bdata%n_x%x_d, &
541 this%bdata%n_y%x_d, this%bdata%n_z%x_d, &
546 s11_msk%x, s22_msk%x, s33_msk%x, &
547 s12_msk%x, s13_msk%x, s23_msk%x, &
548 p_msk%x, this%bdata%n_x%x, &
549 this%bdata%n_y%x, this%bdata%n_z%x, &
555 call this%bdata%tangential(t1, t2, t3)
558 if (this%want_mag)
then
561 t1%x_d, t2%x_d, t3%x_d, n_pts)
564 call vdot3(t_mag%x, t1%x, t2%x, t3%x, &
565 t1%x, t2%x, t3%x, n_pts)
572 if (this%want_x)
call this%bdata%scatter(t1, this%tau_x)
573 if (this%want_y)
call this%bdata%scatter(t2, this%tau_y)
574 if (this%want_z)
call this%bdata%scatter(t3, this%tau_z)
575 if (this%want_mag)
call this%bdata%scatter(t_mag, this%tau_mag)
582 write(log_buf,
'(A,A,A,E15.7,A,*(I0,:,", "))') &
583 "WSS: '", trim(this%name),
"' computed at t = ", &
584 time%t,
", zones: ", this%zone_indices
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.
Compute the strain rate tensor of a vector field.
ALE Manager: Handles Mesh Motion.
type(ale_manager_t), pointer, public neko_ale
Implements the boundary_data_t type.
Defines a simulation case.
subroutine, public device_vdot3(dot_d, u1_d, u2_d, u3_d, v1_d, v2_d, v3_d, n, strm)
Compute a dot product (3-d version) assuming vector components etc.
subroutine, public device_sqrt_inplace(a_d, n, strm)
Sqrt a vector .
subroutine, public calc_force_array(force1, force2, force3, force4, force5, force6, s11, s22, s33, s12, s13, s23, p, n1, n2, n3, mu, n_pts)
Calculate drag and torque from array of points.
subroutine, public device_calc_force_array(force1, force2, force3, force4, force5, force6, s11, s22, s33, s12, s13, s23, p, n1, n2, n3, mu, n_pts)
Calculate drag and torque from array of points.
Utilities for retrieving parameters from the case files.
type(log_t), public neko_log
Global log stream.
integer, parameter, public log_size
subroutine, public sqrt_inplace(a, n)
Sqrt a vector .
subroutine, public vdot3(dot, u1, u2, u3, v1, v2, v3, n)
Compute a dot product (3-d version) assuming vector components etc.
integer, parameter neko_bcknd_device
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.
Defines a registry for storing and requesting temporary objects This can be used when you have a func...
type(scratch_registry_t), target, public neko_scratch_registry
Global scratch 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.
integer, parameter, public neko_varname_len
Implements the wall_shear_stress_t type.
subroutine wall_shear_stress_build_field_list(computed_field, want_x, want_y, want_z, want_mag, fields)
Build the array of selected field names in x, y, z, mag order.
subroutine wall_shear_stress_init_from_controllers(this, name, case, order, preprocess_controller, compute_controller, output_controller, computed_field, viscosity_field, zone_indices, components, coef)
Constructor from components, passing controllers.
subroutine wall_shear_stress_init_common(this, name, computed_field, viscosity_field, zone_indices, components, coef)
Common part of all constructors.
subroutine wall_shear_stress_compute(this, time)
Compute the wall shear stress.
subroutine wall_shear_stress_init_from_json(this, json, case)
Constructor from json.
subroutine wall_shear_stress_parse_components(components, want_x, want_y, want_z, want_mag)
Translate a components list into the four selection flags.
subroutine wall_shear_stress_init_from_controllers_properties(this, name, case, order, preprocess_control, preprocess_value, compute_control, compute_value, output_control, output_value, computed_field, viscosity_field, zone_indices, components, coef)
Constructor from components, passing properties to the time_based_controller components in the base t...
subroutine wall_shear_stress_free(this)
Destructor.
Collects data on the boundary points of one or more labelled zones and perform some bounary operation...
Coefficients defined on a given (mesh, ) tuple. Arrays use indices (i,j,k,e): element e,...
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.
A simulation component that computes the wall shear stress on one or more labelled boundary zones and...