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 
79 namespace Lorene {
80 Matrice _ope_ptens_rr_mat_pas_prevu(int, int, double, int) ;
81 Matrice _ope_ptens_rr_mat_r_chebp(int, int, double, int) ;
82 Matrice _ope_ptens_rr_mat_r_chebi(int, int, double, int) ;
83 Matrice _ope_ptens_rr_mat_r_chebu(int, int, double, int) ;
84 Matrice _ope_ptens_rr_mat_r_cheb(int, int, double, int) ;
85 
86  //-----------------------------------
87  // Routine pour les cas non prevus --
88  //-----------------------------------
89 
90 Matrice _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 
108 Matrice _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 
194 Matrice _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 
278 Matrice _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 
368 Matrice _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 
494 Matrice 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 }
Lorene prototypes.
Definition: app_hor.h:67
#define TRA_R
Translation en R, used for a bitwise shift (in hex)
Definition: type_parite.h:158
#define R_CHEBI
base de Cheb. impaire (rare) seulement
Definition: type_parite.h:170
#define R_CHEBP
base de Cheb. paire (rare) seulement
Definition: type_parite.h:168
#define R_CHEBU
base de Chebychev ordinaire (fin), dev. en 1/r
Definition: type_parite.h:180
#define MAX_BASE
Nombre max. de bases differentes.
Definition: type_parite.h:144
#define R_CHEB
base de Chebychev ordinaire (fin)
Definition: type_parite.h:166