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 char scalar_raccord_zec_C[] = "$Header: /cvsroot/Lorene/C++/Source/Tensor/Scalar/scalar_raccord_zec.C,v 1.6 2004/06/04 16:14:18 j_novak Exp $" ;
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056 #include <stdlib.h>
00057 #include <math.h>
00058
00059
00060 #include "matrice.h"
00061 #include "tensor.h"
00062 #include "proto.h"
00063 #include "nbr_spx.h"
00064 #include "utilitaires.h"
00065
00066
00067
00068
00069
00070 void Scalar::raccord_c1_zec(int puis, int nbre, int lmax) {
00071
00072 assert (nbre>0) ;
00073 assert (etat != ETATNONDEF) ;
00074 if ((etat == ETATZERO) || (etat == ETATUN))
00075 return ;
00076
00077
00078 const Map_af* map = dynamic_cast<const Map_af*>(mp) ;
00079 if (map == 0x0) {
00080 cout << "Le mapping doit etre affine" << endl ;
00081 abort() ;
00082 }
00083
00084 int nz = map->get_mg()->get_nzone() ;
00085 int nr = map->get_mg()->get_nr (nz-1) ;
00086 int nt = map->get_mg()->get_nt (nz-1) ;
00087 int np = map->get_mg()->get_np (nz-1) ;
00088
00089 double alpha = map->get_alpha()[nz-1] ;
00090 double r_cont = -1./2./alpha ;
00091
00092
00093 Tbl coef (nbre+2*lmax, nr) ;
00094 coef.set_etat_qcq() ;
00095
00096 int* deg = new int[3] ;
00097 deg[0] = 1 ; deg[1] = 1 ; deg[2] = nr ;
00098 double* auxi = new double[nr] ;
00099
00100 for (int conte=0 ; conte<nbre+2*lmax ; conte++) {
00101 for (int i=0 ; i<nr ; i++)
00102 auxi[i] = pow(-1-cos(M_PI*i/(nr-1)), (conte+puis)) ;
00103
00104 cfrcheb(deg, deg, auxi, deg, auxi) ;
00105 for (int i=0 ; i<nr ; i++)
00106 coef.set(conte, i) = auxi[i]*pow (alpha, conte+puis) ;
00107 }
00108
00109 delete[] deg ;
00110
00111 Tbl valeurs (nbre, nt, np+1) ;
00112 valeurs.set_etat_qcq() ;
00113
00114 Scalar courant (*this) ;
00115 double* res_val = new double[1] ;
00116
00117 for (int conte=0 ; conte<nbre ; conte++) {
00118
00119 courant.va.coef() ;
00120 courant.va.ylm() ;
00121 courant.va.c_cf->t[nz-1]->annule_hard() ;
00122
00123 int base_r = courant.va.base.get_base_r(nz-2) ;
00124 for (int k=0 ; k<np+1 ; k++)
00125 for (int j=0 ; j<nt ; j++)
00126 if (nullite_plm(j, nt, k, np, courant.va.base) == 1) {
00127
00128 for (int i=0 ; i<nr ; i++)
00129 auxi[i] = (*courant.va.c_cf)(nz-2, k, j, i) ;
00130
00131 switch (base_r) {
00132 case R_CHEB :
00133 som_r_cheb (auxi, nr, 1, 1, 1, res_val) ;
00134 break ;
00135 default :
00136 cout << "Cas non prevu dans raccord_zec" << endl ;
00137 abort() ;
00138 break ;
00139 }
00140 valeurs.set(conte, k, j) = res_val[0] ;
00141 }
00142 Scalar copie (courant) ;
00143 copie.dec_dzpuis(2) ;
00144 courant = copie.dsdr() ;
00145 }
00146
00147 delete [] auxi ;
00148 delete [] res_val ;
00149
00150
00151
00152 va.coef() ;
00153 va.ylm() ;
00154 va.c_cf->t[nz-1]->annule_hard() ;
00155 va.set_etat_cf_qcq() ;
00156
00157 const Base_val& base = va.base ;
00158 int base_r, l_quant, m_quant ;
00159 for (int k=0 ; k<np+1 ; k++)
00160 for (int j=0 ; j<nt ; j++)
00161 if (nullite_plm(j, nt, k, np, va.base) == 1) {
00162
00163 donne_lm (nz, nz-1, j, k, base, m_quant, l_quant, base_r) ;
00164
00165 if (l_quant<=lmax) {
00166
00167 Matrice systeme (nbre, nbre) ;
00168 systeme.set_etat_qcq() ;
00169
00170 for (int col=0 ; col<nbre ; col++)
00171 for (int lig=0 ; lig<nbre ; lig++) {
00172
00173 int facteur = (lig%2==0) ? 1 : -1 ;
00174 for (int conte=0 ; conte<lig ; conte++)
00175 facteur *= puis+col+conte+2*l_quant ;
00176 systeme.set(lig, col) = facteur/pow(r_cont, puis+col+lig+2*l_quant) ;
00177 }
00178
00179 systeme.set_band(nbre, nbre) ;
00180 systeme.set_lu() ;
00181
00182 Tbl sec_membre (nbre) ;
00183 sec_membre.set_etat_qcq() ;
00184 for (int conte=0 ; conte<nbre ; conte++)
00185 sec_membre.set(conte) = valeurs(conte, k, j) ;
00186
00187 Tbl inv (systeme.inverse(sec_membre)) ;
00188
00189 for (int conte=0 ; conte<nbre ; conte++)
00190 for (int i=0 ; i<nr ; i++)
00191 va.c_cf->set(nz-1, k, j, i)+=
00192 inv(conte)*coef(conte+2*l_quant, i) ;
00193 }
00194 else for (int i=0 ; i<nr ; i++)
00195 va.c_cf->set(nz-1, k, j, i)
00196 = 0 ;
00197 }
00198
00199 va.ylm_i() ;
00200 set_dzpuis (0) ;
00201 }
00202
00203
00204
00205
00206 void Scalar::smooth_decay(int kk, int nn) {
00207
00208 assert(kk >= 0) ;
00209
00210 if (etat == ETATZERO) return ;
00211 if (va.get_etat() == ETATZERO) return ;
00212
00213 const Mg3d& mgrid = *(mp->get_mg()) ;
00214
00215 int nz = mgrid.get_nzone() ;
00216 int nzm1 = nz - 1 ;
00217 int np = mgrid.get_np(nzm1) ;
00218 int nt = mgrid.get_nt(nzm1) ;
00219 int nr_ced = mgrid.get_nr(nzm1) ;
00220 int nr_shell = mgrid.get_nr(nzm1-1) ;
00221
00222 assert(mgrid.get_np(nzm1-1) == np) ;
00223 assert(mgrid.get_nt(nzm1-1) == nt) ;
00224
00225 assert(mgrid.get_type_r(nzm1) == UNSURR) ;
00226
00227
00228 const Map_af* mapaf = dynamic_cast<const Map_af*>(mp) ;
00229 if (mapaf == 0x0) {
00230 cout << "Scalar::smooth_decay: present version supports only \n"
00231 << " affine mappings !" << endl ;
00232 abort() ;
00233 }
00234
00235
00236 assert(va.get_etat() == ETATQCQ) ;
00237
00238
00239
00240 va.ylm() ;
00241
00242
00243 assert( va.c_cf->t[nzm1] != 0x0) ;
00244 Tbl& coefresu = *( va.c_cf->t[nzm1] ) ;
00245 coefresu.set_etat_qcq() ;
00246
00247
00248
00249 int nbr1[] = {nr_shell, nr_ced} ;
00250 int nbt1[] = {1, 1} ;
00251 int nbp1[] = {1, 1} ;
00252 int typr1[] = {mgrid.get_type_r(nzm1-1), UNSURR} ;
00253 Mg3d grid1d(2, nbr1, typr1, nbt1, SYM, nbp1, SYM) ;
00254
00255
00256
00257 double rbound = mapaf->get_alpha()[nzm1-1]
00258 + mapaf->get_beta()[nzm1-1] ;
00259 double rmin = - mapaf->get_alpha()[nzm1-1]
00260 + mapaf->get_beta()[nzm1-1] ;
00261 double bound1[] = {rmin, rbound, __infinity} ;
00262
00263 Map_af map1d(grid1d, bound1) ;
00264
00265
00266
00267 Scalar uu(map1d) ;
00268 uu.std_spectral_base() ;
00269 Scalar duu(map1d) ;
00270 Scalar vv(map1d) ;
00271 Scalar tmp(map1d) ;
00272
00273 const Base_val& base = va.get_base() ;
00274
00275
00276
00277 for (int k=0; k<=np; k++) {
00278 for (int j=0; j<nt; j++) {
00279
00280 if (nullite_plm(j, nt, k, np, base) != 1) {
00281 for (int i=0 ; i<nr_ced ; i++) {
00282 coefresu.set(k, j, i) = 0 ;
00283 }
00284 }
00285 else {
00286 int base_r_ced, base_r_shell , l_quant, m_quant ;
00287 donne_lm(nz, nzm1, j, k, base, m_quant, l_quant, base_r_ced) ;
00288 donne_lm(nz, nzm1-1, j, k, base, m_quant, l_quant, base_r_shell) ;
00289
00290 int nn0 = l_quant + nn ;
00291
00292 uu.set_etat_qcq() ;
00293 uu.va.set_etat_cf_qcq() ;
00294 uu.va.c_cf->set_etat_qcq() ;
00295 uu.va.c_cf->t[0]->set_etat_qcq() ;
00296 uu.va.c_cf->t[1]->set_etat_qcq() ;
00297 for (int i=0; i<nr_shell; i++) {
00298 uu.va.c_cf->t[0]->set(0, 0, i) =
00299 va.c_cf->operator()(nzm1-1, k, j, i) ;
00300 uu.va.c_cf->t[0]->set(1, 0, i) = 0. ;
00301 uu.va.c_cf->t[0]->set(2, 0, i) = 0. ;
00302 }
00303
00304 uu.va.c_cf->t[1]->set_etat_zero() ;
00305
00306 uu.va.set_base_r(0, base_r_shell) ;
00307 uu.va.set_base_r(1, base_r_ced) ;
00308
00309
00310
00311
00312 Tbl derivb(kk+1) ;
00313 derivb.set_etat_qcq() ;
00314 duu = uu ;
00315 derivb.set(0) = uu.val_grid_point(0, 0, 0, nr_shell-1) ;
00316 for (int p=1; p<=kk; p++) {
00317 tmp = duu.dsdr() ;
00318 duu = tmp ;
00319 derivb.set(p) = duu.val_grid_point(0, 0, 0, nr_shell-1) ;
00320 }
00321
00322
00323
00324
00325 Matrice mat(kk+1,kk+1) ;
00326 mat.set_etat_qcq() ;
00327
00328 for (int im=0; im<=kk; im++) {
00329
00330 double fact = (im%2 == 0) ? 1. : -1. ;
00331 fact /= pow(rbound, nn0 + im) ;
00332
00333 for (int jm=0; jm<=kk; jm++) {
00334
00335 double prod = 1 ;
00336 for (int ir=0; ir<im; ir++) {
00337 prod *= nn0 + jm + ir ;
00338 }
00339
00340 mat.set(im, jm) = fact * prod / pow(rbound, jm) ;
00341
00342 }
00343 }
00344
00345
00346
00347
00348 mat.set_band(kk+1, kk+1) ;
00349 mat.set_lu() ;
00350 Tbl aa = mat.inverse( derivb ) ;
00351
00352
00353
00354 vv = 0 ;
00355 const Coord& r = map1d.r ;
00356 for (int p=0; p<=kk; p++) {
00357 tmp = aa(p) / pow(r, nn0 + p) ;
00358 vv += tmp ;
00359 }
00360 vv.va.set_base( uu.va.get_base() ) ;
00361
00362
00363
00364
00365 vv.va.coef() ;
00366
00367 if (vv.get_etat() == ETATZERO) {
00368 for (int i=0; i<nr_ced; i++) {
00369 coefresu.set(k,j,i) = 0 ;
00370 }
00371 }
00372 else {
00373 assert( vv.va.c_cf != 0x0 ) ;
00374 for (int i=0; i<nr_ced; i++) {
00375 coefresu.set(k,j,i) = vv.va.c_cf->operator()(1,0,0,i) ;
00376 }
00377 }
00378
00379
00380 }
00381
00382
00383 }
00384 }
00385
00386 if (va.c != 0x0) {
00387 delete va.c ;
00388 va.c = 0x0 ;
00389 }
00390 va.ylm_i() ;
00391
00392
00393
00394
00395 Scalar tmp1(*this) ;
00396 Scalar tmp2(*mp) ;
00397 for (int p=0; p<=kk; p++) {
00398 double rd = pow(rbound, tmp1.get_dzpuis()) ;
00399 double err = 0 ;
00400 for (int k=0; k<np; k++) {
00401 for (int j=0; j<nt; j++) {
00402 double diff = fabs( tmp1.val_grid_point(nzm1, k, j, 0) / rd -
00403 tmp1.val_grid_point(nzm1-1, k, j, nr_shell-1) ) ;
00404 if (diff > err) err = diff ;
00405 }
00406 }
00407 cout <<
00408 "Scalar::smooth_decay: Max error matching of " << p
00409 << "-th derivative: " << err << endl ;
00410 tmp2 = tmp1.dsdr() ;
00411 tmp1 = tmp2 ;
00412 }
00413
00414
00415 }