00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 char map_af_dalembert_C[] = "$Header: /cvsroot/Lorene/C++/Source/Map/map_af_dalembert.C,v 1.16 2008/08/27 08:55:31 jl_cornou Exp $" ;
00024
00025
00026
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
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105 #include <math.h>
00106
00107
00108 #include "tensor.h"
00109 #include "param.h"
00110 #include "proto.h"
00111
00112
00113
00114 void Map_af::dalembert(Param& par, Scalar& fjp1, const Scalar& fj, const Scalar& fjm1,
00115 const Scalar& source) const {
00116
00117
00118 assert(source.get_etat() != ETATNONDEF) ;
00119 assert(source.get_mp().get_mg() == mg) ;
00120 assert(fj.get_etat() != ETATNONDEF) ;
00121 assert(fj.get_mp().get_mg() == mg) ;
00122 assert(fjm1.get_etat() != ETATNONDEF) ;
00123 assert(fjm1.get_mp().get_mg() == mg) ;
00124 assert(fjp1.get_mp().get_mg() == mg) ;
00125
00126 assert(par.get_n_double() == 1) ;
00127 assert(par.get_n_int() >= 1) ;
00128 assert(par.get_n_int_mod() == 1) ;
00129 int& nap = par.get_int_mod() ;
00130 assert ((nap == 0) || (par.get_n_tbl_mod() > 1)) ;
00131
00132 int nz = mg->get_nzone() ;
00133 bool ced = (mg->get_type_r(nz-1) == UNSURR) ;
00134 int nz0 = (ced ? nz - 1 : nz) ;
00135 double dt = par.get_double() ;
00136
00137 Scalar fj_local = fj ;
00138 Scalar fjm1_local = fjm1 ;
00139 if (ced) {
00140 fj_local.annule_domain(nz-1) ;
00141 fjm1_local.annule_domain(nz-1) ;
00142 }
00143 Scalar sigma = 2*fj_local - fjm1_local ;
00144
00145
00146
00147
00148 Tbl* coeff ;
00149 if (nap == 0) {
00150 coeff = new Tbl(12,nz);
00151 coeff->set_etat_qcq() ;
00152 par.add_tbl_mod(*coeff) ;
00153 }
00154 else
00155 coeff= &par.get_tbl_mod() ;
00156 Tbl a1(nz) ; a1 = 1 ;
00157 Tbl a2(nz) ; a2 = 0 ;
00158 Tbl a3(nz) ; a3 = 0 ;
00159
00160 if (par.get_n_tensor_mod() > 0) {
00161 assert(par.get_n_tensor_mod() == 1) ;
00162 Scalar* metri = dynamic_cast<Scalar*>(&par.get_tensor_mod()) ;
00163 assert(metri != 0x0) ;
00164 assert (metri->get_etat() == ETATQCQ) ;
00165
00166 const Map_af* tmap ;
00167 if (nap == 0) {
00168 double* bornes = new double[nz+1] ;
00169 bornes[0] = beta[0] ;
00170 for (int i=0; i<nz; i++) bornes[i+1] = alpha[i] + beta[i] ;
00171 tmap = new Map_af(*mg->get_radial() , bornes) ;
00172 par.add_map(*tmap) ;
00173 delete [] bornes ;
00174 }
00175 else {
00176 tmap = dynamic_cast<const Map_af*>(&par.get_map()) ;
00177 assert (tmap != 0x0) ;
00178 }
00179 metri->set_spectral_va().ylm() ;
00180
00181 Scalar xmetr(*tmap) ;
00182 xmetr.set_etat_qcq() ;
00183 xmetr.std_spectral_base() ;
00184 xmetr.set_spectral_va().set_base_t(T_LEG_PP) ;
00185 xmetr.set_spectral_va().set_etat_cf_qcq() ;
00186 Mtbl_cf* mt = xmetr.set_spectral_va().c_cf ;
00187 mt->annule_hard() ;
00188 for (int lz=0; lz<nz0; lz++)
00189 for (int ir=0; ir<mg->get_nr(lz); ir++)
00190 mt->set(lz,0,0,ir) = (*metri->get_spectral_va().c_cf)(lz, 0, 0, ir) ;
00191
00192 if (mg->get_nt(0) != 1) xmetr = xmetr / sqrt(double(2)) ;
00193 xmetr.set_spectral_va().ylm_i() ;
00194 xmetr.set_spectral_va().coef_i() ;
00195 const Mtbl& erre = this->r ;
00196
00197 a1.set_etat_qcq() ;
00198 a2.set_etat_qcq() ;
00199 a3.set_etat_qcq() ;
00200 Scalar mime(*this) ;
00201 mime.annule_hard() ;
00202 for (int lz=0; lz<nz0; lz++) {
00203 int nr = mg->get_nr(lz);
00204 double r1 = erre(lz, 0, 0, nr-1) ;
00205 double rm1 = erre(lz, 0, 0, 0) ;
00206 double x1 = xmetr.val_grid_point(lz, 0, 0, nr-1) ;
00207 double xm1 = xmetr.val_grid_point(lz, 0, 0, 0) ;
00208
00209 if (mg->get_type_r(lz) == RARE) {
00210 a1.set(lz) = xm1 ;
00211 a2.set(lz) = 0 ;
00212 a3.set(lz) = (x1 - a1(lz)) / (r1 * r1);
00213 }
00214 else {
00215 int i0 = (nr-1)/2 ;
00216 double r0 = erre(lz, 0, 0, i0) ;
00217 double x0 = xmetr.val_grid_point(lz, 0, 0, i0) ;
00218 double p1 = (r1 - rm1)*(r1 - r0) ;
00219 double pm1 = (r0 - rm1)*(r1 - rm1) ;
00220 double p0 = (r0 - rm1)*(r1 - r0) ;
00221 a1.set(lz) = xm1*r1*r0/pm1 + x1*rm1*r0/p1 - x0*rm1*r1/p0 ;
00222 a2.set(lz) = x0*(rm1 + r1)/p0 - xm1*(r1 + r0)/pm1
00223 - x1*(rm1 + r0)/p1 ;
00224 a3.set(lz) = xm1/pm1+x1/p1-x0/p0 ;
00225 }
00226
00227 for (int k=0; k<mg->get_np(lz)+2; k++)
00228 for (int j=0; j<mg->get_nt(lz); j++)
00229 for (int i=0; i<nr; i++)
00230 mime.set_grid_point(lz, k, j, i) = a1(lz) + erre(lz, 0, 0, i)*
00231 (a2(lz) + erre(lz, 0, 0, i)*a3(lz)) ;
00232
00233 Tbl diff = metri->domain(lz) - mime.domain(lz) ;
00234 double offset = max(diff) ;
00235 a1.set(lz) += offset ;
00236 mime.set_domain(lz) += offset ;
00237 }
00238
00239 Scalar reste = (*metri - mime)*fj_local.laplacian() ;
00240 if (ced) reste.annule_domain(nz-1) ;
00241 sigma += (dt*dt)*(source + reste) ;
00242 if (ced) sigma.annule_domain(nz-1) ;
00243 sigma += (0.5*dt*dt)*mime*fjm1_local.laplacian() ;
00244 }
00245 else {
00246 sigma += (dt*dt) * source ;
00247 if (ced) sigma.annule_domain(nz-1) ;
00248 sigma += (0.5*dt*dt)*fjm1_local.laplacian() ;
00249 if (par.get_n_int() > 1) {
00250 int dl = -1 ;
00251 int l_min = par.get_int(1) ;
00252 sigma.set_spectral_va().ylm() ;
00253 Scalar tmp = fjm1_local ;
00254 tmp.div_r() ; tmp.div_r() ;
00255 tmp.set_spectral_va().ylm() ;
00256 const Base_val& base = tmp.get_spectral_base() ;
00257 int l_q, m_q, baser ;
00258
00259 for (int lz=0; lz<nz-1; lz++) {
00260 int nt = mg->get_nt(lz) ;
00261 int np = mg->get_np(lz) ;
00262 for (int k=0; k<np+2; k++)
00263 for (int j=0; j<nt; j++) {
00264 base.give_quant_numbers(lz, k, j, m_q, l_q, baser) ;
00265 if ((nullite_plm(j, nt, k, np, base) == 1) && (l_q+dl >= l_min) ) {
00266 for (int i=0; i<mg->get_nr(lz); i++) {
00267 sigma.set_spectral_va().c_cf->set(lz, k, j, i) -=
00268 0.5*dt*dt*dl*(2*l_q + dl +1)
00269 *(*tmp.get_spectral_va().c_cf)(lz, k, j, i) ;
00270 }
00271 }
00272 }
00273 }
00274 if (sigma.get_spectral_va().c != 0x0) {
00275 delete sigma.set_spectral_va().c ;
00276 sigma.set_spectral_va().c = 0x0 ;
00277 }
00278 }
00279 }
00280 if (ced) sigma.annule_domain(nz-1) ;
00281
00282
00283
00284
00285
00286 for (int i=0; i<nz; i++) {
00287 coeff->set(1,i) = a1(i) ;
00288 coeff->set(2,i) = a2(i) ;
00289 coeff->set(3,i) = a3(i) ;
00290 coeff->set(4,i) = 0. ;
00291 coeff->set(5,i) = 0. ;
00292 coeff->set(6,i) = 0. ;
00293 coeff->set(7,i) = 0. ;
00294 coeff->set(8,i) = 0. ;
00295 coeff->set(9,i) = 0. ;
00296 coeff->set(10,i) = beta[i] ;
00297 coeff->set(11,i) = alpha[i] ;
00298 }
00299
00300
00301
00302 double R = this->val_r(nz0-1, 1., 0., 0.) ;
00303 int nr = mg->get_nr(nz0-1) ;
00304 int nt = mg->get_nt(nz0-1) ;
00305 int np2 = mg->get_np(nz0-1) + 2;
00306
00307
00308
00309
00310 double* bc1 ;
00311 double* bc2 ;
00312 Tbl* tbc3 ;
00313 Tbl* phijm1 = 0x0 ;
00314 Tbl* phij = 0x0 ;
00315 if (nap == 0) {
00316 bc1 = new double ;
00317 bc2 = new double ;
00318 tbc3 = new Tbl(np2,nt) ;
00319 par.add_double_mod(*bc1,1) ;
00320 par.add_double_mod(*bc2,2) ;
00321 par.add_tbl_mod(*tbc3,1) ;
00322
00323
00324
00325 if (par.get_int(0) == 2) {
00326 phijm1 = new Tbl(np2,nt) ;
00327 phij = new Tbl(np2,nt) ;
00328 par.add_tbl_mod(*phijm1,2) ;
00329 par.add_tbl_mod(*phij,3) ;
00330 phij->annule_hard() ;
00331 phijm1->annule_hard() ;
00332 }
00333 nap = 1 ;
00334 }
00335 else {
00336 bc1 = &par.get_double_mod(1) ;
00337 bc2 = &par.get_double_mod(2) ;
00338 tbc3 = &par.get_tbl_mod(1) ;
00339 if (par.get_int(0) == 2) {
00340 phijm1 = &par.get_tbl_mod(2) ;
00341 phij = &par.get_tbl_mod(3) ;
00342 }
00343 }
00344 switch (par.get_int(0)) {
00345 case 0:
00346 *bc1 = 1 ;
00347 *bc2 = 0 ;
00348
00349 *tbc3 = 0 ;
00350
00351 break ;
00352 case 1: {
00353 Valeur bound3(mg) ;
00354 bound3 = R*(4*fj_local.get_spectral_va() - fjm1_local.get_spectral_va()) ;
00355 if (bound3.get_etat() == ETATZERO) {
00356 *bc1 = 3*R + 2*dt ;
00357 *bc2 = 2*R*dt ;
00358 *tbc3 = 0 ;
00359 }
00360 else {
00361 if (nz0>1) bound3.annule(0,nz0-2) ;
00362
00363 bound3.coef() ;
00364 bound3.ylm() ;
00365
00366 *bc1 = 3*R + 2*dt ;
00367 *bc2 = 2*R*dt ;
00368
00369 tbc3->set_etat_qcq() ;
00370 double val ;
00371 for (int k=0; k<np2; k++)
00372 for (int j=0; j<nt; j++) {
00373 val = 0. ;
00374 for (int i=0; i<nr; i++)
00375 val += (*bound3.c_cf)(nz0-1,k,j,i) ;
00376 tbc3->set(k,j) = val ;
00377 }
00378 }
00379 break ;
00380 }
00381
00382
00383
00384
00385
00386 case 2: {
00387 Valeur souphi(mg) ;
00388 souphi = fj_local.get_spectral_va()/R - fj_local.dsdr().get_spectral_va() ;
00389 if (nz0>1) souphi.annule(0,nz0-2) ;
00390 souphi.coef() ;
00391 souphi.ylm() ;
00392
00393 bool zero = (souphi.get_etat() == ETATZERO) ;
00394 if (zero) {
00395 Base_val base_ref(mg->std_base_scal()) ;
00396 base_ref.dsdx() ;
00397 base_ref.ylm() ;
00398 souphi.set_base(base_ref) ;
00399 }
00400
00401 int l_s, m_s, base_r ;
00402 double val ;
00403 int dl = (par.get_n_int() > 1) ? -1 : 0 ;
00404 for (int k=0; k<np2; k++) {
00405 for (int j=0; j<nt; j++) {
00406 donne_lm(nz, nz0-1, j, k, souphi.base, m_s, l_s, base_r) ;
00407 l_s += dl ;
00408 val = 0. ;
00409 if (!zero)
00410 val = -4*dt*dt*l_s*(l_s+1)*souphi.c_cf->val_out_bound_jk(nz0-1, j, k) ;
00411 double multi = 8*R*R + dt*dt*(6+3*l_s*(l_s+1)) + 12*R*dt ;
00412 val = ( 16*R*R*(*phij)(k,j) -
00413 (multi-24*R*dt)*(*phijm1)(k,j)
00414 + val)/multi ;
00415 phijm1->set(k,j) = (*phij)(k,j) ;
00416 phij->set(k,j) = val ;
00417 }
00418 }
00419 Valeur bound3(mg) ;
00420 *bc1 = 3*R + 2*dt ;
00421 *bc2 = 2*R*dt ;
00422 bound3 = R*(4*fj_local.get_spectral_va() - fjm1_local.get_spectral_va()) ;
00423 if (bound3.get_etat() == ETATZERO) *tbc3 = 0 ;
00424 else {
00425 if (nz0 > 1) bound3.annule(0,nz0-2) ;
00426 bound3.coef() ;
00427 bound3.ylm() ;
00428 tbc3->set_etat_qcq() ;
00429 for (int k=0; k<np2; k++)
00430 for (int j=0; j<nt; j++) {
00431 val = 0. ;
00432 for (int i=0; i<nr; i++)
00433 val += (*bound3.c_cf)(nz0-1,k,j,i) ;
00434 tbc3->set(k,j) = val + 2*R*dt*(*phij)(k,j);
00435 }
00436 }
00437 break ;
00438 }
00439 default:
00440 cout << "ERROR: Map_af::dalembert" << endl ;
00441 cout << "The boundary condition par.get_int(0) = "<< par.get_int(0)
00442 << " is unknown!" << endl ;
00443 abort() ;
00444 }
00445
00446 if (sigma.get_etat() == ETATZERO) {
00447 fjp1.set_etat_zero() ;
00448 return ;
00449 }
00450
00451
00452
00453 Valeur& sourva = sigma.set_spectral_va() ;
00454
00455
00456 assert(sourva.get_etat() == ETATQCQ) ;
00457 sourva.ylm() ;
00458
00459
00460
00461 fjp1.set_etat_zero() ;
00462 fjp1.set_etat_qcq() ;
00463
00464
00465
00466 fjp1.set_spectral_va() = sol_dalembert(par, *this, *(sourva.c_cf) ) ;
00467 fjp1.set_spectral_va().ylm_i() ;
00468
00469 if (ced) {
00470 if (fj.get_etat() == ETATZERO) {
00471 fjp1.annule_domain(nz-1) ;
00472 }
00473 else {
00474 fjp1.set_domain(nz-1) = fj.domain(nz-1) ;
00475 }
00476 fjp1.set_dzpuis(fj.get_dzpuis()) ;
00477 }
00478 }
00479
00480