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