-
Notifications
You must be signed in to change notification settings - Fork 112
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
WIP: p4est solver on a spherical shell #1749
Changes from 14 commits
02a35e5
7be12aa
27f1a81
d23b56c
9338d51
b4d0bec
1eb17ac
e180aa4
2d6fc29
37a9afb
3715ea8
b30fe7d
2942c79
b89e333
78436f1
1521e8e
78bdbfd
a18fcd6
d2b5294
245b20d
32b6836
d959d77
500db95
2e2f68e
b3c3fa3
0205203
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
|
||
using OrdinaryDiffEq | ||
using Trixi | ||
|
||
############################################################################### | ||
# semidiscretization of the linear advection equation | ||
|
||
equations = CompressibleEulerEquations3D(1.4) | ||
|
||
# Create DG solver with polynomial degree = 3 and (local) Lax-Friedrichs/Rusanov flux as surface flux | ||
polydeg = 3 | ||
solver = DGSEM(polydeg = polydeg, surface_flux = flux_lax_friedrichs) | ||
|
||
# Initial condition for a Gaussian density profile with constant pressure | ||
# and the velocity of a rotating solid body | ||
function initial_condition_advection_sphere(x, t, equations::CompressibleEulerEquations3D) | ||
# Gaussian density | ||
rho = 1.0 + exp(-20 * (x[1]^2 + x[3]^2)) | ||
# Constant pressure | ||
p = 1.0 | ||
|
||
# Spherical coordinates for the point x | ||
if sign(x[2]) == 0.0 | ||
signy = 1.0 | ||
else | ||
signy = sign(x[2]) | ||
end | ||
# Co-latitude | ||
colat = acos(x[3] / sqrt(x[1]^2 + x[2]^2 + x[3]^2)) | ||
# Latitude (auxiliary variable) | ||
lat = -colat + 0.5 * pi | ||
# Longitude | ||
r_xy = sqrt(x[1]^2 + x[2]^2) | ||
if r_xy == 0.0 | ||
phi = pi / 2 | ||
else | ||
phi = signy * acos(x[1] / r_xy) | ||
end | ||
|
||
# Compute the velocity of a rotating solid body | ||
# (alpha is the angle between the rotation axis and the polar axis of the spherical coordinate system) | ||
v0 = 1.0 # Velocity at the "equator" | ||
alpha = 0.0 #pi / 4 | ||
v_long = v0 * (cos(lat) * cos(alpha) + sin(lat) * cos(phi) * sin(alpha)) | ||
v_lat = -v0 * sin(phi) * sin(alpha) | ||
|
||
# Transform to Cartesian coordinate system | ||
v1 = -cos(colat) * cos(phi) * v_lat - sin(phi) * v_long | ||
v2 = -cos(colat) * sin(phi) * v_lat + cos(phi) * v_long | ||
v3 = sin(colat) * v_lat | ||
|
||
return prim2cons(SVector(rho, v1, v2, v3, p), equations) | ||
end | ||
|
||
# Source term function to transform the Euler equations into the linear advection equations with variable advection velocity | ||
function source_terms_convert_to_linear_advection(u, du, x, t, | ||
equations::CompressibleEulerEquations3D) | ||
v1 = u[2] / u[1] | ||
v2 = u[3] / u[1] | ||
v3 = u[4] / u[1] | ||
|
||
s2 = du[1] * v1 - du[2] | ||
s3 = du[1] * v2 - du[3] | ||
s4 = du[1] * v3 - du[4] | ||
s5 = 0.5 * (s2 * v1 + s3 * v2 + s4 * v3) - du[5] | ||
|
||
return SVector(0.0, s2, s3, s4, s5) | ||
end | ||
|
||
initial_condition = initial_condition_advection_sphere | ||
|
||
mesh = Trixi.P4estMeshCubedSphere2D(5, 1.0, polydeg = polydeg, initial_refinement_level = 0) | ||
|
||
# A semidiscretization collects data structures and functions for the spatial discretization | ||
semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition, solver, | ||
source_terms = source_terms_convert_to_linear_advection) | ||
|
||
############################################################################### | ||
# ODE solvers, callbacks etc. | ||
|
||
# Create ODE problem with time span from 0.0 to π | ||
tspan = (0.0, pi) | ||
ode = semidiscretize(semi, tspan) | ||
|
||
# At the beginning of the main loop, the SummaryCallback prints a summary of the simulation setup | ||
# and resets the timers | ||
summary_callback = SummaryCallback() | ||
|
||
# The AnalysisCallback allows to analyse the solution in regular intervals and prints the results | ||
analysis_callback = AnalysisCallback(semi, interval = 10, | ||
save_analysis = true, | ||
extra_analysis_integrals = (Trixi.density,)) | ||
|
||
# The SaveSolutionCallback allows to save the solution to a file in regular intervals | ||
save_solution = SaveSolutionCallback(interval = 10, | ||
solution_variables = cons2prim) | ||
|
||
# The StepsizeCallback handles the re-calculation of the maximum Δt after each time step | ||
stepsize_callback = StepsizeCallback(cfl = 0.7) | ||
|
||
# Create a CallbackSet to collect all callbacks such that they can be passed to the ODE solver | ||
callbacks = CallbackSet(summary_callback, analysis_callback, save_solution, | ||
stepsize_callback) | ||
|
||
############################################################################### | ||
# run the simulation | ||
|
||
# OrdinaryDiffEq's `solve` method evolves the solution in time and executes the passed callbacks | ||
sol = solve(ode, CarpenterKennedy2N54(williamson_condition = false), | ||
dt = 1.0, # solve needs some value here but it will be overwritten by the stepsize_callback | ||
save_everystep = false, callback = callbacks); | ||
|
||
# Print the timer summary | ||
summary_callback() |
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
@@ -22,9 +22,10 @@ function create_cache(mesh::StructuredMesh, equations::AbstractEquations, dg::DG | |||||||||
end | ||||||||||
|
||||||||||
# Extract contravariant vector Ja^i (i = index) as SVector | ||||||||||
# TODO: Here, size() causes a lot of allocations! Find an alternative to improve performance | ||||||||||
@inline function get_contravariant_vector(index, contravariant_vectors, indices...) | ||||||||||
SVector(ntuple(@inline(dim->contravariant_vectors[dim, index, indices...]), | ||||||||||
Val(ndims(contravariant_vectors) - 3))) | ||||||||||
Val(size(contravariant_vectors, 1)))) | ||||||||||
end | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This new version of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this code only called from your code or also from existing routines? In the current implementation it is not type stable, thus the allocations. We might get around it easily if it is only used from code you control, and harder (but not impossible) if it is in generic routines as well. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No, this is called in the existing volume and surface integral routines. In fact, I temporarily changed the existing volume integral calls, such that the code runs a bit faster. See, e.g., Trixi.jl/src/solvers/dgsem_structured/dg_2d.jl Lines 78 to 81 in b89e333
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hm. I wonder if what you are doing in this PR is fundamental enough of a conceptual difference to require a new mesh type. That is, to not try to shoehorn this into There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Alternatively, we may need to pass an additional argument to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. True. The question is whether the mesh truly "owns" the dimensionality of a problem. But it would certainly be less intrusive than adding a new mesh type. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Well, it looks like there isn't anything like "the dimensionality of a problem" anymore. We need to distinguish between the dimensionality of the geometry and the equations. From my point of view, the contravariant vectors are clearly associated with the geometry, i.e., the However, this is really a tough problem since we want to pass the contravariant vectors as normal directions to the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Exactly!
For the first and last cases, For this particular function, we would actually need to pass the number of dimensions of the equation to define the size of the SVector... Or maybe there is a workaround. 🤔 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
This function is mesh type agnostic, so that won't fix this particular problem. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In amrueda#12, I propose a workaround to this problem using a new type that extends |
||||||||||
|
||||||||||
@inline function calc_boundary_flux_by_direction!(surface_flux_values, u, t, | ||||||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I removed this check because the new implementation requires a 2D mesh (
P4estMesh{2}
) with a 3D equation. Should I just remove this line or maybe change the check?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a good question. I think we should analyze where we use this kind of assumption and try to get it right. For example, I guess everything will fail badly if you use an
UnstructuredMesh2D
with a 3D equation, won't it?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it will fail. We would need special constructors that create those meshes using nodes with three (x, y, z) node coordinates, and we would then need to adjust the metric term computation of all mesh types. It is doable but I think it is out of the scope of the present PR and probably no one will ever use it 🤣.
Then maybe I just check for the particular case of a
P4estMesh2D
with 3D node coordinates in combination with a 3D equation, allow that combination and bring back the@assert
for any other case. Does that sound like a good solution?