Tutorial: create a case from scratch:
This tutorial guides you through the process of creating a new physical problem from scratch. We will cover the necessary setup and command execution.
Prerequisites
Before starting, ensure you have the following:
- Julia Installation: You need to have Julia installed on your system. You can download it from the official Julia website: https://julialang.org/downloads/
- Jexpresso Repository: The
Jexpresso.jlframework needs to be accessible. This tutorial assumes you have the repository cloned locally. If not, you can clone it using Git:bash git clone https://github.com/smarras79/Jexpresso.gitbash git clone https://github.com/smarras79/JexpressoMeshes.gitbash cd Jexpressobash ln -s ../JexpressoMeshes/meshes .
Creating a New Problem called Hello in Jexpresso/problems/equations/CompEuler/
cd problems/equations/CompEuler- Step2: Create a New Directory for Your Case
mkdir Hello- Step3: Enter the New Case Directory
cd Hello- Step4: Copy Essential Files
Copy the generic solver files from the theta directory into your new case directory. These files provide the basic structure for your simulation.
cp ../theta/*.jl .- Step5: Configure Initial Conditions in initialize.jl
Open the initialize.jl file in a text editor. In this file, you will need to define and initialize the solution array q. The structure of q depends on the dimensionality of your problem and the number of conserved variables (e.g., density, momentum components, energy).
Example of initialization for the 2D Euler equations density (rho), momentum (rho u), and potential temperature
Open initialize.jl: (ex.Jepresso/problems/equations/CompEuler/theta/initialize.jl)
function initialize(SD::NSD_2D,
PT,
mesh::St_mesh,
inputs::Dict,
OUTPUT_DIR::String,
TFloat)Define the solution variables and, optional, the array of output variables.
The length of qvars will define the size of the problem. However, the optional array qoutvars can be longer or shorter and is only used by the output writing function. If qoutvars is not defined, the the default output variables coincide with qvars.
qvars = ["ρ", "ρu", "ρv", "ρθ"]
qoutvars = ["ρ", "u", "w", "θ", "p"]Allocate space for the solution array:
q = define_q(SD,
mesh.nelem,
mesh.npoin,
mesh.ngl,
qvars,
TFloat,
inputs[:backend];
neqs=length(qvars),
qoutvars=qoutvars)Now initialize:
For example, a minimal version of Jepresso/problems/equations/CompEuler/theta/initialize.jl: may looks like this:
if (inputs[:backend] == CPU())
PhysConst = PhysicalConst{Float64}()
xc = 0.0; yc = 2500.0
for ip = 1:mesh.npoin
x, y = mesh.x[ip], mesh.y[ip]
r = sqrt( (x - xc)^2 + (y - yc)^2 )
θ = 300
p = 100000
ρ = 1.25
u = 0.0
v = 0.0
q.qn[ip,1] = ρ
q.qn[ip,2] = ρ*u
q.qn[ip,3] = ρ*v
q.qn[ip,4] = ρ*θ
q.qn[ip,end] = p
end
end
return q
endWARNING: refer to a proper working code rather than the simplified version above. The one above was given as an example of what an initialization file may look like.
Add the fluxes for the equations that you are solving:
If we were to solve the 2D Euler equations of compressible flows with gravity, where q and the fluxes are defined as
\[{\bf q}=\begin{bmatrix} \rho \\ \rho u\\ \rho v\\ \rho \theta \end{bmatrix}\quad {\bf F}1=\begin{bmatrix} \rho u\\ \rho u^2 + p\\ \rho u v\\ \rho u \theta \end{bmatrix}\quad {\bf F}2=\begin{bmatrix} \rho v\\ \rho v u\\ \rho v^2 + p\\ \rho v \theta \end{bmatrix}\quad {\bf S}=\begin{bmatrix} 0\\ 0\\ -\rho g\\ 0 \end{bmatrix}\quad \mu\nabla^2{\bf q}=\mu\begin{bmatrix} 0\\ u_{xx} + u_{zz}\\ v_{xx} + v_{zz}\\ \theta_{xx} + \theta_{zz} \end{bmatrix},\]
then the function user_flux.jl is imply:
function user_flux!(F,
G,
SD::NSD_2D,
q, qe,
mesh::St_mesh,
::CL,
::TOTAL;
neqs=4, ip=1)
PhysConst = PhysicalConst{Float64}()
ρ = q[1]
ρu = q[2]
ρv = q[3]
ρθ = q[4]
θ = ρθ/ρ
u = ρu/ρ
v = ρv/ρ
Pressure = perfectGasLaw_ρθtoP(PhysConst, ρ=ρ, θ=θ)
F[1] = ρu
F[2] = ρu*u .+ Pressure
F[3] = ρv*u
F[4] = ρθ*u
G[1] = ρv
G[2] = ρu*v
G[3] = ρv*v .+ Pressure
G[4] = ρθ*v
endNotice how there are no loops and the F and G are exactly defined as you'd write them on paper.
Add the sources:
Similarly, you handle the source through user_source.jl.
Outouts:
By default, the output is written for the solution variables. Follow the output tutorial here
Now run the new case:
push!(empty!(ARGS), "CompEuler", "Hello");
include("./src/Jexpresso.jl")