Neko 1.99.9
A portable framework for high-order spectral element flow simulations
Loading...
Searching...
No Matches
wall_shear_stress_simcomp.f90
Go to the documentation of this file.
1! Copyright (c) 2026, The Neko Authors
2! All rights reserved.
3!
4! Redistribution and use in source and binary forms, with or without
5! modification, are permitted provided that the following conditions
6! are met:
7!
8! * Redistributions of source code must retain the above copyright
9! notice, this list of conditions and the following disclaimer.
10!
11! * Redistributions in binary form must reproduce the above
12! copyright notice, this list of conditions and the following
13! disclaimer in the documentation and/or other materials provided
14! with the distribution.
15!
16! * Neither the name of the authors nor the names of its
17! contributors may be used to endorse or promote products derived
18! from this software without specific prior written permission.
19!
20! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21! "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22! LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23! FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24! COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25! INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26! BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27! LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28! CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29! LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30! ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31! POSSIBILITY OF SUCH DAMAGE.
32!
35 use num_types, only : rp, dp
36 use json_module, only : json_file
40 use time_state, only : time_state_t
41 use case, only : case_t
42 use field, only : field_t
43 use registry, only : neko_registry
45 use coefs, only : coef_t
46 use vector, only : vector_t
48 use operators, only : strain_rate
50 use math, only : vdot3, sqrt_inplace
53 use ale_manager, only : neko_ale
54 use logger, only : neko_log, log_size
56 implicit none
57 private
58
65 type(field_t), pointer :: u => null()
67 type(field_t), pointer :: v => null()
69 type(field_t), pointer :: w => null()
71 type(field_t), pointer :: p => null()
73 type(field_t), pointer :: mu => null()
75 type(field_t), pointer :: tau_x => null()
77 type(field_t), pointer :: tau_y => null()
79 type(field_t), pointer :: tau_z => null()
81 type(field_t), pointer :: tau_mag => null()
83 type(coef_t), pointer :: coef => null()
86 type(boundary_data_t) :: bdata
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
98 contains
100 procedure, pass(this) :: init => wall_shear_stress_init_from_json
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 => &
110 procedure, pass(this) :: free => wall_shear_stress_free
112 procedure, pass(this) :: compute_ => wall_shear_stress_compute
113 end type wall_shear_stress_t
114
115contains
116
120 subroutine wall_shear_stress_init_from_json(this, json, case)
121 class(wall_shear_stress_t), intent(inout), target :: this
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(:)
128
129 call this%free()
130
131 call json_get_or_default(json, "name", name, "wall_shear_stress")
132 call json_get_or_default(json, "computed_field", computed_field, "tau")
133 call json_get_or_default(json, "fluid_name", fluid_name, "fluid")
134 call json_get_or_default(json, "viscosity_field", viscosity_field, &
135 trim(fluid_name) // "_mu_tot")
136 call json_get(json, "zone_indices", zone_indices)
137
138 ! Defaults to all four components.
139 if (json%valid_path("components")) then
140 call json_get(json, "components", components)
141 else
142 allocate(components(1))
143 components(1) = "all"
144 end if
145
146 call this%init_base(json, case)
147
148 call this%init_common(name, computed_field, viscosity_field, &
149 zone_indices, components, case%fluid%c_Xh)
150
152
160 subroutine wall_shear_stress_parse_components(components, &
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
164 integer :: i
165 character(len=:), allocatable :: c
166
167 want_x = .false.
168 want_y = .false.
169 want_z = .false.
170 want_mag = .false.
171
172 if (size(components) .eq. 0) then
173 call neko_error("wall_shear_stress: 'components' must not be empty")
174 end if
175
176 do i = 1, size(components)
177 c = trim(components(i))
178 select case (c)
179 case ("all")
180 want_x = .true.
181 want_y = .true.
182 want_z = .true.
183 want_mag = .true.
184 case ("x")
185 want_x = .true.
186 case ("y")
187 want_y = .true.
188 case ("z")
189 want_z = .true.
190 case ("mag")
191 want_mag = .true.
192 case default
193 call neko_error("wall_shear_stress: unknown component '" // c // &
194 "'. Use x, y, z, mag, or all.")
195 end select
196 end do
197
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")
200 end if
201
203
211 subroutine wall_shear_stress_build_field_list(computed_field, want_x, &
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(:)
216 integer :: n, k
217
218 n = 0
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
223
224 allocate(fields(n))
225 k = 0
226 if (want_x) then
227 k = k + 1
228 fields(k) = trim(computed_field) // "_x"
229 end if
230 if (want_y) then
231 k = k + 1
232 fields(k) = trim(computed_field) // "_y"
233 end if
234 if (want_z) then
235 k = k + 1
236 fields(k) = trim(computed_field) // "_z"
237 end if
238 if (want_mag) then
239 k = k + 1
240 fields(k) = trim(computed_field) // "_mag"
241 end if
242
244
257 subroutine wall_shear_stress_init_from_controllers(this, name, case, order, &
258 preprocess_controller, compute_controller, output_controller, &
259 computed_field, viscosity_field, zone_indices, components, coef)
260 class(wall_shear_stress_t), intent(inout) :: this
261 character(len=*), intent(in) :: name
262 class(case_t), intent(inout), target :: case
263 integer, intent(in) :: order
264 type(time_based_controller_t), intent(in) :: preprocess_controller
265 type(time_based_controller_t), intent(in) :: compute_controller
266 type(time_based_controller_t), intent(in) :: output_controller
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
272
273 call this%free()
274
275 call this%init_base_from_components(case, order, preprocess_controller, &
276 compute_controller, output_controller)
277
278 call this%init_common(name, computed_field, viscosity_field, &
279 zone_indices, components, coef)
280
282
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)
303 class(wall_shear_stress_t), intent(inout) :: this
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=dp), intent(in) :: preprocess_value
309 character(len=*), intent(in) :: compute_control
310 real(kind=dp), intent(in) :: compute_value
311 character(len=*), intent(in) :: output_control
312 real(kind=dp), 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
318
319 call this%free()
320
321 call this%init_base_from_components(case, order, preprocess_control, &
322 preprocess_value, compute_control, compute_value, output_control, &
323 output_value)
324
325 call this%init_common(name, computed_field, viscosity_field, &
326 zone_indices, components, coef)
327
329
337 subroutine wall_shear_stress_init_common(this, name, computed_field, &
338 viscosity_field, zone_indices, components, coef)
339 class(wall_shear_stress_t), intent(inout) :: this
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
350
351 this%name = name
352 this%coef => coef
353 this%computed_field = computed_field
354
355 call wall_shear_stress_parse_components(components, this%want_x, &
356 this%want_y, this%want_z, this%want_mag)
357
358 call wall_shear_stress_build_field_list(computed_field, this%want_x, &
359 this%want_y, this%want_z, this%want_mag, fields)
360
361 ! Register the selected fields so they are available in the registry.
362 do i = 1, size(fields)
363 call neko_registry%add_field(coef%dof, trim(fields(i)), &
364 ignore_existing = .false.)
365 end do
366
367 allocate(this%zone_indices(size(zone_indices)))
368 this%zone_indices = zone_indices
369
370 ale_enabled = .false.
371 if (associated(neko_ale)) then
372 if (neko_ale%active) ale_enabled = .true.
373 end if
374
375 ! Whether the mesh geometry varies during the run.
376 this%mesh_has_changed = .false.
377 if (ale_enabled) then
378 this%mesh_has_changed = .true.
379 end if
380
381 this%u => neko_registry%get_field_by_name("u")
382 this%v => neko_registry%get_field_by_name("v")
383 this%w => neko_registry%get_field_by_name("w")
384 this%p => neko_registry%get_field_by_name("p")
385
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")
389 end if
390 this%mu => neko_registry%get_field_by_name(trim(viscosity_field))
391
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")
400
401 ! The normals are requested in the `coef` convention, pointing out of the
402 ! fluid domain, because that is what `calc_force_array` expects. The
403 ! outward convention would flip the sign of the computed traction.
404 call this%bdata%init(this%coef, this%zone_indices, &
405 outward_normals = .false.)
406
407 glb_n_pts = this%bdata%n_global
408
409 call neko_log%section("Wall shear stress")
410 write(log_buf, '(A,A)') "Name: ", trim(this%name)
411 call neko_log%message(log_buf)
412 write(log_buf, '(A,*(I0,:,", "))') "Zone indices: ", this%zone_indices
413 call neko_log%message(log_buf)
414 write(log_buf, '(A,I0)') "Global number of masked points: ", glb_n_pts
415 call neko_log%message(log_buf)
416 write(log_buf, '(A,A)') "Viscosity field: ", trim(viscosity_field)
417 call neko_log%message(log_buf)
418 log_buf = "Registered fields: "
419 if (this%want_x) log_buf = trim(log_buf) // " " // &
420 trim(computed_field) // "_x"
421 if (this%want_y) log_buf = trim(log_buf) // " " // &
422 trim(computed_field) // "_y"
423 if (this%want_z) log_buf = trim(log_buf) // " " // &
424 trim(computed_field) // "_z"
425 if (this%want_mag) log_buf = trim(log_buf) // " " // &
426 trim(computed_field) // "_mag"
427 call neko_log%message(log_buf)
428 write(log_buf, '(A,L1)') "Moving mesh: ", this%mesh_has_changed
429 call neko_log%message(log_buf)
430 call neko_log%end_section()
431
432 end subroutine wall_shear_stress_init_common
433
435 subroutine wall_shear_stress_free(this)
436 class(wall_shear_stress_t), intent(inout) :: this
437
438 call this%bdata%free()
439
440 if (allocated(this%zone_indices)) deallocate(this%zone_indices)
441 if (allocated(this%computed_field)) deallocate(this%computed_field)
442
443 nullify(this%u)
444 nullify(this%v)
445 nullify(this%w)
446 nullify(this%p)
447 nullify(this%mu)
448 nullify(this%tau_x)
449 nullify(this%tau_y)
450 nullify(this%tau_z)
451 nullify(this%tau_mag)
452 nullify(this%coef)
453
454 call this%free_base()
455
456 end subroutine wall_shear_stress_free
457
460 subroutine wall_shear_stress_compute(this, time)
461 class(wall_shear_stress_t), intent(inout) :: this
462 type(time_state_t), intent(in) :: time
463 type(field_t), pointer :: s11, s22, s33, s12, s13, s23
464 type(vector_t), pointer :: mu_msk, p_msk
465 type(vector_t), pointer :: s11_msk, s22_msk, s33_msk
466 type(vector_t), pointer :: s12_msk, s13_msk, s23_msk
467 type(vector_t), pointer :: t1, t2, t3, t_mag
468 type(vector_t), pointer :: pt1, pt2, pt3
469 integer :: field_indices(6)
470 integer :: vector_indices(15)
471 integer :: n_pts
472 character(len=LOG_SIZE) :: log_buf
473
474 n_pts = this%bdata%n_local
475
476 ! Re-gather the boundary geometry only when the mesh has moved.
477 if (this%mesh_has_changed) then
478 call this%bdata%update_geometry()
479 end if
480
481 ! Strain rate over the whole field, then gather it at the mask.
482 call neko_scratch_registry%request_field(s11, field_indices(1), .false.)
483 call neko_scratch_registry%request_field(s22, field_indices(2), .false.)
484 call neko_scratch_registry%request_field(s33, field_indices(3), .false.)
485 call neko_scratch_registry%request_field(s12, field_indices(4), .false.)
486 call neko_scratch_registry%request_field(s13, field_indices(5), .false.)
487 call neko_scratch_registry%request_field(s23, field_indices(6), .false.)
488
489 call strain_rate(s11, s22, s33, s12, s13, s23, this%u, this%v, &
490 this%w, this%coef)
491
492 if (n_pts .gt. 0) then
493
494 call neko_scratch_registry%request_vector(mu_msk, vector_indices(1), &
495 n_pts, .false.)
496 call neko_scratch_registry%request_vector(p_msk, vector_indices(2), &
497 n_pts, .false.)
498 call neko_scratch_registry%request_vector(s11_msk, vector_indices(3), &
499 n_pts, .false.)
500 call neko_scratch_registry%request_vector(s22_msk, vector_indices(4), &
501 n_pts, .false.)
502 call neko_scratch_registry%request_vector(s33_msk, vector_indices(5), &
503 n_pts, .false.)
504 call neko_scratch_registry%request_vector(s12_msk, vector_indices(6), &
505 n_pts, .false.)
506 call neko_scratch_registry%request_vector(s13_msk, vector_indices(7), &
507 n_pts, .false.)
508 call neko_scratch_registry%request_vector(s23_msk, vector_indices(8), &
509 n_pts, .false.)
510 call neko_scratch_registry%request_vector(t1, vector_indices(9), &
511 n_pts, .false.)
512 call neko_scratch_registry%request_vector(t2, vector_indices(10), &
513 n_pts, .false.)
514 call neko_scratch_registry%request_vector(t3, vector_indices(11), &
515 n_pts, .false.)
516 call neko_scratch_registry%request_vector(t_mag, vector_indices(12), &
517 n_pts, .false.)
518 call neko_scratch_registry%request_vector(pt1, vector_indices(13), &
519 n_pts, .false.)
520 call neko_scratch_registry%request_vector(pt2, vector_indices(14), &
521 n_pts, .false.)
522 call neko_scratch_registry%request_vector(pt3, vector_indices(15), &
523 n_pts, .false.)
524
525 call this%bdata%get(this%mu, mu_msk)
526 call this%bdata%get(this%p, p_msk)
527 call this%bdata%get(s11, s11_msk)
528 call this%bdata%get(s22, s22_msk)
529 call this%bdata%get(s33, s33_msk)
530 call this%bdata%get(s12, s12_msk)
531 call this%bdata%get(s13, s13_msk)
532 call this%bdata%get(s23, s23_msk)
533
534 if (neko_bcknd_device .eq. 1) then
535 call device_calc_force_array(pt1%x_d, pt2%x_d, pt3%x_d, &
536 t1%x_d, t2%x_d, t3%x_d, &
537 s11_msk%x_d, s22_msk%x_d, s33_msk%x_d, &
538 s12_msk%x_d, s13_msk%x_d, s23_msk%x_d, &
539 p_msk%x_d, this%bdata%n_x%x_d, &
540 this%bdata%n_y%x_d, this%bdata%n_z%x_d, &
541 mu_msk%x_d, n_pts)
542 else
543 call calc_force_array(pt1%x, pt2%x, pt3%x, &
544 t1%x, t2%x, t3%x, &
545 s11_msk%x, s22_msk%x, s33_msk%x, &
546 s12_msk%x, s13_msk%x, s23_msk%x, &
547 p_msk%x, this%bdata%n_x%x, &
548 this%bdata%n_y%x, this%bdata%n_z%x, &
549 mu_msk%x, n_pts)
550 end if
551
552 ! Remove the wall-normal part, leaving the tangential traction.
553 ! The projection is invariant to the sign of the normal.
554 call this%bdata%tangential(t1, t2, t3)
555
556 ! Magnitude of the tangential traction.
557 if (this%want_mag) then
558 if (neko_bcknd_device .eq. 1) then
559 call device_vdot3(t_mag%x_d, t1%x_d, t2%x_d, t3%x_d, &
560 t1%x_d, t2%x_d, t3%x_d, n_pts)
561 call device_sqrt_inplace(t_mag%x_d, n_pts)
562 else
563 call vdot3(t_mag%x, t1%x, t2%x, t3%x, &
564 t1%x, t2%x, t3%x, n_pts)
565 call sqrt_inplace(t_mag%x, n_pts)
566 end if
567 end if
568
569 ! Scatter the tangential traction and its magnitude into the
570 ! registered fields.
571 if (this%want_x) call this%bdata%scatter(t1, this%tau_x)
572 if (this%want_y) call this%bdata%scatter(t2, this%tau_y)
573 if (this%want_z) call this%bdata%scatter(t3, this%tau_z)
574 if (this%want_mag) call this%bdata%scatter(t_mag, this%tau_mag)
575
576 call neko_scratch_registry%relinquish_vector(vector_indices)
577 end if
578
579 call neko_scratch_registry%relinquish_field(field_indices)
580
581 write(log_buf, '(A,A,A,E15.7,A,*(I0,:,", "))') &
582 "WSS: '", trim(this%name), "' computed at t = ", &
583 time%t, ", zones: ", this%zone_indices
584 call neko_log%message(log_buf)
585
586 end subroutine wall_shear_stress_compute
587
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.
Definition case.f90:34
Coefficients.
Definition coef.f90:34
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.
Defines a field.
Definition field.f90:34
Utilities for retrieving parameters from the case files.
Logging routines.
Definition log.f90:34
type(log_t), public neko_log
Global log stream.
Definition log.f90:80
integer, parameter, public log_size
Definition log.f90:46
Definition math.f90:60
subroutine, public sqrt_inplace(a, n)
Sqrt a vector .
Definition math.f90:1881
subroutine, public vdot3(dot, u1, u2, u3, v1, v2, v3, n)
Compute a dot product (3-d version) assuming vector components etc.
Definition math.f90:855
Build configurations.
integer, parameter neko_bcknd_device
integer, parameter, public dp
Definition num_types.f90:10
integer, parameter, public rp
Global precision used in computations.
Definition num_types.f90:14
Operators.
Definition operators.f90:34
Implements output_controller_t
Defines a registry for storing solution fields.
Definition registry.f90:34
type(registry_t), target, public neko_registry
Global field registry.
Definition registry.f90:144
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.
Utilities.
Definition utils.f90:35
integer, parameter, public neko_varname_len
Definition utils.f90:43
Defines a vector.
Definition vector.f90:34
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,...
Definition coef.f90:93
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...