~ubuntu-branches/ubuntu/trusty/rheolef/trusty

« back to all changes in this revision

Viewing changes to doc/pusrman/neumann-laplace.tex

  • Committer: Package Import Robot
  • Author(s): Pierre Saramito
  • Date: 2012-04-06 09:12:21 UTC
  • mfrom: (1.1.5)
  • Revision ID: package-import@ubuntu.com-20120406091221-m58me99p1nxqui49
Tags: 6.0-1
* New upstream release 6.0 (major changes):
  - massively distributed and parallel support
  - full FEM characteristic method (Lagrange-Gakerkin method) support
  - enhanced users documentation 
  - source code supports g++-4.7 (closes: #667356)
* debian/control: dependencies for MPI distributed solvers added
* debian/rules: build commands simplified
* debian/librheolef-dev.install: man1/* to man9/* added
* debian/changelog: package description rewritted (closes: #661689)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
%----------------------------------------------------
 
2
%\section{Non-homogeneous Neumann boundary conditions for the Laplace operator}
 
3
%----------------------------------------------------
 
4
\label{sec-neumann-laplace}
 
5
\pbindex{Poisson}%
 
6
\bcindex{Neumann}%
 
7
 
 
8
In this chapter we study how to solve a ill-posed problem
 
9
with a solution defined up to a constant.
 
10
 
 
11
\subsection*{Formulation}
 
12
  Let $f \in L^{2}(\Omega)$ and
 
13
  $g \in H^{\frac{1}{2}}(\partial \Omega)$ satisfying
 
14
  the following compatibility condition:
 
15
  \[
 
16
        \int_\Omega f \, {\rm d}x
 
17
        +
 
18
        \int_{\partial\Omega} g \, {\rm d}s
 
19
        =
 
20
        0
 
21
  \]
 
22
  The problem writes:\\
 
23
  $(P_5)_h$: {\it find $u$, defined in $\Omega$ such that:}
 
24
  \begin{eqnarray*}
 
25
      -\Delta u &=& f \ {\rm in}\ \Omega \\
 
26
      \Frac{\partial u}{ \partial n} &=& g \ {\rm on}\ \partial \Omega
 
27
  \end{eqnarray*}
 
28
\cindex{algorithm!conjugate gradient}
 
29
\cindex{algorithm!minres}
 
30
  Since this problem only involves the derivatives of $u$,
 
31
  it is clear that its solution is never unique~\cite[p.~11]{girault-raviart-86}.
 
32
  A discrete version of this problem could be solved iteratively
 
33
  by the conjugate gradient or the MINRES algorithm~\cite{PaiSau-1975}.
 
34
  In order to solve it by a direct method,
 
35
  we turn the difficulty by seeking $u$ in the following space
 
36
  \[    
 
37
        V = \{ v\in H^1(\Omega);\ \  b(v,1) = 0 \}
 
38
  \]
 
39
  where
 
40
  \[
 
41
        b(v,\mu) = \int_\Omega v \, {\rm d}x,
 
42
                \ \ \forall v\in L^2(\Omega),
 
43
                \forall \mu\in \mathbb{R}
 
44
  \]
 
45
  The variational formulation of this problem writes:
 
46
 
 
47
  $(VF_5)$: {\it find $u \in V$ such that:}
 
48
  $$
 
49
    a(u,v) = l(v), \ \forall v \in V
 
50
  $$
 
51
  where
 
52
  \begin{eqnarray*}
 
53
    a(u,v) &=& \int_\Omega \nabla u . \nabla v \, dx \\
 
54
    l(v) &=& m(f,v) + m_b(g, v) \\ 
 
55
    m(f,v) &=& \int_\Omega f v \, dx \\
 
56
    m_b(g,v) &=& \int_{\partial \Omega} g v \, ds
 
57
  \end{eqnarray*}
 
58
  Since the direct discretization of the space $V$ is not
 
59
  an obvious task,
 
60
  the constraint $b(u,1) = 0$ is enforced by a Lagrange multiplier
 
61
\cindex{Lagrange!multiplier}%
 
62
  $\lambda\in \mathbb{R}$.
 
63
  Let us introduce the Lagrangian, defined
 
64
  for all $v\in H^1(\Omega)$ and $\mu\in\mathbb{R}$ by:
 
65
  \[
 
66
    L(v,\mu) = \Frac{1}{2} a(v,v) + b(v,\mu) - l(v)
 
67
  \]
 
68
  The saddle point $(u,\lambda)\in H^1(\Omega)\times\mathbb{R}$
 
69
  of this Lagrangian is characterized as the unique solution
 
70
  of:
 
71
  \begin{eqnarray*}
 
72
        a(u,v) + b(v,\lambda)
 
73
                &=& l(v), \ \ \forall v\in H^ 1(\Omega) \\
 
74
        b(u,\mu) \phantom{+ b(v,\lambda)}
 
75
                &=& 0,    \ \ \ \ \  \forall \mu\in\mathbb{R}
 
76
  \end{eqnarray*}
 
77
  It is clear that if $(u,\lambda)$ is solution of this problem,
 
78
  then $u\in V$ and $u$ is a solution of $(VF_5)$.
 
79
  Conversely, let $u\in V$ the solution of $(VF_5)$.
 
80
  Choosing $v=v_0$ where $v_0(x)=1$, $\forall x\in\Omega$
 
81
  leads to 
 
82
  \mbox{$
 
83
     \lambda\,{\rm meas}(\Omega)=l(v_0)
 
84
  $}.
 
85
  From the definition of $l(.)$ and the compatibility 
 
86
  condition between the data $f$ and $g$, we get $\lambda=0$.
 
87
  Notice that the saddle point problem extends to the case
 
88
  when $f$ and $g$ does not satisfies the compatibility condition,
 
89
  and in that case $\lambda=l(v_0)/{\rm meas}(\Omega)$.
 
90
  
 
91
\subsection*{Approximation}
 
92
\cindex{Lagrange!interpolation}
 
93
  As usual, we introduce a mesh ${\cal T}_h$ of $\Omega$
 
94
  and the finite dimensional space $X_h$:
 
95
  $$
 
96
      X_h = \{ v \in H^1(\Omega); \
 
97
          v_{/K} \in P_k, \
 
98
          \forall K \in {\cal T}_h \}
 
99
  $$
 
100
  The approximate problem writes:\\
 
101
  {\it $(VF_5)_h$: find $(u_h,\lambda_h)\in X_h\times \mathbb{R}$ such that:}
 
102
  \begin{eqnarray*}
 
103
        a(u_h,v) + b(v,\lambda_h)
 
104
                &=& l_h(v), \ \ \forall v\in X_h \\
 
105
        b(u_h,\mu) \phantom{+ b(v,\lambda)}
 
106
                &=& 0,    \ \ \ \ \  \forall \mu\in\mathbb{R}
 
107
  \end{eqnarray*}
 
108
  where
 
109
  $$
 
110
        l_h(v) = m(\Pi_h f,v_h) + m_b(\pi_h g, v_h)
 
111
  $$
 
112
  
 
113
\subsection*{File \file{neumann-laplace.cc}}
 
114
  \exindex{neumann-laplace.cc}
 
115
  \myexample{neumann-laplace.cc}
 
116
 
 
117
\subsection*{Comments}
 
118
  Let $\Omega \subset R^d$, $d=1,2,3$.
 
119
  We choose $f(x) = 1$ and $g(x) = -1/(2d)$.
 
120
  This example is convenient, since the exact solution is known:
 
121
  $$
 
122
        u(x) = - \Frac{1}{12} + \Frac{1}{2d} \sum_{i=1}^d x_i(1-x_i)
 
123
  $$
 
124
  The code looks like the previous ones.
 
125
  Let us comment the changes.
 
126
  The discrete bilinear form $b$ is computed as $b_h\in X_h$
 
127
  that interprets as a linear application from $X_h$ to $\mathbb{R}$:
 
128
  $b_h(v_h)=m(v_h,1)$. Thus $b_h$ is computed as
 
129
  \begin{lstlisting}[numbers=none,frame=none]
 
130
    field b = m*field(Xh,1.0);
 
131
  \end{lstlisting} 
 
132
  where the discrete bilinear form $m$ is identified to its matrix
 
133
  and {\tt field(Xh,1.0)} is the constant vector equal to $1$.
 
134
  Let 
 
135
  \[
 
136
     \mathcal{A}
 
137
        =
 
138
     \left( \begin{array}{cc} 
 
139
        {\tt a.uu} & {\tt trans(b.u)} \\ 
 
140
        {\tt b.u}  & 0 
 
141
     \end{array} \right)
 
142
        , \ \ \ 
 
143
     \mathcal{U}
 
144
        =
 
145
     \left( \begin{array}{c} 
 
146
        {\tt uh.u} \\ 
 
147
        {\tt lambda} 
 
148
     \end{array} \right)
 
149
        , \ \ \ 
 
150
     \mathcal{B}
 
151
        =
 
152
     \left( \begin{array}{c} 
 
153
        {\tt lh.u} \\
 
154
        0
 
155
     \end{array} \right)
 
156
  \]
 
157
  The problem admits the following matrix form:
 
158
  \[
 
159
     \mathcal{A} \ \mathcal{U} = \mathcal{B}
 
160
  \]
 
161
\clindex{csr<T>}%
 
162
\clindex{vec<T>}%
 
163
\cindex{matrix!concatenation}
 
164
  The matrix and right-hand side of the system are assembled by concatenation:
 
165
  \begin{lstlisting}[numbers=none,frame=none]
 
166
    csr<Float> A = {{  a.uu,    b.u},
 
167
                    {trans(b.u), 0 }};
 
168
    vec<Float> B =  {  lh.u,     0 };
 
169
  \end{lstlisting}
 
170
  where
 
171
    {\color{rheoleftypcolor} \code{csr}}
 
172
  and
 
173
    {\color{rheoleftypcolor} \code{vec}}
 
174
  are respectively the matrix and vector classes.
 
175
  The {\color{rheoleftypcolor} \code{csr}} is the abbreviation
 
176
  of {\em compressed sparse row}, a sparse matrix compression standard format.
 
177
%
 
178
  Notice that the matrix $\mathcal{A}$ is symmetric and non-singular, but indefinite~: 
 
179
  it admits eigenvalues that are either strictly positive or strictly negative.
 
180
  Then, the \code{uh.u} vector is extracted from the \code{U} one:
 
181
  \begin{lstlisting}[numbers=none,frame=none]
 
182
    uh.u = U [range(0,uh.u.size())];
 
183
  \end{lstlisting}
 
184
  The extraction of \code{lambda} from \code{U} is more technical in a distributed 
 
185
  environment. In a sequential one, since it is stored after the \code{uh.u} values,
 
186
  it could be simply written as:
 
187
  \begin{lstlisting}[numbers=none,frame=none]
 
188
    Float lambda = U [uh.u.size()];
 
189
  \end{lstlisting}
 
190
\cindex{distributed computation}%
 
191
\cindex{parallel computation}%
 
192
\toindex{mpirun}%
 
193
\toindex{library!boost}%
 
194
\clindex{communicator}%
 
195
  In a distributed environment, \code{lambda} is stored in \code{U} on
 
196
  the last processor, identified by \code{U.comm().size()-1}.
 
197
  Here \code{U.comm()} denotes the \code{communicator}, from the \code{boost::mpi}
 
198
  library and \code{U.comm().size()} is the number of processors in use,
 
199
  e.g. as specified by the \code{mpirun} command.
 
200
  On this last processor, the array \code{U} has size equal to
 
201
  \code{uh.u.size()+1} and \code{lambda} is stored in \code{U[uh.u.size()]}.
 
202
  On the others processors, the array \code{U} has size equal to
 
203
  \code{uh.u.size()} and lambda is not available.
 
204
  The following statement extract \code{lambda} on the last processor
 
205
  and set it to zero on the others:
 
206
  \begin{lstlisting}[numbers=none,frame=none]
 
207
    Float lambda = (U.size() == uh.u.size()+1) ? U [uh.u.size()] : 0;
 
208
  \end{lstlisting}
 
209
  Then, the value of \code{lambda} is broadcasted on the others processors:
 
210
  \begin{lstlisting}[numbers=none,frame=none]
 
211
    mpi::broadcast (U.comm(), lambda, U.comm().size() - 1);
 
212
  \end{lstlisting}
 
213
  The preprocessing guards \code{\#idef}$\ldots$\code{\#endif} assure that
 
214
  this example compile also when the library is not installed with the MPI support.
 
215
\findex{catchmark}%
 
216
  Finally, the statement
 
217
  \begin{lstlisting}[numbers=none,frame=none]
 
218
    dout << catchmark("u") << uh
 
219
         << catchmark("lambda") << lambda << endl;
 
220
  \end{lstlisting}
 
221
  writes the solution $(u_h,\lambda)$.
 
222
  The \code{catchmark} function writes marks together with the solution in the output stream.
 
223
  These marks are suitable for a future reading with the same format, as:
 
224
  \begin{lstlisting}[numbers=none,frame=none]
 
225
    din  >> catchmark("u") >> uh
 
226
         >> catchmark("lambda") >> lambda;
 
227
  \end{lstlisting}
 
228
  This is usefull for post-treatment, visualization and error analysis.
 
229
 
 
230
\subsection{How to run the program}
 
231
 
 
232
  As usual, enter:
 
233
  \begin{verbatim}
 
234
    make neumann-laplace
 
235
    mkgeo_grid -t 10 > square.geo
 
236
    ./neumann-laplace square P1 | field -
 
237
  \end{verbatim}