KADATH
div_sin_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 "array.hpp"
23 namespace Kadath {
24 int div_sin_1d_pasprevu (Array<double>&) {
25  cout << "div_sin_1d not implemented." << endl ;
26  abort() ;
27 }
28 
29 int div_sin_1d_cos (Array<double>& tab) {
30  assert (tab.get_ndim()==1) ;
31 
32  int nr = tab.get_size(0) ;
33  assert(nr%2==1) ;
34  Array<double> res (nr) ;
35 
36  double somme = 0 ;
37  res.set(nr-1) = 0. ;
38  for (int k=nr-2; k>=0; k-=2) {
39  somme -= 2*tab(k) ;
40  res.set(k-1) = somme ;
41  }
42  somme = 0 ;
43  for (int k=nr-3; k>=0; k-=2) {
44  somme -= 2*tab(k+2) ;
45  res.set(k+1) = somme ;
46  }
47  res.set(0) = 0 ;
48 
49  tab = res ;
50  return SIN ;
51 }
52 
53 int div_sin_1d_sin (Array<double>& tab) {
54  assert (tab.get_ndim()==1) ;
55  int nr = tab.get_size(0) ;
56  assert (nr%2==1) ;
57  Array<double> res (nr) ;
58 
59  double somme = 0 ;
60  res.set(nr-1) = 0. ;
61  for (int k=nr-2; k>=0; k-=2) {
62  somme += 2*tab(k) ;
63  res.set(k-1) = somme ;
64  }
65  somme = 0 ;
66  for (int k=nr-3; k>=0; k-=2) {
67  somme += 2*tab(k+2) ;
68  res.set(k+1) = somme ;
69  }
70  res.set(0) *= 0.5 ;
71 
72  tab = res ;
73  return COS ;
74 }
75 
76 int div_sin_1d_cos_even (Array<double>& tab) {
77  assert (tab.get_ndim()==1) ;
78  int nr = tab.get_size(0) ;
79 
80  Array<double> res (nr) ;
81 
82  double somme = 0 ;
83  res.set(nr-1) = 0. ;
84  for (int k=nr-2; k>=0; k--) {
85  somme -= 2*tab(k+1) ;
86  res.set(k) = somme ;
87  }
88  tab = res ;
89  return SIN_ODD ;
90 }
91 
92 int div_sin_1d_cos_odd (Array<double>& tab) {
93  assert (tab.get_ndim()==1) ;
94  int nr = tab.get_size(0) ;
95 
96  Array<double> res (nr) ;
97 
98  double somme = 0 ;
99  res.set(nr-1) = 0. ;
100  for (int k=nr-2; k>=0; k--) {
101  somme -= 2*tab(k) ;
102  res.set(k) = somme ;
103  }
104 
105  tab = res ;
106  return SIN_EVEN ;
107 }
108 
109 
110 int div_sin_1d_sin_even (Array<double>& tab) {
111  assert (tab.get_ndim()==1) ;
112  int nr = tab.get_size(0) ;
113 
114  Array<double> res (nr) ;
115 
116  double somme = 0 ;
117  res.set(nr-1) = 0. ;
118  for (int k=nr-2; k>=0; k--) {
119  somme += 2*tab(k+1) ;
120  res.set(k) = somme ;
121  }
122 
123  tab = res ;
124  return COS_ODD ;
125 }
126 
127 int div_sin_1d_sin_odd (Array<double>& tab) {
128  assert (tab.get_ndim()==1) ;
129  int nr = tab.get_size(0) ;
130 
131  Array<double> res (nr) ;
132 
133  double somme = 0 ;
134  res.set(nr-1) = 0. ;
135  for (int k=nr-2; k>=0; k--) {
136  somme += 2*tab(k) ;
137  res.set(k) = somme ;
138  }
139  res.set(0) *= 0.5 ;
140  tab = res ;
141  return COS_EVEN ;
142 }
143 
144 
145 int div_sin_1d (int base, Array<double>& tab) {
146  static int (*div_sin_1d[NBR_MAX_BASE])(Array<double>&) ;
147  static bool premier_appel = true ;
148 
149  // Premier appel
150  if (premier_appel) {
151  premier_appel = false ;
152 
153  for (int i=0; i<NBR_MAX_BASE; i++)
154  div_sin_1d[i] = div_sin_1d_pasprevu ;
155 
156  div_sin_1d[COS_EVEN] = div_sin_1d_cos_even ;
157  div_sin_1d[COS_ODD] = div_sin_1d_cos_odd ;
158  div_sin_1d[SIN_EVEN] = div_sin_1d_sin_even ;
159  div_sin_1d[SIN_ODD] = div_sin_1d_sin_odd ;
160  div_sin_1d[COS] = div_sin_1d_cos ;
161  div_sin_1d[SIN] = div_sin_1d_sin ;
162  }
163 
164  return div_sin_1d[base](tab) ;
165 }}