System
The computational grid required is assumed to correspond to a domain $\Omega=\cup_{r=1}^{n_\Omega} \Omega_r$
Grids for VoronoiFVM are managed by the packages ExtendableGrids.jl and SimplexGridFactory.jl
with boundary $\partial\Omega=\Gamma=\cup_{b=1}^{n_\Gamma} \Gamma_b$.
The subdomains $\Omega_r$ are called "regions" and the boundary subdomains $\Gamma_b$ are called "boundary regions".
On this complex of domains "lives" a number of species which are either attached to a number of regions or to a number of boundary regions.
All these data, the matrix for the linear system and other things are hold together by a struct VoronoiFVM.System
. This type is not exported to avoid name clashes.
System constructors
VoronoiFVM.System
— MethodSystem(grid; kwargs...)
Create structure of type VoronoiFVM.System{Tv,Ti, Tm, TSpecMat<:AbstractMatrix, TSolArray<:AbstractMatrix}
holding data for finite volume system solution.
Parameters:
grid::ExtendableGrid
: 1, 2 or 3D computational grid
Keyword arguments:
species
: vector of integer species indices. Added to all grid regions, avoiding the need to callenable_species!
for this default case. If it is kept empty, species have be added to the system after creation viaenable_species!
.unknown_storage
: string or symbol. Information on species distribution is kept in sparse or dense matrices matrices and, correspondingly, the solution array is of type SparseSolutionArray or matrix, respectively. In the case of sparse unknown storage, the system matrix handles exactly those degrees of freedom which correspond to unknowns. However, handling of the sparse matrix structures for the bookkeeping of the unknowns creates overhead.:dense
: solution vector is annspecies
xnnodes
dense matrix:sparse
: solution vector is annspecies
xnnodes
sparse matrix
matrixindextype
: Integer type. Index type for sparse matrices created in the system.is_linear
: whether the system is linear or not. If it is linear, only one Newton step is used to solve it.assembly
: either:cellwise
(default) or:edgewise
. Determine, how the assembly loop is organized.:cellwise
means that the outer loop goes over grid cells (triangles, tetrahedra), and contributions to edge fluxes and node reactions are calculated for each cell. As a consequence, e.g. im 2D for all interior edges, flux functions are callled twice, once for each adjacent cell. Especially in 3D, this becomes a significant overhead. With:edgewise
, geometry factors of these edges are pre-assembled, and the outer assembly loops go over all grid edges resp. nodes, still with separate calls if neigboring cells belong to different regions.
It is planned to make :edgewise
the default in a later version.
Physics keyword arguments:
flux
: Function. Flux between neighboring control volumes:flux(f,u,edge)
orflux(f,u,edge,data)
should return inf[i]
the flux of species i along the edge joining circumcenters of neighboring control volumes. For species i,u[i,1]
andu[i,2]
contain the unknown values at the corresponding ends of the edge.storage
: Function. Storage term (term under time derivative):storage(f,u,node)
orstorage(f,u,node,data)
It should return inf[i]
the storage term for the i-th equation.u[i]
contains the value of the i-th unknown.reaction
: Function. Reaction term:reaction(f,u,node)
orreaction(f,u,node,data)
It should return inf[i]
the reaction term for the i-th equation.u[i]
contains the value of the i-th unknown.edgereaction
: Function. Edge reeaction term:edgereaction(f,u,edge)
oredgereaction(f,u,edge,data)
It should return inf[i]
the reaction term for the i-th equation. For species i,u[i,1]
andu[i,2]
contain the unknown values at the corresponding ends of the edge.source
: Function. Source term:source(f,node)
orsource(f,node,data)
. It should return the inf[i]
the value of the source term for the i-th equation.bflux
: Function. Flux between neighboring control volumes on the boundarybreaction
Function. Boundary reaction term:breaction(f,u,node)
orbreaction(f,u,node,data)
Similar to reaction, but restricted to the inner or outer boundaries.bcondition
Function. Alias forbreaction
.bsource
: Function. Boundary source term:bsource(f,node)
orbsource(f,node,data)
. It should return inf[i]
the value of the source term for the i-th equation.bstorage
: Function. Boundary storage term:bstorage(f,u,node)
orbstorage(f,u,node,data)
Similar to storage, but restricted to the inner or outer boundaries.generic_operator
: Function. Generic operatorgeneric_operator(f,u,sys)
. This operator acts on the full solutionu
of a system. Sparsity is detected automatically unlessgeneric_operator_sparsity
is given.generic_operator_sparsity
: Function defining the sparsity structure of the generic operator. This should return the sparsity pattern of thegeneric_operator
.nparams
: number of parameters the system is depending on, and with respect to which the derivatives need to be obtaineddata
: User data (parameters). This allows to pass various parameters to the callback functions. Ifdata
is given, all callback functions should accept a lastdata
argument. Otherwise, no data are passed explicitly, and constitutive callbacks can take parameters from the closure where the function is defined.matrixtype
: :sparse, :tridiagonal, :banded, :auto. Default: :sparse. :auto leads to automatic choice for dense solution storage depending on space dimension and number of species.
VoronoiFVM.System
— MethodSystem(X; kwargs...)
Create an 1D grid from vector X and call VoronoiFVM.System(grid::ExtendableGrid; kwargs...)
.
VoronoiFVM.System
— MethodSystem(X,Y; kwargs...)
Create a 2D grid from vectors X,Y and call VoronoiFVM.System(grid::ExtendableGrid; kwargs...)
.
VoronoiFVM.System
— MethodSystem(X,Y, Z; kwargs...)
Create a 3D grid from vectors X,Y,Z and call VoronoiFVM.System(grid::ExtendableGrid; kwargs...)
.
VoronoiFVM.update_grid!
— Functionupdate_grid!(system; grid=system.grid)
Update grid (e.g. after rescaling of coordinates). Uses a lock to ensure parallel access.
VoronoiFVM.physics!
— Functionphysics!(system,physics)
Replace System's physics data
physics!(system; kwargs...)
Replace System's physics data.
Adding species by species numbers
VoronoiFVM.enable_species!
— Methodenable_species!(system,ispec,regions)
Add species ispec
to a list of bulk regions. Species numbers for bulk and boundary species have to be distinct. Once a species has been added, it cannot be removed.
VoronoiFVM.enable_species!
— Methodenable_species!(system; kwargs...)
Keyword arguments:
species
: Integer or vector of integers. Species to be added to the system.regions
: Vector of integers. Regions, where these species shall be added.Ifnothing
, they are added to all species.
Once a species has been added, it cannot be removed.
VoronoiFVM.enable_boundary_species!
— Functionenable_boundary_species!(system,ispec,regions)
Add species ispec
to a list of boundary regions. Species numbers for bulk and boundary species have to be distinct. Once a species has been added, it cannot be removed.
VoronoiFVM.is_boundary_species
— Functionis_boundary_species(AbstractSystem, ispec) -> Bool
Check if species number corresponds to a boundary species.
VoronoiFVM.is_bulk_species
— Functionis_bulk_species(AbstractSystem, ispec) -> Bool
Check if species number corresponds to a bulk species.
Allocation warnings
The code checks for allocations in the assembly loop. Care has been taken to ensure that allocations in the assembly loop don't emerge from VoronoiFVM.jl code.
If allocations occur in the assembly loop, they happen in the physics callbacks. The corresponding warnings can bee switched off by passing a verbosity strings without 'a' to the solver. If no data are allocated in the physics callbacks, these allocations are probably due to type instabilities in physics callbacks. Type instabilities can be debugged via the @time
macro applied to expressions in a physics callback.
The following cases provide some ideas where to look for reasons of the problem and possible remedies:
Case 1: a parameter changes its value, and Julia is not sure about the type.
eps=1.0
flux(f,u,edge)
f[1]=eps*(u[1,1]-[1,2])
end
... solve etc ...
eps=2.0
Remedy: use a type annotation eps::Float64=...
to signalize your intent to Julia. This behaviour is explained in the Julia documentation.
Case 2: variables in the closure have the same name as a variable introduced in a callback.
flux(f,u,edge)
x=(u[1,1]-[1,2])
f[1]=x
end
... create etc ...
x=solve(...)
Remedy: rename e.g. x=solve()
to sol=solve()
Various tools
VoronoiFVM.num_dof
— Functionnum_dof(system)
Number of degrees of freedom for system.
VoronoiFVM.num_species
— Functionnum_species(edge::VoronoiFVM.AbstractEdge) -> Any
Return number of species for edge
num_species(system)
Number of species in system
num_species(a)
Number of species (size of first dimension) of solution array.
VoronoiFVM.data
— Functiondata(system)
Retrieve user data record.
VoronoiFVM.unknowns
— Methodunknowns(system; inival, inifunc)
Create a solution vector for system. If inival is not specified, the entries of the returned vector are undefined.
unknowns(impedance_system)
Create a vector of unknowns of the impedance system
VoronoiFVM.unknowns
— Methodunknowns(Tu, system; inival, inifunc)
Create a solution vector for system with elements of type Tu
. If inival is not specified, the entries of the returned vector are undefined.
Base.map
— Functionmap(inifunc, sys)
Create a solution vector for system using the callback inifunc
which has the same signature as a source term.
map(inival, sys)
Create a solution vector for system using a constant initial value
Base.map!
— Functionmap!(inifunc, U, system)
Map inifunc
onto solution array U
VoronoiFVM.isunknownsof
— Functionisunknownsof(u, sys)
Detect if array fits to the system.
Base.reshape
— Methodreshape(v, system)
Reshape vector to fit as solution to system.
Types
VoronoiFVM.AbstractSystem
— Typeabstract type AbstractSystem{Tv<:Number, Tc<:Number, Ti<:Integer, Tm<:Integer}
Abstract type for finite volume system structure.
VoronoiFVM.System
— Typemutable struct System{Tv, Tc, Ti, Tm, TSpecMat<:(AbstractMatrix)} <: VoronoiFVM.AbstractSystem{Tv, Tc, Ti, Tm}
Structure holding data for finite volume system.
Subtype of AbstractSystem
.
Type parameters:
- TSpecMat: Type of matrix storing species information (Matrix or SparseMatrixCSC)
For the other type parameters, see AbstractSystem
.
grid::ExtendableGrid
: Grid
physics::VoronoiFVM.Physics
: Physics data
boundary_values::Matrix
: Array of boundary condition values
boundary_factors::Matrix
: Array of boundary condition factors
region_species::AbstractMatrix
: Matrix containing species numbers for inner regions
bregion_species::AbstractMatrix
: Matrix containing species numbers for boundary regions
node_dof::AbstractMatrix
: Matrix containing degree of freedom numbers for each node
matrixtype::Symbol
: - :multidiagonal (currently disabled)- :sparse
- :banded
- :tridiagonal
species_homogeneous::Bool
: Flag which says if the number of unknowns per node is constant
num_quantities::Any
: Number of quantities defined on system
num_parameters::Any
: Number of parameter the system depends on.
assembly_data::Union{Nothing, VoronoiFVM.AbstractAssemblyData{Tc, Ti}} where {Tc, Ti}
: Precomputed form factors for bulk assembly
boundary_assembly_data::VoronoiFVM.AbstractAssemblyData
: Precomputed form factors for boundary assembly
assembly_type::Symbol
: :edgewise or :cellwise
is_linear::Bool
: Is the system linear ?
outflownoderegions::Union{Nothing, SparseArrays.SparseMatrixCSC{Bool, Int64}}
: Outflow nodes with their region numbers.
generic_matrix::SparseArrays.SparseMatrixCSC
: Sparse matrix for generic operator handling
generic_matrix_colors::Vector
: Sparse matrix colors for generic operator handling
is_complete::Bool
: Has the system been completed (species information compiled)?
Legacy API
VoronoiFVM.boundary_dirichlet!
— Methodboundary_dirichlet!(system, ispec, ibc, v)
Set Dirichlet boundary condition for species ispec at boundary ibc:
$u_{ispec}=v$ on $\Gamma_{ibc}$
Starting with version 0.14, it is preferable to define boundary conditions within the bcondition
physics callback
VoronoiFVM.boundary_dirichlet!
— Method boundary_dirichlet!(system; kwargs...)
Keyword argument version:
species
: species numberregion
: region numbervalue
: value
Starting with version 0.14, it is preferable to define boundary conditions within the bcondition
physics callback
VoronoiFVM.boundary_neumann!
— Methodboundary_neumann!(system, ispec, ibc, v)
Set Neumann boundary condition for species ispec at boundary ibc:
$\mathrm{flux}_{ispec}\cdot \vec n=v$ on $\Gamma_{ibc}$
Starting with version 0.14, it is preferable to define boundary conditions within the bcondition
physics callback
VoronoiFVM.boundary_neumann!
— Method boundary_neumann!(system; kwargs...)
Keyword argument version:
species
: species numberregion
: region numbervalue
: value
Starting with version 0.14, it is preferable to define boundary conditions within the bcondition
physics callback
VoronoiFVM.boundary_robin!
— Methodboundary_robin!(system, ispec, ibc, α, v)
Set Robin boundary condition for species ispec at boundary ibc:
$\mathrm{flux}_{ispec}\cdot \vec n + \alpha u_{ispec}=v$ on $\Gamma_{ibc}$
Starting with version 0.14, it is preferable to define boundary conditions within the bcondition
physics callback
VoronoiFVM.boundary_robin!
— Method boundary_robin!(system; kwargs...)
Keyword argument version:
species
: species numberregion
: region numberfactor
: factorvalue
: value
Starting with version 0.14, it is preferable to define boundary conditions within the bcondition
physics callback
VoronoiFVM.DenseSystem
— Typeconst DenseSystem
Type alias for system with dense matrix based species management
VoronoiFVM.SparseSystem
— Typeconst SparseSystem
Type alias for system with sparse matrix based species management
VoronoiFVM.viewK
— FunctionviewK(
edge::VoronoiFVM.AbstractEdge,
u
) -> VoronoiFVM.VectorUnknowns
Solution view on first edge node
VoronoiFVM.viewL
— FunctionviewL(
edge::VoronoiFVM.AbstractEdge,
u
) -> VoronoiFVM.VectorUnknowns
Solution view on second edge node