KADATH
div_xm1_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 div_xm1_1d_pasprevu (Array<double>&) {
26  cout << "div_xm1_1d not implemented." << endl ;
27  abort() ;
28 }
29 
30 
31 int div_xm1_1d_cheb (Array<double>& so) {
32  assert (so.get_ndim()==1) ;
33  int nr = so.get_size(0) ;
34  Array<double> res (nr) ;
35  res = 0 ;
36  for (int i=0 ; i<nr-1 ; i++)
37  for (int j=i+1 ; j<nr ; j++)
38  res.set(i) += 2*(j-i)*so(j) ;
39  res.set(0) *= 0.5 ;
40 
41  so = res ;
42  return CHEB ;
43 }
44 
45 double leg (int n, double x) ;
46 int div_xm1_1d_leg (Array<double>& so) {
47  assert (so.get_ndim()==1) ;
48  int nr = so.get_size(0) ;
49 
50 
51  Array<double> res (nr) ;
52 
53  static Matrice* ope = 0x0 ;
54  static int nr_done = 0 ;
55 
56  if (nr_done != nr) {
57  // Compute the matrix :
58  nr_done = nr ;
59  if (ope !=0x0)
60  delete ope ;
61  ope = new Matrice (nr, nr) ;
62  *ope = 0 ;
63  ope->set(0,0) = -1 ;
64  ope->set(0,1) = 1./3. ;
65  for (int i=1 ; i<nr-1 ; i++) {
66  ope->set(i,i-1) = double(i)/double(2*i-1) ;
67  ope->set(i,i) = -1 ;
68  ope->set(i, i+1) = double(i+1)/double(2*i+3) ;
69  }
70  ope->set(nr-1, nr-2) = double(nr-1)/double(2*nr-3) ;
71  ope->set(nr-1, nr-1) = -1 ;
72  ope->set_band(1,1) ;
73  ope->set_lu() ;
74  }
75 
76  Array<double> copie (so) ;
77  copie.set(0) = 0 ;
78  for (int i=1 ; i<nr ; i++)
79  copie.set(0) -= so(i)*leg(i, 1.) ;
80  res = ope->solve(copie) ;
81 
82  so = res ;
83  return LEG ;
84 }
85 
86 int div_xm1_1d (int base, Array<double>& so) {
87  static int (*div_xm1_1d[NBR_MAX_BASE])(Array<double>&) ;
88  static bool premier_appel = true ;
89 
90  // Premier appel
91  if (premier_appel) {
92  premier_appel = false ;
93 
94  for (int i=0; i<NBR_MAX_BASE; i++)
95  div_xm1_1d[i] = div_xm1_1d_pasprevu ;
96 
97  div_xm1_1d[CHEB] = div_xm1_1d_cheb ;
98  div_xm1_1d[LEG] = div_xm1_1d_leg ;;
99  }
100 
101  return div_xm1_1d[base](so) ;
102 }}