- JFVM is now prepared for Julia package registration and targets Julia 1.10+.
- Once registered in General, install it with:
] add JFVM
- Until registration is completed, install directly from this repository:
] add https://github.com/FiniteVolumeTransportPhenomena/JFVM.jl
- 3D visualization via Mayavi/PyCall is intentionally disabled in this package.
- Visualization support is maintained in JFVMvis.jl, which can be installed by:
] add https://github.com/simulkade/JFVMvis.jl
You can solve the following PDE (or a subset of it):

with the following boundary conditions:

Believe it or not, the above equations describe the majority of the transport phenomena in chemical and petroleum engineering and similar fields.
This code is a Matlabesque implementation of my Matlab finite volume tool. The code is not in its most beautiful form, but it works if you believe my words. Please remember that the code is written by a chemical/petroleum engineer. Petroleum engineers are known for being simple-minded folks and chemical engineers have only one rule: "any answer is better than no answer". You can expect to easily discretize a linear transient advection-diffusion PDE into the matrix of coefficients and RHS vectors. Domain shape is limited to rectangles, circles (or a section of a circle), cylinders, and soon spheres. The mesh can be uniform or nonuniform:
- Cartesian (1D, 2D, 3D)
- Cylindrical (1D, 2D, 3D)
- Radial (2D r and \theta)
You can have the following boundary conditions or a combination of them on each boundary:
- Dirichlet (constant value)
- Neumann (constant flux)
- Robin (a linear combination of the above)
- Periodic (so funny when visualize)
It is relatively easy to use the code to solve a system of coupled linear PDE's and not too difficult to solve nonlinear PDE's.
Each mesh carries an explicit coordinate-system type, and the discretization
kernels dispatch on it (rather than on the legacy numeric dimension tag). The
constructors are unchanged; the type is selected automatically:
| Constructor | Coordinate system | dimension (legacy) |
|---|---|---|
createMesh1D |
Cartesian1D |
1.0 |
createMeshCylindrical1D |
Cylindrical1D |
1.5 |
createMesh2D |
Cartesian2D |
2.0 |
createMeshCylindrical2D |
Cylindrical2D |
2.5 |
createMeshRadial2D |
Radial2D |
2.8 |
createMesh3D |
Cartesian3D |
3.0 |
createMeshCylindrical3D |
Cylindrical3D |
3.2 |
The coordinate system is available as m.coordinatesystem, with helpers
is_1d(m), is_2d(m), is_3d(m). The numeric m.dimension field and the
coordinatesystem_from_dimension / dimension_from_coordinatesystem bridges are
retained for backward compatibility; prefer dispatching on the coordinate-system
types in new code.
solveLinearPDE and solveLinearPDE! accept a pluggable solver strategy
(default behavior is unchanged):
solveLinearPDE(m, M, RHS) # DirectSolver() — sparse LU via `\`
solveLinearPDE(m, M, RHS; solver = DirectSolver()) # explicit default
# Reuse one factorization across a fixed-matrix transient loop (only RHS changes):
fs = FactorizedSolver(M)
for step in 1:nsteps
phi = solveLinearPDE(m, M, RHS; solver = fs) # M is factored once
# ... update RHS ...
end
solveLinearPDE(m, M, RHS; solver = MUMPSSolver()) # optional MUMPS backend (import MUMPS first)Install from the Julia General registry:
] add JFVM
Install from this repository:
] add https://github.com/FiniteVolumeTransportPhenomena/JFVM.jl
If you need plotting/visualization workflows that were moved out of this package:
] add https://github.com/simulkade/JFVMvis.jl
The examples/ folder is organised into:
examples/tutorial— short.jlscripts introducing the workflow,examples/cases— worked engineering problems (heat conduction, plug-flow reactor) that verify against analytical solutions,examples/legacy— the original Jupyter notebooks.
A short notebook tutorial is also available.
Copy and paste the following code to solve a transient diffusion equation:
using JFVM, JFVMvis
Nx = 10
Lx = 1.0
m = createMesh1D(Nx, Lx)
BC = createBC(m)
BC.left.a[:].=BC.right.a[:].=0.0
BC.left.b[:].=BC.right.b[:].=1.0
BC.left.c[:].=1.0
BC.right.c[:].=0.0
c_init = 0.0 # initial value of the variable
c_old = createCellVariable(m, 0.0, BC)
D_val = 1.0 # value of the diffusion coefficient
D_cell = createCellVariable(m, D_val) # assigned to cells
# Harmonic average
D_face = harmonicMean(D_cell)
N_steps = 20 # number of time steps
dt= sqrt(Lx^2/D_val)/N_steps # time step
M_diff = diffusionTerm(D_face) # matrix of coefficient for diffusion term
(M_bc, RHS_bc)=boundaryConditionTerm(BC) # matrix of coefficient and RHS for the BC
for i =1:5
(M_t, RHS_t)=transientTerm(c_old, dt, 1.0)
M=M_t-M_diff+M_bc # add all the [sparse] matrices of coefficient
RHS=RHS_bc+RHS_t # add all the RHS's together
c_old = solveLinearPDE(m, M, RHS) # solve the PDE
end
visualizeCells(c_old)Now change the 4th line to m=createMesh2D(Nx, Nx, Lx, Lx) and see this:

TO DO
- Introduction
- tutorial
- compare analytical solution of a diffusion equation with uniform and nonuniform grids
- Nonlinear PDE
- Foam flow in porous media
- New notebooks soon...
If you have used the code in your research, please cite it as
Ali A Eftekhari. (2017, August 23). JFVM.jl: A Finite Volume Tool for Solving Advection-Diffusion Equations. Zenodo. http://doi.org/10.5281/zenodo.847056
@misc{ali_a_eftekhari_2017_847056,
author = {Ali A Eftekhari},
title = {{JFVM.jl: A Finite Volume Tool for Solving
Advection-Diffusion Equations}},
month = aug,
year = 2017,
doi = {10.5281/zenodo.847056},
url = {https://doi.org/10.5281/zenodo.847056}
}