Commit a6d51cdb authored by Dave Moxey's avatar Dave Moxey
Browse files

Merge branch 'master' into feature/APE-advection

parents 75fd7a44 59375c22
......@@ -22,7 +22,13 @@ ENABLE_TESTING()
# Use the CMake 2.4 policy for CMake 2.6
IF(COMMAND cmake_policy)
cmake_policy(SET CMP0003 OLD)
CMAKE_POLICY(SET CMP0003 OLD)
# Silence warnings when using generator expressions in
# TARGET_LINK_LIBRARIES.
IF(POLICY CMP0022)
CMAKE_POLICY(SET CMP0022 NEW)
ENDIF()
ENDIF(COMMAND cmake_policy)
# Find the modules included with Nektar
......
......@@ -48,7 +48,7 @@ IF (THIRDPARTY_BUILD_ZLIB)
)
IF (WIN32)
SET(ZLIB_LIBRARY zlib)
SET(ZLIB_LIBRARY_DEBUG zlib)
SET(ZLIB_LIBRARY_DEBUG zlibd)
SET(ZLIB_LIBRARY_RELEASE zlib)
ELSE (WIN32)
SET(ZLIB_LIBRARY z)
......
\chapter{Data Structures and Algorithms}
\label{ch:data}
\input{connectivity}
\input{time-integration}
\ No newline at end of file
\input{time-integration}
\input{preconditioners}
\ No newline at end of file
\section{Preconditioners}
\label{sec:precon}
Most of the solvers in \nekpp, including the incompressible Navier-Stokes
equations, rely on the solution of a Helmholtz equation,
%
\begin{equation}
\nabla^{2}u(\mathbf{x})+\lambda u(\mathbf{x})=f(\mathbf{x}),
\label{eq:precon:helm}
\end{equation}
%
an elliptic boundary value problem, at every time-step, where $u$ is defined on
a domain $\Omega$ of $N_{\mathrm{el}}$ non-overlapping elements. In this
section, we outline the preconditioners which are implemented in \nekpp. Whilst
some of the preconditioners are generic, many are especially designed for the
\emph{modified} basis only.
\subsection{Mathematical formulation}
The standard spectral/$hp$ approach to discretise \eqref{eq:precon:helm} starts
with an expansion in terms of the elemental modes:
%
\begin{equation}
u^{\delta}(\mathbf{x})=\sum_{n=0}^{N_{\mathrm{dof}}-1}\hat{u}_n
\Phi_n(\mathbf{x})=\sum_{e=1}^{{N_{\mathrm{el}}}}
\sum_{n=0}^{N^{e}_m-1}\hat{u}_n^e\phi_n^e(\mathbf{x})
\label{eq:precon:disc}
\end{equation}
%
where $N_{\mathrm{el}}$ is the number of elements, $N^{e}_m$ is the number of
local expansion modes within the element $\Omega^e$, $\phi_n^e(\mathbf{x})$ is
the $n^{\mathrm{th}}$ local expansion mode within the element $\Omega^e$,
$\hat{u}_n^e$ is the $n^{\mathrm{th}}$ local expansion coefficient within the
element $\Omega^e$. Approximating our solution by~\eqref{eq:precon:disc}, we
adopt a Galerkin discretisation of equation~\eqref{eq:precon:helm} where for an
appropriate test space $V^\delta$ we find an approximate solution
$\mathbf{u}^{\delta} \in V^{\delta}$ such that
%
\[
\mathcal L \left({v, u}\right) = \int_{\Omega}\nabla v^{\delta} \cdot \nabla
u^{\delta} + \lambda v^{\delta} u^{\delta} d \mathbf{x} = \int_{\Omega}
v^{\delta} f d\mathbf{x} \quad \forall v^{\delta} \in V^{\delta}
\]
%
This can be formulated in matrix terms as
%
\[
\mathbf{H}\hat{\mathbf{u}} = \mathbf{f}
\]
%
where $\mathbf{H}$ represents the Helmholtz matrix, $\hat{\mathbf{u}}$ are the
unknown global coefficients and $\mathbf{f}$ the inner product the expansion
basis with the forcing function.
\subsubsection{$C^0$ formulation}
We first consider the $C^0$ (i.e. continuous Galerkin) formulation. The
spectral/$hp$ expansion basis is obtained by considering interior modes, which
have support in the interior of the element, separately from boundary modes
which are non-zero on the boundary of the element. We align the boundary modes
across the interface of the elements to obtain a continuous global solution. The
boundary modes can be further decomposed into vertex, edge and face modes,
defined as follows:
\begin{itemize}
\item vertex modes have support on a single vertex and the three adjacent
edges and faces as well as the interior of the element;
\item edge modes have support on a single edge and two adjacent faces as well
as the interior of the element;
\item face modes have support on a single face and the interior of the
element.
\end{itemize}
When the discretisation is continuous, this strong coupling between vertices,
edges and faces leads to a matrix of high condition number $\kappa$. Our aim is
to reduce this condition number by applying specialised
preconditioners. Utilising the above mentioned decomposition, we can write the
matrix equation as:
%
\[
\left[\begin{array}{cc}
\mathbf{H}_{bb} & \mathbf{H}_{bi}\\
\mathbf{H}_{ib} & \mathbf{H}_{ii}
\end{array}\right]
\left[ \begin{array}{c}
\hat{\mathbf{u}}_{b}\\
\hat{\mathbf{u}}_{i}\\
\end{array}\right] =
\left[ \begin{array}{c}
\hat{\mathbf{f}}_{b}\\
\hat{\mathbf{f}}_{i}\\
\end{array}\right]
\]
%
where the subscripts $b$ and $i$ denote the boundary and interior degrees of
freedom respectively. This system then can be statically condensed allowing us
to solve for the boundary and interior degrees of freedom in a decoupled
manor. The statically condensed matrix is given by
%
\[
\left[\begin{array}{cc}
\mathbf{H}_{bb}-\mathbf{H}_{bi} \mathbf{H}_{ii}^{-1} \mathbf{H}_{ib} & 0\\
\mathbf{H}_{ib} & \mathbf{H}_{ii}
\end{array}\right]
\left[ \begin{array}{c}
\hat{\mathbf{u}}_{b}\\
\hat{\mathbf{u}}_{i}\\
\end{array}\right] =
\left[ \begin{array}{c}
\hat{\mathbf{f}}_{b}-\mathbf{H}_{bi} \mathbf{H}_{ii}^{-1}\hat{\mathbf{f}}_{i}\\
\hat{\mathbf{f}}_{i}\\
\end{array}\right]
\]
%
This is highly advantageous since by definition of our interior expansion this
vanishes on the boundary, and so $\mathbf{H}_{ii}$ is block diagonal and thus
can be easily inverted. The above sub-structuring has reduced our problem to
solving the boundary problem:
%
\[
\mathbf{S}_{1}\hat{\mathbf{u}} = \hat{\mathbf{f}}_{1}
\]
%
where
$\mathbf{S_{1}}=\mathbf{H}_{bb}-\mathbf{H}_{bi} \mathbf{H}_{ii}^{-1}
\mathbf{H}_{ib}$
and
$\hat{\mathbf{f}}_{1}=\hat{\mathbf{f}}_{b}-\mathbf{H}_{bi}
\mathbf{H}_{ii}^{-1}\hat{\mathbf{f}}_{i}$.
Although this new system typically has better convergence properties (i.e lower
$\kappa$), the system is still ill-conditioned, leading to a convergence rate of
the conjugate gradient (CG) routine that is prohibitively slow. For this reason
we need to precondition $\mathbf{S}_1$. To do this we solve an equivalent
system of the form:
%
\[
\mathbf{M}^{-1}\left(\mathbf{S}_{1} \hat{\mathbf{u}} - \hat{\mathbf{f}}_{1} \right) = 0
\]
%
where the preconditioning matrix $\mathbf{M}$ is such that
$\kappa\left(\mathbf{M}^{-1} \mathbf{S}_{1}\right)$ is less than
$\kappa\left(\mathbf{S}_{1}\right)$ and speeds up the convergence rate. Within
the conjugate gradient routine the same preconditioner $\mathbf{M}$ is applied
to the residual vector $\hat{\mathbf{r}}_{k+1}$ of the CG routine every
iteration:
%
\[
\hat{\mathbf{z}}_{k+1}=\mathbf{M}^{-1}\hat{\mathbf{r}}_{k+1}.
\]
%
\subsubsection{HDG formulation}
When utilising a hybridizable discontinuous Galerkin formulation, we perform a
static condensation approach but in a discontinuous framework, which for brevity
we omit here. However, we still obtain a matrix equation of the form
%
\[
\mathbf{\Lambda}\hat{\mathbf{u}} = \hat{\mathbf{f}}.
\]
%
where $\mathbf{\Lambda}$ represents an operator which projects the solution of
each face back onto the three-dimensional element or edge onto the
two-dimensional element. In this setting then, $\hat{\mathbf{f}}$ consists of
degrees of freedom for each egde (in 2D) or face (in 3D). The overall system
does not, therefore, results in a weaker coupling between degrees of freedom,
but at the expense of a larger matrix system.
\subsection{Preconditioners}
Within the \nekpp framework a number of preconditioners are available to speed
up the convergence rate of the conjugate gradient routine. The table below
summarises each method, the dimensions of elements which are supported, and also
the discretisation type support which can either be continuous (CG) or
discontinuous (hybridizable DG).
\begin{center}
\begin{tabular}{lll}
\toprule
\textbf{Name} & \textbf{Dimensions} & \textbf{Discretisations} \\
\midrule
\inltt{Null} & All & All \\
\inltt{Diagonal} & All & All \\
\inltt{FullLinearSpace} & 2/3D & CG \\
\inltt{LowEnergyBlock} & 3D & CG \\
\inltt{Block} & 2/3D & All \\
\midrule
\inltt{FullLinearSpaceWithDiagonal} & All & CG \\
\inltt{FullLinearSpaceWithLowEnergyBlock} & 2/3D & CG \\
\inltt{FullLinearSpaceWithBlock} & 2/3D & CG \\
\bottomrule
\end{tabular}
\end{center}
The default is the \inltt{Diagonal} preconditioner. The above preconditioners
are specified through the \inltt{Preconditioner} option of the
\inltt{SOLVERINFO} section in the session file. For example, to enable
\inltt{FullLinearSpace} one can use:
\begin{lstlisting}[style=XMLStyle]
<I PROPERTY="Preconditioner" VALUE="FullLinearSpace" />
\end{lstlisting}
Alternatively one can have more control over different preconditioners for each
solution field by using the \inltt{GlobalSysSoln} section. For more details,
consult the user guide. The following sections specify the details for each
method.
\subsubsection{Diagonal}
Diagonal (or Jacobi) preconditioning is amongst the simplest preconditioning
strategies. In this scheme one takes the global matrix $\mathbf{H} = (h_{ij})$
and computes the diagonal terms $h_{ii}$. The preconditioner is then formed as a
diagonal matrix $\mathbf{M}^{-1} = (h_{ii}^{-1})$.
\subsubsection{Linear space}
The linear space (or coarse space) of the matrix system is that containing
degrees of freedom corresponding only to the vertex modes in the high-order
system. Preconditioning of this space is achieved by forming the matrix
corresponding to the coarse space and inverting it, so that
%
\[
\mathbf{M}^{-1} = (\mathbf{S}^{-1}_{1})_{vv}
\]
%
Since the mesh associated with higher order methods is relatively coarse
compared with traditional finite element discretisations, the linear space can
usually be directly inverted without memory issues. However such a methodology
can be prohibitive on large parallel systems, due to a bottleneck in
communication.
In \nekpp the inversion of the linear space present is handled using the
$XX^{T}$ library. $XX^{T}$ is a parallel direct solver for problems of the form
$\mathbf{A}\hat{\mathbf{x}} = \hat{\mathbf{b}}$ based around a sparse
factorisation of the inverse of $\mathbf{A}$. To precondition utilising this
methodology the linear sub-space is gathered from the expansion and the
preconditioned residual within the CG routine is determined by solving
%
\[
(\mathbf{S}_{1})_{vv}\hat{\mathbf{z}}=\hat{\mathbf{r}}
\]
%
The preconditioned residual $\hat{\mathbf{z}}$ is then scattered back to the
respective location in the global degrees of freedom.
\subsubsection{Block}
Block preconditioning of the $C^0$ continuous system is defined by the
following:
%
\[
\mathbf{M}^{-1}=\left[ \begin{array}{ccc}
(\mathbf{S}^{-1}_{1})_{vv} & 0 & 0 \\
0 & (\mathbf{S}^{-1}_{1})_{eb} & 0\\
0 & 0 & (\mathbf{S}^{-1}_{1})_{ef}\\
\end{array} \right]
\]
%
where $\mathrm{diag}[(\mathbf{S}_{1})_{vv}]$ is the diagonal of the vertex
modes, $(\mathbf{S}_{1})_{eb}$ and $(\mathbf{S}_{1})_{fb}$ are block diagonal
matrices corresponding to coupling of an edge (or face) with itself i.e ignoring
the coupling to other edges and faces. This preconditioner is best suited for
two dimensional problems.
In the HDG system, we take the block corresponding to each face and invert
it. Each of these inverse blocks then forms one of the diagonal components of
the block matrix $\mathbf{M}^{-1}$.
\subsection{Low energy}
Low energy basis preconditioning follows the methodology proposed by Sherwin \&
Casarin. In this method a new basis is numerically constructed from the original
basis which allows the Schur complement matrix to be preconditioned using a
block preconditioner. The method is outlined briefly in the following.
Elementally the local approximation $\mathbf{u}^{\delta}$ can be expressed as
different expansions lying in the same discrete space $V^{\delta}$
%
\[
\mathbf{u}^{\delta}(\mathbf{x})=\sum_{i}^{\dim(V^{\delta})}\hat{u}_{1i}\phi_{1i}(x)
= \sum_{i}^{\dim(V^{\delta})}\hat{u}_{2i}\phi_{2j}(x)
\]
%
Since both expansions lie in the same space it's possible to express one basis
in terms of the other via a transformation, i.e.
%
\[
\phi_{2}=\mathbf{C}\phi_{1} \implies \hat{\mathbf{u}}_{1}=C^{T}\hat{\mathbf{u}}_{2}
\]
%
Applying this to the Helmholtz operator it is possible to show that,
%
\[
\mathbf{H}_{2}=\mathbf{C}\mathbf{H}_{1}\mathbf{C}^{T}
\]
%
For sub-structured matrices ($\mathbf{S}$) the transformation matrix
($\mathbf{C}$) becomes:
%
\[
\mathbf{C}=\left[ \begin{array}{cc}
\mathbf{R} & 0\\
0 & \mathbf{I}
\end{array} \right]
\]
%
Hence the transformation in terms of the Schur complement matrices is:
%
\[
\mathbf{S}_{2}=\mathbf{R}\mathbf{S}_{1}\mathbf{R}^{T}
\]
%
Typically the choice of expansion basis $\phi_{1}$ can lead to a Helmholtz
matrix that has undesirable properties i.e poor condition number. By choosing a
suitable transformation matrix $\mathbf{C}$ it is possible to construct a new
basis, numerically, that is amenable to block diagonal preconditioning.
%
\[
\mathbf{S}_{1}=\left[ \begin{array}{ccc}
\mathbf{S}_{vv} & \mathbf{S}_{ve} & \mathbf{S}_{vf}\\
\mathbf{S}^{T}_{ve}& \mathbf{S}_{ee} & \mathbf{S}_{ef} \\
\mathbf{S}^{T}_{vf} & \mathbf{S}^{T}_{ef} & \mathbf{S}_{ff} \end{array} \right] =\left[ \begin{array}{cc}
\mathbf{S}_{vv} & \mathbf{S}_{v,ef} \\
\mathbf{S}^{T}_{v,ef} & \mathbf{S}_{ef,ef} \end{array} \right]
\]
%
Applying the transformation
$\mathbf{S}_{2}=\mathbf{R} \mathbf{S}_{1} \mathbf{R}^{T}$ leads to the following
matrix
%
\[
\mathbf{S}_{2}=\left[ \begin{array}{cc}
\mathbf{S}_{vv}+\mathbf{R}_{v}\mathbf{S}^{T}_{v,ef}+\mathbf{S}_{v,ef}\mathbf{R}^{T}_{v}+\mathbf{R}_{v}\mathbf{S}_{ef,ef}\mathbf{R}^{T}_{v} & [\mathbf{S}_{v,ef}+\mathbf{R}_{v}\mathbf{S}_{ef,ef}]\mathbf{A}^{T} \\
\mathbf{A}[\mathbf{S}^{T}_{v,ef}+\mathbf{S}_{ef,ef}\mathbf{R}^{T}_{v}] & \mathbf{A}\mathbf{S}_{ef,ef}\mathbf{A}^{T} \end{array} \right]
\]
%
where $\mathbf{A}\mathbf{S}_{ef,ef}\mathbf{A}^{T}$ is given by
%
\[
\mathbf{A}\mathbf{S}_{ef,ef}\mathbf{A}^{T}=\left[ \begin{array}{cc}
\mathbf{S}_{ee}+\mathbf{R}_{ef}\mathbf{S}^{T}_{ef}+\mathbf{S}_{ef}\mathbf{R}^{T}_{ef}+\mathbf{R}_{ef}\mathbf{S}_{ff}\mathbf{R}^{T}_{ef} & \mathbf{S}_{ef}+\mathbf{R}_{ef}\mathbf{S}_{ff}\\
\mathbf{S}^{T}_{ef}+\mathbf{S}_{ff}\mathbf{R}^{T}_{ef} & \mathbf{S}_{ff}
\end{array} \right]
\]
%
To orthogonalise the vertex-edge and vertex-face modes, it can be seen from the
above that
%
\[
\mathbf{R}^{T}_{ef}=-\mathbf{S}^{-1}_{ff}\mathbf{S}^{T}_{ef}
\]
%
and for the edge-face modes:
%
\[
\mathbf{R}^{T}_{v}=-\mathbf{S}^{-1}_{ef,ef}\mathbf{S}^{T}_{v,ef}
\]
%
Here it is important to consider the form of the expansion basis since the
presence of $\mathbf{S}^{-1}_{ff}$ will lead to a new basis which has support on
all other faces; this is problematic when creating a $C^{0}$ continuous global
basis. To circumvent this problem when forming the new basis, the decoupling is
only performed between a specific edge and the two adjacent faces in a symmetric
standard region. Since the decoupling is performed in a rotationally symmetric
standard region the basis does not take into account the Jacobian mapping
between the local element and global coordinates, hence the final expansion will
not be completely orthogonal.
The low energy basis creates a Schur complement matrix that although it is not
completely orthogonal can be spectrally approximated by its block diagonal
contribution. The final form of the preconditioner is:
%
\[
\mathbf{M}^{-1}=\left[ \begin{array}{ccc}
\mathrm{diag}[(\mathbf{S}_{2})_{vv}] & 0 & 0 \\
0 & (\mathbf{S}_{2})_{eb} & 0\\
0 & 0 & (\mathbf{S}_{2})_{fb}\\
\end{array} \right]^{-1}
\]
%
where $\mathrm{diag}[(\mathbf{S}_{2})_{vv}]$ is the diagonal of the vertex
modes, $(\mathbf{S}_{2})_{eb}$ and $(\mathbf{S}_{2})_{fb}$ are block diagonal
matrices corresponding to coupling of an edge (or face) with itself i.e ignoring
the coupling to other edges and faces.
......@@ -38,3 +38,24 @@ When using a fully-Fourier expansion, specifies the number of processes to use i
\lstinline[style=BashInputStyle]{--npz [int]}\\
\hangindent=1.5cm
When using Fourier expansions, specifies the number of processes to use in the z-coordinate direction.
\lstinline[style=BashInputStyle]{--part-info}\\
\hangindent=1.5cm
Prints detailed information about the generated partitioning, such as number of
elements, number of local degrees of freedom and the number of boundary degrees
of freedom.
\lstinline[style=BashInputStyle]{--part-only [int]}\\
\hangindent=1.5cm
Partition the mesh only into the specified number of partitions, write to file
and exit. This can be used to pre-partition a very large mesh on a single
high-memory node, prior to being executed on a multi-node cluster.
\lstinline[style=BashInputStyle]{--use-metis}\\
\hangindent=1.5cm
Forces the use of METIS for mesh partitioning. If \nekpp{} is compiled with
Scotch support, the default is to use Scotch.
\lstinline[style=BashInputStyle]{--use-scotch}\\
\hangindent=1.5cm
Forces the use of Scotch for mesh partitioning.
......@@ -71,15 +71,21 @@ CardiacEPSolver session.xml
\section{Session file configuration}
\subsection{Solver Info}
\begin{itemize}
\item \inltt{Eqtype} Specifies the PDE system to solve. This should take
the value \inltt{Monodomain}.
\item \inltt{Eqtype} Specifies the PDE system to solve. The following values
are supported:
\begin{itemize}
\item \inltt{Monodomain}: solve the monodomain equation.
\item \inltt{BidomainRoth}: solve the bidomain equations using the Roth
formulation.
\end{itemize}
\item \inltt{CellModel} Specifies the cell model to use. Available cell
models are
\begin{center}
\begin{tabular}{l|l|l|l}
\toprule
Value & Description & No. of Var. & Ref. \\
\hline
\midrule
\inltt{AlievPanfilov} & Phenomological & 1 & \cite{AlPa96} \\
\inltt{CourtemancheRamirezNattel98} & Human atrial & 20 & \cite{CoRaNa98} \\
\inltt{FitzHughNagumo} & & & \\
......@@ -88,7 +94,7 @@ CardiacEPSolver session.xml
\inltt{PanditGilesDemir03} & & & \\
\inltt{TenTusscher06} & Human ventricular & 18 & \cite{TuPa06} \\
\inltt{Winslow99} & & & \\
\hline
\bottomrule
\end{tabular}
\end{center}
......@@ -154,7 +160,7 @@ $\mathbf{\sigma}$ of the tissue.
\subsection{Filters}
\begin{itemize}
\item \inltt{CheckpointCellModel} checkpoints the cell model. Can be
used along with the \inltt{Checkpoint Filter} to record complete simulation
used along with the \inltt{Checkpoint} filter to record complete simulation
state and regular intervals.
\begin{lstlisting}[style=XmlStyle]
<FILTER TYPE="CheckpointCellModel">
......@@ -190,6 +196,30 @@ $\mathbf{\sigma}$ of the tissue.
\item \inltt{Points} specifies a list of coordinates at which electrograms
are desired. \emph{They must not lie within the domain.}
\end{itemize}
\item \inltt{Benchmark} Records spatially distributed event times for
activation and repolarisation (recovert) during a simulation, for
undertaking benchmark test problems.
\begin{lstlisting}[style=XmlStyle]
<FILTER TYPE="Benchmark">
<PARAM NAME="ThresholdValue"> -40.0 </PARAM>
<PARAM NAME="InitialValue"> 0.0 </PARAM>
<PARAM NAME="OutputFile"> benchmark </PARAM>
<PARAM NAME="StartTime"> 0.0 </PARAM>
</FILTER>
\end{lstlisting}
\begin{itemize}
\item \inltt{ThresholdValue} specifies the value above which tissue is
considered to be depolarised and below which is considered
repolarised.
\item \inltt{InitialValue} specifies the initial value of the
activation or repolarisation time map.
\item \inltt{OutputFile} specifies the base filename of activation and
repolarisation maps output from the filter. This name is appended
with the index of the event and the suffix `.fld`.
\item \inltt{StartTime} (optional) specifies the simulation time at
which to start detecting events.
\end{itemize}
\end{itemize}
......
......@@ -155,7 +155,7 @@ every 10 timesteps, we use the syntax:
</FILTER>
\end{lstlisting}
\subsection {Threshold value}
\subsection {ThresholdMax}
The threshold value filter writes a field output containing a variable $m$,
defined by the time at which the selected variable first exceeds a specified
......@@ -171,14 +171,16 @@ The following parameters are supported:
\textbf{Option name} & \textbf{Required} & \textbf{Default} &
\textbf{Description} \\
\midrule
\inltt{OutputFile} & & \emph{session}\_max.fld &
\inltt{OutputFile} & \xmark & \emph{session}\_max.fld &
Output filename to which the threshold times are written.\\
\inltt{ThresholdVar} & & \emph{first variable name} &
\inltt{ThresholdVar} & \xmark & \emph{first variable name} &
Specifies the variable on which the threshold will be applied.\\
\inltt{ThresholdValue} & \cmark & - &
Specifies the threshold value.\\
\inltt{InitialValue} & \cmark & - &
Specifies the initial time.\\
\inltt{StartTime} & \xmark & 0.0 &
Specifies the time at which to start recording.\\
\bottomrule
\end{tabularx}
\end{center}
......@@ -194,7 +196,12 @@ An example is given below:
</FILTER>
\end{lstlisting}
which produces a field file \inltt{threshold\_max.fld}.
which produces a field file \inlsh{threshold\_max.fld}.
\subsection{ThresholdMin value}
Performs the same function as the \inltt{ThresholdMax} filter but records the
time at which the threshold variable drops below a prescribed value.
\subsection{Modal energy}
......
......@@ -86,17 +86,15 @@ namespace Nektar
}
void MeshPartition::PartitionMesh(bool shared)
void MeshPartition::PartitionMesh(int nParts, bool shared)
{
ASSERTL0(m_comm->GetRowComm()->GetSize() > 1,
"Partitioning only necessary in parallel case.");
ASSERTL0(m_meshElements.size() >= m_comm->GetRowComm()->GetSize(),
ASSERTL0(m_meshElements.size() >= nParts,
"Too few elements for this many processes.");
m_shared = shared;