LORENE
scalar_sol_div.C
1/*
2 * Resolution of the divergence ODE: df/df + n*f/r = source (source must have dzpuis =2)
3 *
4 * (see file scalar.h for documentation).
5 *
6 */
7
8/*
9 * Copyright (c) 2005 Jerome Novak
10 *
11 * This file is part of LORENE.
12 *
13 * LORENE is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License version 2
15 * as published by the Free Software Foundation.
16 *
17 * LORENE is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with LORENE; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 *
26 */
27
28
29
30/*
31 * $Id: scalar_sol_div.C,v 1.6 2016/12/05 16:18:19 j_novak Exp $
32 * $Log: scalar_sol_div.C,v $
33 * Revision 1.6 2016/12/05 16:18:19 j_novak
34 * Suppression of some global variables (file names, loch, ...) to prevent redefinitions
35 *
36 * Revision 1.5 2014/10/13 08:53:47 j_novak
37 * Lorene classes and functions now belong to the namespace Lorene.
38 *
39 * Revision 1.4 2014/10/06 15:16:16 j_novak
40 * Modified #include directives to use c++ syntax.
41 *
42 * Revision 1.3 2005/09/16 14:33:00 j_novak
43 * Added #include <math.h>.
44 *
45 * Revision 1.2 2005/09/16 12:49:52 j_novak
46 * The case with dzpuis=1 is added.
47 *
48 * Revision 1.1 2005/06/08 12:35:22 j_novak
49 * New method for solving divergence-like ODEs.
50 *
51 *
52 * $Header: /cvsroot/Lorene/C++/Source/Tensor/Scalar/scalar_sol_div.C,v 1.6 2016/12/05 16:18:19 j_novak Exp $
53 *
54 */
55
56// C headers
57#include <cassert>
58#include <cmath>
59
60//Lorene headers
61#include "tensor.h"
62#include "diff.h"
63#include "proto.h"
64
65// Local prototypes
66namespace Lorene {
67void _sx_r_chebp(Tbl* , int& ) ;
68void _sx_r_chebi(Tbl* , int& ) ;
69
70
71Scalar Scalar::sol_divergence(int n_factor) const {
72
73 assert(etat != ETATNONDEF) ;
74 const Map_af* mpaff = dynamic_cast<const Map_af*>(mp) ;
75 assert( mpaff != 0x0) ;
76
77 Scalar result(*mp) ;
78
79 if ( etat == ETATZERO )
80 result.set_etat_zero() ;
81 else { //source not zero
82 Base_val base_resu = get_spectral_base() ;
83 base_resu.mult_x() ;
84 const Mg3d* mg = mp->get_mg() ;
85 result.set_etat_qcq() ; result.set_spectral_base(base_resu) ;
87 Valeur sigma(va) ;
88 sigma.ylm_i() ; // work on Fourier basis
89 const Mtbl_cf& source = *sigma.c_cf ;
90
91 // Checks on the type of domains
92 int nz = mg->get_nzone() ;
93 bool ced = (mg->get_type_r(nz-1) == UNSURR ) ;
94 assert ( (!ced) || (check_dzpuis(2)) || (check_dzpuis(1)) ) ;
95 assert (mg->get_type_r(0) == RARE) ;
96 int nt = mg->get_nt(0) ;
97 int np = mg->get_np(0) ;
98#ifndef NDEBUG
99 for (int lz = 0; lz<nz; lz++)
100 assert( (mg->get_nt(lz) == nt) && (mg->get_np(lz) == np) ) ;
101#endif
102 int nr, base_r,l_quant, m_quant;
103 Tbl *so ;
104 Tbl *s_hom ;
105 Tbl *s_part ;
106
107 // Working objects and initialization
108 Mtbl_cf sol_part(mg, base_resu) ;
109 Mtbl_cf sol_hom(mg, base_resu) ;
110 Mtbl_cf& resu = *result.set_spectral_va().c_cf ;
111 sol_part.annule_hard();
112 sol_hom.annule_hard() ;
113 resu.annule_hard() ;
114
115 //---------------
116 //-- NUCLEUS ---
117 //---------------
118 int lz = 0 ;
119 nr = mg->get_nr(lz) ;
120
121 int dege = 1 ; // the operator is degenerate
122 int nr0 = nr - dege ;
123 Tbl vect1(3, 1, nr) ;
124 Tbl vect2(3, 1, nr) ;
125 int base_pipo = 0 ;
126 double alpha = mpaff->get_alpha()[lz] ;
127 double beta = 0. ;
128 Matrice ope_even(nr0, nr0) ; //when the *result* is decomposed on R_CHEBP
129 ope_even.set_etat_qcq() ;
130 for (int i=dege; i<nr; i++) {
131 vect1.annule_hard() ;
132 vect2.annule_hard() ;
133 vect1.set(0,0,i) = 1. ; vect2.set(0,0,i) = 1. ;
134 _dsdx_r_chebp(&vect1, base_pipo) ;
135 _sx_r_chebp(&vect2, base_pipo) ;
136 for (int j=0; j<nr0; j++)
137 ope_even.set(j,i-dege) = (vect1(0,0,j) + n_factor*vect2(0,0,j)) / alpha ;
138 }
139 ope_even.set_lu() ;
140 Matrice ope_odd(nr0, nr0) ; //when the *result* is decomposed on R_CHEBI
141 ope_odd.set_etat_qcq() ;
142 for (int i=0; i<nr0; i++) {
143 vect1.annule_hard() ;
144 vect2.annule_hard() ;
145 vect1.set(0,0,i) = 1. ; vect2.set(0,0,i) = 1. ;
146 _dsdx_r_chebi(&vect1, base_pipo) ;
147 _sx_r_chebi(&vect2, base_pipo) ;
148 for (int j=0; j<nr0; j++)
149 ope_odd.set(j,i) = (vect1(0,0,j) + n_factor*vect2(0,0,j)) / alpha ;
150 }
151 ope_odd.set_lu() ;
152
153 for (int k=0 ; k<np+1 ; k++)
154 for (int j=0 ; j<nt ; j++) {
155 // to get the spectral base
156 base_resu.give_quant_numbers(lz, k, j, m_quant, l_quant, base_r) ;
157 assert ( (base_r == R_CHEBP) || (base_r == R_CHEBI) ) ;
158 const Matrice& operateur = (( base_r == R_CHEBP ) ?
159 ope_even : ope_odd ) ;
160 // particular solution
161 so = new Tbl(nr0) ;
162 so->set_etat_qcq() ;
163 for (int i=0 ; i<nr0 ; i++)
164 so->set(i) = source(lz, k, j, i) ;
165
166 s_part = new Tbl(operateur.inverse(*so)) ;
167
168 // Putting to Mtbl_cf
169 double somme = 0 ;
170 for (int i=0 ; i<nr0 ; i++) {
171 if (base_r == R_CHEBP) {
172 resu.set(lz, k, j, i+dege) = (*s_part)(i) ;
173 somme += ((i+dege)%2 == 0 ? 1 : -1)*(*s_part)(i) ;
174 }
175 else
176 resu.set(lz,k,j,i) = (*s_part)(i) ;
177 }
178 if (base_r == R_CHEBI)
179 for (int i=nr0; i<nr; i++)
180 resu.set(lz,k,j,i) = 0 ;
181 if (base_r == R_CHEBP) //result must vanish at r=0
182 resu.set(lz, k, j, 0) -= somme ;
183
184 delete so ;
185 delete s_part ;
186
187 }
188
189 //---------------------
190 //-- SHELLS --
191 //---------------------
192 int nz0 = (ced ? nz - 1 : nz) ;
193 for (lz=1 ; lz<nz0 ; lz++) {
194 nr = mg->get_nr(lz) ;
195 alpha = mpaff->get_alpha()[lz] ;
196 beta = mpaff->get_beta()[lz];
197 double ech = beta / alpha ;
198 Diff_id id(R_CHEB, nr) ; const Matrice& mid = id.get_matrice() ;
199 Diff_xdsdx xd(R_CHEB, nr) ; const Matrice& mxd = xd.get_matrice() ;
200 Diff_dsdx dx(R_CHEB, nr) ; const Matrice& mdx = dx.get_matrice() ;
201 Matrice operateur = mxd + ech*mdx + n_factor*mid ;
202 operateur.set_lu() ;
203 // homogeneous solution
204 s_hom = new Tbl(solh(nr, n_factor-1, ech, R_CHEB)) ;
205
206 for (int k=0 ; k<np+1 ; k++)
207 for (int j=0 ; j<nt ; j++) {
208 // to get the spectral base
209 base_resu.give_quant_numbers(lz, k, j, m_quant, l_quant, base_r) ;
210 assert (base_r == R_CHEB) ;
211
212 so = new Tbl(nr) ;
213 so->set_etat_qcq() ;
214 // particular solution
215 Tbl tmp(nr) ;
216 tmp.set_etat_qcq() ;
217 for (int i=0 ; i<nr ; i++)
218 tmp.set(i) = source(lz, k, j, i) ;
219 for (int i=0; i<nr; i++) so->set(i) = beta*tmp(i) ;
220 multx_1d(nr, &tmp.t, R_CHEB) ;
221 for (int i=0; i<nr; i++) so->set(i) += alpha*tmp(i) ;
222
223 s_part = new Tbl (operateur.inverse(*so)) ;
224
225 // cleaning things...
226 for (int i=0 ; i<nr ; i++) {
227 sol_part.set(lz, k, j, i) = (*s_part)(i) ;
228 sol_hom.set(lz, k, j, i) = (*s_hom)(1,i) ;
229 }
230
231 delete so ;
232 delete s_part ;
233 }
234 delete s_hom ;
235 }
236 if (ced) {
237 //---------------
238 //-- CED -----
239 //---------------
240 int dzp = ( check_dzpuis(2) ? 2 : 1) ;
241 nr = source.get_mg()->get_nr(nz-1) ;
242 alpha = mpaff->get_alpha()[nz-1] ;
243 beta = mpaff->get_beta()[nz-1] ;
244 dege = dzp ;
245 nr0 = nr - dege ;
246 Diff_dsdx dx(R_CHEBU, nr) ; const Matrice& mdx = dx.get_matrice() ;
247 Diff_sx sx(R_CHEBU, nr) ; const Matrice& msx = sx.get_matrice() ;
248 Diff_xdsdx xdx(R_CHEBU, nr) ; const Matrice& mxdx = xdx.get_matrice() ;
249 Diff_id id(R_CHEBU, nr) ; const Matrice& mid = id.get_matrice() ;
250 Matrice operateur(nr0, nr0) ;
251 operateur.set_etat_qcq() ;
252 if (dzp == 2)
253 for (int lin=0; lin<nr0; lin++)
254 for (int col=dege; col<nr; col++)
255 operateur.set(lin,col-dege) = (-mdx(lin,col)
256 + n_factor*msx(lin, col)) / alpha ;
257 else {
258 for (int lin=0; lin<nr0; lin++) {
259 for (int col=dege; col<nr; col++)
260 operateur.set(lin,col-dege) = (-mxdx(lin,col)
261 + n_factor*mid(lin, col)) ;
262 }
263 }
264 operateur.set_lu() ;
265 // homogeneous solution
266 s_hom = new Tbl(solh(nr, n_factor-1, 0., R_CHEBU)) ;
267 for (int k=0 ; k<np+1 ; k++)
268 for (int j=0 ; j<nt ; j++) {
269 base_resu.give_quant_numbers(lz, k, j, m_quant, l_quant, base_r) ;
270 assert(base_r == R_CHEBU) ;
271
272 // particular solution
273 so = new Tbl(nr0) ;
274 so->set_etat_qcq() ;
275 for (int i=0 ; i<nr0 ; i++)
276 so->set(i) = source(nz-1, k, j, i) ;
277 s_part = new Tbl(operateur.inverse(*so)) ;
278
279 // cleaning
280 double somme = 0 ;
281 for (int i=0 ; i<nr0 ; i++) {
282 sol_part.set(nz-1, k, j, i+dege) = (*s_part)(i) ;
283 somme += (*s_part)(i) ;
284 sol_hom.set(nz-1, k, j, i) = (*s_hom)(i) ;
285 }
286 for (int i=nr0; i<nr; i++)
287 sol_hom.set(nz-1, k, j, i) = (*s_hom)(i) ;
288 //result must vanish at infinity
289 sol_part.set(nz-1, k, j, 0) = -somme ;
290 delete so ;
291 delete s_part ;
292 }
293 delete s_hom ;
294 }
295
296 //-------------------------
297 //-- matching solutions ---
298 //-------------------------
299 if (nz > 1) {
300 Tbl echelles(nz-1) ;
301 echelles.set_etat_qcq() ;
302 for (lz=1; lz<nz; lz++)
303 echelles.set(lz-1)
304 = pow ( (mpaff->get_beta()[lz]/mpaff->get_alpha()[lz] -1),
305 n_factor) ;
306 if (ced) echelles.set(nz-2) = 1./pow(-2., n_factor) ;
307
308 for (int k=0 ; k<np+1 ; k++)
309 for (int j=0 ; j<nt ; j++) {
310 for (lz=1; lz<nz; lz++) {
311 double val1 = 0 ;
312 double valm1 = 0 ;
313 double valhom1 = 0 ;
314 int nr_prec = mg->get_nr(lz-1) ;
315 nr = mg->get_nr(lz) ;
316 for (int i=0; i<nr_prec; i++)
317 val1 += resu(lz-1, k, j, i) ;
318 for (int i=0; i<nr; i++) {
319 valm1 += ( i%2 == 0 ? 1 : -1)*sol_part(lz, k, j, i) ;
320 valhom1 += ( i%2 == 0 ? 1 : -1)*sol_hom(lz, k, j, i) ;
321 }
322 double lambda = (val1 - valm1) * echelles(lz-1) ;
323 for (int i=0; i<nr; i++)
324 resu.set(lz, k, j, i) = sol_part(lz, k, j, i)
325 + lambda*sol_hom(lz, k, j, i) ;
326
327 }
328 }
329 }
330 }
331 return result ;
332}
333
334}
Bases of the spectral expansions.
Definition base_val.h:325
void mult_x()
The basis is transformed as with a multiplication by .
void give_quant_numbers(int, int, int, int &, int &, int &) const
Computes the various quantum numbers and 1d radial base.
Class for the elementary differential operator (see the base class Diff ).
Definition diff.h:129
virtual const Matrice & get_matrice() const
Returns the matrix associated with the operator.
Definition diff_dsdx.C:97
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:329
virtual const Matrice & get_matrice() const
Returns the matrix associated with the operator.
Definition diff_sx.C:103
Class for the elementary differential operator (see the base class Diff ).
Definition diff.h:409
virtual const Matrice & get_matrice() const
Returns the matrix associated with the operator.
Definition diff_xdsdx.C:101
Affine radial mapping.
Definition map.h:2042
const double * get_beta() const
Returns the pointer on the array beta.
Definition map_af.C:608
const double * get_alpha() const
Returns the pointer on the array alpha.
Definition map_af.C:604
Matrix handling.
Definition matrice.h:152
void set_etat_qcq()
Sets the logical state to ETATQCQ (ordinary state).
Definition matrice.C:178
double & set(int j, int i)
Read/write of a particuliar element.
Definition matrice.h:277
Tbl inverse(const Tbl &sec_membre) const
Solves the linear system represented by the matrix.
Definition matrice.C:427
void set_lu() const
Calculate the LU-representation, assuming the band-storage has been done.
Definition matrice.C:395
Multi-domain grid.
Definition grilles.h:279
int get_np(int l) const
Returns the number of points in the azimuthal direction ( ) in domain no. l.
Definition grilles.h:479
int get_nt(int l) const
Returns the number of points in the co-latitude direction ( ) in domain no. l.
Definition grilles.h:474
int get_nzone() const
Returns the number of domains.
Definition grilles.h:465
int get_nr(int l) const
Returns the number of points in the radial direction ( ) in domain no. l.
Definition grilles.h:469
int get_type_r(int l) const
Returns the type of sampling in the radial direction in domain no.
Definition grilles.h:491
Coefficients storage for the multi-domain spectral method.
Definition mtbl_cf.h:196
Tbl & set(int l)
Read/write of the Tbl containing the coefficients in a given domain.
Definition mtbl_cf.h:304
const Mg3d * get_mg() const
Returns the Mg3d on which the Mtbl_cf is defined.
Definition mtbl_cf.h:463
void annule_hard()
Sets the Mtbl_cf to zero in a hard way.
Definition mtbl_cf.C:315
Scalar sol_divergence(int n) const
Resolution of a divergence-like equation.
virtual void set_etat_qcq()
Sets the logical state to ETATQCQ (ordinary state).
Definition scalar.C:359
bool check_dzpuis(int dzi) const
Returns false if the last domain is compactified and *this is not zero in this domain and dzpuis is n...
Definition scalar.C:879
virtual void set_etat_zero()
Sets the logical state to ETATZERO (zero).
Definition scalar.C:330
Scalar(const Map &mpi)
Constructor from mapping.
Definition scalar.C:210
Valeur & set_spectral_va()
Returns va (read/write version).
Definition scalar.h:610
int etat
The logical state ETATNONDEF (undefined), ETATZERO (null), ETATUN (one), or ETATQCQ (ordinary).
Definition scalar.h:402
const Base_val & get_spectral_base() const
Returns the spectral bases of the Valeur va.
Definition scalar.h:1328
Valeur va
The numerical value of the Scalar.
Definition scalar.h:411
friend Scalar pow(const Scalar &, int)
Power .
void set_spectral_base(const Base_val &)
Sets the spectral bases of the Valeur va.
Definition scalar.C:803
Basic array class.
Definition tbl.h:161
void annule_hard()
Sets the Tbl to zero in a hard way.
Definition tbl.C:375
void set_etat_qcq()
Sets the logical state to ETATQCQ (ordinary state).
Definition tbl.C:364
double & set(int i)
Read/write of a particular element (index i) (1D case).
Definition tbl.h:281
double * t
The array of double.
Definition tbl.h:173
Values and coefficients of a (real-value) function.
Definition valeur.h:297
void set_etat_cf_qcq()
Sets the logical state to ETATQCQ (ordinary state) for values in the configuration space (Mtbl_cf c_c...
Definition valeur.C:715
Mtbl_cf * c_cf
Coefficients of the spectral expansion of the function.
Definition valeur.h:312
void ylm_i()
Inverse of ylm().
#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)
#define R_CHEBP
base de Cheb. paire (rare) seulement
const Map *const mp
Mapping on which the numerical values at the grid points are defined.
Definition tensor.h:301
Lorene prototypes.
Definition app_hor.h:67