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
94namespace Lorene {
95Tbl _sh_pvect_r_pas_prevu (int, int, double) ;
96Tbl _sh_pvect_r_cheb (int, int, double) ;
97Tbl _sh_pvect_r_chebp (int, int, double) ;
98Tbl _sh_pvect_r_chebi (int, int, double) ;
99Tbl _sh_pvect_r_chebu (int, int, double) ;
100
101 //------------------------------------
102 // Routine pour les cas non prevus --
103 //------------------------------------
104Tbl _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
121Tbl _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
221Tbl _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
287Tbl _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
357Tbl _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
420Tbl 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}
Basic array class.
Definition tbl.h:161
Cmp sin(const Cmp &)
Sine.
Definition cmp_math.C:72
Cmp pow(const Cmp &, int)
Power .
Definition cmp_math.C:351
Cmp cos(const Cmp &)
Cosine.
Definition cmp_math.C:97
#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