00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 char scalar_sol_div_C[] = "$Header: /cvsroot/Lorene/C++/Source/Tensor/Scalar/scalar_sol_div.C,v 1.3 2005/09/16 14:33:00 j_novak Exp $" ;
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048 #include<assert.h>
00049 #include<math.h>
00050
00051
00052 #include "tensor.h"
00053 #include "diff.h"
00054 #include "proto.h"
00055
00056
00057 void _sx_r_chebp(Tbl* , int& ) ;
00058 void _sx_r_chebi(Tbl* , int& ) ;
00059
00060
00061 Scalar Scalar::sol_divergence(int n_factor) const {
00062
00063 assert(etat != ETATNONDEF) ;
00064 const Map_af* mpaff = dynamic_cast<const Map_af*>(mp) ;
00065 assert( mpaff != 0x0) ;
00066
00067 Scalar result(*mp) ;
00068
00069 if ( etat == ETATZERO )
00070 result.set_etat_zero() ;
00071 else {
00072 Base_val base_resu = get_spectral_base() ;
00073 base_resu.mult_x() ;
00074 const Mg3d* mg = mp->get_mg() ;
00075 result.set_etat_qcq() ; result.set_spectral_base(base_resu) ;
00076 result.set_spectral_va().set_etat_cf_qcq() ;
00077 Valeur sigma(va) ;
00078 sigma.ylm_i() ;
00079 const Mtbl_cf& source = *sigma.c_cf ;
00080
00081
00082 int nz = mg->get_nzone() ;
00083 bool ced = (mg->get_type_r(nz-1) == UNSURR ) ;
00084 assert ( (!ced) || (check_dzpuis(2)) || (check_dzpuis(1)) ) ;
00085 assert (mg->get_type_r(0) == RARE) ;
00086 int nt = mg->get_nt(0) ;
00087 int np = mg->get_np(0) ;
00088 #ifndef NDEBUG
00089 for (int lz = 0; lz<nz; lz++)
00090 assert( (mg->get_nt(lz) == nt) && (mg->get_np(lz) == np) ) ;
00091 #endif
00092 int nr, base_r,l_quant, m_quant;
00093 Tbl *so ;
00094 Tbl *s_hom ;
00095 Tbl *s_part ;
00096
00097
00098 Mtbl_cf sol_part(mg, base_resu) ;
00099 Mtbl_cf sol_hom(mg, base_resu) ;
00100 Mtbl_cf& resu = *result.set_spectral_va().c_cf ;
00101 sol_part.annule_hard();
00102 sol_hom.annule_hard() ;
00103 resu.annule_hard() ;
00104
00105
00106
00107
00108 int lz = 0 ;
00109 nr = mg->get_nr(lz) ;
00110
00111 int dege = 1 ;
00112 int nr0 = nr - dege ;
00113 Tbl vect1(3, 1, nr) ;
00114 Tbl vect2(3, 1, nr) ;
00115 int base_pipo = 0 ;
00116 double alpha = mpaff->get_alpha()[lz] ;
00117 double beta = 0. ;
00118 Matrice ope_even(nr0, nr0) ;
00119 ope_even.set_etat_qcq() ;
00120 for (int i=dege; i<nr; i++) {
00121 vect1.annule_hard() ;
00122 vect2.annule_hard() ;
00123 vect1.set(0,0,i) = 1. ; vect2.set(0,0,i) = 1. ;
00124 _dsdx_r_chebp(&vect1, base_pipo) ;
00125 _sx_r_chebp(&vect2, base_pipo) ;
00126 for (int j=0; j<nr0; j++)
00127 ope_even.set(j,i-dege) = (vect1(0,0,j) + n_factor*vect2(0,0,j)) / alpha ;
00128 }
00129 ope_even.set_lu() ;
00130 Matrice ope_odd(nr0, nr0) ;
00131 ope_odd.set_etat_qcq() ;
00132 for (int i=0; i<nr0; i++) {
00133 vect1.annule_hard() ;
00134 vect2.annule_hard() ;
00135 vect1.set(0,0,i) = 1. ; vect2.set(0,0,i) = 1. ;
00136 _dsdx_r_chebi(&vect1, base_pipo) ;
00137 _sx_r_chebi(&vect2, base_pipo) ;
00138 for (int j=0; j<nr0; j++)
00139 ope_odd.set(j,i) = (vect1(0,0,j) + n_factor*vect2(0,0,j)) / alpha ;
00140 }
00141 ope_odd.set_lu() ;
00142
00143 for (int k=0 ; k<np+1 ; k++)
00144 for (int j=0 ; j<nt ; j++) {
00145
00146 base_resu.give_quant_numbers(lz, k, j, m_quant, l_quant, base_r) ;
00147 assert ( (base_r == R_CHEBP) || (base_r == R_CHEBI) ) ;
00148 const Matrice& operateur = (( base_r == R_CHEBP ) ?
00149 ope_even : ope_odd ) ;
00150
00151 so = new Tbl(nr0) ;
00152 so->set_etat_qcq() ;
00153 for (int i=0 ; i<nr0 ; i++)
00154 so->set(i) = source(lz, k, j, i) ;
00155
00156 s_part = new Tbl(operateur.inverse(*so)) ;
00157
00158
00159 double somme = 0 ;
00160 for (int i=0 ; i<nr0 ; i++) {
00161 if (base_r == R_CHEBP) {
00162 resu.set(lz, k, j, i+dege) = (*s_part)(i) ;
00163 somme += ((i+dege)%2 == 0 ? 1 : -1)*(*s_part)(i) ;
00164 }
00165 else
00166 resu.set(lz,k,j,i) = (*s_part)(i) ;
00167 }
00168 if (base_r == R_CHEBI)
00169 for (int i=nr0; i<nr; i++)
00170 resu.set(lz,k,j,i) = 0 ;
00171 if (base_r == R_CHEBP)
00172 resu.set(lz, k, j, 0) -= somme ;
00173
00174 delete so ;
00175 delete s_part ;
00176
00177 }
00178
00179
00180
00181
00182 int nz0 = (ced ? nz - 1 : nz) ;
00183 for (lz=1 ; lz<nz0 ; lz++) {
00184 nr = mg->get_nr(lz) ;
00185 alpha = mpaff->get_alpha()[lz] ;
00186 beta = mpaff->get_beta()[lz];
00187 double ech = beta / alpha ;
00188 Diff_id id(R_CHEB, nr) ; const Matrice& mid = id.get_matrice() ;
00189 Diff_xdsdx xd(R_CHEB, nr) ; const Matrice& mxd = xd.get_matrice() ;
00190 Diff_dsdx dx(R_CHEB, nr) ; const Matrice& mdx = dx.get_matrice() ;
00191 Matrice operateur = mxd + ech*mdx + n_factor*mid ;
00192 operateur.set_lu() ;
00193
00194 s_hom = new Tbl(solh(nr, n_factor-1, ech, R_CHEB)) ;
00195
00196 for (int k=0 ; k<np+1 ; k++)
00197 for (int j=0 ; j<nt ; j++) {
00198
00199 base_resu.give_quant_numbers(lz, k, j, m_quant, l_quant, base_r) ;
00200 assert (base_r == R_CHEB) ;
00201
00202 so = new Tbl(nr) ;
00203 so->set_etat_qcq() ;
00204
00205 Tbl tmp(nr) ;
00206 tmp.set_etat_qcq() ;
00207 for (int i=0 ; i<nr ; i++)
00208 tmp.set(i) = source(lz, k, j, i) ;
00209 for (int i=0; i<nr; i++) so->set(i) = beta*tmp(i) ;
00210 multx_1d(nr, &tmp.t, R_CHEB) ;
00211 for (int i=0; i<nr; i++) so->set(i) += alpha*tmp(i) ;
00212
00213 s_part = new Tbl (operateur.inverse(*so)) ;
00214
00215
00216 for (int i=0 ; i<nr ; i++) {
00217 sol_part.set(lz, k, j, i) = (*s_part)(i) ;
00218 sol_hom.set(lz, k, j, i) = (*s_hom)(1,i) ;
00219 }
00220
00221 delete so ;
00222 delete s_part ;
00223 }
00224 delete s_hom ;
00225 }
00226 if (ced) {
00227
00228
00229
00230 int dzp = ( check_dzpuis(2) ? 2 : 1) ;
00231 nr = source.get_mg()->get_nr(nz-1) ;
00232 alpha = mpaff->get_alpha()[nz-1] ;
00233 beta = mpaff->get_beta()[nz-1] ;
00234 dege = dzp ;
00235 nr0 = nr - dege ;
00236 Diff_dsdx dx(R_CHEBU, nr) ; const Matrice& mdx = dx.get_matrice() ;
00237 Diff_sx sx(R_CHEBU, nr) ; const Matrice& msx = sx.get_matrice() ;
00238 Diff_xdsdx xdx(R_CHEBU, nr) ; const Matrice& mxdx = xdx.get_matrice() ;
00239 Diff_id id(R_CHEBU, nr) ; const Matrice& mid = id.get_matrice() ;
00240 Matrice operateur(nr0, nr0) ;
00241 operateur.set_etat_qcq() ;
00242 if (dzp == 2)
00243 for (int lin=0; lin<nr0; lin++)
00244 for (int col=dege; col<nr; col++)
00245 operateur.set(lin,col-dege) = (-mdx(lin,col)
00246 + n_factor*msx(lin, col)) / alpha ;
00247 else {
00248 for (int lin=0; lin<nr0; lin++) {
00249 for (int col=dege; col<nr; col++)
00250 operateur.set(lin,col-dege) = (-mxdx(lin,col)
00251 + n_factor*mid(lin, col)) ;
00252 }
00253 }
00254 operateur.set_lu() ;
00255
00256 s_hom = new Tbl(solh(nr, n_factor-1, 0., R_CHEBU)) ;
00257 for (int k=0 ; k<np+1 ; k++)
00258 for (int j=0 ; j<nt ; j++) {
00259 base_resu.give_quant_numbers(lz, k, j, m_quant, l_quant, base_r) ;
00260 assert(base_r == R_CHEBU) ;
00261
00262
00263 so = new Tbl(nr0) ;
00264 so->set_etat_qcq() ;
00265 for (int i=0 ; i<nr0 ; i++)
00266 so->set(i) = source(nz-1, k, j, i) ;
00267 s_part = new Tbl(operateur.inverse(*so)) ;
00268
00269
00270 double somme = 0 ;
00271 for (int i=0 ; i<nr0 ; i++) {
00272 sol_part.set(nz-1, k, j, i+dege) = (*s_part)(i) ;
00273 somme += (*s_part)(i) ;
00274 sol_hom.set(nz-1, k, j, i) = (*s_hom)(i) ;
00275 }
00276 for (int i=nr0; i<nr; i++)
00277 sol_hom.set(nz-1, k, j, i) = (*s_hom)(i) ;
00278
00279 sol_part.set(nz-1, k, j, 0) = -somme ;
00280 delete so ;
00281 delete s_part ;
00282 }
00283 delete s_hom ;
00284 }
00285
00286
00287
00288
00289 if (nz > 1) {
00290 Tbl echelles(nz-1) ;
00291 echelles.set_etat_qcq() ;
00292 for (lz=1; lz<nz; lz++)
00293 echelles.set(lz-1)
00294 = pow ( (mpaff->get_beta()[lz]/mpaff->get_alpha()[lz] -1),
00295 n_factor) ;
00296 if (ced) echelles.set(nz-2) = 1./pow(-2., n_factor) ;
00297
00298 for (int k=0 ; k<np+1 ; k++)
00299 for (int j=0 ; j<nt ; j++) {
00300 for (lz=1; lz<nz; lz++) {
00301 double val1 = 0 ;
00302 double valm1 = 0 ;
00303 double valhom1 = 0 ;
00304 int nr_prec = mg->get_nr(lz-1) ;
00305 nr = mg->get_nr(lz) ;
00306 for (int i=0; i<nr_prec; i++)
00307 val1 += resu(lz-1, k, j, i) ;
00308 for (int i=0; i<nr; i++) {
00309 valm1 += ( i%2 == 0 ? 1 : -1)*sol_part(lz, k, j, i) ;
00310 valhom1 += ( i%2 == 0 ? 1 : -1)*sol_hom(lz, k, j, i) ;
00311 }
00312 double lambda = (val1 - valm1) * echelles(lz-1) ;
00313 for (int i=0; i<nr; i++)
00314 resu.set(lz, k, j, i) = sol_part(lz, k, j, i)
00315 + lambda*sol_hom(lz, k, j, i) ;
00316
00317 }
00318 }
00319 }
00320 }
00321 return result ;
00322 }
00323