LORENE
sh_pvect_r.C
1 /*
2  * Methods for computing the homogeneous solutions for Ope_pois_vect_r.
3  *
4  * (see file Ope_elementary 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: sh_pvect_r.C,v 1.7 2018/11/16 14:34:36 j_novak Exp $
32  * $Log: sh_pvect_r.C,v $
33  * Revision 1.7 2018/11/16 14:34:36 j_novak
34  * Changed minor points to avoid some compilation warnings.
35  *
36  * Revision 1.6 2016/12/05 16:18:12 j_novak
37  * Suppression of some global variables (file names, loch, ...) to prevent redefinitions
38  *
39  * Revision 1.5 2014/10/13 08:53:34 j_novak
40  * Lorene classes and functions now belong to the namespace Lorene.
41  *
42  * Revision 1.4 2014/10/06 15:16:13 j_novak
43  * Modified #include directives to use c++ syntax.
44  *
45  * Revision 1.3 2004/12/23 16:00:10 j_novak
46  * Modif. comments.
47  *
48  * Revision 1.2 2004/05/10 15:36:42 j_novak
49  * Corrected a missing #include
50  *
51  * Revision 1.1 2004/05/10 15:28:22 j_novak
52  * First version of functions for the solution of the r-component of the
53  * vector Poisson equation.
54  *
55  *
56  * $Header: /cvsroot/Lorene/C++/Source/Ope_elementary/Ope_pois_vect_r/sh_pvect_r.C,v 1.7 2018/11/16 14:34:36 j_novak Exp $
57  *
58  */
59 
60 //fichiers includes
61 #include <cstdlib>
62 #include <cmath>
63 
64 #include "matrice.h"
65 #include "type_parite.h"
66 #include "proto.h"
67 
68 /*
69  *
70  * Renvoie une ou 2 solution homogene
71  * Si l <> 0 :
72  * Si base_r = R_CHEB deux solutions (x+echelle)^(l-1) dans (0, *) et
73  * 1/(x+echelle)^(l+2) dans (1, *)
74  * Si base_r = R_CHEBU 1 solution (x-1)^(l+2) dans (*)
75  * Si base_r = R_CHEBP ou R_CHEBI x^(l-1) dans (*)
76  *
77  * Si l = 0:
78  * Si base_r = R_CHEB deux solutions (x+echelle) dans (0, *) et
79  * 1/(x+echelle)^(l+2) dans (1, *)
80  * Si base_r = R_CHEBU 1 solution (x-1)^(l+2) dans (*)
81  * Si base_r = R_CHEBP ou R_CHEBI x dans (*)
82  *
83  * Entree :
84  * n : nbre de points en r
85  * l : nbre quantique associe
86  * echelle : cf ci-dessus, utile que dans le cas R_CHEB
87  * base_r : base de decomposition
88  *
89  * Sortie :
90  * Tbl contenant les coefficient de la ou des solution homogenes
91  *
92  */
93 
94 namespace Lorene {
95 Tbl _sh_pvect_r_pas_prevu (int, int, double) ;
96 Tbl _sh_pvect_r_cheb (int, int, double) ;
97 Tbl _sh_pvect_r_chebp (int, int, double) ;
98 Tbl _sh_pvect_r_chebi (int, int, double) ;
99 Tbl _sh_pvect_r_chebu (int, int, double) ;
100 
101  //------------------------------------
102  // Routine pour les cas non prevus --
103  //------------------------------------
104 Tbl _sh_pvect_r_pas_prevu (int n, int l, double echelle) {
105 
106  cout << " Solution homogene pas prevue ..... : "<< endl ;
107  cout << " N : " << n << endl ;
108  cout << " l : " << l << endl ;
109  cout << " echelle : " << echelle << endl ;
110  abort() ;
111  exit(-1) ;
112  Tbl res(1) ;
113  return res;
114 }
115 
116 
117  //-------------------
118  //-- R_CHEB ------
119  //-------------------
120 
121 Tbl _sh_pvect_r_cheb (int n, int l, double echelle) {
122 
123  const int nmax = 200 ; // Nombre de Tbl stockes
124  static Tbl* tab[nmax] ; // les Tbl calcules
125  static int nb_dejafait = 0 ; // nbre de Tbl calcules
126  static int l_dejafait[nmax] ;
127  static int nr_dejafait[nmax] ;
128  static double vieux_echelle = 0;
129 
130  // Si on a change l'echelle : on detruit tout :
131  if (vieux_echelle != echelle) {
132  for (int i=0 ; i<nb_dejafait ; i++) {
133  l_dejafait[i] = -1 ;
134  nr_dejafait[i] = -1 ;
135  delete tab[i] ;
136  }
137  nb_dejafait = 0 ;
138  vieux_echelle = echelle ;
139  }
140 
141  int indice = -1 ;
142 
143  // On determine si la matrice a deja ete calculee :
144  for (int conte=0 ; conte<nb_dejafait ; conte ++)
145  if ((l_dejafait[conte] == l) && (nr_dejafait[conte] == n))
146  indice = conte ;
147 
148  // Calcul a faire :
149  if (indice == -1) {
150  if (nb_dejafait >= nmax) {
151  cout << "_sh_pvect_r_cheb : trop de Tbl" << endl ;
152  abort() ;
153  exit (-1) ;
154  }
155 
156 
157  l_dejafait[nb_dejafait] = l ;
158  nr_dejafait[nb_dejafait] = n ;
159 
160  // assert (l < n) ;
161 
162  Tbl res(2, n) ;
163  res.set_etat_qcq() ;
164  double* coloc = new double[n] ;
165 
166  int * deg = new int[3] ;
167  deg[0] = 1 ;
168  deg[1] = 1 ;
169  deg[2] = n ;
170 
171  //Construction de la premiere solution homogene :
172  // cad celle polynomiale.
173 
174  if (l==0) {
175  for (int i=0 ; i<n ; i++)
176  coloc[i] = echelle - cos(M_PI*i/(n-1)) ;
177 
178  cfrcheb(deg, deg, coloc, deg, coloc) ;
179  for (int i=0 ; i<n ;i++)
180  res.set(0, i) = coloc[i] ;
181  }
182  else if (l==1) {
183  res.set(0, 0) = 1 ;
184  for (int i=1 ; i<n ; i++)
185  res.set(0, i) = 0 ;
186  }
187  else {
188 
189  for (int i=0 ; i<n ; i++)
190  coloc[i] = pow(echelle-cos(M_PI*i/(n-1)), double(l-1)) ;
191 
192  cfrcheb(deg, deg, coloc, deg, coloc) ;
193  for (int i=0 ; i<n ;i++)
194  res.set(0, i) = coloc[i] ;
195  }
196 
197 
198  // construction de la seconde solution homogene :
199  // cad celle fractionnelle.
200  for (int i=0 ; i<n ; i++)
201  coloc[i] = 1/pow(echelle-cos(M_PI*i/(n-1)), double(l+2)) ;
202 
203  cfrcheb(deg, deg, coloc, deg, coloc) ;
204  for (int i=0 ; i<n ;i++)
205  res.set(1, i) = coloc[i] ;
206 
207  delete [] coloc ;
208  delete [] deg ;
209  tab[nb_dejafait] = new Tbl(res) ;
210  nb_dejafait ++ ;
211  return res ;
212  }
213 
214  else return *tab[indice] ;
215 }
216 
217  //-------------------
218  //-- R_CHEBP ------
219  //-------------------
220 
221 Tbl _sh_pvect_r_chebp (int n, int l, double) {
222 
223  const int nmax = 200 ; // Nombre de Tbl stockes
224  static Tbl* tab[nmax] ; // les Tbl calcules
225  static int nb_dejafait = 0 ; // nbre de Tbl calcules
226  static int l_dejafait[nmax] ;
227  static int nr_dejafait[nmax] ;
228 
229  int indice = -1 ;
230 
231  // On determine si la matrice a deja ete calculee :
232  for (int conte=0 ; conte<nb_dejafait ; conte ++)
233  if ((l_dejafait[conte] == l) && (nr_dejafait[conte] == n))
234  indice = conte ;
235 
236  // Calcul a faire :
237  if (indice == -1) {
238  if (nb_dejafait >= nmax) {
239  cout << "_sh_pvect_r_chebp : trop de Tbl" << endl ;
240  abort() ;
241  exit (-1) ;
242  }
243 
244 
245  l_dejafait[nb_dejafait] = l ;
246  nr_dejafait[nb_dejafait] = n ;
247 
248  Tbl res(n) ;
249  res.set_etat_qcq() ;
250  double* coloc = new double[n] ;
251 
252  int * deg = new int[3] ;
253  deg[0] = 1 ;
254  deg[1] = 1 ;
255  deg[2] = n ;
256 
257  assert (div(l, 2).rem == 1) ;
258  if (l==1) {
259  res.set(0) = 1 ;
260  for (int i=1 ; i<n ; i++)
261  res.set(i) = 0 ;
262  }
263  else {
264  for (int i=0 ; i<n ; i++)
265  coloc[i] = pow(sin(M_PI*i/2/(n-1)), double(l-1)) ;
266 
267  cfrchebp(deg, deg, coloc, deg, coloc) ;
268  for (int i=0 ; i<n ;i++)
269  res.set(i) = coloc[i] ;
270  }
271 
272  delete [] coloc ;
273  delete [] deg ;
274  tab[nb_dejafait] = new Tbl(res) ;
275  nb_dejafait ++ ;
276  return res ;
277  }
278 
279  else return *tab[indice] ;
280 }
281 
282 
283  //-------------------
284  //-- R_CHEBI -----
285  //-------------------
286 
287 Tbl _sh_pvect_r_chebi (int n, int l, double) {
288 
289  const int nmax = 200 ; // Nombre de Tbl stockes
290  static Tbl* tab[nmax] ; // les Tbl calcules
291  static int nb_dejafait = 0 ; // nbre de Tbl calcules
292  static int l_dejafait[nmax] ;
293  static int nr_dejafait[nmax] ;
294 
295  int indice = -1 ;
296 
297  // On determine si la matrice a deja ete calculee :
298  for (int conte=0 ; conte<nb_dejafait ; conte ++)
299  if ((l_dejafait[conte] == l) && (nr_dejafait[conte] == n))
300  indice = conte ;
301 
302  // Calcul a faire :
303  if (indice == -1) {
304  if (nb_dejafait >= nmax) {
305  cout << "_sh_pvect_r_chebi : trop de Tbl" << endl ;
306  abort() ;
307  exit (-1) ;
308  }
309 
310 
311  l_dejafait[nb_dejafait] = l ;
312  nr_dejafait[nb_dejafait] = n ;
313 
314 
315  assert (div(l, 2).rem == 0) ;
316  // assert (l < 2*n) ;
317 
318  Tbl res(n) ;
319  res.set_etat_qcq() ;
320  double* coloc = new double[n] ;
321 
322  int * deg = new int[3] ;
323  deg[0] = 1 ;
324  deg[1] = 1 ;
325  deg[2] = n ;
326 
327  if (l==0) {
328  res.set(0) = 1 ;
329  for (int i=1 ; i<n ; i++)
330  res.set(i) = 0 ;
331  }
332  else {
333  for (int i=0 ; i<n ; i++)
334  coloc[i] = pow(sin(M_PI*i/2/(n-1)), double(l-1)) ;
335 
336  cfrchebi(deg, deg, coloc, deg, coloc) ;
337  for (int i=0 ; i<n ;i++)
338  res.set(i) = coloc[i] ;
339  }
340 
341  delete [] coloc ;
342  delete [] deg ;
343  tab[nb_dejafait] = new Tbl(res) ;
344  nb_dejafait ++ ;
345  return res ;
346  }
347 
348  else return *tab[indice] ;
349 }
350 
351 
352 
353  //-------------------
354  //-- R_CHEBU -----
355  //-------------------
356 
357 Tbl _sh_pvect_r_chebu (int n, int l, double) {
358 
359  const int nmax = 200 ; // Nombre de Tbl stockes
360  static Tbl* tab[nmax] ; // les Tbl calcules
361  static int nb_dejafait = 0 ; // nbre de Tbl calcules
362  static int l_dejafait[nmax] ;
363  static int nr_dejafait[nmax] ;
364 
365  int indice = -1 ;
366 
367  // On determine si la matrice a deja ete calculee :
368  for (int conte=0 ; conte<nb_dejafait ; conte ++)
369  if ((l_dejafait[conte] == l) && (nr_dejafait[conte] == n))
370  indice = conte ;
371 
372  // Calcul a faire :
373  if (indice == -1) {
374  if (nb_dejafait >= nmax) {
375  cout << "_sh_pvect_r_chebu : trop de Tbl" << endl ;
376  abort() ;
377  exit (-1) ;
378  }
379 
380 
381  l_dejafait[nb_dejafait] = l ;
382  nr_dejafait[nb_dejafait] = n ;
383 
384 
385  // assert (l < n-1) ;
386  Tbl res(n) ;
387  res.set_etat_qcq() ;
388  double* coloc = new double[n] ;
389 
390  int * deg = new int[3] ;
391  deg[0] = 1 ;
392  deg[1] = 1 ;
393  deg[2] = n ;
394 
395  for (int i=0 ; i<n ; i++)
396  coloc[i] = pow(-1-cos(M_PI*i/(n-1)), double(l+2)) ;
397 
398  cfrcheb(deg, deg, coloc, deg, coloc) ;
399  for (int i=0 ; i<n ;i++)
400  res.set(i) = coloc[i] ;
401 
402  delete [] coloc ;
403  delete [] deg ;
404  tab[nb_dejafait] = new Tbl(res) ;
405  nb_dejafait ++ ;
406  return res ;
407  }
408 
409  else return *tab[indice] ;
410 }
411 
412 
413 
414 
415  //-------------------
416  //-- Fonction ----
417  //-------------------
418 
419 
420 Tbl sh_pvect_r(int n, int l, double echelle, int base_r) {
421 
422  // Routines de derivation
423  static Tbl (*sh_pvect_r[MAX_BASE])(int, int, double) ;
424  static int nap = 0 ;
425 
426  // Premier appel
427  if (nap==0) {
428  nap = 1 ;
429  for (int i=0 ; i<MAX_BASE ; i++) {
430  sh_pvect_r[i] = _sh_pvect_r_pas_prevu ;
431  }
432  // Les routines existantes
433  sh_pvect_r[R_CHEB >> TRA_R] = _sh_pvect_r_cheb ;
434  sh_pvect_r[R_CHEBU >> TRA_R] = _sh_pvect_r_chebu ;
435  sh_pvect_r[R_CHEBP >> TRA_R] = _sh_pvect_r_chebp ;
436  sh_pvect_r[R_CHEBI >> TRA_R] = _sh_pvect_r_chebi ;
437  }
438 
439  Tbl res(sh_pvect_r[base_r](n, l, echelle)) ;
440  return res ;
441 }
442 }
Lorene prototypes.
Definition: app_hor.h:67
Cmp cos(const Cmp &)
Cosine.
Definition: cmp_math.C:97
#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
Cmp pow(const Cmp &, int)
Power .
Definition: cmp_math.C:351
Cmp sin(const Cmp &)
Sine.
Definition: cmp_math.C:72
#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