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_r2_solh_C[] = "$Header: /cvsroot/Lorene/C++/Source/Ope_elementary/Ope_sec_order_r2/ope_sec_order_r2_solh.C,v 1.2 2004/03/09 09:15:12 p_grandclement 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_r2_pas_prevu (int, double, double,double,double,double,Tbl&) {
00038
00039 cout << "Homogeneous solution not implemented in Sec_order_r2 : "<< 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_r2_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* air = new double[n] ;
00066 for (int i=0 ; i<n ; i++)
00067 air[i] = alpha*(-cos(M_PI*i/(n-1))) + beta ;
00068
00069 double r_minus = beta-alpha ;
00070 double r_plus = beta+alpha ;
00071
00072
00073 double delta = (b-a)*(b-a)-4*a*c ;
00074 int signe ;
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 = ((a-b) + sqrt(delta)) / 2./a ;
00087 double lambda_two = ((a-b) - sqrt(delta)) / 2./a ;
00088
00089
00090 for (int i=0 ; i<n ; i++)
00091 coloc[i] = pow(air[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] = pow(air[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) = pow(r_minus, lambda_one) ;
00105 val_lim.set(0,1) = lambda_one*pow(r_minus, lambda_one-1) ;
00106 val_lim.set(0,2) = pow(r_plus, lambda_one) ;
00107 val_lim.set(0,3) = lambda_one*pow(r_plus, lambda_one-1) ;
00108
00109 val_lim.set(1,0) = pow(r_minus, lambda_two) ;
00110 val_lim.set(1,1) = lambda_two*pow(r_minus, lambda_two-1) ;
00111 val_lim.set(1,2) = pow(r_plus, lambda_two) ;
00112 val_lim.set(1,3) = lambda_two*pow(r_plus, lambda_two-1) ;
00113 val_lim /= sqrt(double(2)) ;
00114 break ;
00115 }
00116 case 0: {
00117
00118 double lambda = (a-b)/2./a ;
00119
00120 for (int i=0 ; i<n ; i++)
00121 coloc[i] = pow(air[i], lambda) ;
00122 cfrcheb(deg, deg, coloc, deg, coloc) ;
00123 for (int i=0 ; i<n ;i++)
00124 res.set(0,i) = coloc[i] ;
00125
00126
00127 for (int i=0 ; i<n ; i++)
00128 coloc[i] = log(air[i])*pow(air[i], lambda) ;
00129 cfrcheb(deg, deg, coloc, deg, coloc) ;
00130 for (int i=0 ; i<n ;i++)
00131 res.set(1,i) = coloc[i] ;
00132
00133
00134 val_lim.set(0,0) = pow(r_minus, lambda) ;
00135 val_lim.set(0,1) = lambda*pow(r_minus, lambda-1) ;
00136 val_lim.set(0,2) = pow(r_plus, lambda) ;
00137 val_lim.set(0,3) = lambda*pow(r_plus, lambda-1) ;
00138
00139 val_lim.set(1,0) = log(r_minus)*pow(r_minus, lambda) ;
00140 val_lim.set(1,1) = (1+lambda*log(r_minus))*pow(r_minus, lambda-1) ;
00141 val_lim.set(1,2) = log(r_plus)*pow(r_plus, lambda) ;
00142 val_lim.set(1,3) = (1+lambda*log(r_plus))*pow(r_plus, lambda-1) ;
00143 val_lim /= sqrt(double(2)) ;
00144 break ;
00145 }
00146 case -1:{
00147
00148 double real_part = (a-b)/2./a ;
00149 double imag_part = sqrt(-delta)/2./a ;
00150
00151
00152 for (int i=0 ; i<n ; i++)
00153 coloc[i] = pow(air[i], real_part)*cos(imag_part*log(air[i])) ;
00154 cfrcheb(deg, deg, coloc, deg, coloc) ;
00155 for (int i=0 ; i<n ;i++)
00156 res.set(0,i) = coloc[i] ;
00157
00158
00159 for (int i=0 ; i<n ; i++)
00160 coloc[i] = pow(air[i], real_part)*sin(imag_part*log(air[i])) ;
00161 cfrcheb(deg, deg, coloc, deg, coloc) ;
00162 for (int i=0 ; i<n ;i++)
00163 res.set(1,i) = coloc[i] ;
00164
00165
00166 val_lim.set(0,0) = pow(r_minus, real_part)*cos(imag_part*log(r_minus)) ;
00167 val_lim.set(0,1) = (real_part*cos(imag_part*log(r_minus)) -
00168 imag_part*sin(imag_part*log(r_minus))) *
00169 pow(r_minus, real_part-1) ;
00170 val_lim.set(0,2) = pow(r_plus, real_part)*cos(imag_part*log(r_plus)) ;
00171 val_lim.set(0,3) = (real_part*cos(imag_part*log(r_plus)) -
00172 imag_part*sin(imag_part*log(r_plus))) *
00173 pow(r_plus, real_part-1) ;
00174
00175 val_lim.set(1,0) = pow(r_minus, real_part)*sin(imag_part*log(r_minus)) ;
00176 val_lim.set(1,1) = (real_part*sin(imag_part*log(r_minus)) +
00177 imag_part*cos(imag_part*log(r_minus))) *
00178 pow(r_minus, real_part-1) ;
00179 val_lim.set(1,2) = pow(r_plus, real_part)*sin(imag_part*log(r_plus)) ;
00180 val_lim.set(1,3) = (real_part*sin(imag_part*log(r_plus)) +
00181 imag_part*cos(imag_part*log(r_plus))) *
00182 pow(r_plus, real_part-1) ;
00183 val_lim /= sqrt(double(2)) ;
00184 break ;
00185 }
00186 default:
00187 cout << "What are you doing here ? Get out or I call the police !" << endl;
00188 abort() ;
00189 break ;
00190 }
00191
00192 delete [] deg ;
00193 delete [] coloc ;
00194 delete [] air ;
00195
00196 return res ;
00197 }
00198
00199
00200 Tbl Ope_sec_order_r2::get_solh () const {
00201
00202
00203 static Tbl (*solh_sec_order_r2[MAX_BASE]) (int, double, double,
00204 double, double, double, Tbl&) ;
00205 static int nap = 0 ;
00206
00207
00208 if (nap==0) {
00209 nap = 1 ;
00210 for (int i=0 ; i<MAX_BASE ; i++) {
00211 solh_sec_order_r2[i] = _solh_sec_order_r2_pas_prevu ;
00212 }
00213
00214 solh_sec_order_r2[R_CHEB >> TRA_R] = _solh_sec_order_r2_r_cheb ;
00215 }
00216
00217 Tbl val_lim (2,4) ;
00218 val_lim.set_etat_qcq() ;
00219 Tbl res(solh_sec_order_r2[base_r](nr,alpha,beta,a_param,b_param,c_param,
00220 val_lim)) ;
00221
00222 s_one_minus = val_lim(0,0) ;
00223 ds_one_minus = val_lim(0,1) ;
00224 s_one_plus = val_lim(0,2) ;
00225 ds_one_plus = val_lim(0,3) ;
00226
00227 s_two_minus = val_lim(1,0) ;
00228 ds_two_minus = val_lim(1,1) ;
00229 s_two_plus = val_lim(1,2) ;
00230 ds_two_plus = val_lim(1,3) ;
00231
00232 return res ;
00233 }