-
Notifications
You must be signed in to change notification settings - Fork 90
/
Copy pathbiharmonic2_example.dox
118 lines (85 loc) · 5.27 KB
/
biharmonic2_example.dox
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
namespace gismo {
/**
\page biharmonic2_example biharmonic2_example.cpp
The boundary value problem for the first biharmonic equation is defined as follows:
\f{eqnarray*}{
\Delta^2 u &=& f \quad \text{in} \quad \Omega, \\
u &=& g_1 \quad \text{on} \quad \partial \Omega, \\
\mathbf{n} \cdot \nabla u &=& g_2 \quad \text{on} \quad \partial \Omega,
\f}
where \f$\mathbf{n}\f$ is the outward pointing unit normal vector.
The boundary value problem for the second biharmonic equation is defined as follows:
\f{eqnarray*}{
\Delta^2 u &=& f \quad \text{in} \quad \Omega, \\
u &=& g_1 \quad \text{on} \quad \partial \Omega, \\
\Delta u &=& g_2 \quad \text{on} \quad \partial \Omega.
\f}
The system to assemble a system of equations based on this weak formulation is
constructed in \ref biharmonic2_example using the \ref gsExprAssembler. The biharmonic problem
is only solvable on domains with a single patch.
Then we define our command line options.
For example, we use the option \c -f or \c --file to set the path to the file that contains
our geometry. If we wish to use the second biharmonic problem, then we use the option
\c --second to run the biharmonic problem with \f$u=g_1\f$ and \f$\Delta u=g_2\f$
\snippet biharmonic2_example.cpp Parse command line
Then we read the geometry: Either it can be from a file that contains the geometry or we
use the default one.
\snippet biharmonic2_example.cpp Read geometry
Before we run the problem, we set the degree and/or refine the basis. This is done in the following snippet:
\snippet biharmonic2_example.cpp Refinement
Then we set the boundary conditions. Depending on which biharmonic problem we choose,
each boundary will be is set to the corresponding functions.
\snippet biharmonic2_example.cpp Boundary condition
Now it is time to look at the setup of our boundary value problem.
In the code snippet below, we first define our \ref gsExprAssembler.
The inputs (1,1) here mean that we have 1 test function space and 1 trial function space.
Furthermore, few \c typedef s can be seen. These are just there to prevent lengthy types.
The assembler is fed with the basis using the gsExprAssembler::setIntegrationElements() function.
When the basis is defined, a \ref gsExprEvaluator is constructed for later use.
The geometry is connected to the \ref gsExprAssembler via the gsExprAssembler::getMap() function
and we create an expression for the space via gsExprAssembler::getSpace().
Functions for the right-hand side and the manufactured solution are constructed
via gsExprAssembler::getCoef() and gsExprEvaluator::getVariable() functions, respectively.
Note that the manufactured solution is defined in the \ref gsExprEvaluator
because it will not be used in assembly of the system.
The problem setup finishes by defining the solution object,
which is constructed via gsExprAssembler::getSolution() which requires a space
and a reference to a vector that will contain the solution coefficients later.
\snippet biharmonic2_example.cpp Problem setup
The next step is to actually solve the system at hand.
In this particular example, this is done within a loop of uniform refinement
(unless the \c last option is selected) in order to study convergence behaviour of the method.
As seen in the snippet below, we first define the solver that we will use
(based on the Eigen-library) and we define the vectors to store the errors.
Then, within the loop, we first refine the basis uniformly.
For the biharmonic problem, we fix the dofs in the function setMapperForBiharmonic(),
which is defined in the beginning of the file (see the full file at the end).
Then the gsExprAssembler<>::space::setupMapper() function is used.
This function initialize the matrix and the rhs depending on the mapper.
Then we compute the eliminated boundary values with the L2-projection where we call
setDirichletNeumannValuesL2Projection(). Again this function is defined
at the beginning of the file.
Then the \ref gsExprAssembler is initialized using gsExprAssembler::initSystem()
and using gsExprAssembler::assemble() the matrix expression (first argument)
and the rhs expression (second argument) are assembled to a system.
When the System is assembled,
the system is factorized using gsSparseSolver::compute()
and solved via gsSparseSolver::solve().
The errors are then computed via the \ref gsExprEvaluator,
where it should be noted that the solution object is appearing,
which uses the solution vector and the space as defined earlier.
\snippet biharmonic2_example.cpp Solver loop
When the loop is runnig several times, we can compute the
L2-error, H1-error and H2-error. The expected rates
should be p+1 for the L2-error, p for the H1-error
and p-1 for the H2-error.
\snippet biharmonic2_example.cpp Error and convergence rates
If we set the flag \c --plot then the export to ParaView is done in the snipped below.
The output file is solution.pvd.
\snippet biharmonic2_example.cpp Export visualization in ParaView
\section adaptiveConvectionDiffusionReaction_exampleAnnotated Annotated source file
Here is the full file \c examples/biharmonic2_example.cpp. Clicking on a function
or class name will lead you to its reference documentation.
\include biharmonic2_example.cpp
*/
}