Skip to content

Commit 821260d

Browse files
LasNikasLasNikassvchbefaulhaber
authored
Add dvdu_ode vector to custom_quantities (#879)
* add dvu_ode vector to custom quantities * add for fluid and boundary * fix tests * fix tests * Rename 'tlsph' to 'place_on_shell' (#814) * rename * format * forgot some * format * naming * forgot some more * fix test * incorporate review comments * format --------- Co-authored-by: Niklas Neher <73897120+LasNikas@users.noreply.github.com> * Rename 'tlsph' to 'place_on_shell' (#814) * rename * format * forgot some * format * naming * forgot some more * fix test * incorporate review comments * format --------- Co-authored-by: Niklas Neher <73897120+LasNikas@users.noreply.github.com> * Combine PST and TVF into a unified framework (#884) * Combine PST and TVF into a unified framework * Require update callback for PST * Fix WCSPH * Update PST only in callback * Fix EDAC * Update docs * Fix alle example files * Fix tests * Fix periodic channel * Fix docs * Update news * Fix tests * Fix example file * Rename 'tlsph' to 'place_on_shell' (#814) * rename * format * forgot some * format * naming * forgot some more * fix test * incorporate review comments * format --------- Co-authored-by: Niklas Neher <73897120+LasNikas@users.noreply.github.com> * Combine PST and TVF into a unified framework (#884) * Combine PST and TVF into a unified framework * Require update callback for PST * Fix WCSPH * Update PST only in callback * Fix EDAC * Update docs * Fix alle example files * Fix tests * Fix periodic channel * Fix docs * Update news * Fix tests * Fix example file * fix tests * fix doctests * implement suggestions * fix tests * fix tests * implement suggestions * fix * fix --------- Co-authored-by: LasNikas <niklas.nehe@web.de> Co-authored-by: Sven Berger <berger.sven@gmail.com> Co-authored-by: Erik Faulhaber <44124897+efaulhaber@users.noreply.github.com>
1 parent 34c6c19 commit 821260d

19 files changed

Lines changed: 150 additions & 94 deletions

File tree

examples/postprocessing/interpolation_plane.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,10 +104,10 @@ combined_plot = Plots.plot(plot1, plot2, plot3, plot_3d, layout=(2, 2),
104104
size=(1000, 1500), margin=3mm)
105105

106106
# If we want to save planes at regular intervals, we can use the postprocessing callback.
107-
# Note that the arguments `system, v_ode, u_ode, semi, t` are more powerful than the
107+
# Note that the arguments `system, dv_ode, du_ode, v_ode, u_ode, semi, t` are more powerful than the
108108
# documented arguments `system, data, t`, allowing us to use interpolation (which requires
109109
# a semidiscretization).
110-
function save_interpolated_plane(system, v_ode, u_ode, semi, t)
110+
function save_interpolated_plane(system, dv_ode, du_ode, v_ode, u_ode, semi, t)
111111
# Size of the patch to be interpolated
112112
interpolation_start = [0.0, 0.0]
113113
interpolation_end = [tank_size[1], tank_size[2]]

examples/postprocessing/postprocessing.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@ using CSV
1313
using DataFrames
1414
using JSON
1515

16-
# Any custom function with the arguments `v, u, t, system` can be passed to the callback
16+
# Any custom function with the arguments `system, data, t` can be passed to the callback
1717
# to be called every 10th timestep. See example below:
18-
function hello(system, v_ode, u_ode, semi, t)
18+
function hello(system, data, t)
1919
# Will write "hello" and the current simulation time
2020
println("hello at ", t)
2121

src/TrixiParticles.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ using ReadVTK: ReadVTK
2323
using RecipesBase: RecipesBase, @series
2424
using Random: seed!
2525
using SciMLBase: CallbackSet, DiscreteCallback, DynamicalODEProblem, u_modified!,
26-
get_tmp_cache, set_proposed_dt!, ODESolution, ODEProblem, terminate!
26+
get_tmp_cache, set_proposed_dt!, ODESolution, ODEProblem, terminate!,
27+
get_du
2728
@reexport using StaticArrays: SVector
2829
using StaticArrays: @SMatrix, SMatrix, setindex
2930
using StrideArrays: PtrArray, StaticInt

src/callbacks/post_process.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,7 @@ end
229229
# `affect!`
230230
function (pp::PostprocessCallback)(integrator)
231231
@trixi_timeit timer() "apply postprocess cb" begin
232+
dv_ode, du_ode = get_du(integrator).x
232233
vu_ode = integrator.u
233234
v_ode, u_ode = vu_ode.x
234235
semi = integrator.p
@@ -251,7 +252,7 @@ function (pp::PostprocessCallback)(integrator)
251252
system_index = system_indices(system, semi)
252253

253254
for (key, f) in pp.func
254-
result = custom_quantity(f, system, v_ode, u_ode, semi, t)
255+
result = custom_quantity(f, system, dv_ode, du_ode, v_ode, u_ode, semi, t)
255256
if result !== nothing
256257
add_entry!(pp, string(key), t, result, filenames[system_index])
257258
new_data = true

src/callbacks/solution_saving.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ function (solution_callback::SolutionSavingCallback)(integrator)
154154
(; interval, output_directory, custom_quantities, write_meta_data, git_hash,
155155
verbose, prefix, latest_saved_iter, max_coordinates) = solution_callback
156156

157+
dvdu_ode = get_du(integrator)
157158
vu_ode = integrator.u
158159
semi = integrator.p
159160
iter = get_iter(interval, integrator)
@@ -173,7 +174,7 @@ function (solution_callback::SolutionSavingCallback)(integrator)
173174
println("Writing solution to $output_directory at t = $(integrator.t)")
174175
end
175176

176-
@trixi_timeit timer() "save solution" trixi2vtk(vu_ode, semi, integrator.t;
177+
@trixi_timeit timer() "save solution" trixi2vtk(dvdu_ode, vu_ode, semi, integrator.t;
177178
iter, output_directory, prefix,
178179
write_meta_data, git_hash=git_hash[],
179180
max_coordinates, custom_quantities...)

src/callbacks/steady_state_reached.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,11 +131,12 @@ end
131131

132132
vu_ode = integrator.u
133133
v_ode, u_ode = vu_ode.x
134+
dv_ode, du_ode = get_du(integrator).x
134135
semi = integrator.p
135136

136137
# Calculate kinetic energy
137138
ekin = sum(semi.systems) do system
138-
return kinetic_energy(system, v_ode, u_ode, semi, 0)
139+
return kinetic_energy(system, dv_ode, du_ode, v_ode, u_ode, semi, 0)
139140
end
140141

141142
if length(previous_ekin) == interval_size

src/general/custom_quantities.jl

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
44
Returns the total kinetic energy of all particles in a system.
55
"""
6-
function kinetic_energy(system, v_ode, u_ode, semi, t)
6+
function kinetic_energy(system, dv_ode, du_ode, v_ode, u_ode, semi, t)
77
v = wrap_v(v_ode, system, semi)
88

99
# TODO: `current_velocity` should only contain active particles
@@ -17,18 +17,20 @@ function kinetic_energy(system, v_ode, u_ode, semi, t)
1717
end
1818
end
1919

20-
kinetic_energy(system::BoundarySystem, v_ode, u_ode, semi, t) = zero(eltype(system))
20+
function kinetic_energy(system::BoundarySystem, dv_ode, du_ode, v_ode, u_ode, semi, t)
21+
return zero(eltype(system))
22+
end
2123

2224
"""
2325
total_mass
2426
2527
Returns the total mass of all particles in a system.
2628
"""
27-
function total_mass(system, v_ode, u_ode, semi, t)
29+
function total_mass(system, dv_ode, du_ode, v_ode, u_ode, semi, t)
2830
return sum(system.mass)
2931
end
3032

31-
function total_mass(system::BoundarySystem, v_ode, u_ode, semi, t)
33+
function total_mass(system::BoundarySystem, dv_ode, du_ode, v_ode, u_ode, semi, t)
3234
# It does not make sense to return a mass for boundary systems.
3335
# The material density and therefore the physical mass of the boundary is not relevant
3436
# when simulating a solid, stationary wall. The boundary always behaves as if it had
@@ -47,12 +49,12 @@ end
4749
4850
Returns the maximum pressure over all particles in a system.
4951
"""
50-
function max_pressure(system::FluidSystem, v_ode, u_ode, semi, t)
52+
function max_pressure(system::FluidSystem, dv_ode, du_ode, v_ode, u_ode, semi, t)
5153
v = wrap_v(v_ode, system, semi)
5254
return maximum(current_pressure(v, system))
5355
end
5456

55-
function max_pressure(system, v_ode, u_ode, semi, t)
57+
function max_pressure(system, dv_ode, du_ode, v_ode, u_ode, semi, t)
5658
return NaN
5759
end
5860

@@ -61,12 +63,12 @@ end
6163
6264
Returns the minimum pressure over all particles in a system.
6365
"""
64-
function min_pressure(system::FluidSystem, v_ode, u_ode, semi, t)
66+
function min_pressure(system::FluidSystem, dv_ode, du_ode, v_ode, u_ode, semi, t)
6567
v = wrap_v(v_ode, system, semi)
6668
return minimum(current_pressure(v, system))
6769
end
6870

69-
function min_pressure(system, v_ode, u_ode, semi, t)
71+
function min_pressure(system, dv_ode, du_ode, v_ode, u_ode, semi, t)
7072
return NaN
7173
end
7274

@@ -75,13 +77,13 @@ end
7577
7678
Returns the average pressure over all particles in a system.
7779
"""
78-
function avg_pressure(system::FluidSystem, v_ode, u_ode, semi, t)
80+
function avg_pressure(system::FluidSystem, dv_ode, du_ode, v_ode, u_ode, semi, t)
7981
v = wrap_v(v_ode, system, semi)
8082
sum_ = sum(current_pressure(v, system))
8183
return sum_ / nparticles(system)
8284
end
8385

84-
function avg_pressure(system, v_ode, u_ode, semi, t)
86+
function avg_pressure(system, dv_ode, du_ode, v_ode, u_ode, semi, t)
8587
return NaN
8688
end
8789

@@ -90,12 +92,12 @@ end
9092
9193
Returns the maximum density over all particles in a system.
9294
"""
93-
function max_density(system::FluidSystem, v_ode, u_ode, semi, t)
95+
function max_density(system::FluidSystem, dv_ode, du_ode, v_ode, u_ode, semi, t)
9496
v = wrap_v(v_ode, system, semi)
9597
return maximum(current_density(v, system))
9698
end
9799

98-
function max_density(system, v_ode, u_ode, semi, t)
100+
function max_density(system, dv_ode, du_ode, v_ode, u_ode, semi, t)
99101
return NaN
100102
end
101103

@@ -104,12 +106,12 @@ end
104106
105107
Returns the minimum density over all particles in a system.
106108
"""
107-
function min_density(system::FluidSystem, v_ode, u_ode, semi, t)
109+
function min_density(system::FluidSystem, dv_ode, du_ode, v_ode, u_ode, semi, t)
108110
v = wrap_v(v_ode, system, semi)
109111
return minimum(current_density(v, system))
110112
end
111113

112-
function min_density(system, v_ode, u_ode, semi, t)
114+
function min_density(system, dv_ode, du_ode, v_ode, u_ode, semi, t)
113115
return NaN
114116
end
115117

@@ -118,12 +120,12 @@ end
118120
119121
Returns the average_density over all particles in a system.
120122
"""
121-
function avg_density(system::FluidSystem, v_ode, u_ode, semi, t)
123+
function avg_density(system::FluidSystem, dv_ode, du_ode, v_ode, u_ode, semi, t)
122124
v = wrap_v(v_ode, system, semi)
123125
sum_ = sum(current_density(v, system))
124126
return sum_ / nparticles(system)
125127
end
126128

127-
function avg_density(system, v_ode, u_ode, semi, t)
129+
function avg_density(system, dv_ode, du_ode, v_ode, u_ode, semi, t)
128130
return NaN
129131
end

src/io/write_vtk.jl

Lines changed: 52 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -48,15 +48,27 @@ trixi2vtk(sol.u[end], semi, 0.0, iter=1, my_custom_quantity=kinetic_energy)
4848
4949
```
5050
"""
51-
function trixi2vtk(vu_ode, semi, t; iter=nothing, output_directory="out", prefix="",
52-
write_meta_data=true, git_hash=compute_git_hash(),
51+
function trixi2vtk(vu_ode, semi, t; iter=nothing, output_directory="out",
52+
prefix="", write_meta_data=true, git_hash=compute_git_hash(),
53+
max_coordinates=Inf, custom_quantities...)
54+
55+
# The first argument is not necessary in most cases. Since it is usually not available to the user,
56+
# this API wrapper makes it optional.
57+
# Note that custom quantities using the fluid acceleration will not work and return NaN acceleration.
58+
return trixi2vtk(fill!(similar(vu_ode), NaN), vu_ode, semi, t; iter, output_directory,
59+
prefix, write_meta_data, git_hash, max_coordinates,
60+
custom_quantities...)
61+
end
62+
63+
function trixi2vtk(dvdu_ode, vu_ode, semi, t; iter=nothing, output_directory="out",
64+
prefix="", write_meta_data=true, git_hash=compute_git_hash(),
5365
max_coordinates=Inf, custom_quantities...)
5466
(; systems) = semi
55-
v_ode, u_ode = vu_ode.x
5667

5768
# Update quantities that are stored in the systems. These quantities (e.g. pressure)
5869
# still have the values from the last stage of the previous step if not updated here.
5970
@trixi_timeit timer() "update systems" begin
71+
v_ode, u_ode = vu_ode.x
6072
# Don't create sub-timers here to avoid cluttering the timer output
6173
@notimeit timer() update_systems_and_nhs(v_ode, u_ode, semi, t)
6274
end
@@ -67,24 +79,26 @@ function trixi2vtk(vu_ode, semi, t; iter=nothing, output_directory="out", prefix
6779
system_index = system_indices(system, semi)
6880
periodic_box = get_neighborhood_search(system, semi).periodic_box
6981

70-
trixi2vtk(system, v_ode, u_ode, semi, t, periodic_box;
82+
trixi2vtk(system, dvdu_ode, vu_ode, semi, t, periodic_box;
7183
system_name=filenames[system_index], output_directory, iter, prefix,
7284
write_meta_data, git_hash, max_coordinates, custom_quantities...)
7385
end
7486
end
7587

7688
# Convert data for a single TrixiParticle system to VTK format
77-
function trixi2vtk(system_, v_ode_, u_ode_, semi_, t, periodic_box; output_directory="out",
78-
prefix="", iter=nothing, system_name=vtkname(system_),
79-
write_meta_data=true, max_coordinates=Inf, git_hash=compute_git_hash(),
80-
custom_quantities...)
89+
function trixi2vtk(system_, dvdu_ode_, vu_ode_, semi_, t, periodic_box;
90+
output_directory="out", prefix="", iter=nothing,
91+
system_name=vtkname(system_), write_meta_data=true, max_coordinates=Inf,
92+
git_hash=compute_git_hash(), custom_quantities...)
8193
mkpath(output_directory)
8294

8395
# Skip empty systems
8496
if nparticles(system_) == 0
8597
return
8698
end
8799

100+
v_ode_, u_ode_ = vu_ode_.x
101+
88102
# Transfer to CPU if data is on the GPU. Do nothing if already on CPU.
89103
v_ode, u_ode, system, semi = transfer2cpu(v_ode_, u_ode_, system_, semi_)
90104

@@ -136,10 +150,16 @@ function trixi2vtk(system_, v_ode_, u_ode_, semi_, t, periodic_box; output_direc
136150
end
137151

138152
# Extract custom quantities for this system
139-
for (key, quantity) in custom_quantities
140-
value = custom_quantity(quantity, system, v_ode, u_ode, semi, t)
141-
if value !== nothing
142-
vtk[string(key)] = value
153+
if !isempty(custom_quantities)
154+
dv_ode, du_ode = dvdu_ode_.x
155+
dv_ode, du_ode = transfer2cpu(dv_ode, du_ode)
156+
157+
for (key, quantity) in custom_quantities
158+
value = custom_quantity(quantity, system, dv_ode, du_ode, v_ode, u_ode,
159+
semi, t)
160+
if value !== nothing
161+
vtk[string(key)] = value
162+
end
143163
end
144164
end
145165

@@ -150,33 +170,45 @@ function trixi2vtk(system_, v_ode_, u_ode_, semi_, t, periodic_box; output_direc
150170
end
151171

152172
function transfer2cpu(v_::AbstractGPUArray, u_, system_, semi_)
153-
v = Adapt.adapt(Array, v_)
154-
u = Adapt.adapt(Array, u_)
155173
semi = Adapt.adapt(Array, semi_)
156174
system_index = system_indices(system_, semi_)
157175
system = semi.systems[system_index]
158176

177+
v, u = transfer2cpu(v_, u_)
178+
159179
return v, u, system, semi
160180
end
161181

162182
function transfer2cpu(v_, u_, system_, semi_)
163183
return v_, u_, system_, semi_
164184
end
165185

166-
function custom_quantity(quantity::AbstractArray, system, v_ode, u_ode, semi, t)
186+
function transfer2cpu(v_::AbstractGPUArray, u_)
187+
v = Adapt.adapt(Array, v_)
188+
u = Adapt.adapt(Array, u_)
189+
190+
return v, u
191+
end
192+
193+
function transfer2cpu(v_, u_)
194+
return v_, u_
195+
end
196+
197+
function custom_quantity(quantity::AbstractArray, system, dv_ode, du_ode, v_ode, u_ode,
198+
semi, t)
167199
return quantity
168200
end
169201

170-
function custom_quantity(quantity, system, v_ode, u_ode, semi, t)
202+
function custom_quantity(quantity, system, dv_ode, du_ode, v_ode, u_ode, semi, t)
171203
# Check if `quantity` is a function of `system`, `v_ode`, `u_ode`, `semi` and `t`
172204
if !isempty(methods(quantity,
173-
(typeof(system), typeof(v_ode), typeof(u_ode),
174-
typeof(semi), typeof(t))))
175-
return quantity(system, v_ode, u_ode, semi, t)
205+
(typeof(system), typeof(dv_ode), typeof(du_ode), typeof(v_ode),
206+
typeof(u_ode), typeof(semi), typeof(t))))
207+
return quantity(system, dv_ode, du_ode, v_ode, u_ode, semi, t)
176208
end
177209

178210
# Assume `quantity` is a function of `data`
179-
data = system_data(system, v_ode, u_ode, semi)
211+
data = system_data(system, dv_ode, du_ode, v_ode, u_ode, semi)
180212
return quantity(system, data, t)
181213
end
182214

src/schemes/boundary/open_boundary/system.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -484,7 +484,7 @@ end
484484
# When the neighbor is an open boundary system, just use the viscosity of the fluid `system` instead
485485
@inline viscosity_model(system, neighbor_system::OpenBoundarySPHSystem) = system.viscosity
486486

487-
function system_data(system::OpenBoundarySPHSystem, v_ode, u_ode, semi)
487+
function system_data(system::OpenBoundarySPHSystem, dv_ode, du_ode, v_ode, u_ode, semi)
488488
v = wrap_v(v_ode, system, semi)
489489
u = wrap_u(u_ode, system, semi)
490490

src/schemes/boundary/system.jl

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -453,23 +453,24 @@ function system_correction(system::BoundarySPHSystem{<:BoundaryModelDummyParticl
453453
return system.boundary_model.correction
454454
end
455455

456-
function system_data(system::BoundarySPHSystem, v_ode, u_ode, semi)
456+
function system_data(system::BoundarySPHSystem, dv_ode, du_ode, v_ode, u_ode, semi)
457+
dv = [current_acceleration(system, particle) for particle in eachparticle(system)]
457458
v = wrap_v(v_ode, system, semi)
458459
u = wrap_u(u_ode, system, semi)
459460

460461
coordinates = current_coordinates(u, system)
461-
velocity = current_velocity(v, system)
462+
velocity = [current_velocity(v, system, particle) for particle in eachparticle(system)]
462463
density = current_density(v, system)
463464
pressure = current_pressure(v, system)
464465

465-
return (; coordinates, velocity, density, pressure)
466+
return (; coordinates, velocity, density, pressure, acceleration=dv)
466467
end
467468

468469
function available_data(::BoundarySPHSystem)
469-
return (:coordinates, :velocity, :density, :pressure)
470+
return (:coordinates, :velocity, :density, :pressure, :acceleration)
470471
end
471472

472-
function system_data(system::BoundaryDEMSystem, v_ode, u_ode, semi)
473+
function system_data(system::BoundaryDEMSystem, dv_ode, du_ode, v_ode, u_ode, semi)
473474
(; coordinates, radius, normal_stiffness) = system
474475

475476
return (; coordinates, radius, normal_stiffness)

0 commit comments

Comments
 (0)