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