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  */
61 namespace Lorene {
62 Scalar 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 }
Lorene prototypes.
Definition: app_hor.h:67
#define R_CHEBI
base de Cheb. impaire (rare) seulement
Definition: type_parite.h:170
#define R_CHEBU
base de Chebychev ordinaire (fin), dev. en 1/r
Definition: type_parite.h:180
const Map & get_mp() const
Returns the mapping.
Definition: tensor.h:874
#define R_CHEB
base de Chebychev ordinaire (fin)
Definition: type_parite.h:166