diff --git a/doc/tutorial/heat.tex b/doc/tutorial/heat.tex index 797a0d637e7f2b0c8d8a66b992f91c18e1a756a5..63afa09221d344d8c06ddd2b4800fba3f8e4acec 100644 --- a/doc/tutorial/heat.tex +++ b/doc/tutorial/heat.tex @@ -85,7 +85,7 @@ The first lines of class \verb+Heat+ are: class Heat : public ProblemInstatScal { public: - Heat(ProblemScal *heatSpace) + Heat(ProblemScal &heatSpace) : ProblemInstatScal("heat", heatSpace) { theta = -1.0; @@ -102,9 +102,7 @@ The next lines show the implementation of the time interface. \begin{lstlisting}{} void setTime(AdaptInfo *adaptInfo) { - rhsTime = - adaptInfo->getTime()- - (1-theta)*adaptInfo->getTimestep(); + rhsTime = adaptInfo->getTime() - (1 - theta) * adaptInfo->getTimestep(); boundaryTime = adaptInfo->getTime(); tau1 = 1.0 / adaptInfo->getTimestep(); } @@ -179,12 +177,12 @@ int main(int argc, char** argv) Parameters::init(false, argv[1]); // ===== create and init stationary problem ===== - ProblemScal *heatSpace = new ProblemScal("heat->space"); - heatSpace->initialize(INIT_ALL); + ProblemScal heatSpace("heat->space"); + heatSpace.initialize(INIT_ALL); // ===== create instationary problem ===== - Heat *heat = new Heat(heatSpace); - heat->initialize(INIT_ALL); + Heat heat(heatSpace); + 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. @@ -193,17 +191,17 @@ The next step is the creation of the needed \verb+AdaptInfo+ objects and of the \begin{lstlisting}{} // create adapt info for heat - AdaptInfo *adaptInfo = new AdaptInfo("heat->adapt"); + AdaptInfo adaptInfo("heat->adapt"); // create initial adapt info - AdaptInfo *adaptInfoInitial = new AdaptInfo("heat->initial->adapt"); + AdaptInfo adaptInfoInitial("heat->initial->adapt"); // create instationary adapt - AdaptInstationary *adaptInstat = new AdaptInstationary("heat->adapt", - heatSpace, - adaptInfo, - heat, - adaptInfoInitial); + AdaptInstationary adaptInstat("heat->adapt", + heatSpace, + adaptInfo, + heat, + 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+). @@ -213,15 +211,15 @@ The definitions of functions $f$ and $g$ are: \begin{lstlisting}{} // ===== create boundary functions ===== G *boundaryFct = new G; - boundaryFct->setTimePtr(heat->getBoundaryTimePtr()); - heat->setExactSolution(boundaryFct); + boundaryFct->setTimePtr(heat.getBoundaryTimePtr()); + heat.setExactSolution(boundaryFct); - heatSpace->addDirichletBC(1, boundaryFct); + heatSpace.addDirichletBC(1, boundaryFct); // ===== create rhs functions ===== - int degree = heatSpace->getFESpace()->getBasisFcts()->getDegree(); + int degree = heatSpace.getFESpace()->getBasisFcts()->getDegree(); F *rhsFct = new F(degree); - rhsFct->setTimePtr(heat->getRHSTimePtr()); + 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+. @@ -234,61 +232,68 @@ Now, we define the operators: double zero = 0.0; // create laplace - Operator *A = new Operator(Operator::MATRIX_OPERATOR | - Operator::VECTOR_OPERATOR, - heatSpace->getFESpace()); - - A->addSecondOrderTerm(new Laplace_SOT); - - A->setUhOld(heat->getOldSolution()); - - if((*(heat->getThetaPtr())) != 0.0) - heatSpace->addMatrixOperator(A, heat->getThetaPtr(), &one); - - if((*(heat->getTheta1Ptr())) != 0.0) - heatSpace->addVectorOperator(A, heat->getTheta1Ptr(), &zero); + Operator A(Operator::MATRIX_OPERATOR | Operator::VECTOR_OPERATOR, + heatSpace.getFESpace()); + A.addSecondOrderTerm(new Laplace_SOT); + A.setUhOld(heat.getOldSolution()); + if (*(heat.getThetaPtr()) != 0.0) + heatSpace.addMatrixOperator(A, heat.getThetaPtr(), &one); + if (*(heat.getTheta1Ptr()) != 0.0) + heatSpace.addVectorOperator(A, heat.getTheta1Ptr(), &zero); \end{lstlisting} -Operator \verb+A+ represents $-\Delta u$. It is used as matrix operator on the left hand side with factor $\theta$ and as vector operator on the right hand side with factor $-(1-\theta) = \theta - 1$. These assemble factors are the second arguments of \verb+addMatrixOperator+ and \verb+addVectorOperator+. The third argument is the factor used for estimation. In this example, the estimator will consider the operator only on the left hand side with factor $1$. On the right hand side the operator is applied to the solution of the last timestep. So the old solution is handed to the operator by \verb+setUhOld+. +Operator \verb+A+ represents $-\Delta u$. It is used as matrix +operator on the left hand side with factor $\theta$ and as vector +operator on the right hand side with factor $-(1-\theta) = \theta - +1$. These assemble factors are the second arguments of +\verb+addMatrixOperator+ and \verb+addVectorOperator+. The third +argument is the factor used for estimation. In this example, the +estimator will consider the operator only on the left hand side with +factor $1$. On the right hand side the operator is applied to the +solution of the last timestep. So the old solution is handed to the +operator by \verb+setUhOld+. \begin{lstlisting}{} // create zero order operator - Operator *C = new Operator(Operator::MATRIX_OPERATOR | - Operator::VECTOR_OPERATOR, - heatSpace->getFESpace()); - - C->addZeroOrderTerm(new Simple_ZOT); - - C->setUhOld(heat->getOldSolution()); - - heatSpace->addMatrixOperator(C, heat->getTau1Ptr(), heat->getTau1Ptr()); - heatSpace->addVectorOperator(C, heat->getTau1Ptr(), heat->getTau1Ptr()); + Operator C(Operator::MATRIX_OPERATOR | Operator::VECTOR_OPERATOR, + heatSpace.getFESpace()); + C.addZeroOrderTerm(new Simple_ZOT); + C.setUhOld(heat.getOldSolution()); + heatSpace.addMatrixOperator(C, heat.getTau1Ptr(), heat.getTau1Ptr()); + heatSpace.addVectorOperator(C, heat.getTau1Ptr(), heat.getTau1Ptr()); \end{lstlisting} -The \verb+Simple_ZOT+ of operator \verb+C+ represents the zero order terms for the time discretization. On both sides of the equation $u$ is added with $\frac{1}{\tau}$ as assemble factor and as estimate factor. +The \verb+Simple_ZOT+ of operator \verb+C+ represents the zero order +terms for the time discretization. On both sides of the equation $u$ +is added with $\frac{1}{\tau}$ as assemble factor and as estimate +factor. -Finally, the operator for the right hand side function $f$ is added and the adaptation loop is started: +Finally, the operator for the right hand side function $f$ is added +and the adaptation loop is started: \begin{lstlisting}{} // create RHS operator - Operator *F = new Operator(Operator::VECTOR_OPERATOR, - heatSpace->getFESpace()); - - F->addZeroOrderTerm(new CoordsAtQP_ZOT(rhsFct)); - - heatSpace->addVectorOperator(F); + Operator F(Operator::VECTOR_OPERATOR, heatSpace.getFESpace()); + F.addZeroOrderTerm(new CoordsAtQP_ZOT(rhsFct)); + heatSpace.addVectorOperator(F); // ===== start adaption loop ===== - adaptInstat->adapt(); + int errorCode = adaptInstat.adapt(); } \end{lstlisting} -\verb+CoordsAtQP_ZOT+ is a zero order term that evaluates a given function $fct$ at all needed quadrature points. At the left hand side, it would represent the term $fct(x, t)\cdot u$, on the right hand side, just $fct(x, t)$. Note that the old solution isn't given to the operator here. Otherwise the term would represent $fct(x, t) \cdot u^{old}$ on the right hand side. +\verb+CoordsAtQP_ZOT+ is a zero order term that evaluates a given +function $fct$ at all needed quadrature points. At the left hand side, +it would represent the term $fct(x, t)\cdot u$, on the right hand +side, just $fct(x, t)$. Note that the old solution isn't given to the +operator here. Otherwise the term would represent $fct(x, t) \cdot +u^{old}$ on the right hand side. \subsection{Parameter file} \label{s:heat parameter} -In this section, we show only the relevant parts of the parameter file \verb+heat.dat.2d+. +In this section, we show only the relevant parts of the parameter file +\verb+heat.dat.2d+. First the parameter $\theta$ for the time discretization is defined: @@ -314,7 +319,15 @@ heat->adapt->time theta 1: 1.0 heat->adapt->time theta 2: 0.3 \end{lstlisting} -The total tolerance is divided in a space tolerance and a time tolerance. The space tolerance is the maximal allowed space error, given by the product of \verb+tolerance+ and \verb+rel space error+. It is reached by adaptive mesh refinements. The time tolerance is the maximal allowed error, due to the timestep size. It is given by the product of \verb+tolerance+ and \verb+rel time error+ and \verb+time theta 1+. It is relevant, only if an implicit time strategy with adaptive timestep size is used. The parameter \verb+time theta 2+ is used to enlarge the timestep, if the estimated time error falls beneath a given threshold. +The total tolerance is divided in a space tolerance and a time +tolerance. The space tolerance is the maximal allowed space error, +given by the product of \verb+tolerance+ and \verb+rel space error+. It is reached by adaptive mesh refinements. The time tolerance +is the maximal allowed error, due to the timestep size. It is given by +the product of \verb+tolerance+ and \verb+rel time error+ and +\verb+time theta 1+. It is relevant, only if an implicit time strategy +with adaptive timestep size is used. The parameter \verb+time theta 2+ +is used to enlarge the timestep, if the estimated time error falls +beneath a given threshold. \begin{lstlisting}{} heat->adapt->strategy: 1 @@ -322,9 +335,17 @@ heat->adapt->time delta 1: 0.7071 heat->adapt->time delta 2: 1.4142 \end{lstlisting} -If \verb+strategy+ is $0$, an explicit time strategy with fixed timestep size is used. A value of $1$ stands for the implicit strategy. The time tolerance is reached by successively multiplying the timestep with \verb+time delta 1+. If the estimated timestep error is smaller than the product of \verb+tolerance+ and \verb+rel time error+ and \verb+time theta 2+ at the end of a timestep, the timestep size is multiplied by \verb+time delta 2+. - -The following lines determine, whether coarsening is allowed in regions with sufficient small errors, and how many refinements or coarsenings are performed for marked elements. +If \verb+strategy+ is $0$, an explicit time strategy with fixed +timestep size is used. A value of $1$ stands for the implicit +strategy. The time tolerance is reached by successively multiplying +the timestep with \verb+time delta 1+. If the estimated timestep error +is smaller than the product of \verb+tolerance+ and +\verb+rel time error+ and \verb+time theta 2+ at the end of a +timestep, the timestep size is multiplied by \verb+time delta 2+. + +The following lines determine, whether coarsening is allowed in +regions with sufficient small errors, and how many refinements or +coarsenings are performed for marked elements. \begin{lstlisting}{} heat->adapt->coarsen allowed: 1 heat->adapt->refine bisections: 2 @@ -347,19 +368,33 @@ heat->space->output->index length: 6 heat->space->output->index decimals: 3 \end{lstlisting} -In this example, all output filenames start with prefix \verb+output/heat+ and end with the extensions \verb+.mesh+ and \verb+.dat+. Output is written after every $10$th timestep. The time of the single solution is added after the filename prefix with 6 letters, three of them are decimals. The solution for $t=0$ e.g. would be written in the files \verb+output/heat00.000.mesh+ and \verb+output/heat00.000.dat+. +In this example, all output filenames start with prefix +\verb+output/heat+ and end with the extensions \verb+.mesh+ and +\verb+.dat+. Output is written after every $10$th timestep. The time +of the single solution is added after the filename prefix with 6 +letters, three of them are decimals. The solution for $t=0$ e.g. would +be written in the files \verb+output/heat00.000.mesh+ and +\verb+output/heat00.000.dat+. -Finally, we set parameter \verb+WAIT+ to $1$. So each call of the macro \verb+WAIT+ in the application will lead to an interruption of the program, until the \verb+return+ key is pressed. +Finally, we set parameter \verb+WAIT+ to $1$. So each call of the +macro \verb+WAIT+ in the application will lead to an interruption of +the program, until the \verb+return+ key is pressed. \begin{lstlisting}{} WAIT: 1 \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} -As mentioned above, the output files look like \verb+output/heat00.000.mesh+ and \verb+output/heat00.000.dat+. Depending on the corresponding value in the parameter file only the solution after every $i$-th timestep is written. In Figure \ref{f:heat}, the solution at three timesteps is visualized. +As mentioned above, the output files look like +\verb+output/heat00.000.mesh+ and +\verb+output/heat00.000.dat+. Depending on the corresponding value in +the parameter file only the solution after every $i$-th timestep is +written. In Figure \ref{f:heat}, the solution at three timesteps is +visualized. \begin{figure} \center diff --git a/doc/tutorial/installation.tex b/doc/tutorial/installation.tex index 28ebc3a53c2af05797fbe3caa143d2f03b650752..b6e5a54cd59f0df682be11537de5e067198cfd06 100644 --- a/doc/tutorial/installation.tex +++ b/doc/tutorial/installation.tex @@ -9,37 +9,45 @@ To install the AMDiS library, the following steps must be performed: \item Create the AMDiS source directory. This can be done in different ways. Here, we show three possibilities: \begin{itemize} - \item Unpacking the archive file {\tt AMDiS.tar.gz}: + \item Unpacking the archive file {\tt AMDiS.tgz}: \begin{itemize} - \item {\tt > gunzip AMDiS.tar.gz} - \item {\tt > tar xvf AMDiS.tar} + \item {\tt > tar xvfz AMDiS.tgz} \end{itemize} - \item Checking out a CVS project: + \item Checking out an SVN project: \begin{itemize} - \item {\tt > export CVSROOT=<cvsroot>} - \item {\tt > cvs checkout AMDiS} - \end{itemize} - \item Checking out a CVS project: - \begin{itemize} - \item {\tt > svn checkout file://<SVN-REPOSITORY-PATH>/AMDiS} + \item {\tt > svn checkout --username developername \\} + {\tt https://gforge.zih.tu-dresden.de/svn/amdis/trunk amdis} \end{itemize} \end{itemize} \item Change into the AMDiS directory: \begin{verbatim} -> cd AMDiS +> cd amdis/AMDiS \end{verbatim} \item Create the makefiles for your system using the \verb+configure+ script: \begin{verbatim} > ./configure <CONFIGURE-OPTIONS> \end{verbatim} -The \verb+configure+ script creates the needed makefiles. It can be called with the following options: + The \verb+configure+ script creates the needed makefiles. It can be + called with the following options: \begin{description} -\item \verb+--prefix=<AMDIS-DIR>+: Installation path of the AMDiS library. The library file will be stored in \verb+<AMDIS-DIR>/lib+. With \verb+--prefix=`pwd`+ AMDiS will be installed in the current working directory, which mostly is a good choice. -\item \verb+--enable-debug+: If this option is used, AMDiS will be compiled with debug support. By default, AMDiS is compiled in an optimized mode without debug support. -\item \verb+--with-mpi=<MPI-DIR>+: MPI installation path. Used for parallelization support. -\item \verb+--with-parmetis=<PARMETIS-DIR>+: ParMETIS installation path. ParMETIS is a parallel graph partitioning library, see \\\verb+http://glaros.dtc.umn.edu/gkhome/metis/parmetis/overview+. Used for parallelization support. +\item \verb+--prefix=<AMDIS-DIR>+: Installation path of the AMDiS + library. The library file will be stored in + \verb+<AMDIS-DIR>/lib+. With \verb+--prefix=`pwd`+ AMDiS will be + installed in the current working directory, which mostly is a good + choice. +\item \verb+--enable-debug+: If this option is used, AMDiS will be + compiled with debug support. By default, AMDiS is compiled in an + optimized mode without debug support. +\item \verb+--enable-umfpack+: If this option is used, AMDiS is + compiled with support for the UMFPACK solver library. +\item \verb+--with-mpi=<MPI-DIR>+: MPI installation path. Used for + parallelization support. +\item \verb+--with-parmetis=<PARMETIS-DIR>+: ParMETIS installation + path. ParMETIS is a parallel graph partitioning library, see + \\\verb+http://glaros.dtc.umn.edu/gkhome/metis/parmetis/overview+. Used + for parallelization support. \end{description} If AMDiS should be compiled for parallel usage, the MPI and ParMETIS paths must be set. diff --git a/doc/tutorial/tutorial.pdf b/doc/tutorial/tutorial.pdf index 304796008ac8a37e3e86ac2bff3a4851d42b783a..ba36150ac5ed1c7796730294fc0ae46053098912 100644 Binary files a/doc/tutorial/tutorial.pdf and b/doc/tutorial/tutorial.pdf differ diff --git a/doc/tutorial/vecellipt.tex b/doc/tutorial/vecellipt.tex index 0bea73f8d6077ca5ff72f9ee51429fe09e83b1d7..4905bad5208ed1edebcf4619d8398a75f70f1460 100644 --- a/doc/tutorial/vecellipt.tex +++ b/doc/tutorial/vecellipt.tex @@ -1,18 +1,26 @@ \section{Systems of PDEs} \label{s:vecellipt} -In this example, we show how to implement a system of coupled PDEs. We define +In this example, we show how to implement a system of coupled PDEs. We +define \begin{eqnarray} -\Delta u &=& f\\ u - v &=& 0. \end{eqnarray} -For the first equation, we use the boundary condition and definition of function $f$ from Section \ref{s:ellipt}. The second equation defines a second solution component $v$, which is coupled to $u$, such that $v=u$. For the second equation, no boundary conditions have to be defined. The system can be written in matrix-vector form as +For the first equation, we use the boundary condition and definition +of function $f$ from Section \ref{s:ellipt}. The second equation +defines a second solution component $v$, which is coupled to $u$, such +that $v=u$. For the second equation, no boundary conditions have to be +defined. The system can be written in matrix-vector form as \begin{equation} \left( \begin{array}{rr}-\Delta & 0 \\I & -I\end{array}\right) \left(\begin{array}{r}u\\v\end{array}\right) = \left( \begin{array}{r}f\\0\end{array}\right), \end{equation} -where $I$ stands for the identity and $0$ for a {\it zero operator} (or for the absence of any operator). This is a very simple example without practical relevance. But it is appropriate to demonstrate the main principles of implementing vector valued problems. +where $I$ stands for the identity and $0$ for a {\it zero operator} +(or for the absence of any operator). This is a very simple example +without practical relevance. But it is appropriate to demonstrate the +main principles of implementing vector valued problems. \begin{table} \center @@ -33,31 +41,30 @@ where $I$ stands for the identity and $0$ for a {\it zero operator} (or for the \end{table} \subsection{Source code} -Instead of a scalar problem, we now create and initialize the vector valued problem \verb+vecellipt+: +Instead of a scalar problem, we now create and initialize the vector +valued problem \verb+vecellipt+: \begin{lstlisting}{} ProblemVec vecellipt("vecellipt"); vecellipt.initialize(INIT_ALL); \end{lstlisting} -The \verb+AdaptInfo+ constructor is called with the number of problem components, which is defined in the parameter file. +The \verb+AdaptInfo+ constructor is called with the number of problem +components, which is defined in the parameter file. \begin{lstlisting}{} // === create adapt info === - AdaptInfo *adaptInfo = new AdaptInfo("vecellipt->adapt", - vecellipt.getNumComponents()); + AdaptInfo adaptInfo("vecellipt->adapt", vecellipt.getNumComponents()); - // === create adapt === - AdaptStationary *adapt = new AdaptStationary("vecellipt->adapt", - &vecellipt, - adaptInfo); - + // === create adapt === + AdaptStationary adapt("vecellipt->adapt", vecellipt, adaptInfo); \end{lstlisting} -The adaptation loop doesn't care about the component number. It treats \verb+vecellipt+ only as implementation of the iteration interface. +The adaptation loop doesn't care about the component number. It treats +\verb+vecellipt+ only as implementation of the iteration interface. -The Dirichlet boundary condition for the first equation is defined by +The Dirichlet boundary condition for the first equation is defined by \begin{lstlisting}{} // ===== add boundary conditions ===== @@ -78,43 +85,49 @@ The operator definitions for the first equation are: matrixOperator00.addSecondOrderTerm(new Laplace_SOT); vecellipt.addMatrixOperator(&matrixOperator00, 0, 0); + int degree = vecellipt.getFESpace(0)->getBasisFcts()->getDegree(); Operator rhsOperator0(Operator::VECTOR_OPERATOR, vecellipt.getFESpace(0)); - - int degree = vecellipt.getFESpace(0)->getBasisFcts()->getDegree(); - rhsOperator0.addZeroOrderTerm(new CoordsAtQP_ZOT(new F(degree))); - vecellipt.addVectorOperator(&rhsOperator0, 0); \end{lstlisting} -Operator \verb+matrixOperator00+ represents the $-\Delta$ operator. Each operator belongs to two finite element spaces, the {\it row space} and the {\it column space}. If an operator has the position $(i,j)$ in the operator matrix, the row space is the finite element space of component $i$ and the column space is the finite element space of component $j$. The finite element spaces can differ in the used basis function degree. The underlying meshes must be the same. After \verb+matrixOperator00+ is created, it is handed to the problems operator matrix at position $(0,0)$. -The right hand side operator \verb+rhsOperator0+ only needs a row space, which is the finite element space of component $0$ ($u$). It is handed to the operator vector at position $0$. +Operator \verb+matrixOperator00+ represents the $-\Delta$ +operator. Each operator belongs to two finite element spaces, the {\it + row space} and the {\it column space}. If an operator has the +position $(i,j)$ in the operator matrix, the row space is the finite +element space of component $i$ and the column space is the finite +element space of component $j$. The finite element spaces can differ +in the used basis function degree. The underlying meshes must be the +same. After \verb+matrixOperator00+ is created, it is handed to the +problems operator matrix at position $(0,0)$. The right hand side +operator \verb+rhsOperator0+ only needs a row space, which is the +finite element space of component $0$ ($u$). It is handed to the +operator vector at position $0$. Now, the operators for the second equation are defined: \begin{lstlisting}{} Operator matrixOperator10(Operator::MATRIX_OPERATOR, - vecellipt.getFESpace(1), - vecellipt.getFESpace(0)); - - Operator matrixOperator11(Operator::MATRIX_OPERATOR, - vecellipt.getFESpace(1), - vecellipt.getFESpace(1)); - + vecellipt.getFESpace(1), vecellipt.getFESpace(0)); matrixOperator10.addZeroOrderTerm(new Simple_ZOT); + vecellipt.addMatrixOperator(matrixOperator10, 1, 0); - vecellipt.addMatrixOperator(&matrixOperator10, 1, 0); - + Operator matrixOperator11(Operator::MATRIX_OPERATOR, + vecellipt.getFESpace(1), vecellipt.getFESpace(1)); matrixOperator11.addZeroOrderTerm(new Simple_ZOT(-1.0)); - - vecellipt.addMatrixOperator(&matrixOperator11, 1, 1); + vecellipt.addMatrixOperator(matrixOperator11, 1, 1); \end{lstlisting} -Note that the operator \verb+matrixOperator10+ can have different finite element spaces, if the spaces of the two components differ. The operators $I$ and $-I$ are implemented by \verb+Simple_ZOT+, once with a fixed factor of $1$ and once with a factor of $-1$. +Note that the operator \verb+matrixOperator10+ can have different +finite element spaces, if the spaces of the two components differ. The +operators $I$ and $-I$ are implemented by \verb+Simple_ZOT+, once with +a fixed factor of $1$ and once with a factor of $-1$. \subsection{Parameter file} -First, the number of components and the basis function degrees are given. We use Lagrange polynomials of degree 1 for the first component and of degree 2 for the second component. +First, the number of components and the basis function degrees are +given. We use Lagrange polynomials of degree 1 for the first component +and of degree 2 for the second component. \begin{lstlisting}{} vecellipt->components: 2 @@ -123,29 +136,41 @@ vecellipt->polynomial degree[0]: 1 vecellipt->polynomial degree[1]: 2 \end{lstlisting} -In general, the linear system of equations for systems of PDEs is not symmetric. So with the GMRes solver, we use a solver that doesn't assume symmetric matrices. +In general, the linear system of equations for systems of PDEs is not +symmetric. So with the GMRes solver, we use a solver that doesn't +assume symmetric matrices. \begin{lstlisting}{} vecellipt->solver: gmres \end{lstlisting} -Note that we have only one solver, because the equations of our system are assembled in one linear system of equations. +Note that we have only one solver, because the equations of our system +are assembled in one linear system of equations. -Each equation can have its own estimator. In this case, adaptivity should be managed only by the first component. So the second equation has no estimator. +Each equation can have its own estimator. In this case, adaptivity +should be managed only by the first component. So the second equation +has no estimator. \begin{lstlisting}{} vecellipt->estimator[0]: residual vecellipt->estimator[1]: no \end{lstlisting} -Also the marking strategy can differ between the components. Refinement is done, if at least one component has marked an element for refinement. Coarsening only is done, if all components have marked the element for coarsening. In our example, only component $0$ will mark elements. +Also the marking strategy can differ between the +components. Refinement is done, if at least one component has marked +an element for refinement. Coarsening only is done, if all components +have marked the element for coarsening. In our example, only component +$0$ will mark elements. \begin{lstlisting}{} vecellipt->marker[0]->strategy: 2 vecellipt->marker[1]->strategy: 0 \end{lstlisting} -We have only one adaptation loop, which does maximal $6$ iterations. The tolerance can be determined for each component. The total tolerance criterion is fulfilled, if all criteria of all components are fulfilled. +We have only one adaptation loop, which does maximal $6$ +iterations. The tolerance can be determined for each component. The +total tolerance criterion is fulfilled, if all criteria of all +components are fulfilled. \begin{lstlisting}{} vecellipt->adapt->max iteration: 6 @@ -171,12 +196,15 @@ vecellipt->output[1]->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} \label{s:vecellipt output} -Component $0$ of the solution (approximation of $u$) is written to the files \verb+output/vecellipt0.mesh+ and \verb+output/vecellipt0.dat+. -Component $1$ of the solution (approximation of $v$) is written to the files \verb+output/vecellipt1.mesh+ and \verb+output/vecellipt1.dat+. +Component $0$ of the solution (approximation of $u$) is written to the +files \verb+output/vecellipt0.mesh+ and \verb+output/vecellipt0.dat+. +Component $1$ of the solution (approximation of $v$) is written to the +files \verb+output/vecellipt1.mesh+ and \verb+output/vecellipt1.dat+. The two components are visualized in Figure \ref{f:vecellipt}. \begin{figure}