00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 char ope_sec_order_solh_C[] = "$Header: /cvsroot/Lorene/C++/Source/Ope_elementary/Ope_sec_order/ope_sec_order_solh.C,v 1.2 2005/02/18 13:14:18 j_novak Exp $" ;
00022
00023
00024
00025
00026
00027
00028 #include <math.h>
00029 #include <stdlib.h>
00030
00031 #include "proto.h"
00032 #include "ope_elementary.h"
00033
00034
00035
00036
00037 Tbl _solh_sec_order_pas_prevu (int, double, double,double,double,double,Tbl&) {
00038
00039 cout << "Homogeneous solution not implemented in Sec_order : "<< endl ;
00040 abort() ;
00041 exit(-1) ;
00042 Tbl res(1) ;
00043 return res;
00044 }
00045
00046
00047
00048
00049
00050
00051 Tbl _solh_sec_order_r_cheb (int n, double alpha, double beta,
00052 double a, double b, double c, Tbl& val_lim) {
00053
00054
00055 Tbl res(2,n) ;
00056 res.set_etat_qcq() ;
00057 double* coloc = new double[n] ;
00058
00059 int * deg = new int[3] ;
00060 deg[0] = 1 ;
00061 deg[1] = 1 ;
00062 deg[2] = n ;
00063
00064
00065 double* sigma = new double[n] ;
00066 for (int i=0 ; i<n ; i++)
00067 sigma[i] = alpha*(-cos(M_PI*i/(n-1))) + beta ;
00068
00069 double sigma_minus = beta-alpha ;
00070 double sigma_plus = beta+alpha ;
00071
00072
00073 double delta = b*b-4*a*c ;
00074 int signe = 0 ;
00075 if (delta > 0)
00076 signe = + 1 ;
00077 if (delta < 0)
00078 signe = -1 ;
00079 if (fabs(delta) < 1e-14)
00080 signe = 0 ;
00081
00082 switch (signe) {
00083
00084 case 1: {
00085
00086 double lambda_one = (-b + sqrt(delta)) / 2./a ;
00087 double lambda_two = (-b - sqrt(delta)) / 2./a ;
00088
00089
00090 for (int i=0 ; i<n ; i++)
00091 coloc[i] = exp(sigma[i]*lambda_one) ;
00092 cfrcheb(deg, deg, coloc, deg, coloc) ;
00093 for (int i=0 ; i<n ;i++)
00094 res.set(0,i) = coloc[i] ;
00095
00096
00097 for (int i=0 ; i<n ; i++)
00098 coloc[i] = exp(sigma[i]*lambda_two) ;
00099 cfrcheb(deg, deg, coloc, deg, coloc) ;
00100 for (int i=0 ; i<n ;i++)
00101 res.set(1,i) = coloc[i] ;
00102
00103
00104 val_lim.set(0,0) = exp(sigma_minus*lambda_one) ;
00105 val_lim.set(0,1) = lambda_one*exp(sigma_minus*lambda_one)
00106 /exp(sigma_minus) ;
00107 val_lim.set(0,2) = exp(sigma_plus*lambda_one) ;
00108 val_lim.set(0,3) = lambda_one*exp(sigma_plus*lambda_one)
00109 /exp(sigma_plus) ;
00110
00111 val_lim.set(1,0) = exp(sigma_minus*lambda_two) ;
00112 val_lim.set(1,1) = lambda_two*exp(sigma_minus*lambda_two)/
00113 exp(sigma_minus);
00114 val_lim.set(1,2) = exp(sigma_plus*lambda_two) ;
00115 val_lim.set(1,3) = lambda_two*exp(sigma_plus*lambda_two)
00116 /exp(sigma_plus) ;
00117 val_lim /= sqrt(double(2)) ;
00118 break ;
00119 }
00120 case 0: {
00121
00122 double lambda = -b/2./a ;
00123
00124 for (int i=0 ; i<n ; i++)
00125 coloc[i] = exp(sigma[i]*lambda) ;
00126 cfrcheb(deg, deg, coloc, deg, coloc) ;
00127 for (int i=0 ; i<n ;i++)
00128 res.set(0,i) = coloc[i] ;
00129
00130
00131 for (int i=0 ; i<n ; i++)
00132 coloc[i] = sigma[i]*exp(sigma[i]*lambda) ;
00133 cfrcheb(deg, deg, coloc, deg, coloc) ;
00134 for (int i=0 ; i<n ;i++)
00135 res.set(1,i) = coloc[i] ;
00136
00137
00138 val_lim.set(0,0) = exp(sigma_minus*lambda) ;
00139 val_lim.set(0,1) = lambda*exp(sigma_minus*lambda)/exp(sigma_minus) ;
00140 val_lim.set(0,2) = exp(sigma_plus*lambda) ;
00141 val_lim.set(0,3) = lambda*exp(sigma_plus*lambda)/exp(sigma_plus) ;
00142
00143 val_lim.set(1,0) = sigma_minus*exp(sigma_minus*lambda) ;
00144 val_lim.set(1,1) = exp(sigma_minus*lambda)* (lambda*sigma_minus+1)
00145 /exp(sigma_minus);
00146 val_lim.set(1,2) = sigma_plus*exp(sigma_plus*lambda) ;
00147 val_lim.set(1,3) = exp(sigma_plus*lambda)* (lambda*sigma_plus+1)/
00148 exp(sigma_plus) ;
00149 val_lim /= sqrt(double(2)) ;
00150 break ;
00151 }
00152 case -1:{
00153
00154 double real_part = -b/2./a ;
00155 double imag_part = sqrt(-delta)/2./a ;
00156
00157
00158 for (int i=0 ; i<n ; i++)
00159 coloc[i] = exp(sigma[i]*real_part)*cos(imag_part*sigma[i]) ;
00160 cfrcheb(deg, deg, coloc, deg, coloc) ;
00161 for (int i=0 ; i<n ;i++)
00162 res.set(0,i) = coloc[i] ;
00163
00164
00165 for (int i=0 ; i<n ; i++)
00166 coloc[i] = exp(sigma[i]*real_part)*sin(imag_part*sigma[i]) ;
00167 cfrcheb(deg, deg, coloc, deg, coloc) ;
00168 for (int i=0 ; i<n ;i++)
00169 res.set(1,i) = coloc[i] ;
00170
00171
00172 val_lim.set(0,0) = exp(sigma_minus*real_part)*cos(imag_part*sigma_minus) ;
00173 val_lim.set(0,1) = (real_part*cos(imag_part*sigma_minus) -
00174 imag_part*sin(imag_part*sigma_minus)) * exp(real_part*sigma_minus)
00175 /exp(sigma_minus);
00176 val_lim.set(0,2) = exp(sigma_plus*real_part)*cos(imag_part*sigma_plus) ;
00177 val_lim.set(0,3) = (real_part*cos(imag_part*sigma_plus) -
00178 imag_part*sin(imag_part*sigma_plus)) * exp(real_part*sigma_plus)
00179 /exp(sigma_plus) ;
00180
00181 val_lim.set(1,0) = exp(sigma_minus*real_part)*sin(imag_part*sigma_minus) ;
00182 val_lim.set(1,1) = (real_part*sin(imag_part*sigma_minus) +
00183 imag_part*cos(imag_part*sigma_minus)) * exp(real_part*sigma_minus)
00184 /exp(sigma_minus);
00185 val_lim.set(1,2) = exp(sigma_plus*real_part)*sin(imag_part*sigma_plus);
00186 val_lim.set(1,3) = (real_part*sin(imag_part*sigma_plus) +
00187 imag_part*cos(imag_part*sigma_plus)) * exp(real_part*sigma_plus)
00188 /exp(sigma_plus) ;
00189 val_lim /= sqrt(double(2)) ;
00190 break ;
00191 }
00192 default:
00193 cout << "What are you doing here ? Get out or I call the police !" << endl;
00194 abort() ;
00195 break ;
00196 }
00197
00198 delete [] deg ;
00199 delete [] coloc ;
00200 delete [] sigma ;
00201
00202 return res ;
00203 }
00204
00205
00206 Tbl Ope_sec_order::get_solh () const {
00207
00208
00209 static Tbl (*solh_sec_order[MAX_BASE]) (int, double, double,
00210 double, double, double, Tbl&) ;
00211 static int nap = 0 ;
00212
00213
00214 if (nap==0) {
00215 nap = 1 ;
00216 for (int i=0 ; i<MAX_BASE ; i++) {
00217 solh_sec_order[i] = _solh_sec_order_pas_prevu ;
00218 }
00219
00220 solh_sec_order[R_CHEB >> TRA_R] = _solh_sec_order_r_cheb ;
00221 }
00222
00223 Tbl val_lim (2,4) ;
00224 val_lim.set_etat_qcq() ;
00225 Tbl res(solh_sec_order[base_r](nr,alpha,beta,a_param,b_param,c_param,
00226 val_lim)) ;
00227
00228 s_one_minus = val_lim(0,0) ;
00229 ds_one_minus = val_lim(0,1) ;
00230 s_one_plus = val_lim(0,2) ;
00231 ds_one_plus = val_lim(0,3) ;
00232
00233 s_two_minus = val_lim(1,0) ;
00234 ds_two_minus = val_lim(1,1) ;
00235 s_two_plus = val_lim(1,2) ;
00236 ds_two_plus = val_lim(1,3) ;
00237
00238 return res ;
00239 }