Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .JuliaFormatter.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
style = "sciml"
format_markdown = true
format_docstrings = true
26 changes: 13 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,42 +5,42 @@
[![Stable](https://img.shields.io/badge/docs-stable-blue.svg)](https://SciML.github.io/FiniteVolumeMethod.jl/stable)
[![Coverage](https://codecov.io/gh/SciML/FiniteVolumeMethod.jl/branch/main/graph/badge.svg?token=XPM5KN89R6)](https://codecov.io/gh/SciML/FiniteVolumeMethod.jl)

This is a Julia package for solving partial differential equations (PDEs) of the form
This is a Julia package for solving partial differential equations (PDEs) of the form

$$
\dfrac{\partial u(\boldsymbol x, t)}{\partial t} + \boldsymbol{\nabla} \boldsymbol{\cdot} \boldsymbol{q}(\boldsymbol x, t, u) = S(\boldsymbol x, t, u), \quad (x, y)^{\mkern-1.5mu\mathsf{T}} \in \Omega \subset \mathbb R^2,t>0,
$$

in two dimensions using the finite volume method, with support also provided for steady-state problems and for systems of PDEs of the above form. In addition to this generic form above, we also provide support for specific problems that can be solved in a more efficient manner, namely:

1. `DiffusionEquation`s: $\partial_tu = \boldsymbol\nabla\boldsymbol\cdot[D(\boldsymbol x)\boldsymbol\nabla u]$.
2. `MeanExitTimeProblem`s: $\boldsymbol\nabla\boldsymbol\cdot[D(\boldsymbol x)\boldsymbol\nabla T(\boldsymbol x)] = -1$.
3. `LinearReactionDiffusionEquation`s: $\partial_tu = \boldsymbol\nabla\boldsymbol\cdot[D(\boldsymbol x)\boldsymbol\nabla u] + f(\boldsymbol x)u$.
4. `PoissonsEquation`: $\boldsymbol\nabla\boldsymbol\cdot[D(\boldsymbol x)\boldsymbol\nabla u] = f(\boldsymbol x)$.
5. `LaplacesEquation`: $\boldsymbol\nabla\boldsymbol\cdot[D(\boldsymbol x)\boldsymbol\nabla u] = 0$.
1. `DiffusionEquation`s: $\partial_tu = \boldsymbol\nabla\boldsymbol\cdot[D(\boldsymbol x)\boldsymbol\nabla u]$.
2. `MeanExitTimeProblem`s: $\boldsymbol\nabla\boldsymbol\cdot[D(\boldsymbol x)\boldsymbol\nabla T(\boldsymbol x)] = -1$.
3. `LinearReactionDiffusionEquation`s: $\partial_tu = \boldsymbol\nabla\boldsymbol\cdot[D(\boldsymbol x)\boldsymbol\nabla u] + f(\boldsymbol x)u$.
4. `PoissonsEquation`: $\boldsymbol\nabla\boldsymbol\cdot[D(\boldsymbol x)\boldsymbol\nabla u] = f(\boldsymbol x)$.
5. `LaplacesEquation`: $\boldsymbol\nabla\boldsymbol\cdot[D(\boldsymbol x)\boldsymbol\nabla u] = 0$.

See the documentation for more information.

If this package doesn't suit what you need, you may like to review some of the other PDE packages shown [here](https://github.com/JuliaPDE/SurveyofPDEPackages).

As a very quick demonstration, here is how we could solve a diffusion equation with Dirichlet boundary conditions on a square domain using the standard `FVMProblem` formulation; please see the docs for more information.
As a very quick demonstration, here is how we could solve a diffusion equation with Dirichlet boundary conditions on a square domain using the standard `FVMProblem` formulation; please see the docs for more information.

```julia
using FiniteVolumeMethod, DelaunayTriangulation, CairoMakie, OrdinaryDiffEq
a, b, c, d = 0.0, 2.0, 0.0, 2.0
nx, ny = 50, 50
tri = triangulate_rectangle(a, b, c, d, nx, ny, single_boundary=true)
tri = triangulate_rectangle(a, b, c, d, nx, ny, single_boundary = true)
mesh = FVMGeometry(tri)
bc = (x, y, t, u, p) -> zero(u)
BCs = BoundaryConditions(mesh, bc, Dirichlet)
f = (x, y) -> y ≤ 1.0 ? 50.0 : 0.0
initial_condition = [f(x, y) for (x, y) in DelaunayTriangulation.each_point(tri)]
D = (x, y, t, u, p) -> 1 / 9
final_time = 0.5
prob = FVMProblem(mesh, BCs; diffusion_function=D, initial_condition, final_time)
sol = solve(prob, Tsit5(), saveat=0.001)
prob = FVMProblem(mesh, BCs; diffusion_function = D, initial_condition, final_time)
sol = solve(prob, Tsit5(), saveat = 0.001)
u = Observable(sol.u[1])
fig, ax, sc = tricontourf(tri, u, levels=0:5:50, colormap=:matter)
fig, ax, sc = tricontourf(tri, u, levels = 0:5:50, colormap = :matter)
tightlimits!(ax)
record(fig, "anim.gif", eachindex(sol)) do i
u[] = sol.u[i]
Expand All @@ -49,10 +49,10 @@ end

![Animation of a solution](https://github.com/SciML/FiniteVolumeMethod.jl/blob/main/anim.gif)

We could have equivalently used the `DiffusionEquation` template, so that `prob` could have also been defined by
We could have equivalently used the `DiffusionEquation` template, so that `prob` could have also been defined by

```julia
prob = DiffusionEquation(mesh, BCs; diffusion_function=D, initial_condition, final_time)
prob = DiffusionEquation(mesh, BCs; diffusion_function = D, initial_condition, final_time)
```

and be solved much more efficiently. See the documentation for more information.
14 changes: 7 additions & 7 deletions docs/liveserver.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ Pkg.instantiate()
import LiveServer
withenv("LIVESERVER_ACTIVE" => "true") do
LiveServer.servedocs(;
launch_browser=true,
foldername=joinpath(repo_root, "docs"),
include_dirs=[joinpath(repo_root, "src")],
skip_dirs=[joinpath(repo_root, "docs/src/tutorials"),
launch_browser = true,
foldername = joinpath(repo_root, "docs"),
include_dirs = [joinpath(repo_root, "src")],
skip_dirs = [joinpath(repo_root, "docs/src/tutorials"),
joinpath(repo_root, "docs/src/wyos"),
joinpath(repo_root, "docs/src/figures"),
],
joinpath(repo_root, "docs/src/figures")
]
)
end
end
66 changes: 34 additions & 32 deletions docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -22,21 +22,23 @@ if RUN_EXAMPLES
function update_edit_url(content, file, folder)
content = replace(content, "<unknown>" => "https://github.com/SciML/FiniteVolumeMethod.jl/tree/main")
content = replace(content, "temp/" => "") # as of Literate 2.14.1
content = replace(content, r"EditURL\s*=\s*\"[^\"]*\"" => "EditURL = \"https://github.com/SciML/FiniteVolumeMethod.jl/tree/main/docs/src/literate_$(folder)/$file\"")
content = replace(content,
r"EditURL\s*=\s*\"[^\"]*\"" => "EditURL = \"https://github.com/SciML/FiniteVolumeMethod.jl/tree/main/docs/src/literate_$(folder)/$file\"")
return content
end
# We can add the code to the end of each file in its uncommented form programatically.
function add_just_the_code_section(dir, file)
file_name, file_ext = splitext(file)
file_path = joinpath(dir, file)
new_file_path = joinpath(session_tmp, file_name * "_just_the_code" * file_ext)
cp(file_path, new_file_path, force=true)
cp(file_path, new_file_path, force = true)
folder = splitpath(dir)[end] # literate_tutorials or literate_applications
open(new_file_path, "a") do io
write(io, "\n")
write(io, "# ## Just the code\n")
write(io, "# An uncommented version of this example is given below.\n")
write(io, "# You can view the source code for this file [here](<unknown>/docs/src/$folder/@__NAME__.jl).\n")
write(io,
"# You can view the source code for this file [here](<unknown>/docs/src/$folder/@__NAME__.jl).\n")
write(io, "\n")
write(io, "# ```julia\n")
write(io, "# @__CODE__\n")
Expand All @@ -59,7 +61,7 @@ if RUN_EXAMPLES
"tutorials/piecewise_linear_and_natural_neighbour_interpolation_for_an_advection_diffusion_equation.jl",
"tutorials/helmholtz_equation_with_inhomogeneous_boundary_conditions.jl",
"tutorials/laplaces_equation_with_internal_dirichlet_conditions.jl",
"tutorials/diffusion_equation_on_an_annulus.jl",
"tutorials/diffusion_equation_on_an_annulus.jl"
]
wyos_files = [
"wyos/diffusion_equations.jl",
Expand All @@ -71,7 +73,6 @@ if RUN_EXAMPLES
example_files = vcat(tutorial_files, wyos_files)
session_tmp = mktempdir()


map(1:length(example_files)) do n
example = example_files[n]
folder, file = splitpath(example)
Expand All @@ -80,7 +81,8 @@ if RUN_EXAMPLES
file_path = joinpath(dir, file)
# See also https://github.com/Ferrite-FEM/Ferrite.jl/blob/d474caf357c696cdb80d7c5e1edcbc7b4c91af6b/docs/generate.jl for some of this
new_file_path = add_just_the_code_section(dir, file)
script = Literate.script(file_path, session_tmp, name=splitext(file)[1] * "_just_the_code_cleaned")
script = Literate.script(file_path, session_tmp, name = splitext(file)[1] *
"_just_the_code_cleaned")
code = strip(read(script, String))
@info "[$(ct())] Processing $file: Converting markdown script"
line_ending_symbol = occursin(code, "\r\n") ? "\r\n" : "\n"
Expand All @@ -93,12 +95,12 @@ if RUN_EXAMPLES
Literate.markdown(
new_file_path,
outputdir;
documenter=true,
postprocess=editurl_update ∘ post_strip,
credit=true,
execute=!IS_LIVESERVER,
flavor=Literate.DocumenterFlavor(),
name=splitext(file)[1]
documenter = true,
postprocess = editurl_update ∘ post_strip,
credit = true,
execute = !IS_LIVESERVER,
flavor = Literate.DocumenterFlavor(),
name = splitext(file)[1]
)
end
end
Expand Down Expand Up @@ -128,15 +130,15 @@ _PAGES = [
"Diffusion Equation on an Annulus" => "tutorials/diffusion_equation_on_an_annulus.md",
"Mean Exit Time" => "tutorials/mean_exit_time.md",
"Solving Mazes with Laplace's Equation" => "tutorials/solving_mazes_with_laplaces_equation.md",
"Keller-Segel Model of Chemotaxis" => "tutorials/keller_segel_chemotaxis.md",
"Keller-Segel Model of Chemotaxis" => "tutorials/keller_segel_chemotaxis.md"
],
"Solvers for Specific Problems, and Writing Your Own" => [
"Section Overview" => "wyos/overview.md",
"Diffusion Equations" => "wyos/diffusion_equations.md",
"Mean Exit Time Problems" => "wyos/mean_exit_time.md",
"Linear Reaction-Diffusion Equations" => "wyos/linear_reaction_diffusion_equations.md",
"Poisson's Equation" => "wyos/poissons_equation.md",
"Laplace's Equation" => "wyos/laplaces_equation.md",
"Laplace's Equation" => "wyos/laplaces_equation.md"
],
"Mathematical and Implementation Details" => "math.md"
]
Expand Down Expand Up @@ -172,32 +174,32 @@ end

# Make and deploy
DocMeta.setdocmeta!(FiniteVolumeMethod, :DocTestSetup, :(using FiniteVolumeMethod, Test);
recursive=true)
recursive = true)
IS_LIVESERVER = get(ENV, "LIVESERVER_ACTIVE", "false") == "true"
IS_CI = get(ENV, "CI", "false") == "true"
makedocs(;
modules=[FiniteVolumeMethod],
authors="Daniel VandenHeuvel <danj.vandenheuvel@gmail.com>",
sitename="FiniteVolumeMethod.jl",
format=Documenter.HTML(;
canonical="https://SciML.github.io/FiniteVolumeMethod.jl",
edit_link="main",
collapselevel=1,
assets=String[],
mathengine=MathJax3(Dict(
modules = [FiniteVolumeMethod],
authors = "Daniel VandenHeuvel <danj.vandenheuvel@gmail.com>",
sitename = "FiniteVolumeMethod.jl",
format = Documenter.HTML(;
canonical = "https://SciML.github.io/FiniteVolumeMethod.jl",
edit_link = "main",
collapselevel = 1,
assets = String[],
mathengine = MathJax3(Dict(
:loader => Dict("load" => ["[tex]/physics"]),
:tex => Dict(
"inlineMath" => [["\$", "\$"], ["\\(", "\\)"]],
"tags" => "ams",
"packages" => ["base", "ams", "autoload", "physics"],
),
"packages" => ["base", "ams", "autoload", "physics"]
)
))),
draft=IS_LIVESERVER,
pages=_PAGES,
warnonly=true
draft = IS_LIVESERVER,
pages = _PAGES,
warnonly = true
)

deploydocs(;
repo="github.com/SciML/FiniteVolumeMethod.jl",
devbranch="main",
push_preview=true)
repo = "github.com/SciML/FiniteVolumeMethod.jl",
devbranch = "main",
push_preview = true)
14 changes: 7 additions & 7 deletions docs/src/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
CurrentModule = FiniteVolumeMethod
```

# Introduction
# Introduction

This is the documentation for FiniteVolumeMethod.jl. [Click here to go back to the GitHub repository](https://github.com/SciML/FiniteVolumeMethod.jl).

Expand All @@ -20,10 +20,10 @@ using the finite volume method, with additional support for steady-state problem

The [tutorials](tutorials/overview.md) in the sidebar demonstrate the many possibilities of this package. In addition to these two generic forms, we also provide support for specific problems that can be solved in a more efficient manner, namely:

1. `DiffusionEquation`s: $\partial_tu = \div[D(\vb x)\grad u]$.
2. `MeanExitTimeProblem`s: $\div[D(\vb x)\grad T(\vb x)] = -1$.
3. `LinearReactionDiffusionEquation`s: $\partial_tu = \div[D(\vb x)\grad u] + f(\vb x)u$.
4. `PoissonsEquation`: $\div[D(\vb x)\grad u] = f(\vb x)$.
5. `LaplacesEquation`: $\div[D(\vb x)\grad u] = 0$.
1. `DiffusionEquation`s: $\partial_tu = \div[D(\vb x)\grad u]$.
2. `MeanExitTimeProblem`s: $\div[D(\vb x)\grad T(\vb x)] = -1$.
3. `LinearReactionDiffusionEquation`s: $\partial_tu = \div[D(\vb x)\grad u] + f(\vb x)u$.
4. `PoissonsEquation`: $\div[D(\vb x)\grad u] = f(\vb x)$.
5. `LaplacesEquation`: $\div[D(\vb x)\grad u] = 0$.

See the [Solvers for Specific Problems, and Writing Your Own](wyos/overview.md) section for more information on these templates.
See the [Solvers for Specific Problems, and Writing Your Own](wyos/overview.md) section for more information on these templates.
35 changes: 17 additions & 18 deletions docs/src/interface.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,34 +2,34 @@
CurrentModule = FiniteVolumeMethod
```

# Interface
# Interface

```@contents
```@contents
Pages = ["interface.md"]
```

In this section, we describe the basic interface for defining and solving PDEs using this package. This interface will also be made clearer in the tutorials. The basic summary of the discussion below is as follows:

1. Use `FVMGeometry` to define the problem's mesh.
2. Provide boundary conditions using `BoundaryConditions`.
3. (Optional) Provide internal conditions using `InternalConditions`.
4. Convert the problem into an `FVMProblem`.
5. If you want to make the problem steady, use `SteadyFVMProblem` on the `FVMProblem`.
6. If you want a system of equations, construct an `FVMSystem` from multiple `FVMProblem`s; if you want this problem to be steady, skip step 5 and only now apply `SteadyFVMProblem`.
7. Solve the problem using `solve`.
8. For a discussion of custom constraints, see the tutorials.
9. For interpolation, we provide `pl_interpolate` (but you might prefer [NaturalNeighbours.jl](https://github.com/DanielVandH/NaturalNeighbours.jl) - see [this tutorial for an example](tutorials/piecewise_linear_and_natural_neighbour_interpolation_for_an_advection_diffusion_equation.md)).
1. Use `FVMGeometry` to define the problem's mesh.
2. Provide boundary conditions using `BoundaryConditions`.
3. (Optional) Provide internal conditions using `InternalConditions`.
4. Convert the problem into an `FVMProblem`.
5. If you want to make the problem steady, use `SteadyFVMProblem` on the `FVMProblem`.
6. If you want a system of equations, construct an `FVMSystem` from multiple `FVMProblem`s; if you want this problem to be steady, skip step 5 and only now apply `SteadyFVMProblem`.
7. Solve the problem using `solve`.
8. For a discussion of custom constraints, see the tutorials.
9. For interpolation, we provide `pl_interpolate` (but you might prefer [NaturalNeighbours.jl](https://github.com/DanielVandH/NaturalNeighbours.jl) - see [this tutorial for an example](tutorials/piecewise_linear_and_natural_neighbour_interpolation_for_an_advection_diffusion_equation.md)).

# `FVMGeometry`: Defining the mesh
# `FVMGeometry`: Defining the mesh

The finite volume method (FVM) requires an underlying triangular mesh, as outlined in the [mathematical details section](math.md). This triangular mesh is to be defined from [DelaunayTriangulation.jl](https://github.com/JuliaGeometry/DelaunayTriangulation.jl). The `FVMGeometry` type wraps the resulting `Triangulation` and computes information about the geometry required for solving the PDEs. The docstring for `FVMGeometry` is below; the fields of `FVMGeometry` are public API.
The finite volume method (FVM) requires an underlying triangular mesh, as outlined in the [mathematical details section](math.md). This triangular mesh is to be defined from [DelaunayTriangulation.jl](https://github.com/JuliaGeometry/DelaunayTriangulation.jl). The `FVMGeometry` type wraps the resulting `Triangulation` and computes information about the geometry required for solving the PDEs. The docstring for `FVMGeometry` is below; the fields of `FVMGeometry` are public API.

```@docs
FVMGeometry
```

The `FVMGeometry` struct uses `TriangleProperties` for storing properties of a control volume that intersects a given triangle, defined below. This struct is
public API, although it is unlikely you would ever need it.
The `FVMGeometry` struct uses `TriangleProperties` for storing properties of a control volume that intersects a given triangle, defined below. This struct is
public API, although it is unlikely you would ever need it.

```@docs
TriangleProperties
Expand Down Expand Up @@ -152,15 +152,14 @@ These `solve` functions rely on `fvm_eqs!` for evaluating the equations. You sho
fvm_eqs!
```

# Custom constraints
# Custom constraints

You can also provide custom constraints. Rather than outlining this precisely here, it is best explained in the tutorials, namely [this tutorial](tutorials/solving_mazes_with_laplaces_equation.md). We note that one useful function for this is `compute_flux`, which allows you to compute the flux across a given edge. The docstring for `compute_flux` is below, and this function is public API.

```@docs
compute_flux
```


# Piecewise linear interpolation

You can evaluate the piecewise linear interpolation corresponding to a solution using `pl_interpolate`, defined below; this function is public API.
Expand All @@ -169,4 +168,4 @@ You can evaluate the piecewise linear interpolation corresponding to a solution
pl_interpolate
```

Better interpolants are available from [NaturalNeighbours.jl](https://github.com/DanielVandH/NaturalNeighbours.jl) - see the [this tutorial](tutorials/piecewise_linear_and_natural_neighbour_interpolation_for_an_advection_diffusion_equation.md) for some examples.
Better interpolants are available from [NaturalNeighbours.jl](https://github.com/DanielVandH/NaturalNeighbours.jl) - see the [this tutorial](tutorials/piecewise_linear_and_natural_neighbour_interpolation_for_an_advection_diffusion_equation.md) for some examples.
Loading
Loading