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 char poisson_falloff_C[] = "$Header: /cvsroot/Lorene/C++/Source/Non_class_members/PDE/poisson_falloff.C,v 1.1 2004/11/30 20:55:03 k_taniguchi Exp $" ;
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041 #include <stdlib.h>
00042 #include <math.h>
00043
00044
00045 #include "matrice.h"
00046 #include "tbl.h"
00047 #include "mtbl_cf.h"
00048 #include "map.h"
00049 #include "base_val.h"
00050 #include "proto.h"
00051 #include "type_parite.h"
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075 Mtbl_cf sol_poisson_falloff(const Map_af& mapping, const Mtbl_cf& source, const int k_falloff)
00076 {
00077
00078
00079 int nz = source.get_mg()->get_nzone() ;
00080 assert (nz>1) ;
00081 assert (source.get_mg()->get_type_r(0) == RARE) ;
00082
00083 for (int l=1 ; l<nz ; l++)
00084 assert(source.get_mg()->get_type_r(l) == FIN) ;
00085
00086
00087
00088
00089
00090 const Base_val& base = source.base ;
00091
00092
00093
00094 int nr, nt, np ;
00095 int base_r ;
00096 double alpha, beta, echelle ;
00097 int l_quant, m_quant;
00098
00099
00100 Tbl *so ;
00101 Tbl *sol_hom ;
00102 Tbl *sol_part ;
00103 Matrice *operateur ;
00104 Matrice *nondege ;
00105
00106
00107
00108 Mtbl_cf solution_part(source.get_mg(), base) ;
00109 Mtbl_cf solution_hom_un(source.get_mg(), base) ;
00110 Mtbl_cf solution_hom_deux(source.get_mg(), base) ;
00111 Mtbl_cf resultat(source.get_mg(), base) ;
00112
00113 solution_part.set_etat_qcq() ;
00114 solution_hom_un.set_etat_qcq() ;
00115 solution_hom_deux.set_etat_qcq() ;
00116 resultat.set_etat_qcq() ;
00117
00118 for (int l=0 ; l<nz ; l++) {
00119 solution_part.t[l]->set_etat_qcq() ;
00120 solution_hom_un.t[l]->set_etat_qcq() ;
00121 solution_hom_deux.t[l]->set_etat_qcq() ;
00122 resultat.t[l]->set_etat_qcq() ;
00123 for (int k=0 ; k<source.get_mg()->get_np(l)+2 ; k++)
00124 for (int j=0 ; j<source.get_mg()->get_nt(l) ; j++)
00125 for (int i=0 ; i<source.get_mg()->get_nr(l) ; i++)
00126 resultat.set(l, k, j, i) = 0 ;
00127 }
00128
00129
00130 int np_max, nt_max ;
00131
00132
00133
00134
00135
00136 nr = source.get_mg()->get_nr(0) ;
00137 nt = source.get_mg()->get_nt(0) ;
00138 np = source.get_mg()->get_np(0) ;
00139
00140 nt_max = nt ;
00141 np_max = np ;
00142
00143 alpha = mapping.get_alpha()[0] ;
00144 beta = mapping.get_beta()[0] ;
00145
00146 for (int k=0 ; k<np+1 ; k++)
00147 for (int j=0 ; j<nt ; j++)
00148 if (nullite_plm(j, nt, k, np, base) == 1)
00149 {
00150
00151 donne_lm(nz, 0, j, k, base, m_quant, l_quant, base_r) ;
00152
00153
00154 operateur = new Matrice(laplacien_mat(nr, l_quant, 0., 0, base_r)) ;
00155 (*operateur) = combinaison(*operateur, l_quant, 0., 0, base_r) ;
00156
00157
00158 nondege = new Matrice(prepa_nondege(*operateur, l_quant, 0., 0, base_r)) ;
00159
00160
00161 sol_hom = new Tbl(solh(nr, l_quant, 0., base_r)) ;
00162
00163
00164 so = new Tbl(nr) ;
00165 so->set_etat_qcq() ;
00166 for (int i=0 ; i<nr ; i++)
00167 so->set(i) = source(0, k, j, i) ;
00168
00169 sol_part = new Tbl(solp(*operateur, *nondege, alpha, beta,
00170 *so, 0, base_r)) ;
00171
00172
00173
00174 for (int i=0 ; i<nr ; i++) {
00175 solution_part.set(0, k, j, i) = (*sol_part)(i) ;
00176 solution_hom_un.set(0, k, j, i) = (*sol_hom)(i) ;
00177 solution_hom_deux.set(0, k, j, i) = 0. ;
00178 }
00179
00180
00181
00182 delete operateur ;
00183 delete nondege ;
00184 delete so ;
00185 delete sol_hom ;
00186 delete sol_part ;
00187 }
00188
00189
00190
00191
00192
00193
00194
00195 for (int zone=1 ; zone<nz ; zone++) {
00196 nr = source.get_mg()->get_nr(zone) ;
00197 nt = source.get_mg()->get_nt(zone) ;
00198 np = source.get_mg()->get_np(zone) ;
00199
00200 if (np > np_max) np_max = np ;
00201 if (nt > nt_max) nt_max = nt ;
00202
00203 alpha = mapping.get_alpha()[zone] ;
00204 beta = mapping.get_beta()[zone] ;
00205
00206 for (int k=0 ; k<np+1 ; k++)
00207 for (int j=0 ; j<nt ; j++)
00208 if (nullite_plm(j, nt, k, np, base) == 1)
00209 {
00210
00211 donne_lm(nz, zone, j, k, base, m_quant, l_quant, base_r) ;
00212
00213
00214 operateur = new Matrice(laplacien_mat
00215 (nr, l_quant, beta/alpha, 0, base_r)) ;
00216
00217 (*operateur) = combinaison(*operateur, l_quant, beta/alpha, 0,
00218 base_r) ;
00219
00220
00221 nondege = new Matrice(prepa_nondege(*operateur, l_quant,
00222 beta/alpha, 0, base_r)) ;
00223
00224
00225 sol_hom = new Tbl(solh(nr, l_quant, beta/alpha, base_r)) ;
00226
00227
00228 so = new Tbl(nr) ;
00229 so->set_etat_qcq() ;
00230 for (int i=0 ; i<nr ; i++)
00231 so->set(i) = source(zone, k, j, i) ;
00232
00233 sol_part = new Tbl (solp(*operateur, *nondege, alpha,
00234 beta, *so, 0, base_r)) ;
00235
00236
00237
00238 for (int i=0 ; i<nr ; i++) {
00239 solution_part.set(zone, k, j, i) = (*sol_part)(i) ;
00240 solution_hom_un.set(zone, k, j, i) = (*sol_hom)(0, i) ;
00241 solution_hom_deux.set(zone, k, j, i) = (*sol_hom)(1, i) ;
00242 }
00243
00244
00245 delete operateur ;
00246 delete nondege ;
00247 delete so ;
00248 delete sol_hom ;
00249 delete sol_part ;
00250 }
00251 }
00252
00253
00254
00255
00256
00257
00258 int * indic = new int [nz] ;
00259 int taille ;
00260 Tbl *sec_membre ;
00261 Matrice *systeme ;
00262
00263
00264 int ligne ;
00265 int colonne ;
00266
00267
00268 int sup ;
00269 int inf ;
00270 int sup_new, inf_new ;
00271
00272
00273 for (int k=0 ; k<np_max+1 ; k++)
00274 for (int j=0 ; j<nt_max ; j++)
00275 if (nullite_plm(j, nt_max, k, np_max, base) == 1) {
00276
00277 ligne = 0 ;
00278 colonne = 0 ;
00279 sup = 0 ;
00280 inf = 0 ;
00281
00282 for (int zone=0 ; zone<nz ; zone++)
00283 indic[zone] = nullite_plm(j, source.get_mg()->get_nt(zone),
00284 k, source.get_mg()->get_np(zone), base);
00285
00286
00287 taille = indic[0] ;
00288 for (int zone=1 ; zone<nz ; zone++)
00289 taille+=2*indic[zone] ;
00290
00291
00292
00293
00294 if (taille != 0) {
00295
00296 sec_membre = new Tbl(taille) ;
00297 sec_membre->set_etat_qcq() ;
00298 for (int l=0 ; l<taille ; l++)
00299 sec_membre->set(l) = 0 ;
00300
00301 systeme = new Matrice(taille, taille) ;
00302 systeme->set_etat_qcq() ;
00303 for (int l=0 ; l<taille ; l++)
00304 for (int c=0 ; c<taille ; c++)
00305 systeme->set(l, c) = 0 ;
00306
00307
00308
00309
00310
00311 donne_lm (nz, 0, j, k, base, m_quant, l_quant, base_r) ;
00312
00313
00314
00315
00316
00317
00318 if (indic[0] == 1) {
00319 nr = source.get_mg()->get_nr(0) ;
00320
00321 alpha = mapping.get_alpha()[0] ;
00322
00323 systeme->set(ligne, colonne) = 1. ;
00324
00325 for (int i=0 ; i<nr ; i++)
00326 sec_membre->set(ligne) -= solution_part(0, k, j, i) ;
00327
00328 ligne++ ;
00329
00330
00331
00332 if (indic[1] == 1) {
00333
00334 systeme->set(ligne, colonne) = 1./alpha*l_quant ;
00335
00336
00337 if (base_r == R_CHEBP)
00338
00339 for (int i=0 ; i<nr ; i++)
00340 sec_membre->set(ligne) -=
00341 4*i*i/alpha
00342 *solution_part(0, k, j, i) ;
00343 else
00344
00345 for (int i=0 ; i<nr ; i++)
00346 sec_membre->set(ligne) -=
00347 (2*i+1)*(2*i+1)/alpha
00348 *solution_part(0, k, j, i) ;
00349
00350
00351 inf = 1 ;
00352 }
00353 colonne++ ;
00354 }
00355
00356
00357
00358
00359
00360 for (int zone=1 ; zone<nz ; zone++)
00361 if (indic[zone] == 1) {
00362
00363 nr = source.get_mg()->get_nr(zone) ;
00364 alpha = mapping.get_alpha()[zone] ;
00365 echelle = mapping.get_beta()[zone]/alpha ;
00366
00367
00368 if (indic[zone-1] == 1) ligne -- ;
00369
00370
00371 systeme->set(ligne, colonne) =
00372 -pow(echelle-1, double(l_quant)) ;
00373
00374
00375 systeme->set(ligne, colonne+1) =
00376 -1/pow(echelle-1, double(l_quant+1)) ;
00377
00378
00379 for (int i=0 ; i<nr ; i++)
00380 if (i%2 == 0)
00381 sec_membre->set(ligne) += solution_part(zone, k, j, i) ;
00382 else sec_membre->set(ligne) -= solution_part(zone, k, j, i) ;
00383
00384
00385 sup_new = colonne+1-ligne ;
00386 if (sup_new > sup) sup = sup_new ;
00387
00388 ligne++ ;
00389
00390
00391
00392
00393 if (indic[zone-1] == 1) {
00394
00395 systeme->set(ligne, colonne) =
00396 -l_quant*pow(echelle-1, double(l_quant-1))/alpha ;
00397
00398 systeme->set(ligne, colonne+1) =
00399 (l_quant+1)/pow(echelle-1, double(l_quant+2))/alpha ;
00400
00401
00402
00403
00404 for (int i=0 ; i<nr ; i++)
00405 if (i%2 == 0)
00406 sec_membre->set(ligne) -=
00407 i*i/alpha*solution_part(zone, k, j, i) ;
00408 else
00409 sec_membre->set(ligne) +=
00410 i*i/alpha*solution_part(zone, k, j, i) ;
00411
00412
00413 sup_new = colonne+1-ligne ;
00414 if (sup_new > sup) sup = sup_new ;
00415
00416 ligne++ ;
00417 }
00418
00419
00420 if(zone < nz-1) {
00421
00422
00423
00424 systeme->set(ligne, colonne) =
00425 pow(echelle+1, double(l_quant)) ;
00426
00427
00428 systeme->set(ligne, colonne+1) =
00429 1/pow(echelle+1, double(l_quant+1)) ;
00430
00431
00432 for (int i=0 ; i<nr ; i++)
00433 sec_membre->set(ligne) -= solution_part(zone, k, j, i) ;
00434
00435
00436 inf_new = ligne-colonne ;
00437 if (inf_new > inf) inf = inf_new ;
00438
00439 ligne ++ ;
00440
00441
00442
00443 if (indic[zone+1] == 1) {
00444
00445
00446 systeme->set(ligne, colonne) =
00447 l_quant*pow(echelle+1, double(l_quant-1))/alpha ;
00448
00449
00450 systeme->set(ligne, colonne+1) =
00451 -(l_quant+1)/pow(echelle+1, double(l_quant+2))/alpha ;
00452
00453
00454 for (int i=0 ; i<nr ; i++)
00455 sec_membre->set(ligne) -=
00456 i*i/alpha*solution_part(zone, k, j, i) ;
00457
00458
00459 inf_new = ligne-colonne ;
00460 if (inf_new > inf) inf = inf_new ;
00461
00462 }
00463 colonne += 2 ;
00464 } else {
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475 systeme->set(ligne, colonne) =
00476 double(k_falloff+l_quant)*pow(echelle+1, double(l_quant)) ;
00477
00478
00479 systeme->set(ligne, colonne+1) =
00480 double(k_falloff-l_quant-1)/pow(echelle+1, double(l_quant+1)) ;
00481
00482
00483
00484 for (int i=0 ; i<nr ; i++)
00485 sec_membre->set(ligne) -=
00486 (k_falloff+(echelle+1)*i*i)*solution_part(zone, k, j, i) ;
00487
00488
00489 inf_new = ligne-colonne ;
00490 if (inf_new > inf) inf = inf_new ;
00491
00492 }
00493 }
00494
00495
00496
00497
00498
00499
00500 systeme->set_band(sup, inf) ;
00501 systeme->set_lu() ;
00502
00503 Tbl facteurs(systeme->inverse(*sec_membre)) ;
00504 int conte = 0 ;
00505
00506
00507
00508
00509 if (indic[0] == 1) {
00510 nr = source.get_mg()->get_nr(0) ;
00511 for (int i=0 ; i<nr ; i++)
00512 resultat.set(0, k, j, i) = solution_part(0, k, j, i)
00513 +facteurs(conte)*solution_hom_un(0, k, j, i) ;
00514 conte++ ;
00515 }
00516
00517
00518 for (int zone=1 ; zone<nz ; zone++)
00519 if (indic[zone] == 1) {
00520 nr = source.get_mg()->get_nr(zone) ;
00521 for (int i=0 ; i<nr ; i++)
00522 resultat.set(zone, k, j, i) =
00523 solution_part(zone, k, j, i)
00524 +facteurs(conte)*solution_hom_un(zone, k, j, i)
00525 +facteurs(conte+1)*solution_hom_deux(zone, k, j, i) ;
00526 conte+=2 ;
00527 }
00528
00529 delete sec_membre ;
00530 delete systeme ;
00531 }
00532
00533 }
00534
00535 delete [] indic ;
00536
00537 return resultat;
00538 }