KADATH
mult_x_1d.cpp
1 /*
2  Copyright 2017 Philippe Grandclement
3 
4  This file is part of Kadath.
5 
6  Kadath is free software: you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  Kadath is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with Kadath. If not, see <http://www.gnu.org/licenses/>.
18 */
19 
20 #include "base_spectral.hpp"
21 #include "headcpp.hpp"
22 #include "matrice.hpp"
23 #include "array.hpp"
24 namespace Kadath {
25 int mult_x_1d_pasprevu (Array<double>&) {
26  cout << "mult_x_1d not implemented." << endl ;
27  abort() ;
28 }
29 
30 int mult_x_1d_cheb (Array<double>& so) {
31  assert (so.get_ndim()==1) ;
32  int nr = so.get_size(0) ;
33  Array<double> res (nr) ;
34  res.set(0) = 0.5*so(1) ;
35  res.set(1) = so(0)+0.5*so(2) ;
36  for (int i=2 ; i<nr-1 ; i++)
37  res.set(i) = 0.5*(so(i+1)+so(i-1)) ;
38  res.set(nr-1) = 0.5*so(nr-2) ;
39  so = res ;
40  return CHEB ;
41 }
42 
43 int mult_x_1d_cheb_even (Array<double>& so) {
44  assert (so.get_ndim()==1) ;
45  int nr = so.get_size(0) ;
46  Array<double> res (nr) ;
47 
48  res.set(0) = so(0) + 0.5*so(1) ;
49  for (int i=1 ; i<nr-1 ; i++)
50  res.set(i) = 0.5*(so(i)+so(i+1)) ;
51  res.set(nr-1) = 0. ;
52  so = res ;
53 
54  return CHEB_ODD ;
55 }
56 
57 int mult_x_1d_cheb_odd (Array<double>& so) {
58  assert (so.get_ndim()==1) ;
59  int nr = so.get_size(0) ;
60  Array<double> res (nr) ;
61  res.set(0) = 0.5*so(0) ;
62  for (int i=1 ; i<nr-1 ; i++)
63  res.set(i) = 0.5*(so(i)+so(i-1)) ;
64  res.set(nr-1) = 0.5*so(nr-2) ;
65 
66  so = res ;
67  return CHEB_EVEN ;
68 }
69 
70 int mult_x_1d_leg (Array<double>& so) {
71  assert (so.get_ndim()==1) ;
72  int nr = so.get_size(0) ;
73  Array<double> res (nr) ;
74  res.set(0) = 1./3.*so(1) ;
75  for (int i=1 ; i<nr-1 ; i++)
76  res.set(i) = (double(i)/double(2*i-1)*so(i-1)+double(i+1)/double(2*i+3)*so(i+1)) ;
77  res.set(nr-1) = double(nr-1)/double(2*nr-3)*so(nr-2);
78  so = res ;
79  return LEG ;
80 }
81 
82 int mult_x_1d_leg_odd (Array<double>& so) {
83  assert (so.get_ndim()==1) ;
84  int nr = so.get_size(0) ;
85  Array<double> res (nr) ;
86 
87  res.set(0) = 1./3.*so(0) ;
88  for (int i=1 ; i<nr-1 ; i++)
89  res.set(i) = (double(2*i)/double(4*i-1)*so(i-1)+double(2*i+1)/double(4*i+3)*so(i)) ;
90  res.set(nr-1) = double(2*nr-2)/double(4*nr-5)*so(nr-2);
91 
92  so = res ;
93  return LEG_EVEN ;
94 }
95 
96 int mult_x_1d_leg_even (Array<double>& so) {
97  assert (so.get_ndim()==1) ;
98  int nr = so.get_size(0) ;
99  Array<double> res (nr) ;
100  for (int i=0 ; i<nr-1 ; i++)
101  res.set(i) = (double(2*i+1)/double(4*i+1)*so(i)+double(2*i+2)/double(4*i+5)*so(i+1)) ;
102  res.set(nr-1) = 0. ;
103 
104  so = res ;
105  return LEG_ODD ;
106 }
107 
108 int mult_x_1d (int base, Array<double>& so) {
109  static int (*mult_x_1d[NBR_MAX_BASE])(Array<double>&) ;
110  static bool premier_appel = true ;
111 
112  // Premier appel
113  if (premier_appel) {
114  premier_appel = false ;
115 
116  for (int i=0; i<NBR_MAX_BASE; i++)
117  mult_x_1d[i] = mult_x_1d_pasprevu ;
118 
119  mult_x_1d[CHEB_EVEN] = mult_x_1d_cheb_even ;
120  mult_x_1d[CHEB] = mult_x_1d_cheb ;
121  mult_x_1d[CHEB_ODD] = mult_x_1d_cheb_odd ;
122  mult_x_1d[LEG_EVEN] = mult_x_1d_leg_even ;
123  mult_x_1d[LEG_ODD] = mult_x_1d_leg_odd ;
124  mult_x_1d[LEG] = mult_x_1d_leg ;
125  }
126 
127  return mult_x_1d[base](so) ;
128 }}