At the left hand side, we have just an ordinary \verb+Simple_ZOT+. At the right hand side, we have a zero order term of the form $f(u)$ with $f=I$ the identity. $u$ is given by the solution DOF vector of \verb+problem1+. $I$ maps the values of the DOF vector evaluated at quadrature points to itself. The function degree is used to determine the needed quadrature degree in the assembler.

At the left hand side, we have just an ordinary \verb+Simple_ZOT+. At

the right hand side, we have a zero order term of the form $f(u)$ with

$f=I$ the identity. $u$ is given by the solution DOF vector of

\verb+problem1+. $I$ maps the values of the DOF vector evaluated at

quadrature points to itself. The function degree is used to determine

the needed quadrature degree in the assembler.

Now, the adaptation loop is created:

...

...

@@ -214,9 +220,12 @@ Now, the adaptation loop is created:

adaptInfo);

\end{lstlisting}

Note that not a pointer to one of the problems is passed to the adaptation loop, but a pointer to the \verb+coupledIteration+ object, which in turn knows both problems.

Note that not a pointer to one of the problems is passed to the

adaptation loop, but a pointer to the \verb+coupledIteration+ object,

which in turn knows both problems.

The adaptation loop is now started. After it is finished, the solutions of both problems are written.

The adaptation loop is now started. After it is finished, the

The coupled problem consits of two sub problems. The first problem creates the mesh, solves its linear system of equations, estimates the error, adapts the mesh, and finally writes its output:

The coupled problem consits of two sub problems. The first problem

creates the mesh, solves its linear system of equations, estimates the

error, adapts the mesh, and finally writes its output:

The second problem uses the mesh of \verb+problem1+. So it creates no mesh, no estimator, and no marker. But a solver is needed to solve \verb+problem2+s linear system of equations, and a file writer to write the solution:

The second problem uses the mesh of \verb+problem1+. So it creates no

mesh, no estimator, and no marker. But a solver is needed to solve

\verb+problem2+s linear system of equations, and a file writer to

write the solution:

\begin{lstlisting}{}

problem2->dim: 2

...

...

@@ -288,9 +302,13 @@ problem2->output->AMDiS data ext: .dat

\end{lstlisting}

\subsection{Macro file}

We again use the macro file \verb+macro/macro.stand.2d+, which was described in Section \ref{s:ellipt macro}.

We again use the macro file \verb+macro/macro.stand.2d+, which was

described in Section \ref{s:ellipt macro}.

\subsection{Output}

The solution of the first problem is written to the files \verb+output/problem1.mesh+ and\\\verb+output/problem1.dat+.

The solution of the second problem is written to the files\\\verb+output/problem2.mesh+ and \verb+output/problem2.dat+.

We don't visualize the results here, because they conform with the results showed in Section \ref{s:vecellipt output}.

The solution of the first problem is written to the files

\verb+output/problem1.mesh+ and\\\verb+output/problem1.dat+. The

solution of the second problem is written to the files\\

\verb+output/problem2.mesh+ and \verb+output/problem2.dat+. We don't

visualize the results here, because they conform with the results

This is an example for a time dependent scalar problem. The problem is described by the heat equation

This is an example for a time dependent scalar problem. The problem is

described by the heat equation

\begin{eqnarray}

\label{eq:heat}

\partial_t u - \Delta u &=& f ~~~~~~~ \mbox{in }\Omega\subset\mathbb{R}^{dim}\times\left({t^{begin}},t^{end}\right)\\

...

...

@@ -9,18 +10,30 @@ u &=& g ~~~~~~~ \mbox{on } \partial\Omega \times\left({t^{begin}},t^{end}\right)

u &=& u_0 ~~~~~ \mbox{on }\Omega\times\left({t^{begin}}\right).

\end{eqnarray}

We solve the problem in the time interval $\left(t^{begin},t^{end}\right)$ with Dirichlet boundary conditions on $\partial\Omega$. The problem is constructed, such that the exact solution is $u(x,t)=\mbox{sin}(\pi t)e^{-10x^2}$. So we set

We solve the problem in the time interval

$\left(t^{begin},t^{end}\right)$ with Dirichlet boundary conditions on

$\partial\Omega$. The problem is constructed, such that the exact

solution is $u(x,t)=\mbox{sin}(\pi t)e^{-10x^2}$. So we set

$\tau= t^{new}- t^{old}$ is the timestep size between the old and the new problem time. $u^{new}$ is the (searched) solution at $t=t^{new}$. $u^{old}$ is the solution at $t=t^{old}$, which is already known from the last timestep. The parameter $\theta$ determines the implicit and explicit treatment of $\Delta u$. For $\theta=0$ we have the forward explicit Euler scheme, for $\theta=1$ the backward implicit Euler scheme. $\theta=0.5$ results in the Crank-Nicholson scheme. If we bring all terms that depend on $u^{old}$ to the right hand side, the equation reads

$\tau= t^{new}- t^{old}$ is the timestep size between the old and

the new problem time. $u^{new}$ is the (searched) solution at

$t=t^{new}$. $u^{old}$ is the solution at $t=t^{old}$, which is

already known from the last timestep. The parameter $\theta$

determines the implicit and explicit treatment of $\Delta u$. For

$\theta=0$ we have the forward explicit Euler scheme, for $\theta=

1$ the backward implicit Euler scheme. $\theta=0.5$ results in the

Crank-Nicholson scheme. If we bring all terms that depend on $u^{old}$

@@ -114,11 +127,31 @@ The next lines show the implementation of the time interface.

}

\end{lstlisting}

The method \verb+setTime+ is called by the adaptation loop to inform the problem about the current time. The right hand side function $f$ will be evaluated at $t^{old}+\theta\tau= t^{new}-(1-\theta)\tau$, the Dirichlet boundary function $g$ at $t^{new}$. $t^{new}$ is the current time, $\tau$ is the current timestep, both set by the adaptation loop and stored in \verb+adaptInfo+. \verb+tau1+ stores the value of $\frac{1}{\tau}$, which is used later as factor for the zero order time discretization terms.

The method \verb+closeTimestep+ is called at the end of each timestep by the adaptation loop. In the default implementation of \verb+ProblemInstatScal::closeTimestep+, the solution is written to output files, if specified in the parameter file. Note that the base class implementation of a method must be explicitly called, if the method is overwritten in a sub class. The macro \verb+WAIT+ waits until the \verb+return+ key is pressed by the user, if the corresponding entry in the parameter file is set to 1. The macro \verb+WAIT_REALLY+ would wait, independent of parameter settings. If \verb+closeTimestep+ wouldn't be overloaded here, the default implementation without the \verb+WAIT+ statement would be called after each timestep.

Now, the implementation of the \verb+ProblemStatBase+ interface begins. As mentioned above, the instationary problem plays the role of the initial problem by implementing this interface.

The method \verb+setTime+ is called by the adaptation loop to inform

the problem about the current time. The right hand side function $f$

will be evaluated at $t^{old}+\theta\tau= t^{new}-(1-\theta)\tau$,

the Dirichlet boundary function $g$ at $t^{new}$. $t^{new}$ is the

current time, $\tau$ is the current timestep, both set by the

adaptation loop and stored in \verb+adaptInfo+. \verb+tau1+ stores the

value of $\frac{1}{\tau}$, which is used later as factor for the zero

order time discretization terms.

The method \verb+closeTimestep+ is called at the end of each timestep

by the adaptation loop. In the default implementation of

\verb+ProblemInstatScal::closeTimestep+, the solution is written to

output files, if specified in the parameter file. Note that the base

class implementation of a method must be explicitly called, if the

method is overwritten in a sub class. The macro \verb+WAIT+ waits

until the \verb+return+ key is pressed by the user, if the

corresponding entry in the parameter file is set to 1. The macro

\verb+WAIT_REALLY+ would wait, independent of parameter settings. If

\verb+closeTimestep+ wouldn't be overloaded here, the default

implementation without the \verb+WAIT+ statement would be called after

each timestep.

Now, the implementation of the \verb+ProblemStatBase+ interface

begins. As mentioned above, the instationary problem plays the role of

the initial problem by implementing this interface.

\begin{lstlisting}{}

void solve(AdaptInfo *adaptInfo)

...

...

@@ -137,7 +170,16 @@ Now, the implementation of the \verb+ProblemStatBase+ interface begins. As menti

}

\end{lstlisting}

Here, only the solve and the estimate step are overloaded. For the other steps, there are empty default implementations in \verb+ProblemInstatScal+. Since the mesh is not adapted in the initial problem, the initial adaptation loop will stop after one iteration. In the solve step, the exact solution is interpolated on the macro mesh and stored in the solution vector of the stationary problem. In the estimate step, the L2 error is computed. The maximal element error and the sum over all element errors are stored in \verb+adaptInfo+. To make the exact solution known to the problem, we need a setting function:

Here, only the solve and the estimate step are overloaded. For the

other steps, there are empty default implementations in

\verb+ProblemInstatScal+. Since the mesh is not adapted in the initial

problem, the initial adaptation loop will stop after one iteration. In

the solve step, the exact solution is interpolated on the macro mesh

and stored in the solution vector of the stationary problem. In the

estimate step, the L2 error is computed. The maximal element error and

the sum over all element errors are stored in \verb+adaptInfo+. To

make the exact solution known to the problem, we need a setting

The definition of class \verb+Heat+ is now finished. In the following, the main program is described.

The definition of class \verb+Heat+ is now finished. In the following,

the main program is described.

\begin{lstlisting}{}

int main(int argc, char** argv)

...

...

@@ -185,9 +228,15 @@ int main(int argc, char** argv)

heat.initialize(INIT_ALL);

\end{lstlisting}

So far, the stationary space problem \verb+heatSpace+ and the instationary problem \verb+heat+ were created and initialized. \verb+heatSpace+ is an instance of \verb+ProblemScal+. \verb+heat+ is an instance of the class \verb+Heat+ we defined above. \verb+heatSpace+ is given to \verb+heat+ as its stationary problem.

So far, the stationary space problem \verb+heatSpace+ and the

instationary problem \verb+heat+ were created and

initialized. \verb+heatSpace+ is an instance of

\verb+ProblemScal+. \verb+heat+ is an instance of the class

\verb+Heat+ we defined above. \verb+heatSpace+ is given to \verb+heat+

as its stationary problem.

The next step is the creation of the needed \verb+AdaptInfo+ objects and of the instationary adaptation loop:

The next step is the creation of the needed \verb+AdaptInfo+ objects

and of the instationary adaptation loop:

\begin{lstlisting}{}

// create adapt info for heat

...

...

@@ -204,7 +253,11 @@ The next step is the creation of the needed \verb+AdaptInfo+ objects and of the

adaptInfoInitial);

\end{lstlisting}

The object \verb+heatSpace+ is handed as \verb+ProblemIterationInterface+ (implemented by class\\\verb+ProblemScal+) to the adaptation loop. \verb+heat+ is interpreted as \verb+ProblemTimeInterface+ (implemented by class \verb+ProblemInstatScal+).

The object \verb+heatSpace+ is handed as

\verb+ProblemIterationInterface+ (implemented by class\\

\verb+ProblemScal+) to the adaptation loop. \verb+heat+ is interpreted

as \verb+ProblemTimeInterface+ (implemented by class

\verb+ProblemInstatScal+).

The definitions of functions $f$ and $g$ are:

...

...

@@ -222,7 +275,10 @@ The definitions of functions $f$ and $g$ are:

rhsFct->setTimePtr(heat.getRHSTimePtr());

\end{lstlisting}

The functions interpreted as \verb+TimedObject+s are linked with the corresponding time pointers by \verb+setTimePtr+. The boundary function is handed to \verb+heat+ as exact solution and as Dirichlet boundary function with identifier $1$ to \verb+heatSpace+.

The functions interpreted as \verb+TimedObject+s are linked with the

corresponding time pointers by \verb+setTimePtr+. The boundary

function is handed to \verb+heat+ as exact solution and as Dirichlet

boundary function with identifier $1$ to \verb+heatSpace+.

We linearize the problem using the Newton method. First, we define an initial guess $u_0$ of the solution which is $0$ for the first adaptation loop iteration. In later iterations we can use the solution of the last iteration interpolated to the current mesh as initial guess. In each Newton step, a correction $d$ for the solution of the last step is computed by solving

We linearize the problem using the Newton method. First, we define an

initial guess $u_0$ of the solution which is $0$ for the first

adaptation loop iteration. In later iterations we can use the solution

of the last iteration interpolated to the current mesh as initial

guess. In each Newton step, a correction $d$ for the solution of the

last step is computed by solving

\begin{eqnarray}

\label{eq:newton step}

DF(u_n)(d) = F(u_n)

...

...

@@ -361,9 +366,26 @@ int main(int argc, char* argv[])

adaptInfo);

\end{lstlisting}

An instance of class \verb+NewtonMethod+ was created with a pointer to a \verb+Nonlin+ object as nonlinear problem and as Newton-step implementation. Instead of the nonlinear problem, now, the object \verb+newtonMethod+ is handed to the adaptation loop as implementation of \verb+ProblemIterationInterface+.

We have to add operators representing the Newton step equation $-\Delta d +4u_n^3d=-\Delta u_n + u_n^4-f$ as well as operators representing the nonlinear problem $-\Delta u_n + u_n^4= f$. When the operators are given to the problem, one can determine an assemble factor (second argument of \verb+addMatrixOperator+ and \verb+addVectorOperator+) as well as an estimation factor (third argument) for each operator. So, we can manage both equations in one problem instance. Note that in the Newton step we solve for $d$. $u_n$ there is known from the last Newton step. The term $u_n^4$ was implemented as $u_n^3 v$, where $v$ for the Newton step equation is equal to $d$ and in the nonlinear problem equation equal to $u_n$. So, the corresponding operator can be used in both equations just with different factors. In Figure \ref{f:nonlin operators}, the operator factors for the assemble and the estimate step are shown.

An instance of class \verb+NewtonMethod+ was created with a pointer to

a \verb+Nonlin+ object as nonlinear problem and as Newton-step

implementation. Instead of the nonlinear problem, now, the object

\verb+newtonMethod+ is handed to the adaptation loop as implementation

of \verb+ProblemIterationInterface+.

We have to add operators representing the Newton step equation

$-\Delta d +4u_n^3d=-\Delta u_n + u_n^4-f$ as well as operators

representing the nonlinear problem $-\Delta u_n + u_n^4= f$. When the

operators are given to the problem, one can determine an assemble

factor (second argument of \verb+addMatrixOperator+ and

\verb+addVectorOperator+) as well as an estimation factor (third

argument) for each operator. So, we can manage both equations in one

problem instance. Note that in the Newton step we solve for $d$. $u_n$

there is known from the last Newton step. The term $u_n^4$ was

implemented as $u_n^3 v$, where $v$ for the Newton step equation is

equal to $d$ and in the nonlinear problem equation equal to $u_n$. So,

the corresponding operator can be used in both equations just with

different factors. In Figure \ref{f:nonlin operators}, the operator

factors for the assemble and the estimate step are shown.