LORENE
pois_vect_r0.C
1/*
2 * Solution of the l=0 part of the vector Poisson equation (only r-component)
3 *
4 */
5
6/*
7 * Copyright (c) 2007 Jerome Novak
8 *
9 * This file is part of LORENE.
10 *
11 * LORENE is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2
13 * as published by the Free Software Foundation.
14 *
15 * LORENE is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with LORENE; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 *
24 */
25
26
27
28/*
29 * $Id: pois_vect_r0.C,v 1.3 2016/12/05 16:18:09 j_novak Exp $
30 * $Log: pois_vect_r0.C,v $
31 * Revision 1.3 2016/12/05 16:18:09 j_novak
32 * Suppression of some global variables (file names, loch, ...) to prevent redefinitions
33 *
34 * Revision 1.2 2014/10/13 08:53:29 j_novak
35 * Lorene classes and functions now belong to the namespace Lorene.
36 *
37 * Revision 1.1 2007/01/23 17:08:46 j_novak
38 * New function pois_vect_r0.C to solve the l=0 part of the vector Poisson
39 * equation, which involves only the r-component.
40 *
41 *
42 * $Header: /cvsroot/Lorene/C++/Source/Non_class_members/PDE/pois_vect_r0.C,v 1.3 2016/12/05 16:18:09 j_novak Exp $
43 *
44 */
45
46// Lorene headers
47#include "metric.h"
48#include "proto.h"
49#include "diff.h"
50
51/*
52 * This function solves for the l=0 component of
53 *
54 * d2 f 2 df 2f
55 * ---- + - -- - -- = source
56 * dr2 r dr r2
57 *
58 * and returns the soluton f.
59 * The input Scalar must have dzpuis = 4.
60 */
61namespace Lorene {
62Scalar pois_vect_r0(const Scalar& source) {
63
64 const Map& map0 = source.get_mp() ;
65 const Map_af* map1 = dynamic_cast<const Map_af*>(&map0) ;
66 assert(map1 != 0x0) ;
67 const Map_af& map = *map1 ;
68
69 const Mg3d& mgrid = *map.get_mg() ;
70 int nz = mgrid.get_nzone() ;
71
72 Scalar resu(map) ;
73 if (source.get_etat() == ETATZERO) {
74 resu = 0 ;
75 return resu ;
76 }
77
78 resu.annule_hard() ;
79 resu.std_spectral_base_odd() ;
80 resu.set_spectral_va().ylm() ;
81 Mtbl_cf& sol_coef = (*resu.set_spectral_va().c_cf) ;
82 const Base_val& base = source.get_spectral_base() ;
83 assert(resu.get_spectral_base() == base) ;
84 assert(source.check_dzpuis(4)) ;
85
86 Mtbl_cf sol_part(mgrid, base) ; sol_part.annule_hard() ;
87 Mtbl_cf sol_hom1(mgrid, base) ; sol_hom1.annule_hard() ;
88 Mtbl_cf sol_hom2(mgrid, base) ; sol_hom2.annule_hard() ;
89
90 { int lz = 0 ;
91 int nr = mgrid.get_nr(lz) ;
92 double alpha2 = map.get_alpha()[lz]*map.get_alpha()[lz] ;
93 assert(mgrid.get_type_r(lz) == RARE) ;
94 int base_r = R_CHEBI ;
95 Matrice ope(nr,nr) ;
96 ope.annule_hard() ;
97 Diff_dsdx2 dx2(base_r, nr) ; const Matrice& mdx2 = dx2.get_matrice() ;
98 Diff_sxdsdx sdx(base_r, nr) ; const Matrice& msdx = sdx.get_matrice() ;
99 Diff_sx2 sx2(base_r, nr) ; const Matrice& ms2 = sx2.get_matrice() ;
100
101 for (int lin=0; lin<nr-1; lin++)
102 for (int col=0; col<nr; col++)
103 ope.set(lin,col) = (mdx2(lin,col) + 2*msdx(lin,col) - 2*ms2(lin,col))/alpha2 ;
104
105 ope.set(nr-1, 0) = 1 ; //for the true homogeneous solution
106 for (int i=1; i<nr; i++)
107 ope.set(nr-1, i) = 0 ;
108
109 Tbl rhs(nr) ;
110 rhs.annule_hard() ;
111 for (int i=0; i<nr-1; i++)
112 rhs.set(i) = (*source.get_spectral_va().c_cf)(lz, 0, 0, i) ;
113 rhs.set(nr-1) = 0 ;
114 ope.set_lu() ;
115 Tbl sol = ope.inverse(rhs) ;
116
117 for (int i=0; i<nr; i++)
118 sol_part.set(lz, 0, 0, i) = sol(i) ;
119
120 rhs.annule_hard() ;
121 rhs.set(nr-1) = 1 ;
122 sol = ope.inverse(rhs) ;
123 for (int i=0; i<nr; i++)
124 sol_hom1.set(lz, 0, 0, i) = sol(i) ;
125
126 }
127
128 for (int lz=1; lz<nz-1; lz++) {
129 int nr = mgrid.get_nr(lz) ;
130 double alpha = map.get_alpha()[lz] ;
131 double beta = map.get_beta()[lz] ;
132 double ech = beta / alpha ;
133 assert(mgrid.get_type_r(lz) == FIN) ;
134 int base_r = R_CHEB ;
135
136 Matrice ope(nr,nr) ;
137 ope.annule_hard() ;
138
139 Diff_dsdx dx(base_r, nr) ; const Matrice& mdx = dx.get_matrice() ;
140 Diff_dsdx2 dx2(base_r, nr) ; const Matrice& mdx2 = dx2.get_matrice() ;
141 Diff_id id(base_r, nr) ; const Matrice& mid = id.get_matrice() ;
142 Diff_xdsdx xdx(base_r, nr) ; const Matrice& mxdx = xdx.get_matrice() ;
143 Diff_xdsdx2 xdx2(base_r, nr) ; const Matrice& mxdx2 = xdx2.get_matrice() ;
144 Diff_x2dsdx2 x2dx2(base_r, nr) ; const Matrice& mx2dx2 = x2dx2.get_matrice() ;
145
146 for (int lin=0; lin<nr-2; lin++)
147 for (int col=0; col<nr; col++)
148 ope.set(lin, col) = mx2dx2(lin, col) + 2*ech*mxdx2(lin, col) + ech*ech*mdx2(lin, col)
149 + 2*(mxdx(lin, col) + ech*mdx(lin, col)) - 2*mid(lin, col) ;
150
151 ope.set(nr-2, 0) = 0 ;
152 ope.set(nr-2, 1) = 1 ;
153 for (int col=2; col<nr; col++) {
154 ope.set(nr-2, col) = 0 ;
155 }
156 ope.set(nr-1, 0) = 1 ;
157 for (int col=1; col<nr; col++)
158 ope.set(nr-1, col) = 0 ;
159
160 Tbl src(nr) ;
161 src.set_etat_qcq() ;
162 for (int i=0; i<nr; i++)
163 src.set(i) = (*source.get_spectral_va().c_cf)(lz, 0, 0, i) ;
164 Tbl xsrc = src ; multx_1d(nr, &xsrc.t, base_r) ;
165 Tbl x2src = src ; multx2_1d(nr, &x2src.t, base_r) ;
166 Tbl rhs(nr) ;
167 rhs.set_etat_qcq() ;
168 for (int i=0; i<nr-2; i++)
169 rhs.set(i) = beta*beta*src(i) + 2*beta*alpha*xsrc(i) + alpha*alpha*x2src(i) ;
170 rhs.set(nr-2) = 0 ;
171 rhs.set(nr-1) = 0 ;
172 ope.set_lu() ;
173 Tbl sol = ope.inverse(rhs) ;
174
175 for (int i=0; i<nr; i++)
176 sol_part.set(lz, 0, 0, i) = sol(i) ;
177
178 rhs.annule_hard() ;
179 rhs.set(nr-2) = 1 ;
180 sol = ope.inverse(rhs) ;
181 for (int i=0; i<nr; i++)
182 sol_hom1.set(lz, 0, 0, i) = sol(i) ;
183
184 rhs.set(nr-2) = 0 ;
185 rhs.set(nr-1) = 1 ;
186 sol = ope.inverse(rhs) ;
187 for (int i=0; i<nr; i++)
188 sol_hom2.set(lz, 0, 0, i) = sol(i) ;
189
190 }
191
192 { int lz = nz-1 ;
193 int nr = mgrid.get_nr(lz) ;
194 double alpha2 = map.get_alpha()[lz]*map.get_alpha()[lz] ;
195 assert(mgrid.get_type_r(lz) == UNSURR) ;
196 int base_r = R_CHEBU ;
197
198 Matrice ope(nr,nr) ;
199 ope.annule_hard() ;
200 Diff_dsdx2 dx2(base_r, nr) ; const Matrice& mdx2 = dx2.get_matrice() ;
201 Diff_sx2 sx2(base_r, nr) ; const Matrice& ms2 = sx2.get_matrice() ;
202
203 for (int lin=0; lin<nr-3; lin++)
204 for (int col=0; col<nr; col++)
205 ope.set(lin, col) = (mdx2(lin, col) - 2*ms2(lin, col))/alpha2 ;
206
207 for (int i=0; i<nr; i++) {
208 ope.set(nr-3, i) = i*i ; //for the finite part (derivative = 0 at infty)
209 }
210
211 for (int i=0; i<nr; i++) {
212 ope.set(nr-2, i) = 1 ; //for the limit at inifinity
213 }
214
215 ope.set(nr-1, 0) = 1 ; //for the true homogeneous solution
216 for (int i=1; i<nr; i++)
217 ope.set(nr-1, i) = 0 ;
218
219 Tbl rhs(nr) ;
220 rhs.annule_hard() ;
221 for (int i=0; i<nr-3; i++)
222 rhs.set(i) = (*source.get_spectral_va().c_cf)(lz, 0, 0, i) ;
223 rhs.set(nr-3) = 0 ;
224 rhs.set(nr-2) = 0 ;
225 rhs.set(nr-1) = 0 ;
226 ope.set_lu() ;
227 Tbl sol = ope.inverse(rhs) ;
228 for (int i=0; i<nr; i++)
229 sol_part.set(lz, 0, 0, i) = sol(i) ;
230
231 rhs.annule_hard() ;
232 rhs.set(nr-1) = 1 ;
233 sol = ope.inverse(rhs) ;
234 for (int i=0; i<nr; i++)
235 sol_hom2.set(lz, 0, 0, i) = sol(i) ;
236
237 }
238
239 Mtbl_cf dpart = sol_part ; dpart.dsdx() ;
240 Mtbl_cf dhom1 = sol_hom1 ; dhom1.dsdx() ;
241 Mtbl_cf dhom2 = sol_hom2 ; dhom2.dsdx() ;
242
243 Matrice systeme(2*(nz-1), 2*(nz-1)) ;
244 systeme.annule_hard() ;
245 Tbl rhs(2*(nz-1)) ;
246 rhs.annule_hard() ;
247
248 //Nucleus
249 int lin = 0 ;
250 int col = 0 ;
251 double alpha = map.get_alpha()[0] ;
252 systeme.set(lin,col) = sol_hom1.val_out_bound_jk(0, 0, 0) ;
253 rhs.set(lin) -= sol_part.val_out_bound_jk(0, 0, 0) ;
254 lin++ ;
255 systeme.set(lin,col) = dhom1.val_out_bound_jk(0, 0, 0) / alpha ;
256 rhs.set(lin) -= dpart.val_out_bound_jk(0, 0, 0) / alpha ;
257 col++ ;
258
259 //Shells
260 for (int lz=1; lz<nz-1; lz++) {
261 alpha = map.get_alpha()[lz] ;
262 lin-- ;
263 systeme.set(lin,col) -= sol_hom1.val_in_bound_jk(lz, 0, 0) ;
264 systeme.set(lin,col+1) -= sol_hom2.val_in_bound_jk(lz, 0, 0) ;
265 rhs.set(lin) += sol_part.val_in_bound_jk(lz, 0, 0) ;
266
267 lin++ ;
268 systeme.set(lin,col) -= dhom1.val_in_bound_jk(lz, 0, 0) / alpha ;
269 systeme.set(lin,col+1) -= dhom2.val_in_bound_jk(lz, 0, 0) / alpha ;
270 rhs.set(lin) += dpart.val_in_bound_jk(lz, 0, 0) / alpha;
271
272 lin++ ;
273 systeme.set(lin, col) += sol_hom1.val_out_bound_jk(lz, 0, 0) ;
274 systeme.set(lin, col+1) += sol_hom2.val_out_bound_jk(lz, 0, 0) ;
275 rhs.set(lin) -= sol_part.val_out_bound_jk(lz, 0, 0) ;
276
277 lin++ ;
278 systeme.set(lin, col) += dhom1.val_out_bound_jk(lz, 0, 0) / alpha ;
279 systeme.set(lin, col+1) += dhom2.val_out_bound_jk(lz, 0, 0) / alpha ;
280 rhs.set(lin) -= dpart.val_out_bound_jk(lz, 0, 0) / alpha ;
281 col += 2 ;
282 }
283
284 //CED
285 alpha = map.get_alpha()[nz-1] ;
286 lin-- ;
287 systeme.set(lin,col) -= sol_hom2.val_in_bound_jk(nz-1, 0, 0) ;
288 rhs.set(lin) += sol_part.val_in_bound_jk(nz-1, 0, 0) ;
289
290 lin++ ;
291 systeme.set(lin,col) -= (-4*alpha)*dhom2.val_in_bound_jk(nz-1, 0, 0) ;
292 rhs.set(lin) += (-4*alpha)*dpart.val_in_bound_jk(nz-1, 0, 0) ;
293
294 systeme.set_lu() ;
295 Tbl coef = systeme.inverse(rhs) ;
296 int indice = 0 ;
297
298 for (int i=0; i<mgrid.get_nr(0); i++)
299 sol_coef.set(0, 0, 0, i) = sol_part(0, 0, 0, i)
300 + coef(indice)*sol_hom1(0, 0, 0, i) ;
301 indice++ ;
302 for (int lz=1; lz<nz-1; lz++) {
303 for (int i=0; i<mgrid.get_nr(lz); i++)
304 sol_coef.set(lz, 0, 0, i) = sol_part(lz, 0, 0, i)
305 +coef(indice)*sol_hom1(lz, 0, 0, i)
306 +coef(indice+1)*sol_hom2(lz, 0, 0, i) ;
307 indice += 2 ;
308 }
309 for (int i=0; i<mgrid.get_nr(nz-1); i++)
310 sol_coef.set(nz-1, 0, 0, i) = sol_part(nz-1, 0, 0, i)
311 +coef(indice)*sol_hom2(nz-1, 0, 0, i) ;
312
313 delete resu.set_spectral_va().c ;
314 resu.set_spectral_va().c = 0x0 ;
315 resu.set_dzpuis(0) ;
316 resu.set_spectral_va().ylm_i() ;
317
318 return resu ;
319}
320}
Bases of the spectral expansions.
Definition base_val.h:325
Class for the elementary differential operator (see the base class Diff ).
Definition diff.h:172
Class for the elementary differential operator (see the base class Diff ).
Definition diff.h:129
Class for the elementary differential operator Identity (see the base class Diff ).
Definition diff.h:210
Class for the elementary differential operator division by (see the base class Diff ).
Definition diff.h:369
Class for the elementary differential operator (see the base class Diff ).
Definition diff.h:450
Class for the elementary differential operator (see the base class Diff ).
Definition diff.h:490
Class for the elementary differential operator (see the base class Diff ).
Definition diff.h:531
Class for the elementary differential operator (see the base class Diff ).
Definition diff.h:409
Affine radial mapping.
Definition map.h:2042
Matrix handling.
Definition matrice.h:152
double & set(int j, int i)
Read/write of a particuliar element.
Definition matrice.h:277
Multi-domain grid.
Definition grilles.h:279
int get_nzone() const
Returns the number of domains.
Definition grilles.h:465
Coefficients storage for the multi-domain spectral method.
Definition mtbl_cf.h:196
Tensor field of valence 0 (or component of a tensorial field).
Definition scalar.h:393
Basic array class.
Definition tbl.h:161
double & set(int i)
Read/write of a particular element (index i) (1D case).
Definition tbl.h:281
#define R_CHEBU
base de Chebychev ordinaire (fin), dev. en 1/r
#define R_CHEBI
base de Cheb. impaire (rare) seulement
#define R_CHEB
base de Chebychev ordinaire (fin)
Lorene prototypes.
Definition app_hor.h:67
Map(const Mg3d &)
Constructor from a multi-domain 3D grid.
Definition map.C:142