Skip to content
This repository was archived by the owner on Jul 19, 2023. It is now read-only.

Commit 9894a7c

Browse files
committed
Documentation changes
Stylistic revision, punctuation, typos, consistency, etc.
1 parent f9dc4c1 commit 9894a7c

18 files changed

Lines changed: 181 additions & 183 deletions

README.md

Lines changed: 40 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -6,74 +6,74 @@
66
[![Coverage Status](https://coveralls.io/repos/JuliaDiffEq/DiffEqOperators.jl/badge.svg?branch=master&service=github)](https://coveralls.io/github/JuliaDiffEq/DiffEqOperators.jl?branch=master)
77
[![codecov.io](http://codecov.io/github/shivin9/DiffEqOperators.jl/coverage.svg?branch=master)](http://codecov.io/github/JuliaDiffEq/DiffEqOperators.jl?branch=master)
88

9-
Construct high order finite-difference operators to discretize a partial
9+
Construct high-order finite-difference operators to discretize a partial
1010
differential equation and its boundary conditions by the method of
11-
lines. This reduces it to a system of ordinary differential
11+
lines. This reduces it to a system of ordinary differential
1212
equations that can be solved by [`DifferentialEquations.jl`](https://juliadiffeq.org/).
1313

1414
Both centered and [upwind](https://en.wikipedia.org/wiki/Upwind_scheme)
1515
operators are provided, for domains of any dimension, arbitrarily
16-
spaced grids, and for any order of accuracy. The cases of 1, 2 and
16+
spaced grids, and for any order of accuracy. The cases of 1, 2, and
1717
3 dimensions with an evenly spaced grid are optimized with a
18-
convolution routine from `NNlib.jl`. Care is taken to avoid
18+
convolution routine from `NNlib.jl`. Care is taken to avoid
1919
unnecessary allocations.
2020

21-
Any operator can be concretised as an `Array`, a `BandedMatrix` or
21+
Any operator can be concretized as an `Array`, a `BandedMatrix` or
2222
a sparse matrix.
2323

2424
## The simplest case
2525

2626
As shown in the figure, the operators act on a set of samples
27-
`f_j = f(x_j)` for a function `f` at a grid of points `x_j`. The
27+
`f_j = f(x_j)` for a function `f` at a grid of points `x_j`. The
2828
grid has `n` interior points at `x_j = jh` for `j = 1` to `n`, and 2
29-
boundary points at `x_0 = 0` and `x_{n+1} = (n+1) h`. The input to
29+
boundary points at `x_0 = 0` and `x_{n+1} = (n+1) h`. The input to
3030
the numerical operators is a vector `u = [f_1, f_2, …, f_N]`, and
3131
they output a vector of sampled derivatives `du ≈ [f'(x_1), f'(x_2),
32-
…, f'(x_N)]`, or a higher order derivative as requested.
32+
…, f'(x_N)]`, or a higher-order derivative as requested.
3333

3434
A numerical derivative operator `D` of order `m` can be constructed
35-
for this grid with `D = CenteredDifference(1, m, h, n)` The argument
36-
`1` indicates that this is a first derivative. Order `m` means
35+
for this grid with `D = CenteredDifference(1, m, h, n)`. The argument
36+
`1` indicates that this is the first derivative. Order `m` means
3737
that the operator is exact up to rounding when `f` is a polynomial
3838
of degree `m` or lower.
3939

4040
The derivative operator `D` is used along with a boundary condition
41-
operator `Q`, to compute derivatives at the interior points of the
42-
grid. A simple boundary condition `f(x_0) = f(x_n+1) = 0` is
41+
operator `Q` to compute derivatives at the interior points of the
42+
grid. A simple boundary condition `f(x_0) = f(x_n+1) = 0` is
4343
constructed with `Q = Dirichlet0BC(eltype(u))`.
4444

4545
Given these definitions, the derivatives are calculated as if the
46-
operators `D` and `Q` were matrices. `du = D*Q*u`. This is an
47-
abuse of notation! The particular `Q` in this example is a linear
48-
operator, but in general boundary conditions are affine operators.
46+
operators `D` and `Q` were matrices, `du = D*Q*u`. This is an
47+
abuse of notation! The particular `Q` in this example is a linear
48+
operator but, in general, boundary conditions are affine operators.
4949
They have the form `Q(x) = M*x + c`, where `M` is a matrix and `c`
50-
is a constant vector. As a consequence, `Q` can not be concretized
50+
is a constant vector. As a consequence, `Q` cannot be concretized
5151
to a matrix.
5252

5353
![Actions of DiffEqOperators on interior points and ghost points](action.svg)
5454

5555
The operator `D` works by interpolating a polynomial of degree `m`
56-
through `m+1` adjacent points on the grid. Near the middle of the
56+
through `m+1` adjacent points on the grid. Near the middle of the
5757
grid, the derivative is approximated at `x_j` by interpolating a
58-
polynomial of order `m` with `x_j` at its centre. To define a
59-
order-`m` polynomial, values are required at `m+1` points. When
58+
polynomial of order `m` with `x_j` at its centre. To define an
59+
order-`m` polynomial, values are required at `m+1` points. When
6060
`x_j` is too close to the boundary for that to fit, the polynomial
6161
is interpolated through the leftmost or rightmost `m+1` points,
6262
including two “ghost” points that `Q` appends on the boundaries.
6363
The numerical derivatives are linear combinations of the values
64-
through which the polynomials are interpolated. The vectors of
64+
through which the polynomials are interpolated. The vectors of the
6565
coefficients in these linear combinations are called “stencils”.
6666
Because `D` takes values at the ghost points and returns values at
67-
the interior points, it is a `n×(n+2)` matrix.
67+
the interior points, it is an `n×(n+2)` matrix.
6868

6969
The boundary condition operator `Q`
70-
acts as an `(n+2)×n` matrix. The output `Q*u` is a vector of values
70+
acts as an `(n+2)×n` matrix. The output `Q*u` is a vector of values
7171
on the `n` interior and the 2 boundary points, `[a, f(x_1), …, f(x_N), b]`.
72-
The interior points take the values of `u`. The values `a` and `b` are
73-
samples at “ghost” points on the grid boundaries. As shown, these
72+
The interior points take the values of `u`. The values `a` and `b` are
73+
samples at “ghost” points on the grid boundaries. As shown, these
7474
values are assigned so that an interpolated polynomial `P(x)` satisfies
75-
the left hand boundary condition, and `Q(x)` satisfies the right hand
76-
boundary condition. The boundary conditions provided by the
75+
the left hand boundary condition, and `Q(x)` satisfies the right-hand
76+
boundary condition. The boundary conditions provided by the
7777
library are precisely those for which the values `a` and `b` are affine
7878
functions of the interior values `f_j`, so that `Q` is an affine operator.
7979

@@ -84,28 +84,28 @@ and the derivative and boundary condition operators are similar
8484
to matrices.
8585

8686
In two dimensions, the values `f(x_j)` are naturally stored as a
87-
matrix. Taking derivatives along the downwards axis is easy, because
88-
matrices act columnwise. Horizontal derivatives can be taken by
89-
transposing the matrices. The derivative along the rightward axis
90-
is `(D*F')' = F*D' `. This is easy to code, but less easy to read
87+
matrix. Taking derivatives along the downwards axis is easy, because
88+
matrices act columnwise. Horizontal derivatives can be taken by
89+
transposing the matrices. The derivative along the rightward axis
90+
is `(D*F')' = F*D' `. This is easy to code, but less easy to read
9191
for those who haven't seen it before.
9292

9393
When a function has three or more arguments, its values are naturally
94-
stored in a higher dimensional array. Julia's multiplication
94+
stored in a higher-dimensional array. Julia's multiplication
9595
operator is only defined for `Vector` and `Matrix`, so applying an
9696
operator matrix to these arrays would require a complicated and
9797
error prone series of `reshape` and axis permutation functions.
9898

9999
Therefore the types of derivative and boundary condition operators
100-
are parameterised by the axis along which the operator acts. With
100+
are parameterised by the axis along which the operator acts. With
101101
derivative operators, the axis is supplied as a type parameter.
102102
The simple case `CenteredDifference(…)` is equivalent to
103103
`CenteredDifference{1}(…)`, row-wise derivatives are taken by
104104
`CenteredDifference{2}(…)`, sheet-wise by `CenteredDifference{3}(…)`,
105105
and along the `N`th axis by `CenteredDifference{N}(…)`.
106106

107-
Boundary conditions are more complicated. See `@doc MultiDimBC`
108-
for how they are supposed to work in multiple dimensions. They
107+
Boundary conditions are more complicated. See `@doc MultiDimBC`
108+
for how they are supposed to work in multiple dimensions. They
109109
don't currently work that way.
110110

111111
## Constructors
@@ -125,15 +125,15 @@ UpwindDifference{N}(derivative_order::Int,
125125
The arguments are:
126126

127127
- `N`: The directional dimension of the discretization. If `N` is not given,
128-
it is assumed to be 1, i.e. differencing occurs along columns.
128+
it is assumed to be 1, i.e., differencing occurs along columns.
129129
- `derivative_order`: the order of the derivative to discretize.
130130
- `approximation_order`: the order of the discretization in terms of O(dx^order).
131131
- `dx`: the spacing of the discretization. If `dx` is a `Number`, the operator
132132
is a uniform discretization. If `dx` is an array, then the operator is a
133133
non-uniform discretization.
134134
- `len`: the length of the discretization in the direction of the operator.
135135
- `coeff_func`: An operational argument for a coefficient function `f(du,u,p,t)`
136-
which sets the coefficients of the operator. If `coeff_func` is a `Number`
136+
which sets the coefficients of the operator. If `coeff_func` is a `Number`,
137137
then the coefficients are set to be constant with that number. If `coeff_func`
138138
is an `AbstractArray` with length matching `len`, then the coefficients are
139139
constant but spatially dependent.
@@ -159,11 +159,11 @@ The following concretizations are provided:
159159

160160
Additionally, the function `sparse` is overloaded to give the most efficient
161161
matrix type for a given operator. For one-dimensional derivatives this is a
162-
`BandedMatrix`, while for higher dimensional operators this is a `BlockBandedMatrix`.
162+
`BandedMatrix`, while for higher-dimensional operators this is a `BlockBandedMatrix`.
163163
The concretizations are made to act on `vec(u)`.
164164

165-
A contraction operator concretizes to an ordinary matrix, no matter which dimension
166-
the contraction acts along, by doing the kroncker product formulation. I.e., the
165+
A contraction operator concretizes to an ordinary matrix, no matter which dimension
166+
the contraction acts along, by doing the Kronecker product formulation. I.e., the
167167
action of the built matrix will match the action on `vec(u)`.
168168

169169
## Boundary Condition Operators
@@ -281,4 +281,4 @@ will inherit the appropriate action.
281281
### Efficiency of Composed Operator Actions
282282

283283
Composed operator actions utilize NNLib.jl in order to do cache-efficient
284-
convolution operations in higher dimensional combinations.
284+
convolution operations in higher-dimensional combinations.

examples/heat_equation.jl

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# # Heat Equation
22
#
3-
# This example demonstrates how to combine `OrdinaryDiffEq` with `DiffEqOperators` to solve a time dependent PDE.
3+
# This example demonstrates how to combine `OrdinaryDiffEq` with `DiffEqOperators` to solve a time-dependent PDE.
44
# We consider the heat equation on the unit interval, with Dirichlet boundary conditions:
55
# ∂ₜu = Δu
66
# u(x=0,t) = a
@@ -35,10 +35,9 @@ sol = solve(prob, alg)
3535
using Test
3636
@test u_analytic.(knots, t1) sol[end] rtol=1e-3
3737

38-
# Because the creation of boundary conditions is cheap, we can
38+
# Because the creation of boundary conditions is cheap, we can
3939
# implement time-dependent boundary conditions as follows:
4040
# function step(u,p,t)
4141
# bc = DirichletBC(cos(t*1.5), sin(t))
4242
# Δ*bc*u
4343
# end
44-

examples/poisson.jl

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
# # Poisson Equation
22
#
33
# We want to solve the [poisson equation](https://en.wikipedia.org/wiki/Poisson_equation) on the unit interval. It is given by
4-
# `Δu = f` with boundary conditions `u(0) = a` and `u(1) = b`
5-
# First of all let us choose some values for the parameters and remark, that there is an exact solution:
4+
# `Δu = f` with boundary conditions `u(0) = a` and `u(1) = b`.
5+
# First of all, let us choose some values for the parameters and remark that there is an exact solution:
66
f = 1.0
77
a = -1.0
88
b = 2.0
@@ -20,16 +20,16 @@ ord_approx = 2
2020
Δ = CenteredDifference(ord_deriv, ord_approx, h, nknots)
2121
bc = DirichletBC(a, b)
2222

23-
# Before solving the equation, lets take a look at Δ and bc:
23+
# Before solving the equation, let's take a look at Δ and bc:
2424
# display(Array(Δ))
2525
# display(bc*zeros(nknots))
26-
# We see that `Δ` is a (lazy) matrix with the laplace stencil extended over the boundaries.
26+
# We see that `Δ` is a (lazy) matrix with the Laplace stencil extended over the boundaries.
2727
# And `bc` acts by padding the values just outside the boundaries.
2828

2929
u =*bc) \ fill(f, nknots)
3030
knots = range(h, step=h, length=nknots)
3131

32-
# Since we used a second order approximation and the analytic solution itself was a second order
33-
# polynomial, we expect that they are equal up to rounding errors:
32+
# Since we used a second order approximation and the analytic solution itself was a second-order
33+
# polynomial, we expect them to be equal up to rounding errors:
3434
using Test
3535
@test u u_analytic.(knots)

src/MOL_discretization.jl

Lines changed: 20 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,16 @@ function get_bcs(bcs,tdomain,domain)
1717
lhs_deriv_depvars_bcs[var] = Array{Expr}(undef,3)
1818
end
1919
j = 0
20-
if isequal(bcs[i].lhs.args[1],tdomain.lower) # u(t=0,x)
21-
j = 1
20+
if isequal(bcs[i].lhs.args[1],tdomain.lower) # u(t=0,x)
21+
j = 1
2222
elseif isequal(bcs[i].lhs.args[2],domain.lower) # u(t,x=x_init)
2323
j = 2
2424
elseif isequal(bcs[i].lhs.args[2],domain.upper) # u(t,x=x_final)
2525
j = 3
2626
end
2727
if bcs[i].rhs isa ModelingToolkit.Constant
2828
lhs_deriv_depvars_bcs[var][j] = :(var=$(bcs[i].rhs.value))
29-
else
29+
else
3030
lhs_deriv_depvars_bcs[var][j] = Expr(bcs[i].rhs)
3131
end
3232
end
@@ -38,14 +38,14 @@ end
3838
# Recursively traverses the input expression (rhs), replacing derivatives by
3939
# finite difference schemes. It returns a time dependent expression (expr)
4040
# that will be evaluated in the "f" ODE function (in DiffEqBase.discretize),
41-
# Note: 'non-derived' dependent variables are inserted into the diff. equations
42-
# E.g. Dx(u(t,x))=v(t,x)*Dx(u(t,x)), v(t,x)=t*x
41+
# Note: 'non-derived' dependent variables are inserted into the differential equations
42+
# E.g., Dx(u(t,x))=v(t,x)*Dx(u(t,x)), v(t,x)=t*x
4343
# => Dx(u(t,x))=t*x*Dx(u(t,x))
44-
44+
4545
function discretize_2(input,deriv_order,approx_order,dx,X,len,
4646
deriv_var,dep_var_idx,indep_var_idx)
4747
if input isa ModelingToolkit.Constant
48-
return :($(input.value))
48+
return :($(input.value))
4949
elseif input isa Operation
5050
if input.op isa Variable
5151
expr = :(0.0)
@@ -64,7 +64,7 @@ function discretize_2(input,deriv_order,approx_order,dx,X,len,
6464
if deriv_order == 0
6565
expr = :(u[:,$j])
6666
elseif deriv_order == 1
67-
# TODO: approx_order and forward/backward should be
67+
# TODO: approx_order and forward/backward should be
6868
# input parameters of each derivative
6969
approx_order = 1
7070
L = UpwindDifference(deriv_order,approx_order,dx[i],len[i]-2,-1)
@@ -92,7 +92,7 @@ function discretize_2(input,deriv_order,approx_order,dx,X,len,
9292
aux_2 = discretize_2(input.args[2],deriv_order,approx_order,dx,X,
9393
len,deriv_var,dep_var_idx,indep_var_idx)
9494
return :(broadcast($(input.op), $aux_1, $aux_2))
95-
end
95+
end
9696
end
9797
end
9898
end
@@ -105,22 +105,22 @@ function DiffEqBase.discretize(pdesys::PDESystem,discretization::MOLFiniteDiffer
105105
# 1) PDE System
106106
# 1.a) Transient
107107
# There is more than one indep. variable, including 't'
108-
# E.g. du/dt = d2u/dx2 + d2u/dy2 + f(t,x,y)
108+
# E.g., du/dt = d2u/dx2 + d2u/dy2 + f(t,x,y)
109109
# 1.b) Stationary
110110
# There is more than one indep. variable, 't' is not included
111-
# E.g. 0 = d2u/dx2 + d2u/dy2 + f(x,y)
111+
# E.g., 0 = d2u/dx2 + d2u/dy2 + f(x,y)
112112
# 2) ODE System
113113
# 't' is the only independent variable
114114
# The ODESystem is packed inside a PDESystem
115-
# E.g. du/dt = f(t)
115+
# E.g., du/dt = f(t)
116116
#
117117
# Note: regarding input format, lhs must be "du/dt" or "0".
118118
#
119119

120-
# The following code deals with 1.a case for 1D,
121-
# i.e. only considering 't' and 'x'
120+
# The following code deals with 1.a case for 1-D,
121+
# i.e., only considering 't' and 'x'.
122+
122123

123-
124124
### Declare and define independent-variable data structures ###############
125125

126126
tdomain = 0.0
@@ -155,9 +155,9 @@ function DiffEqBase.discretize(pdesys::PDESystem,discretization::MOLFiniteDiffer
155155
approx_order = discretization.order
156156

157157
lhs_deriv_depvars = Dict()
158-
dep_var_idx = Dict()
158+
dep_var_idx = Dict()
159159
dep_var_disc = Dict() # expressions evaluated in the ODE function (f)
160-
160+
161161
# if there is only one equation
162162
if pdesys.eq isa Equation
163163
eqs = [pdesys.eq]
@@ -181,7 +181,7 @@ function DiffEqBase.discretize(pdesys::PDESystem,discretization::MOLFiniteDiffer
181181
# TODO: is there a better way to convert an Expr into a Function?
182182
dep_var_disc[var] = @eval (Q,u,t) -> $aux
183183
end
184-
184+
185185
### Declare and define boundary conditions ################################
186186

187187
# TODO: extend to Neumann BCs and Robin BCs
@@ -191,7 +191,7 @@ function DiffEqBase.discretize(pdesys::PDESystem,discretization::MOLFiniteDiffer
191191
u_x0 = Array{Any}(undef,no_dep_vars)
192192
u_x1 = Array{Any}(undef,no_dep_vars)
193193
Q = Array{RobinBC}(undef,no_dep_vars)
194-
194+
195195
for var in keys(dep_var_idx)
196196
j = dep_var_idx[var]
197197
bcs = lhs_deriv_depvars_bcs[var]
@@ -210,7 +210,7 @@ function DiffEqBase.discretize(pdesys::PDESystem,discretization::MOLFiniteDiffer
210210
### Define the discretized PDE as an ODE function #########################
211211

212212
function f(du,u,p,t)
213-
213+
214214
# Boundary conditions can vary with respect to time
215215
for j in 1:no_dep_vars
216216
a = Base.invokelatest(u_x0[j],X[2][1],t)
@@ -233,4 +233,3 @@ function DiffEqBase.discretize(pdesys::PDESystem,discretization::MOLFiniteDiffer
233233
# Return problem ##########################################################
234234
return PDEProblem(ODEProblem(f,u_t0,(tdomain.lower,tdomain.upper),nothing),Q,X)
235235
end
236-

src/boundary_padded_arrays.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ function Base.getindex(Q::BoundaryPaddedVector,i)
3333
end
3434

3535
"""
36-
Higher dimensional generalization of BoundaryPaddedVector, pads an array of dimension N along the dimension D with 2 Arrays of dimension N-1, stored in lower and upper
36+
Higher-dimensional generalization of BoundaryPaddedVector pads an array of dimension N along the dimension D with 2 Arrays of dimension N-1, stored in lower and upper
3737
3838
"""
3939
struct BoundaryPaddedArray{T, D, N, M, V<:AbstractArray{T, N}, B<: AbstractArray{T, M}} <: AbstractDirectionalBoundaryPaddedArray{T,N, D}
@@ -60,9 +60,9 @@ Example:
6060
A = compose(Ax, Ay, Az) # 3D domain
6161
A = compose(Ax, Ay) # 2D Domain
6262
63-
Composes BoundaryPaddedArrays that extend the same u for each different dimension that u has in to a ComposedBoundaryPaddedArray
63+
Composes BoundaryPaddedArrays that extend the same u for each different dimension that u has in to a ComposedBoundaryPaddedArray.
6464
65-
Ax Ay and Az can be passed in any order, as long as there is exactly one BoundaryPaddedArray that extends each dimension.
65+
Ax, Ay, and Az can be passed in any order, as long as there is exactly one BoundaryPaddedArray that extends each dimension.
6666
"""
6767
function compose(padded_arrays::BoundaryPaddedArray...)
6868
N = ndims(padded_arrays[1])
@@ -105,7 +105,7 @@ Ax, Ay,... = decompose(A::ComposedBoundaryPaddedArray)
105105
106106
-------------------------------------------------------------------------------------
107107
108-
Decomposes a ComposedBoundaryPaddedArray in to components that extend along each dimension individually
108+
Decomposes a ComposedBoundaryPaddedArray in to components that extend along each dimension individually.
109109
"""
110110
decompose(A::ComposedBoundaryPaddedArray) = Tuple([BoundaryPaddedArray{gettype(A), i, ndims(A), ndims(A)-1, typeof(lower[1])}(A.lower[i], A.upper[i], A.u) for i in 1:ndims(A)])
111111

0 commit comments

Comments
 (0)