36 use json_module,
only : json_file
75 character(:),
allocatable :: name
77 type(
field_t),
pointer :: u_field => null()
78 type(
field_t),
pointer :: v_field => null()
79 type(
field_t),
pointer :: w_field => null()
80 type(
field_t),
pointer :: mu_fluid => null()
81 type(
field_t),
pointer :: rho_fluid => null()
82 type(
mesh_t),
pointer :: msh => null()
84 type(
coef_t),
pointer :: coef => null()
85 integer :: time_order, lag_len
86 integer :: history_len = 0
87 logical :: inertia = .false.
88 real(kind=
rp) :: nonlinear_coefficient, nonlinear_exponent
89 logical :: elastic_wall_enabled = .false.
90 integer,
allocatable :: wall_zone_indices(:)
91 logical,
allocatable :: wall_facet_mask(:, :)
93 logical :: lpt_time_initialized = .false.
100 logical :: output_enabled = .false.
101 logical :: log = .true.
102 real(kind=
rp) :: start_time = -huge(0.0_rp)
122 module subroutine lpt_init_wall_facet_mask(wall_facet_mask, msh, &
124 logical,
allocatable,
intent(inout) :: wall_facet_mask(:, :)
125 type(
mesh_t),
intent(in) :: msh
126 integer,
intent(in) :: wall_zone_indices(:)
127 end subroutine lpt_init_wall_facet_mask
130 module subroutine lpt_handle_elastic_wall_collisions(this, x_old, y_old, &
131 z_old, u_old, v_old, w_old)
132 class(lpt_t),
intent(inout) :: this
133 type(
vector_t),
intent(in) :: x_old, y_old, z_old
134 type(
vector_t),
intent(inout) :: u_old, v_old, w_old
135 end subroutine lpt_handle_elastic_wall_collisions
143 subroutine lpt_init_from_json(this, json, case)
144 class(lpt_t),
intent(inout),
target :: this
145 type(json_file),
intent(inout) :: json
146 class(
case_t),
intent(inout),
target :: case
147 type(json_file) :: interp_subdict
148 character(len=:),
allocatable :: name
149 character(len=:),
allocatable :: migration_strategy
150 character(len=:),
allocatable :: output_filename
151 character(len=:),
allocatable :: output_format
152 character(len=:),
allocatable :: snapshots_per_file_str
153 character(len=:),
allocatable :: output_path
154 integer :: migration_strategy_id
155 integer :: snapshots_per_file
156 integer :: snapshots_per_file_type
157 logical :: snapshots_per_file_found
167 this%time_order =
case%fluid%ext_bdf%advection_time_order
168 this%msh =>
case%fluid%msh
169 this%dm_Xh =>
case%fluid%dm_Xh
170 this%coef =>
case%fluid%c_Xh
172 this%lag_len = this%time_order - 1
175 select case (trim(migration_strategy))
181 call neko_error(
"lpt migration_strategy must be 'owner' or 'none'")
183 call this%migration%init(this%lag_len, migration_strategy_id)
185 call json_get(json,
"inertia", this%inertia)
187 if (this%inertia)
then
189 this%nonlinear_coefficient, 0.15_rp)
191 this%nonlinear_exponent, 0.687_rp)
193 case%fluid%name //
"_mu")
195 case%fluid%name //
"_rho")
201 if (
case%params%valid_path(
"case.fluid.wall_zone_indices"))
then
202 call json_get(
case%params,
"case.fluid.wall_zone_indices", &
203 this%wall_zone_indices)
204 if (.not. this%inertia .and.
size(this%wall_zone_indices) .gt. 0)
then
205 call neko_error(
"lpt wall_zone_indices requires inertia = true")
207 this%elastic_wall_enabled =
size(this%wall_zone_indices) .gt. 0
208 if (this%elastic_wall_enabled .and. &
210 call neko_error(
"lpt migration_strategy = none is not " // &
211 "compatible with elastic wall collisions")
213 if (this%elastic_wall_enabled)
then
214 call lpt_init_wall_facet_mask(this%wall_facet_mask, this%msh, &
215 this%wall_zone_indices)
219 call this%read_particles_json(json)
220 call this%migration%initialize_particle_distribution(this%inertia, &
224 call this%global_interp%init(
case%fluid%dm_Xh, &
225 params_subdict = interp_subdict)
226 call this%periodic_bc%init(
case%fluid%msh,
case%fluid%dm_Xh, &
228 call this%migration%migrate_particles(this%global_interp, &
229 this%periodic_bc, this%inertia, this%particles)
230 call this%sync_time_controller(
case%time)
231 call this%update_current_rhs()
237 call json%info(
"snapshots_per_file", found = snapshots_per_file_found, &
238 var_type = snapshots_per_file_type)
239 if (snapshots_per_file_found)
then
240 select case (snapshots_per_file_type)
242 call json_get(json,
"snapshots_per_file", snapshots_per_file)
243 if (snapshots_per_file .lt. 1)
then
244 call neko_error(
"lpt snapshots_per_file must be a positive " // &
248 call json_get(json,
"snapshots_per_file", snapshots_per_file_str)
249 if (trim(snapshots_per_file_str) .eq.
"all")
then
250 snapshots_per_file = 0
252 call neko_error(
"lpt snapshots_per_file must be a positive " // &
256 call neko_error(
"lpt snapshots_per_file must be a positive " // &
260 snapshots_per_file = 0
261 call json%add(
"snapshots_per_file",
"all")
263 output_path =
case%output_directory // trim(output_filename) //
"." // &
265 call this%output%init(output_path, this%inertia, snapshots_per_file)
268 this%output_enabled = .true.
269 call this%write_output(
case%time)
271 call this%log_status()
272 end subroutine lpt_init_from_json
277 subroutine read_particles_json(this, json)
278 class(lpt_t),
intent(inout) :: this
279 type(json_file),
intent(inout) :: json
280 real(kind=
rp),
allocatable :: coords(:)
281 real(kind=
rp),
allocatable :: vels(:)
282 real(kind=
rp),
allocatable :: diams(:)
283 real(kind=
rp),
allocatable :: densities(:)
285 integer :: n_particles, ind(6)
288 if (json%valid_path(
"coordinates"))
then
289 call json_get(json,
"coordinates", coords)
290 if (mod(
size(coords), 3) .ne. 0)
then
291 call neko_error(
"lpt coordinates must contain 3 values per " // &
294 n_particles =
size(coords) / 3
295 if (this%inertia)
then
296 call json_get(json,
"velocities", vels)
297 if (mod(
size(vels), 3) .ne. 0)
then
298 call neko_error(
"lpt velocities must contain 3 values per " // &
301 call json_get(json,
"diameters", diams)
302 call json_get(json,
"densities", densities)
303 if (
size(vels) / 3 .ne. n_particles .or. &
304 size(diams) .ne. n_particles .or. &
305 size(densities) .ne. n_particles)
then
306 call neko_error(
"lpt coordinates, velocities, diameters " // &
307 "and densities must describe the same number of " // &
311 allocate(vels(
size(coords)))
312 allocate(diams(n_particles))
313 allocate(densities(n_particles))
330 call this%particles%init(x%x, y%x, z%x, this%time_order, u%x, v%x, &
331 w%x, diams, densities)
335 deallocate(densities)
338 else if (json%valid_path(
"points_file"))
then
339 call this%read_particles_csv(json)
341 call neko_error(
"lpt requires either coordinates or points_file")
346 end subroutine read_particles_json
350 subroutine read_particles_csv(this, json)
351 class(lpt_t),
intent(inout) :: this
352 type(json_file),
intent(inout) :: json
353 character(len=:),
allocatable :: points_file
357 real(kind=
rp),
allocatable :: diams(:)
358 real(kind=
rp),
allocatable :: densities(:)
359 integer :: n_particles, ind_basic(3), ind_inertia(6)
363 call json_get(json,
"points_file", points_file)
364 call file_in%init(trim(points_file))
366 select type (ft => file_in%file_type)
368 if (this%inertia)
then
369 call mat_in%init(ft%count_lines(), 8)
371 n_particles = mat_in%get_nrows()
390 diams = mat_in%x(:, 7)
391 densities = mat_in%x(:, 8)
392 call this%particles%init(x%x, y%x, z%x, this%time_order, u%x, v%x, &
393 w%x, diams, densities)
395 deallocate(densities)
398 call mat_in%init(ft%count_lines(), 3)
400 n_particles = mat_in%get_nrows()
402 n_particles, .false.)
404 n_particles, .false.)
406 n_particles, .false.)
410 call this%particles%init(x%x, y%x, z%x, this%time_order)
414 call neko_error(
"lpt points_file must be a csv file")
418 end subroutine read_particles_csv
424 subroutine evaluate_velocity(this, u_fluid, v_fluid, w_fluid)
425 class(lpt_t),
intent(inout) :: this
426 type(
vector_t),
intent(inout) :: u_fluid, v_fluid, w_fluid
427 logical :: do_interp_on_host
429 if (this%particles%n .eq. 0)
return
431 do_interp_on_host = .false.
432 call this%global_interp%evaluate(u_fluid%x, this%u_field%x, &
434 call this%global_interp%evaluate(v_fluid%x, this%v_field%x, &
436 call this%global_interp%evaluate(w_fluid%x, this%w_field%x, &
439 end subroutine evaluate_velocity
448 subroutine evaluate_acceleration(this, acc_x, acc_y, acc_z, &
449 u_fluid, v_fluid, w_fluid)
450 class(lpt_t),
intent(inout) :: this
451 type(
vector_t),
intent(in) :: u_fluid, v_fluid, w_fluid
452 type(
vector_t),
intent(inout) :: acc_x, acc_y, acc_z
453 type(
vector_t),
pointer :: tau_p, Re_p, f, rho_fluid_local
454 type(
vector_t),
pointer :: mu_fluid_local, nu_fluid_local
458 logical :: do_interp_on_host
460 if (this%particles%n .eq. 0)
return
476 do_interp_on_host = .false.
477 call this%global_interp%evaluate(mu_fluid_local%x, this%mu_fluid%x, &
479 call this%global_interp%evaluate(rho_fluid_local%x, this%rho_fluid%x, &
493 nu_fluid_local => mu_fluid_local
500 call vector_vdot3(re_p, acc_x, acc_y, acc_z, acc_x, acc_y, acc_z)
520 end subroutine evaluate_acceleration
523 subroutine update_current_rhs(this)
524 class(lpt_t),
intent(inout) :: this
525 type(
vector_t),
pointer :: u_fluid, v_fluid, w_fluid
530 call this%migration%migrate_particles(this%global_interp, &
531 this%periodic_bc, this%inertia, this%particles)
534 this%particles%n, .false.)
536 this%particles%n, .false.)
538 this%particles%n, .false.)
540 call this%evaluate_velocity(u_fluid, v_fluid, w_fluid)
542 if (this%inertia)
then
543 call this%evaluate_acceleration(this%particles%acc_x, &
544 this%particles%acc_y, this%particles%acc_z, &
545 u_fluid, v_fluid, w_fluid)
547 this%particles%u = u_fluid
548 this%particles%v = v_fluid
549 this%particles%w = w_fluid
555 end subroutine update_current_rhs
561 subroutine update_lags(lag, laglag, new_values)
562 type(
vector_t),
intent(inout) :: lag, laglag
563 type(
vector_t),
intent(in) :: new_values
568 end subroutine update_lags
572 subroutine lpt_preprocess(this, time)
573 class(lpt_t),
intent(inout) :: this
575 type(
vector_t),
pointer :: x_old, y_old, z_old, u_old, v_old, w_old
578 associate(x => this%particles%x, y => this%particles%y, &
579 z => this%particles%z, u => this%particles%u, &
580 v => this%particles%v, w => this%particles%w, &
581 acc_x => this%particles%acc_x, &
582 acc_y => this%particles%acc_y, &
583 acc_z => this%particles%acc_z, &
584 u_lag => this%particles%u_lag, &
585 v_lag => this%particles%v_lag, &
586 w_lag => this%particles%w_lag, &
587 u_laglag => this%particles%u_laglag, &
588 v_laglag => this%particles%v_laglag, &
589 w_laglag => this%particles%w_laglag, &
590 acc_xlag => this%particles%acc_xlag, &
591 acc_ylag => this%particles%acc_ylag, &
592 acc_zlag => this%particles%acc_zlag, &
593 acc_xlaglag => this%particles%acc_xlaglag, &
594 acc_ylaglag => this%particles%acc_ylaglag, &
595 acc_zlaglag => this%particles%acc_zlaglag, &
596 n => this%particles%n)
597 if (time%t .lt. this%start_time)
return
598 call this%sync_time_controller(time)
599 if (abs(this%lpt_time%dt) .le. epsilon(1.0_rp))
return
618 if (this%inertia)
then
619 call this%ODE_integrate_ab_3c(u, v, w, acc_x, acc_y, acc_z, &
620 acc_xlag, acc_ylag, acc_zlag, acc_xlaglag, acc_ylaglag, &
626 call this%ODE_integrate_ab_3c(x, y, z, u_old, v_old, w_old, &
627 u_lag, v_lag, w_lag, u_laglag, v_laglag, w_laglag, n)
630 if (this%inertia .and. this%elastic_wall_enabled)
then
631 call lpt_handle_elastic_wall_collisions(this, x_old, y_old, z_old, &
636 if (this%lag_len .gt. 0)
then
637 call update_lags(u_lag, u_laglag, u_old)
638 call update_lags(v_lag, v_laglag, v_old)
639 call update_lags(w_lag, w_laglag, w_old)
640 if (this%inertia)
then
641 call update_lags(acc_xlag, acc_xlaglag, acc_x)
642 call update_lags(acc_ylag, acc_ylaglag, acc_y)
643 call update_lags(acc_zlag, acc_zlaglag, acc_z)
645 this%history_len = min(this%history_len + 1, this%lag_len)
654 end subroutine lpt_preprocess
658 subroutine lpt_compute(this, time)
659 class(lpt_t),
intent(inout) :: this
660 type(time_state_t),
intent(in) :: time
662 if (time%t .lt. this%start_time)
return
664 call this%update_current_rhs()
666 if (this%output_enabled)
then
667 if (this%output_controller%check(time))
then
668 call this%write_output(time)
669 call this%output_controller%register_execution()
672 end subroutine lpt_compute
676 subroutine sync_time_controller(this, time)
677 class(lpt_t),
intent(inout) :: this
678 type(time_state_t),
intent(in) :: time
679 real(kind=rp) :: dt_local
680 real(kind=rp) :: t_ref
683 if (.not. this%lpt_time_initialized)
then
686 if (this%start_time .gt. time%t) t_ref = this%start_time
687 this%lpt_time%t = t_ref
688 this%lpt_time%tlag = t_ref
689 this%lpt_time%dt = 0.0_rp
690 this%lpt_time%dtlag = 0.0_rp
691 this%lpt_time_initialized = .true.
695 dt_local = time%t - this%lpt_time%t
696 if (abs(dt_local) .le. epsilon(1.0_rp))
then
697 this%lpt_time%t = time%t
698 this%lpt_time%tstep = time%tstep
699 this%lpt_time%dt = 0.0_rp
703 do i =
size(this%lpt_time%dtlag), 2, -1
704 this%lpt_time%dtlag(i) = this%lpt_time%dtlag(i - 1)
705 this%lpt_time%tlag(i) = this%lpt_time%tlag(i - 1)
707 this%lpt_time%dtlag(1) = this%lpt_time%dt
708 this%lpt_time%tlag(1) = this%lpt_time%t
709 this%lpt_time%dt = dt_local
710 this%lpt_time%t = time%t
711 this%lpt_time%tstep = time%tstep
712 end subroutine sync_time_controller
719 subroutine ode_integrate_ab_3c(this, sol_x, sol_y, sol_z, &
720 rhs_x, rhs_y, rhs_z, rhs_xlag, rhs_ylag, rhs_zlag, &
721 rhs_xlaglag, rhs_ylaglag, rhs_zlaglag, n)
722 class(lpt_t),
intent(inout) :: this
723 type(vector_t),
intent(inout) :: sol_x, sol_y, sol_z
724 type(vector_t),
intent(in) :: rhs_x, rhs_y, rhs_z
725 type(vector_t),
intent(in) :: rhs_xlag, rhs_ylag, rhs_zlag
726 type(vector_t),
intent(in) :: rhs_xlaglag, rhs_ylaglag
727 type(vector_t),
intent(in) :: rhs_zlaglag
728 integer,
intent(in) :: n
729 type(ab_time_scheme_t) :: ab_scheme
730 real(kind=rp) :: ab_coeffs(4), dt_history(10)
738 nadv = this%time_order
739 nadv = min(nadv, this%history_len + 1)
742 dt_history(1) = this%lpt_time%dt
743 dt_history(2) = this%lpt_time%dtlag(1)
744 dt_history(3) = this%lpt_time%dtlag(2)
745 call ab_scheme%compute_coeffs(ab_coeffs, dt_history, nadv)
748 dtc = this%lpt_time%dt * ab_coeffs(1)
750 call vector_add2s2(sol_x, rhs_x, dtc, n)
751 call vector_add2s2(sol_y, rhs_y, dtc, n)
752 call vector_add2s2(sol_z, rhs_z, dtc, n)
754 if (nadv .ge. 2)
then
755 dtc = this%lpt_time%dt * ab_coeffs(2)
756 call vector_add2s2(sol_x, rhs_xlag, dtc, n)
757 call vector_add2s2(sol_y, rhs_ylag, dtc, n)
758 call vector_add2s2(sol_z, rhs_zlag, dtc, n)
761 if (nadv .ge. 3)
then
762 dtc = this%lpt_time%dt * ab_coeffs(3)
763 call vector_add2s2(sol_x, rhs_xlaglag, dtc, n)
764 call vector_add2s2(sol_y, rhs_ylaglag, dtc, n)
765 call vector_add2s2(sol_z, rhs_zlaglag, dtc, n)
768 end subroutine ode_integrate_ab_3c
772 subroutine write_output(this, time)
773 class(lpt_t),
intent(inout) :: this
774 type(time_state_t),
intent(in) :: time
775 real(kind=rp),
allocatable :: local_data(:,:)
780 n_local = this%particles%n
782 call this%particles%device_sync(device_to_host)
784 if (this%inertia)
then
789 allocate(local_data(n_data, n_local))
791 local_data(1,i) =
real(time%tstep, rp)
792 local_data(2,i) = time%t
793 local_data(3,i) =
real(this%particles%ids(i), rp)
794 local_data(4,i) = this%particles%x%x(i)
795 local_data(5,i) = this%particles%y%x(i)
796 local_data(6,i) = this%particles%z%x(i)
797 local_data(7,i) = this%particles%u%x(i)
798 local_data(8,i) = this%particles%v%x(i)
799 local_data(9,i) = this%particles%w%x(i)
800 if (this%inertia)
then
801 local_data(10,i) = this%particles%d%x(i)
802 local_data(11,i) = this%particles%rho%x(i)
806 call this%output%write(local_data, n_local)
807 deallocate(local_data)
808 end subroutine write_output
811 subroutine lpt_free(this)
812 class(lpt_t),
intent(inout) :: this
814 call this%particles%free()
815 call this%global_interp%free()
816 call this%periodic_bc%free()
817 call this%migration%free()
818 call this%output%free()
819 call this%output_controller%free()
821 this%u_field => null()
822 this%v_field => null()
823 this%w_field => null()
827 if (
allocated(this%wall_zone_indices))
deallocate(this%wall_zone_indices)
828 if (
allocated(this%wall_facet_mask))
deallocate(this%wall_facet_mask)
829 this%elastic_wall_enabled = .false.
830 this%output_enabled = .false.
832 this%start_time = -huge(0.0_rp)
834 if (
allocated(this%name))
deallocate(this%name)
835 call this%lpt_time%reset()
836 this%lpt_time_initialized = .false.
837 end subroutine lpt_free
840 subroutine log_status(this)
841 class(lpt_t),
intent(in) :: this
842 character(len=LOG_SIZE) :: log_buf
844 if (.not. this%log)
return
846 call neko_log%section(
"Lagrangian particle tracking")
847 write(log_buf,
'(A,A)')
"Name: ", trim(this%name)
848 call neko_log%message(log_buf)
849 write(log_buf,
'(A,I0)')
"Global seeded particles: ", &
850 this%particles%n_global
851 call neko_log%message(log_buf)
852 if (this%periodic_bc%periodic_enabled)
then
853 write(log_buf,
'(A,I0)')
"Periodic wrap directions: ", &
854 this%periodic_bc%n_periodic_dirs
855 call neko_log%message(log_buf)
857 if (this%periodic_bc%rotational_periodic_enabled)
then
858 write(log_buf,
'(A,3(ES13.5,A),ES13.5)') &
859 "Rotational periodic sector: theta_min = ", &
860 this%periodic_bc%rotational_theta_min,
", theta_max = ", &
861 this%periodic_bc%rotational_theta_max,
", theta_len = ", &
862 this%periodic_bc%rotational_theta_len,
""
863 call neko_log%message(log_buf)
865 if (this%elastic_wall_enabled)
then
866 write(log_buf,
'(A,I0)')
"Elastic wall zones configured: ", &
867 size(this%wall_zone_indices)
868 call neko_log%message(log_buf)
870 write(log_buf,
'(A,I0)')
"Local particles on rank 0 at init: ", &
872 if (pe_rank .eq. 0)
call neko_log%message(log_buf)
873 call neko_log%end_section()
874 end subroutine log_status
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.
Adam-Bashforth scheme for time integration.
Defines a simulation case.
integer, public pe_rank
MPI rank.
File format for .csv files, used for any read/write operations involving floating point data.
Device abstraction, common interface for various accelerators.
integer, parameter, public device_to_host
Defines a mapping of the degrees of freedom.
Module for file I/O operations.
Implements global_interpolation given a dofmap.
Module containing host-only array type.
Utilities for retrieving parameters from the case files.
subroutine, public json_get_subdict_or_empty(json, key, output)
Extract a sub-object from a json object and returns an empty object if the key is missing.
type(log_t), public neko_log
Global log stream.
integer, parameter, public log_size
Particle redistribution support for LPT.
integer, parameter, public lpt_migrate_to_owner
integer, parameter, public lpt_migrate_none
Output support for Lagrangian particle tracking.
Periodic and cyclic boundary-condition support for LPT.
Implements lpt_t. (Lagrangian Particle Tracking)
subroutine lpt_compute(this, time)
Refresh particle/fluid coupling after the fluid step and emit output.
subroutine lpt_init_from_json(this, json, case)
Build a mask of elastic wall facets from configured mesh zone ids.
subroutine evaluate_velocity(this, u_fluid, v_fluid, w_fluid)
Interpolate the carrier velocity at the local particles.
subroutine lpt_free(this)
Free all LPT-owned state and reset pointers/flags.
subroutine log_status(this)
Emit a setup summary for the configured LPT instance.
subroutine ode_integrate_ab_3c(this, sol_x, sol_y, sol_z, rhs_x, rhs_y, rhs_z, rhs_xlag, rhs_ylag, rhs_zlag, rhs_xlaglag, rhs_ylaglag, rhs_zlaglag, n)
Advance a three-component state with variable-step Adams-Bashforth.
subroutine, private update_lags(lag, laglag, new_values)
Shift one particle history level and store new current values.
subroutine write_output(this, time)
Write one trajectory snapshot.
subroutine read_particles_csv(this, json)
Read particle data from a CSV file and initialise particles on rank 0.
subroutine update_current_rhs(this)
Refresh particle RHS values using the current fluid solution.
subroutine sync_time_controller(this, time)
Build an LPT-local time-step history from the times at which LPT runs.
subroutine read_particles_json(this, json)
Read particle data from JSON and initialise particles on rank 0.
subroutine evaluate_acceleration(this, acc_x, acc_y, acc_z, u_fluid, v_fluid, w_fluid)
Estimate particle acceleration from local carrier-fluid velocity.
subroutine lpt_preprocess(this, time)
Advance particle positions and, for inertial particles, velocities.
integer, parameter, public rp
Global precision used in computations.
Implements output_controller_t
Defines a collection of Lagrangian particles.
subroutine, public profiler_start_region(name, region_id)
Started a named (name) profiler region.
subroutine, public profiler_end_region(name, region_id)
End the most recently started profiler region.
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.
Contains the time_based_controller_t type.
Module with things related to the simulation time.
subroutine, public vector_vdot3(dot, u1, u2, u3, v1, v2, v3, n)
Compute a dot product (3-d version) assuming vector components etc.
subroutine, public vector_sub3(a, b, c, n)
Vector subtraction .
subroutine, public vector_power(ap, a, p, n)
Take the power of a vector .
subroutine, public vector_cmult(a, c, n)
Multiplication by constant c .
subroutine, public vector_col2(a, b, n)
Vector multiplication .
subroutine, public vector_cfill(a, c, n)
Set all elements to a constant c .
subroutine, public vector_invcol2(a, b, n)
Vector division .
subroutine, public vector_sqrt_inplace(a, n)
Sqrt a vector .
subroutine, public vector_cadd(a, s, n)
Add a scalar to vector .
subroutine, public vector_add2s2(a, b, c1, n)
Vector addition with scalar multiplication (multiplication on second argument)
subroutine, public vector_cmult2(a, b, c, n)
Multiplication by constant c .
subroutine, public vector_col3(a, b, c, n)
Vector multiplication with 3 vectors .
Explicit Adam-Bashforth scheme for time integration.
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...
Implements global interpolation for arbitrary points in the domain.
Host-only temporary array.
Passive Lagrangian particle tracking.
Particle positions, velocities, properties, and time-history data.
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.