1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177
|
#include "headcpp.h"
#include "math.h"
#include "tbl.h"
#include "matrice.h"
#include "cheby.h"
double f_source (double x) {
static double constante = -4*exp(1.)/(1+exp(1.)*exp(1.)) ;
return constante + exp(x) ;
}
double f_solution (double x) {
static double constante = -4*exp(1.)/(1+exp(1.)*exp(1.)) ;
return exp(x) - sinh(1.)/sinh(2.)*exp(2*x) + constante/4 ;
}
//*******************
// First derivative
//*******************
Tbl ope_der (const Tbl& so) {
// Verification of size :
assert (so.get_ndim() == 1) ;
int size = so.get_dim(0) ;
// The result is set to zero
Tbl res (size) ;
res.annule_hard() ;
// the computation
for (int n=0 ; n<size ; n++)
for (int p=n+1 ; p<size ; p++)
if ((p+n)%2 == 1)
res.set(n) += p*so(p)*2 ;
// Normalisation of the first coef :
res.set(0) /= 2. ;
return res ;
}
//*******************
// Second derivative
//*******************
Tbl ope_der_sec (const Tbl& so) {
// Verification of size :
assert (so.get_ndim() == 1) ;
int size = so.get_dim(0) ;
// The result is set to zero
Tbl res (size) ;
res.annule_hard() ;
// the computation
for (int n=0 ; n<size ; n++)
for (int p=n+2 ; p<size ; p++)
if ((p+n)%2 == 0)
res.set(n) += p*(p*p-n*n)*so(p) ;
// Normalisation of the first coef :
res.set(0) /= 2. ;
return res ;
}
//*******************
// The operator
//*******************
Matrice matrix_ope (int n) {
// The result :
Matrice res(n,n) ;
res.set_etat_qcq() ;
// Work arrays :
Tbl so (n) ;
Tbl d_so (n) ;
Tbl dd_so (n) ;
// Column by column :
for (int col=0 ; col<n ; col++) {
so.annule_hard() ;
so.set(col) = 1 ;
// The derivatives
d_so = ope_der(so) ;
dd_so = ope_der_sec(so) ;
// Put in the matrix :
for (int line=0 ; line<n ; line++)
res.set(line, col) = dd_so(line) -4*d_so(line) + 4*so(line) ;
}
return res ;
}
int main () {
int nr ;
cout << "Please enter the number of coefficients :" << endl ;
cin >> nr ;
cout << "The operator matrix is " << endl ;
Matrice operator_mat (matrix_ope(nr)) ;
cout << operator_mat << endl ;
// Resolution with a collocation method :
Matrice systeme(nr, nr) ;
systeme.annule_hard() ;
// Boundary conditions are inforced by additional equations:
// Left boundary condition :
for (int i=0 ; i<nr ; i++)
systeme.set(0, i) = (i%2==0) ? 1 : -1 ;
// Right boundary condition :
for (int i=0 ; i<nr ; i++)
systeme.set(nr-1, i) = 1 ;
// The rest of the equations :
Tbl colocation(coloc_cheb(nr)) ;
for (int n=1 ; n<nr-1 ; n++)
for (int k=0 ; k<nr ; k++)
for (int j=0 ; j<nr ; j++)
systeme.set(n,k) += operator_mat(j, k) * cheby(j, colocation(n)) ;
systeme.set_lu() ;
cout << "The colocation matrix is" << endl ;
cout << systeme << endl ;
// Second member of the system :
Tbl sec_member (nr) ;
sec_member.set_etat_qcq() ;
// Boundary conditions :
sec_member.set(0) = 0 ;
sec_member.set(nr-1) = 0 ;
// Coefficients of the source :
for (int i=1 ; i<nr-1 ; i++)
sec_member.set(i) = f_source(colocation(i)) ;
cout << "Second member for the colocation system" << endl ;
cout << sec_member << endl ;
// The system is inverted :
Tbl coef_sol (systeme.inverse(sec_member)) ;
cout << "Coefficients of the solution : " << endl ;
cout << coef_sol << endl ;
// Output in a file for plotting purposes :
char name_out[30] ;
sprintf(name_out, "plot_tau_%i.dat", nr) ;
ofstream fiche (name_out) ;
int resolution = 200 ;
double x=-1 ;
double step = 2./resolution ;
// We will also compute the maximum difference between the solution and its numerical value :
double error_max = 0 ;
for (int i=0 ; i<resolution+1 ; i++) {
// One computes the solution at the current point
double val_func = 0 ;
for (int j=0 ; j<nr ; j++)
val_func += coef_sol(j)*cheby(j, x) ;
fiche << x << " " << val_func << " " << f_solution(x) << endl ;
double error = fabs(val_func-f_solution(x)) ;
if (error > error_max)
error_max = error ;
x += step ;
}
cout << "Error max : " << endl ;
cout << error_max << endl ;
return 0 ;
}
|