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 
78 namespace Lorene {
79 Matrice _ope_pvect_r_mat_pas_prevu(int, int, double, int) ;
80 Matrice _ope_pvect_r_mat_r_chebp(int, int, double, int) ;
81 Matrice _ope_pvect_r_mat_r_chebi(int, int, double, int) ;
82 Matrice _ope_pvect_r_mat_r_chebu(int, int, double, int) ;
83 Matrice _ope_pvect_r_mat_r_cheb(int, int, double, int) ;
84 
85  //-----------------------------------
86  // Routine pour les cas non prevus --
87  //-----------------------------------
88 
89 Matrice _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 
107 Matrice _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 
196 Matrice _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 
283 Matrice _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 
376 Matrice _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 
505 Matrice 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 }
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