GeMotion.jl is a Julia finite-element solver for steady two-dimensional Navier-Stokes-Fourier natural-convection problems with generalized material laws. It is built on Gridap.jl and supports Cartesian Gridap models as well as named-boundary Gmsh meshes through GridapGmsh.jl.
The main entry point is GeMotion.simulate, which solves the coupled velocity,
pressure, and temperature system, then computes derived fields for streamlines,
heatlines, and entropy generation. The examples reproduce and compare against
published benchmark cases for square cavities and concentric annuli.
- Steady coupled Navier-Stokes-Fourier solve for 2D natural convection.
- Newtonian fluids (
n = 1) and regularized power-law fluids (n != 1). - Dimensionless parameters for Prandtl number
Pr, Rayleigh numberRa, and power-law indexn. - Taylor-Hood-like finite-element discretization: second-order velocity and temperature fields with first-order pressure.
- Nonlinear solves through Gridap's
NLSolver, with configurable method, tolerances, line search, and initial guess. - Derived fields written for inspection in ParaView:
velocity
uh, pressureph, temperatureTh, stream functionpsih, heat functionPih, thermal entropySth, and fluid-friction entropySfl. - Plot helpers for unit-square and co-annulus postprocessing with CairoMakie.
GeMotion.jl is currently intended to be used from a source checkout.
git clone git@github.com:lamBOOO/GeMotion.jl.git
cd GeMotion.jl
git lfs pull
julia --project -e 'import Pkg; Pkg.instantiate()'The repository pins a Julia 1.10 manifest. The GitHub workflows currently test
with Julia 1.10.4, while the checked-in Manifest.toml was generated with
Julia 1.10.7.
Some examples use large meshes and reference images stored with Git LFS. Run
git lfs pull before executing validation cases that load .msh assets.
Run the small unit-square example from the repository root:
julia --project examples/simple.jlThis creates a simple/ output directory with:
results.vtu: fields for ParaView or another VTK viewer.results.csv: integrated entropy quantities.streamfunction.pdf,heatfunction.pdf,temperature.pdf,Sth.pdf, andSfl.pdf: contour plots generated by the postprocessing helper.
A minimal script looks like this:
using GeMotion
using Gridap
using LineSearches: BackTracking
model = CartesianDiscreteModel((0, 1, 0, 1), (50, 50))
out = GeMotion.simulate(
name="simple",
Pr=0.7,
Ra=1e3,
n=1.0,
model=model,
nlsolver_opts=(;
show_trace=true,
method=:newton,
linesearch=BackTracking(),
ftol=1e-8,
xtol=1e-10,
);
T_diri_tags=[5, 7, 8, 1, 2],
T_diri_expressions=[1.0, 0.0, 0.0, 0.5, 0.5],
T_natural_tags=[3, 4, 6],
V_diri_tags=[1, 2, 3, 4, 5, 6, 7, 8],
)For Gridap Cartesian models, boundary tags are integer labels. For Gmsh models,
they can be physical group names such as "inner", "outer", or "all", as
shown in the annulus examples.
out = GeMotion.simulate(; name, Pr, Ra, n, model, nlsolver_opts, kwargs...)Key arguments:
name: output directory for VTK, CSV, and plot files.Pr: Prandtl number.Ra: Rayleigh number.n: power-law index. Usen = 1.0for Newtonian flow.model: aGridap.DiscreteModel, for exampleCartesianDiscreteModelorGmshDiscreteModel.nlsolver_opts: keyword options passed to Gridap's nonlinear solver.T_diri_tags,T_diri_expressions: temperature Dirichlet boundary conditions.T_natural_tags: adiabatic or natural temperature boundaries used when constraining the heat-function postprocessing problem.V_diri_tags: no-slip velocity boundary tags.nlsolver_init_guess_type::zero,:ones,:random, or:custom.nlsolver_custom_init_guess: vector used with:custom.jac_scaling: scalar multiplier for the assembled Jacobian.
The returned named tuple includes:
uh,ph,Th: velocity, pressure, and temperature finite-element fields.psih: stream function.Pih: heat function.Sth,Sfl: local thermal and fluid-friction entropy fields.btrian,model,Ωₕ: Gridap geometry objects for further processing.Pr,Ra,n: copied simulation parameters.res_op: residual operator.
GeMotion.plot_all_unitsquare(psih, Pih, Th, uh, model, name, levels)writes the standard unit-square contour plots.GeMotion.contourplot_unitsquare(; fun, name, kwargs...)samples one scalar finite-element field on the unit square and writesname * ".pdf".GeMotion.contourplot_coannulus(; fun, name, ri, ro, kwargs...)does the same for concentric-annulus postprocessing.GeMotion.cmap_cold_to_hot_paraview()returns a ParaView-like cold-to-hot Makie color map.
The examples/ directory contains both short usage examples and larger
validation studies. Most validation scripts assume they are run from their own
directory because they read local data files.
# Small unit-square example
julia --project examples/simple.jl
# Square-cavity validation against Basak et al.
(cd examples/validation-basak && julia --project=../.. basak.jl)
# Power-law square-cavity validation against Turan et al.
(cd examples/validation-turan && julia --project=../.. turan.jl)
# Annulus validation against Kuehn et al.
(cd examples/validation-kuehn && julia --project=../.. kuehn.jl)
# Non-Newtonian annulus validation against Matin et al.
(cd examples/validate-matin && julia --project=../.. matin.jl)Large validation runs can take substantially longer than the simple example.
Several scripts reduce mesh resolution or case count automatically when the
GITHUB_ACTIONS environment variable is set.
src/
GeMotion.jl Package module.
Solver.jl Coupled nonlinear solve and derived-field export.
Postprocessing.jl Makie contour and color-map helpers.
examples/
simple.jl Small runnable unit-square example.
validation-*/ Literature validation studies.
meshes/ Gmsh meshes for annulus cases.
docs/
src/ Documenter.jl pages.
test/
runtests.jl Package smoke test plus example execution.
media/
logo assets.
Instantiate dependencies:
julia --project -e 'import Pkg; Pkg.instantiate()'Run tests:
julia --project -e 'import Pkg; Pkg.test()'Build the docs locally:
julia --project -e 'include("docs/make.jl")'The full test suite executes all Julia examples and may be expensive. To reduce linear-algebra oversubscription during nonlinear solves, set:
export OPENBLAS_NUM_THREADS=2GeMotion.jl is distributed under the MIT License. See LICENSE.

