LORENE
op_mult_sp.C
1/*
2 * Sets of routines for multiplication by sin(phi)
3 * (internal use)
4 *
5 * void _mult_sp_XXXX(Tbl * t, int & b)
6 * t pointer on the Tbl containing the spectral coefficients
7 * b spectral base
8 *
9 */
10
11/*
12 * Copyright (c) 2000-2001 Eric Gourgoulhon
13 *
14 * This file is part of LORENE.
15 *
16 * LORENE is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * LORENE is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with LORENE; if not, write to the Free Software
28 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29 *
30 */
31
32
33
34
35/*
36 * $Id: op_mult_sp.C,v 1.6 2016/12/05 16:18:08 j_novak Exp $
37 * $Log: op_mult_sp.C,v $
38 * Revision 1.6 2016/12/05 16:18:08 j_novak
39 * Suppression of some global variables (file names, loch, ...) to prevent redefinitions
40 *
41 * Revision 1.5 2014/10/13 08:53:25 j_novak
42 * Lorene classes and functions now belong to the namespace Lorene.
43 *
44 * Revision 1.4 2007/12/14 10:19:33 jl_cornou
45 * *** empty log message ***
46 *
47 * Revision 1.3 2007/10/05 12:37:20 j_novak
48 * Corrected a few errors in the theta-nonsymmetric case (bases T_COSSIN_C and
49 * T_COSSIN_S).
50 *
51 * Revision 1.2 2004/11/23 15:16:01 m_forot
52 *
53 * Added the bases for the cases without any equatorial symmetry
54 * (T_COSSIN_C, T_COSSIN_S, T_LEG, R_CHEBPI_P, R_CHEBPI_I).
55 *
56 * Revision 1.1.1.1 2001/11/20 15:19:29 e_gourgoulhon
57 * LORENE
58 *
59 * Revision 2.4 2000/11/14 15:12:01 eric
60 * Traitement du cas np=1
61 *
62 * Revision 2.3 2000/09/18 10:14:59 eric
63 * Ajout des bases P_COSSIN_P et P_COSSIN_I
64 *
65 * Revision 2.2 2000/09/12 13:36:38 eric
66 * Met les bonnes bases meme dans le cas ETATZERO
67 *
68 * Revision 2.1 2000/09/12 08:29:11 eric
69 * Traitement des bases qui dependent de la parite de m
70 *
71 * Revision 2.0 2000/09/11 13:53:42 eric
72 * *** empty log message ***
73 *
74 *
75 * $Header: /cvsroot/Lorene/C++/Source/Non_class_members/Operators/op_mult_sp.C,v 1.6 2016/12/05 16:18:08 j_novak Exp $
76 *
77 */
78
79// Headers Lorene
80#include "tbl.h"
81
82 //-----------------------------------
83 // Routine for unknown cases
84 //-----------------------------------
85
86namespace Lorene {
87void _mult_sp_pas_prevu(Tbl* , int& base) {
88 cout << "mult_sp() is not not implemented for the basis " << base << " !"
89 << endl ;
90 abort() ;
91}
92
93 //----------------
94 // basis P_COSSIN
95 //----------------
96
97void _mult_sp_p_cossin(Tbl* tb, int& base) {
98
99 assert(tb->get_etat() != ETATNONDEF) ; // Protection
100
101 // The spectral bases in r and theta which depend on the parity of m
102 // are changed
103 // -----------------------------------------------------------------
104
105 int base_r = base & MSQ_R ;
106 int base_t = base & MSQ_T ;
107 const int base_p = base & MSQ_P ;
108
109 switch (base_r) {
110
111 case R_CHEBPIM_P : {
112 base_r = R_CHEBPIM_I ;
113 break ;
114 }
115
116 case R_CHEBPIM_I : {
117 base_r = R_CHEBPIM_P ;
118 break ;
119 }
120
121 case R_CHEBPI_P : {
122 break ;
123 }
124
125 case R_CHEBPI_I : {
126 break ;
127 }
128
129 case R_CHEB : {
130 break ;
131 }
132
133 case R_JACO02 : {
134 break ;
135 }
136
137 case R_CHEBU : {
138 break ;
139 }
140
141 default : {
142 cout << "_mult_cp_p_cossin : unknown basis in r !" << endl ;
143 cout << " base_r = " << hex << base_r << endl ;
144 abort() ;
145 }
146 }
147
148 switch (base_t) {
149
150 case T_COSSIN_CP : {
151 base_t = T_COSSIN_SI ;
152 break ;
153 }
154
155 case T_COSSIN_SI : {
156 base_t = T_COSSIN_CP ;
157 break ;
158 }
159
160 case T_COSSIN_CI : {
161 base_t = T_COSSIN_SP ;
162 break ;
163 }
164
165 case T_COSSIN_SP : {
166 base_t = T_COSSIN_CI ;
167 break ;
168 }
169
170 case T_COSSIN_S : {
171 base_t = T_COSSIN_C ;
172 break ;
173 }
174
175 case T_COSSIN_C : {
176 base_t = T_COSSIN_S ;
177 break ;
178 }
179
180 default : {
181 cout << "_mult_cp_p_cossin : unknown basis in theta !" << endl ;
182 cout << " base_t = " << hex << base_t << endl ;
183 abort() ;
184 }
185 }
186
187 base = base_r | base_t | base_p ;
188
189
190 //----------------------------------
191 // Start of computation
192 //----------------------------------
193
194 // Nothing to do ?
195 if (tb->get_etat() == ETATZERO) {
196 return ;
197 }
198
199 assert(tb->get_etat() == ETATQCQ) ; // Protection
200
201 // Number of degrees of freedom
202 int nr = tb->get_dim(0) ;
203 int nt = tb->get_dim(1) ;
204 int np = tb->get_dim(2) - 2 ;
205
206
207 // Special case np = 1 (axisymmetry) --> zero is returned
208 // ---------------------------------
209
210 if (np==1) {
211 tb->set_etat_zero() ;
212 return ;
213 }
214
215
216 assert(np >= 4) ;
217
218 int ntnr = nt*nr ;
219
220 double* const cf = tb->t ; // input coefficients
221 double* const resu = new double[ tb->get_taille() ] ; // final result
222 double* co = resu ; // initial position
223
224 // Case k=0 (m=0)
225 // --------------
226
227 int q = 3 * ntnr ;
228 for (int i=0; i<ntnr; i++) {
229 co[i] = 0.5 * cf[q + i] ;
230 }
231 co += ntnr ;
232
233 // Case k = 1
234 // ----------
235
236 for (int i=0; i<ntnr; i++) {
237 co[i] = 0 ;
238 }
239 co += ntnr ;
240
241 if (np==4) {
242
243 // Case k = 2 for np=4
244 // ----------
245
246 for (int i=0; i<ntnr; i++) {
247 co[i] = 0 ;
248 }
249 co += ntnr ;
250
251 // Case k = 3 for np=4
252 // ----------
253
254 q = 4*ntnr ;
255 for (int i=0; i<ntnr; i++) {
256 co[i] = cf[i] - 0.5 * cf[q+i] ;
257 }
258 co += ntnr ;
259
260 }
261 else{
262
263 // Case k = 2 for np>4
264 // ----------
265
266 q = 5*ntnr ;
267 for (int i=0; i<ntnr; i++) {
268 co[i] = 0.5 * cf[q+i] ;
269 }
270 co += ntnr ;
271
272 // Case k = 3 for np>4
273 // ----------
274
275 q = 4*ntnr ;
276 for (int i=0; i<ntnr; i++) {
277 co[i] = cf[i] - 0.5 * cf[q+i] ;
278 }
279 co += ntnr ;
280
281
282 // Cases 4 <= k <= np-3
283 // --------------------
284
285 for (int k=4; k<np-2; k+=2) {
286
287 int k1 = k ; // k1 even
288
289 int q1 = (k1-1)*ntnr ;
290 int q2 = (k1+3)*ntnr ;
291 for (int i=0; i<ntnr; i++) {
292 co[i] = 0.5 * ( cf[q2+i] - cf[q1+i] ) ;
293 }
294 co += ntnr ;
295 k1++ ; // k1 odd
296
297 q1 = (k1-3)*ntnr ;
298 q2 = (k1+1)*ntnr ;
299 for (int i=0; i<ntnr; i++) {
300 co[i] = 0.5 * ( cf[q1+i] - cf[q2+i] ) ;
301 }
302 co += ntnr ;
303 }
304
305 // Case k = np - 2 for np>4
306 // ---------------
307
308 q = (np-3)*ntnr ;
309 for (int i=0; i<ntnr; i++) {
310 co[i] = - 0.5 * cf[q + i] ;
311 }
312 co += ntnr ;
313
314 // Case k = np - 1 for np>4
315 // ---------------
316
317 int q1 = (np-4)*ntnr ;
318 int q2 = np*ntnr ;
319 for (int i=0; i<ntnr; i++) {
320 co[i] = 0.5 * ( cf[q1+i] - cf[q2+i] ) ;
321 }
322 co += ntnr ;
323
324 } // End of case np > 4
325
326
327 // Case k = np
328 // -----------
329
330 q = (np-1)*ntnr ;
331 for (int i=0; i<ntnr; i++) {
332 co[i] = - 0.5 * cf[q+i] ;
333 }
334 co += ntnr ;
335
336 // Case k = np+1
337 // -------------
338
339 for (int i=0; i<ntnr; i++) {
340 co[i] = 0 ;
341 }
342
343 //## verif :
344 co += ntnr ;
345 assert( co == resu + (np+2)*ntnr ) ;
346
347
348 // The result is set to tb :
349 // -----------------------
350 delete [] tb->t ;
351 tb->t = resu ;
352
353 return ;
354}
355
356 //------------------
357 // basis P_COSSIN_P
358 //------------------
359
360void _mult_sp_p_cossin_p(Tbl* tb, int& base) {
361
362 assert(tb->get_etat() != ETATNONDEF) ; // Protection
363
364 // New spectral bases
365 // ------------------
366 int base_r = base & MSQ_R ;
367 int base_t = base & MSQ_T ;
368 base = base_r | base_t | P_COSSIN_I ;
369
370 //----------------------------------
371 // Start of computation
372 //----------------------------------
373
374 // Nothing to do ?
375 if (tb->get_etat() == ETATZERO) {
376 return ;
377 }
378
379 assert(tb->get_etat() == ETATQCQ) ; // Protection
380
381 // Number of degrees of freedom
382 int nr = tb->get_dim(0) ;
383 int nt = tb->get_dim(1) ;
384 int np = tb->get_dim(2) - 2 ;
385
386 // Special case np = 1 (axisymmetry) --> zero is returned
387 // ---------------------------------
388
389 if (np==1) {
390 tb->set_etat_zero() ;
391 return ;
392 }
393
394 assert(np >= 4) ;
395
396 int ntnr = nt*nr ;
397
398 double* const cf = tb->t ; // input coefficients
399 double* const resu = new double[ tb->get_taille() ] ; // final result
400 double* co = resu ; // initial position
401
402 // Case k=0
403 // --------
404
405 int q = 3 * ntnr ;
406 for (int i=0; i<ntnr; i++) {
407 co[i] = 0.5 * cf[q + i] ;
408 }
409 co += ntnr ;
410
411 // Case k = 1
412 // ----------
413
414 for (int i=0; i<ntnr; i++) {
415 co[i] = 0 ;
416 }
417 co += ntnr ;
418
419 // Case k = 2
420 // ----------
421
422 q = 2*ntnr ;
423 for (int i=0; i<ntnr; i++) {
424 co[i] = cf[i] - 0.5 * cf[q+i] ;
425 }
426 co += ntnr ;
427
428 // Cases 3 <= k <= np-2
429 // --------------------
430
431 for (int k=3; k<np-1; k+=2) {
432
433 int k1 = k ; // k1 odd
434
435 int q1 = k1*ntnr ;
436 int q2 = (k1+2)*ntnr ;
437 for (int i=0; i<ntnr; i++) {
438 co[i] = 0.5 * ( cf[q2+i] - cf[q1+i] ) ;
439 }
440 co += ntnr ;
441 k1++ ; // k1 even
442
443 q1 = (k1-2)*ntnr ;
444 q2 = k1*ntnr ;
445 for (int i=0; i<ntnr; i++) {
446 co[i] = 0.5 * ( cf[q1+i] - cf[q2+i] ) ;
447 }
448 co += ntnr ;
449 }
450
451 // Case k = np - 1
452 // ---------------
453
454 q = (np-1)*ntnr ;
455 for (int i=0; i<ntnr; i++) {
456 co[i] = - 0.5 * cf[q+i] ;
457 }
458 co += ntnr ;
459
460 // Case k = np
461 // -----------
462
463 int q1 = (np-2)*ntnr ;
464 int q2 = np*ntnr ;
465 for (int i=0; i<ntnr; i++) {
466 co[i] = 0.5 * ( cf[q1+i] - cf[q2+i] ) ;
467 }
468 co += ntnr ;
469
470 // Case k = np+1
471 // -------------
472
473 for (int i=0; i<ntnr; i++) {
474 co[i] = 0 ;
475 }
476
477 //## verif :
478 co += ntnr ;
479 assert( co == resu + (np+2)*ntnr ) ;
480
481
482 // The result is set to tb :
483 // -----------------------
484 delete [] tb->t ;
485 tb->t = resu ;
486
487 return ;
488}
489
490
491 //------------------
492 // basis P_COSSIN_I
493 //------------------
494
495void _mult_sp_p_cossin_i(Tbl* tb, int& base) {
496
497 assert(tb->get_etat() != ETATNONDEF) ; // Protection
498
499 // New spectral bases
500 // ------------------
501 int base_r = base & MSQ_R ;
502 int base_t = base & MSQ_T ;
503 base = base_r | base_t | P_COSSIN_P ;
504
505 //----------------------------------
506 // Start of computation
507 //----------------------------------
508
509 // Nothing to do ?
510 if (tb->get_etat() == ETATZERO) {
511 return ;
512 }
513
514 assert(tb->get_etat() == ETATQCQ) ; // Protection
515
516 // Number of degrees of freedom
517 int nr = tb->get_dim(0) ;
518 int nt = tb->get_dim(1) ;
519 int np = tb->get_dim(2) - 2 ;
520
521 // Special case np = 1 (axisymmetry) --> zero is returned
522 // ---------------------------------
523
524 if (np==1) {
525 tb->set_etat_zero() ;
526 return ;
527 }
528
529 assert(np >= 4) ;
530
531 int ntnr = nt*nr ;
532
533 double* const cf = tb->t ; // input coefficients
534 double* const resu = new double[ tb->get_taille() ] ; // final result
535 double* co = resu ; // initial position
536
537 // Case k=0
538 // --------
539
540 int q = 2 * ntnr ;
541 for (int i=0; i<ntnr; i++) {
542 co[i] = 0.5 * cf[q + i] ;
543 }
544 co += ntnr ;
545
546 // Case k = 1
547 // ----------
548
549 for (int i=0; i<ntnr; i++) {
550 co[i] = 0 ;
551 }
552 co += ntnr ;
553
554 // Case k = 2
555 // ----------
556
557 int q1 = 2*ntnr ;
558 int q2 = 4*ntnr ;
559 for (int i=0; i<ntnr; i++) {
560 co[i] = 0.5 * ( cf[q2+i] - cf[q1+i] ) ;
561 }
562 co += ntnr ;
563
564 // Case k = 3
565 // ----------
566
567 q = 3*ntnr ;
568 for (int i=0; i<ntnr; i++) {
569 co[i] = 0.5 * ( cf[i] - cf[q+i] ) ;
570 }
571 co += ntnr ;
572
573 // Cases 4 <= k <= np-1
574 // --------------------
575
576 for (int k=4; k<np; k+=2) {
577
578 int k1 = k ; // k1 even
579
580 q1 = k1*ntnr ;
581 q2 = (k1+2)*ntnr ;
582 for (int i=0; i<ntnr; i++) {
583 co[i] = 0.5 * ( cf[q2+i] - cf[q1+i] ) ;
584 }
585 co += ntnr ;
586 k1++ ; // k1 odd
587
588 q1 = (k1-2)*ntnr ;
589 q2 = k1*ntnr ;
590 for (int i=0; i<ntnr; i++) {
591 co[i] = 0.5 * ( cf[q1+i] - cf[q2+i] ) ;
592 }
593 co += ntnr ;
594 }
595
596 // Case k = np
597 // -----------
598
599 q = np*ntnr ;
600 for (int i=0; i<ntnr; i++) {
601 co[i] = - 0.5 * cf[q+i] ;
602 }
603 co += ntnr ;
604
605 // Case k = np+1
606 // -------------
607
608 for (int i=0; i<ntnr; i++) {
609 co[i] = 0 ;
610 }
611
612 //## verif :
613 co += ntnr ;
614 assert( co == resu + (np+2)*ntnr ) ;
615
616
617 // The result is set to tb :
618 // -----------------------
619 delete [] tb->t ;
620 tb->t = resu ;
621
622 return ;
623}
624
625}
Basic array class.
Definition tbl.h:161
#define P_COSSIN_P
dev. sur Phi = 2*phi, freq. paires
#define R_CHEBU
base de Chebychev ordinaire (fin), dev. en 1/r
#define R_JACO02
base de Jacobi(0,2) ordinaire (finjac)
#define T_COSSIN_SP
sin pair-cos impair alternes, sin pour m=0
#define MSQ_R
Extraction de l'info sur R.
#define T_COSSIN_S
dev. cos-sin alternes, sin pour m=0
#define R_CHEBPIM_I
Cheb. pair-impair suivant m, impair pour m=0.
#define T_COSSIN_SI
sin impair-cos pair alternes, sin pour m=0
#define R_CHEBPI_I
Cheb. pair-impair suivant l impair pour l=0.
#define T_COSSIN_CI
cos impair-sin pair alternes, cos pour m=0
#define P_COSSIN_I
dev. sur Phi = 2*phi, freq. impaires
#define R_CHEBPIM_P
Cheb. pair-impair suivant m, pair pour m=0.
#define MSQ_T
Extraction de l'info sur Theta.
#define T_COSSIN_CP
cos pair-sin impair alternes, cos pour m=0
#define R_CHEB
base de Chebychev ordinaire (fin)
#define MSQ_P
Extraction de l'info sur Phi.
#define T_COSSIN_C
dev. cos-sin alternes, cos pour m=0
#define R_CHEBPI_P
Cheb. pair-impair suivant l pair pour l=0.
Lorene prototypes.
Definition app_hor.h:67