LORENE
ope_ptens_rr_mat.C
1/*
2 * Builds the operator for Ope_pois_tens_rr
3 *
4 * (see file ope_elementary.h for documentation).
5 *
6 */
7
8/*
9 * Copyright (c) 2004 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: ope_ptens_rr_mat.C,v 1.4 2016/12/05 16:18:12 j_novak Exp $
32 * $Log: ope_ptens_rr_mat.C,v $
33 * Revision 1.4 2016/12/05 16:18:12 j_novak
34 * Suppression of some global variables (file names, loch, ...) to prevent redefinitions
35 *
36 * Revision 1.3 2014/10/13 08:53:34 j_novak
37 * Lorene classes and functions now belong to the namespace Lorene.
38 *
39 * Revision 1.2 2014/10/06 15:16:13 j_novak
40 * Modified #include directives to use c++ syntax.
41 *
42 * Revision 1.1 2004/12/23 16:30:15 j_novak
43 * New files and class for the solution of the rr component of the tensor Poisson
44 * equation.
45 *
46 *
47 *
48 * $Header: /cvsroot/Lorene/C++/Source/Ope_elementary/Ope_pois_vect_r/ope_ptens_rr_mat.C,v 1.4 2016/12/05 16:18:12 j_novak Exp $
49 *
50 */
51
52//fichiers includes
53#include <cstdlib>
54
55#include "matrice.h"
56#include "type_parite.h"
57#include "proto.h"
58
59/*
60 * Routine caluclant l'operateur suivant :
61 *
62 * -R_CHEB : r^2d2sdx2+6*rdsdx+6-l*(l+1)Id
63 *
64 * -R_CHEBP et R_CHEBI : d2sdx2+6/r dsdx +(6-l(l+1))/r^2
65 *
66 * -R_CHEBU : d2sdx2+(6-l(l+1))/x^2
67 *
68 * Entree :
69 * -n nbre de points en r
70 * -l voire operateur. (doit etre >=2)
71 * -echelle utile uniquement pour R_CHEB : represente beta/alpha
72 * (cf mapping)
73 * - puis : exposant de multiplication dans la ZEC
74 * - base_r : base de developpement
75 * Sortie :
76 * La fonction renvoie la matrice.
77 */
78
79namespace Lorene {
80Matrice _ope_ptens_rr_mat_pas_prevu(int, int, double, int) ;
81Matrice _ope_ptens_rr_mat_r_chebp(int, int, double, int) ;
82Matrice _ope_ptens_rr_mat_r_chebi(int, int, double, int) ;
83Matrice _ope_ptens_rr_mat_r_chebu(int, int, double, int) ;
84Matrice _ope_ptens_rr_mat_r_cheb(int, int, double, int) ;
85
86 //-----------------------------------
87 // Routine pour les cas non prevus --
88 //-----------------------------------
89
90Matrice _ope_ptens_rr_mat_pas_prevu(int n, int l, double echelle, int puis) {
91 cout << "laplacien tens_rr pas prevu..." << endl ;
92 cout << "n : " << n << endl ;
93 cout << "l : " << l << endl ;
94 cout << "puissance : " << puis << endl ;
95 cout << "echelle : " << echelle << endl ;
96 abort() ;
97 exit(-1) ;
98 Matrice res(1, 1) ;
99 return res;
100}
101
102
103 //-------------------------
104 //---- CAS R_CHEBP ----
105 //-------------------------
106
107
108Matrice _ope_ptens_rr_mat_r_chebp (int n, int l, double, int) {
109
110 const int nmax = 100 ;// Nombre de Matrices stockees
111 static Matrice* tab[nmax] ; // les matrices calculees
112 static int nb_dejafait = 0 ; // nbre de matrices calculees
113 static int l_dejafait[nmax] ;
114 static int nr_dejafait[nmax] ;
115
116 int indice = -1 ;
117
118 // On determine si la matrice a deja ete calculee :
119 for (int conte=0 ; conte<nb_dejafait ; conte ++)
120 if ((l_dejafait[conte] == l) && (nr_dejafait[conte] == n))
121 indice = conte ;
122
123 // Calcul a faire :
124 if (indice == -1) {
125 if (nb_dejafait >= nmax) {
126 cout << "_ope_ptens_rr_mat_r_chebp : trop de matrices" << endl ;
127 abort() ;
128 exit (-1) ;
129 }
130
131
132 l_dejafait[nb_dejafait] = l ;
133 nr_dejafait[nb_dejafait] = n ;
134
135 Matrice dd(n, n) ;
136 dd.set_etat_qcq() ;
137 Matrice xd(n, n) ;
138 xd.set_etat_qcq() ;
139 Matrice xx(n, n) ;
140 xx.set_etat_qcq() ;
141
142 double* vect = new double[n] ;
143
144 for (int i=0 ; i<n ; i++) {
145 for (int j=0 ; j<n ; j++)
146 vect[j] = 0 ;
147 vect[i] = 1 ;
148 d2sdx2_1d (n, &vect, R_CHEBP) ;
149
150 for (int j=0 ; j<n ; j++)
151 dd.set(j, i) = vect[j] ;
152 }
153
154 for (int i=0 ; i<n ; i++) {
155 for (int j=0 ; j<n ; j++)
156 vect[j] = 0 ;
157 vect[i] = 1 ;
158 sxdsdx_1d (n, &vect, R_CHEBP) ;
159 for (int j=0 ; j<n ; j++)
160 xd.set(j, i) = vect[j] ;
161
162 }
163
164 for (int i=0 ; i<n ; i++) {
165 for (int j=0 ; j<n ; j++)
166 vect[j] = 0 ;
167 vect[i] = 1 ;
168 sx2_1d (n, &vect, R_CHEBP) ;
169 for (int j=0 ; j<n ; j++)
170 xx.set(j, i) = vect[j] ;
171 }
172
173 delete [] vect ;
174
175 Matrice res(n, n) ;
176 res = dd+6*xd+(6-l*(l+1))*xx ;
177 tab[nb_dejafait] = new Matrice(res) ;
178 nb_dejafait ++ ;
179 return res ;
180 }
181
182 // Cas ou le calcul a deja ete effectue :
183 else
184 return *tab[indice] ;
185}
186
187
188
189 //------------------------
190 //-- CAS R_CHEBI ----
191 //------------------------
192
193
194Matrice _ope_ptens_rr_mat_r_chebi (int n, int l, double, int) {
195
196 const int nmax = 100 ;// Nombre de Matrices stockees
197 static Matrice* tab[nmax] ; // les matrices calculees
198 static int nb_dejafait = 0 ; // nbre de matrices calculees
199 static int l_dejafait[nmax] ;
200 static int nr_dejafait[nmax] ;
201
202 int indice = -1 ;
203
204 // On determine si la matrice a deja ete calculee :
205 for (int conte=0 ; conte<nb_dejafait ; conte ++)
206 if ((l_dejafait[conte] == l) && (nr_dejafait[conte] == n))
207 indice = conte ;
208
209 // Calcul a faire :
210 if (indice == -1) {
211 if (nb_dejafait >= nmax) {
212 cout << "_ope_ptens_rr_mat_r_chebi : trop de matrices" << endl ;
213 abort() ;
214 exit (-1) ;
215 }
216
217
218 l_dejafait[nb_dejafait] = l ;
219 nr_dejafait[nb_dejafait] = n ;
220
221 Matrice dd(n, n) ;
222 dd.set_etat_qcq() ;
223 Matrice xd(n, n) ;
224 xd.set_etat_qcq() ;
225 Matrice xx(n, n) ;
226 xx.set_etat_qcq() ;
227
228 double* vect = new double[n] ;
229
230 for (int i=0 ; i<n ; i++) {
231 for (int j=0 ; j<n ; j++)
232 vect[j] = 0 ;
233 vect[i] = 1 ;
234 d2sdx2_1d (n, &vect, R_CHEBI) ; // appel dans le cas impair
235 for (int j=0 ; j<n ; j++)
236 dd.set(j, i) = vect[j] ;
237 }
238
239 for (int i=0 ; i<n ; i++) {
240 for (int j=0 ; j<n ; j++)
241 vect[j] = 0 ;
242 vect[i] = 1 ;
243 sxdsdx_1d (n, &vect, R_CHEBI) ;
244 for (int j=0 ; j<n ; j++)
245 xd.set(j, i) = vect[j] ;
246 }
247
248 for (int i=0 ; i<n ; i++) {
249 for (int j=0 ; j<n ; j++)
250 vect[j] = 0 ;
251 vect[i] = 1 ;
252 sx2_1d (n, &vect, R_CHEBI) ;
253 for (int j=0 ; j<n ; j++)
254 xx.set(j, i) = vect[j] ;
255 }
256
257 delete [] vect ;
258
259 Matrice res(n, n) ;
260 res = dd+6*xd+(6-l*(l+1))*xx ;
261 tab[nb_dejafait] = new Matrice(res) ;
262 nb_dejafait ++ ;
263 return res ;
264 }
265
266 // Cas ou le calcul a deja ete effectue :
267 else
268 return *tab[indice] ;
269}
270
271
272
273
274 //------------------------
275 //---- CAS R_CHEBU ----
276 //------------------------
277
278Matrice _ope_ptens_rr_mat_r_chebu( int n, int l, double, int puis) {
279
280 if (puis != 4) {
281 cout << "_ope_ptens_rr_mat_r_chebu : only the case dzpuis = 4 "
282 << '\n' << "is implemented! \n"
283 << "dzpuis = " << puis << endl ;
284 abort() ;
285 }
286
287 const int nmax = 200 ;// Nombre de Matrices stockees
288 static Matrice* tab[nmax] ; // les matrices calculees
289 static int nb_dejafait = 0 ; // nbre de matrices calculees
290 static int l_dejafait[nmax] ;
291 static int nr_dejafait[nmax] ;
292
293 int indice = -1 ;
294
295 // On determine si la matrice a deja ete calculee :
296 for (int conte=0 ; conte<nb_dejafait ; conte ++)
297 if ((l_dejafait[conte] == l) && (nr_dejafait[conte] == n))
298 indice = conte ;
299
300 // Calcul a faire :
301 if (indice == -1) {
302 if (nb_dejafait >= nmax) {
303 cout << "_ope_ptens_rr_mat_r_chebu : trop de matrices" << endl ;
304 abort() ;
305 exit (-1) ;
306 }
307
308 l_dejafait[nb_dejafait] = l ;
309 nr_dejafait[nb_dejafait] = n ;
310
311 Matrice dd(n, n) ;
312 dd.set_etat_qcq() ;
313 Matrice xd(n, n) ;
314 xd.set_etat_qcq() ;
315 Matrice xx(n, n) ;
316 xx.set_etat_qcq() ;
317
318 double* vect = new double[n] ;
319
320 for (int i=0 ; i<n ; i++) {
321 for (int j=0 ; j<n ; j++)
322 vect[j] = 0 ;
323 vect[i] = 1 ;
324 d2sdx2_1d (n, &vect, R_CHEBU) ; // appel dans le cas unsurr
325 for (int j=0 ; j<n ; j++)
326 dd.set(j, i) = vect[j] ;
327 }
328
329 for (int i=0 ; i<n ; i++) {
330 for (int j=0 ; j<n ; j++)
331 vect[j] = 0 ;
332 vect[i] = 1 ;
333 dsdx_1d (n, &vect, R_CHEBU) ; // appel dans le cas unsurr
334 sxm1_1d_cheb (n, vect) ;
335 for (int j=0 ; j<n ; j++)
336 xd.set(j, i) = vect[j] ;
337 }
338
339 for (int i=0 ; i<n ; i++) {
340 for (int j=0 ; j<n ; j++)
341 vect[j] = 0 ;
342 vect[i] = 1 ;
343 sx2_1d (n, &vect, R_CHEBU) ;
344 for (int j=0 ; j<n ; j++)
345 xx.set(j, i) = vect[j] ;
346 }
347
348 delete [] vect ;
349
350 Matrice res(n, n) ;
351 res = dd - 4*xd + (6 -l*(l+1))*xx ;
352 tab[nb_dejafait] = new Matrice(res) ;
353 nb_dejafait ++ ;
354 return res ;
355 }
356
357 // Cas ou le calcul a deja ete effectue :
358 else
359 return *tab[indice] ;
360}
361
362
363 //-----------------------
364 //---- CAS R_CHEB ----
365 //-----------------------
366
367
368Matrice _ope_ptens_rr_mat_r_cheb (int n, int l, double echelle, int) {
369
370 const int nmax = 200 ;// Nombre de Matrices stockees
371 static Matrice* tab[nmax] ; // les matrices calculees
372 static int nb_dejafait = 0 ; // nbre de matrices calculees
373 static int l_dejafait[nmax] ;
374 static int nr_dejafait[nmax] ;
375 static double vieux_echelle = 0;
376
377 // Si on a change l'echelle : on detruit tout :
378 if (vieux_echelle != echelle) {
379 for (int i=0 ; i<nb_dejafait ; i++) {
380 l_dejafait[i] = -1 ;
381 nr_dejafait[i] = -1 ;
382 delete tab[i] ;
383 }
384
385 nb_dejafait = 0 ;
386 vieux_echelle = echelle ;
387 }
388
389 int indice = -1 ;
390
391 // On determine si la matrice a deja ete calculee :
392 for (int conte=0 ; conte<nb_dejafait ; conte ++)
393 if ((l_dejafait[conte] == l) && (nr_dejafait[conte] == n))
394 indice = conte ;
395
396 // Calcul a faire :
397 if (indice == -1) {
398 if (nb_dejafait >= nmax) {
399 cout << "_ope_ptens_rr_mat_r_cheb : trop de matrices" << endl ;
400 abort() ;
401 exit (-1) ;
402 }
403
404
405 l_dejafait[nb_dejafait] = l ;
406 nr_dejafait[nb_dejafait] = n ;
407
408 Matrice dd(n, n) ;
409 dd.set_etat_qcq() ;
410 Matrice xd(n, n) ;
411 xd.set_etat_qcq() ;
412 Matrice xx(n, n) ;
413 xx.set_etat_qcq() ;
414
415 double* vect = new double[n] ;
416
417 for (int i=0 ; i<n ; i++) {
418 for (int j=0 ; j<n ; j++)
419 vect[j] = 0 ;
420 vect[i] = 1 ;
421 d2sdx2_1d (n, &vect, R_CHEB) ; // appel dans le cas fin
422 for (int j=0 ; j<n ; j++)
423 dd.set(j, i) = vect[j]*echelle*echelle ;
424 }
425
426 for (int i=0 ; i<n ; i++) {
427 for (int j=0 ; j<n ; j++)
428 vect[j] = 0 ;
429 vect[i] = 1 ;
430 d2sdx2_1d (n, &vect, R_CHEB) ; // appel dans le cas fin
431 multx_1d (n, &vect, R_CHEB) ;
432 for (int j=0 ; j<(n>i+1 ? i+1 : n) ; j++)
433 dd.set(j, i) += 2*echelle*vect[j] ;
434 }
435
436 for (int i=0 ; i<n ; i++) {
437 for (int j=0 ; j<n ; j++)
438 vect[j] = 0 ;
439 vect[i] = 1 ;
440 d2sdx2_1d (n, &vect, R_CHEB) ; // appel dans le cas fin
441 multx_1d (n, &vect, R_CHEB) ;
442 multx_1d (n, &vect, R_CHEB) ;
443 for (int j=0 ; j<(n>i+1 ? i+1 : n) ; j++)
444 dd.set(j, i) += vect[j] ;
445 }
446
447 for (int i=0 ; i<n ; i++) {
448 for (int j=0 ; j<n ; j++)
449 vect[j] = 0 ;
450 vect[i] = 1 ;
451 sxdsdx_1d (n, &vect, R_CHEB) ;
452 for (int j=0 ; j<n ; j++)
453 xd.set(j, i) = vect[j]*echelle ;
454 }
455
456 for (int i=0 ; i<n ; i++) {
457 for (int j=0 ; j<n ; j++)
458 vect[j] = 0 ;
459 vect[i] = 1 ;
460 sxdsdx_1d (n, &vect, R_CHEB) ;
461 multx_1d (n, &vect, R_CHEB) ;
462 for (int j=0 ; j<(n>i+1 ? i+1 : n) ; j++)
463 xd.set(j, i) += vect[j] ;
464 }
465
466 for (int i=0 ; i<n ; i++) {
467 for (int j=0 ; j<n ; j++)
468 vect[j] = 0 ;
469 vect[i] = 1 ;
470 sx2_1d (n, &vect, R_CHEB) ;
471 for (int j=0 ; j<n ; j++)
472 xx.set(j, i) = vect[j] ;
473 }
474
475 delete [] vect ;
476
477 Matrice res(n, n) ;
478 res = dd + 6*xd + (6 - l*(l+1))*xx ;
479 tab[nb_dejafait] = new Matrice(res) ;
480 nb_dejafait ++ ;
481 return res ;
482 }
483
484 // Cas ou le calcul a deja ete effectue :
485 else
486 return *tab[indice] ;
487}
488
489
490 //----------------------------
491 //--- La routine a appeler ---
492 //----------------------------
493
494Matrice ope_ptens_rr_mat(int n, int l, double echelle, int puis, int base_r)
495{
496
497 // Routines de derivation
498 static Matrice (*ope_ptens_rr_mat[MAX_BASE])(int, int, double, int) ;
499 static int nap = 0 ;
500
501 // Premier appel
502 if (nap==0) {
503 nap = 1 ;
504 for (int i=0 ; i<MAX_BASE ; i++) {
505 ope_ptens_rr_mat[i] = _ope_ptens_rr_mat_pas_prevu ;
506 }
507 // Les routines existantes
508 ope_ptens_rr_mat[R_CHEB >> TRA_R] = _ope_ptens_rr_mat_r_cheb ;
509 ope_ptens_rr_mat[R_CHEBU >> TRA_R] = _ope_ptens_rr_mat_r_chebu ;
510 ope_ptens_rr_mat[R_CHEBP >> TRA_R] = _ope_ptens_rr_mat_r_chebp ;
511 ope_ptens_rr_mat[R_CHEBI >> TRA_R] = _ope_ptens_rr_mat_r_chebi ;
512 }
513 assert (l>1) ;
514 Matrice res(ope_ptens_rr_mat[base_r](n, l, echelle, puis)) ;
515 return res ;
516}
517
518}
Matrix handling.
Definition matrice.h:152
#define MAX_BASE
Nombre max. de bases differentes.
#define R_CHEBU
base de Chebychev ordinaire (fin), dev. en 1/r
#define R_CHEBI
base de Cheb. impaire (rare) seulement
#define TRA_R
Translation en R, used for a bitwise shift (in hex).
#define R_CHEB
base de Chebychev ordinaire (fin)
#define R_CHEBP
base de Cheb. paire (rare) seulement
Lorene prototypes.
Definition app_hor.h:67