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 char poisson_compact_C[] = "$Header: /cvsroot/Lorene/C++/Source/Non_class_members/PDE/poisson_compact.C,v 1.4 2007/10/16 21:54:23 e_gourgoulhon Exp $" ;
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 #include <stdlib.h>
00059 #include <math.h>
00060 #include <assert.h>
00061
00062
00063 #include "map.h"
00064 #include "diff.h"
00065 #include "matrice.h"
00066 #include "type_parite.h"
00067 #include "proto.h"
00068 #include "base_val.h"
00069 #include "utilitaires.h"
00070
00072
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083 Mtbl_cf sol_poisson_compact(const Mtbl_cf& source, double a, double b,
00084 bool reamorce) {
00085
00086
00087 assert (source.get_etat() != ETATNONDEF) ;
00088
00089 assert (a>0) ;
00090 assert (b<0) ;
00091
00092
00093 const int nmax = 200 ;
00094 static Matrice* tab_op[nmax] ;
00095 static int nb_deja_fait = 0 ;
00096 static int l_deja_fait[nmax] ;
00097 static int n_deja_fait[nmax] ;
00098
00099 if (reamorce) {
00100 for (int i=0 ; i<nb_deja_fait ; i++)
00101 delete tab_op[i] ;
00102 nb_deja_fait = 0 ;
00103 }
00104
00105 int nz = source.get_mg()->get_nzone() ;
00106
00107
00108 int nr = source.get_mg()->get_nr(0) ;
00109 int nt = source.get_mg()->get_nt(0) ;
00110 int np = source.get_mg()->get_np(0) ;
00111
00112 int l_quant ;
00113 int m_quant ;
00114 int base_r ;
00115
00116
00117 Mtbl_cf solution(source.get_mg(), source.base) ;
00118 solution.set_etat_qcq() ;
00119 solution.t[0]->set_etat_qcq() ;
00120
00121 for (int k=0 ; k<np+1 ; k++)
00122 for (int j=0 ; j<nt ; j++)
00123 if (nullite_plm(j, nt, k, np, source.base) == 1)
00124 {
00125
00126 donne_lm(nz, 0, j, k, source.base, m_quant, l_quant, base_r) ;
00127
00128
00129
00130 if (l_quant == 0) {
00131 for (int i=0 ; i<nr ; i++)
00132 solution.set(0, k, j, i) = 0 ;
00133 }
00134
00135
00136 else {
00137
00138 int indice = -1 ;
00139
00140
00141 int taille = (l_quant == 1) ? nr : nr-1 ;
00142
00143 Matrice operateur (taille, taille) ;
00144 for (int conte=0 ; conte<nb_deja_fait ; conte++)
00145 if ((l_deja_fait[conte]== l_quant) && (n_deja_fait[conte] == nr))
00146 indice = conte ;
00147
00148 if (indice == -1) {
00149 if (nb_deja_fait >= nmax) {
00150 cout << "sol_poisson_compact : trop de matrices ..." << endl;
00151 abort() ;
00152 }
00153
00154 operateur = a*lap_cpt_mat (nr, l_quant, base_r)
00155 + b*xdsdx_mat(nr, l_quant, base_r) ;
00156 operateur = combinaison_cpt (operateur, l_quant, base_r) ;
00157
00158 l_deja_fait[nb_deja_fait] = l_quant ;
00159 n_deja_fait[nb_deja_fait] = nr ;
00160 tab_op[nb_deja_fait] = new Matrice(operateur) ;
00161
00162 nb_deja_fait++ ;
00163 }
00164 else {
00165
00166 operateur = *tab_op[indice] ;
00167 }
00168
00169
00170 Tbl so(taille) ;
00171 so.set_etat_qcq() ;
00172 for (int i=0 ; i<taille ; i++)
00173 so.set(i) = source(0, k, j, i) ;
00174 so = combinaison_cpt (so, base_r) ;
00175
00176 Tbl part (operateur.inverse(so)) ;
00177
00178 if (taille == nr)
00179 for (int i=0 ; i<nr ; i++)
00180 solution.set(0, k, j, i) = part(i) ;
00181 else {
00182 solution.set(0, k, j, nr-1) = 0 ;
00183 for (int i=nr-2 ; i>=0 ; i--)
00184 if (base_r == R_CHEBP) {
00185 solution.set(0, k, j, i) = part(i) ;
00186 solution.set(0, k, j, i+1) += part(i) ;
00187 }
00188 else {
00189 solution.set(0, k, j, i) = part(i)*(2*i+3) ;
00190 solution.set(0, k, j, i+1) += part(i)*(2*i+1) ;
00191 }
00192 }
00193 }
00194 }
00195 else
00196 for (int i=0 ; i<nr ; i++)
00197 solution.set(0, k, j, i) = 0 ;
00198
00199
00200 for (int j=0; j<nt; j++)
00201 for(int i=0 ; i<nr ; i++)
00202 solution.set(0, np+1, j, i) = 0 ;
00203
00204 for (int zone=1 ; zone<nz ; zone++)
00205 solution.t[zone]->set_etat_zero() ;
00206
00207 return solution ;
00208 }
00209
00210
00211
00213
00215
00216
00217 Mtbl_cf sol_poisson_compact(const Map_af& mapping, const Mtbl_cf& source,
00218 const Tbl& ac, const Tbl& bc, bool ) {
00219
00220
00221 int nzet = ac.get_dim(1) ;
00222 assert(nzet<=source.get_mg()->get_nzone()) ;
00223
00224
00225 assert (source.get_mg()->get_type_r(0) == RARE) ;
00226 for (int l=1 ; l<nzet ; l++)
00227 assert(source.get_mg()->get_type_r(l) == FIN) ;
00228
00229
00230 const Base_val& base = source.base ;
00231
00232
00233 Mtbl_cf resultat(source.get_mg(), base) ;
00234 resultat.annule_hard() ;
00235
00236
00237 int nr, nt, np ;
00238 int base_r ;
00239 double alpha, beta, echelle ;
00240 int l_quant, m_quant;
00241
00242
00243 int size = 0 ;
00244 int max_nr = 0 ;
00245 for (int l=0 ; l<nzet ; l++) {
00246 nr = mapping.get_mg()->get_nr(l) ;
00247 size += nr ;
00248 if (nr > max_nr) max_nr = nr ;
00249 }
00250
00251 Matrice systeme (size, size) ;
00252 systeme.set_etat_qcq() ;
00253 Tbl sec_membre (size) ;
00254 Tbl soluce (size) ;
00255 soluce.set_etat_qcq() ;
00256
00257 np = mapping.get_mg()->get_np(0) ;
00258 nt = mapping.get_mg()->get_nt(0) ;
00259 Matrice* work ;
00260
00261
00262 for (int k=0 ; k<np+1 ; k++)
00263 for (int j=0 ; j<nt ; j++)
00264 if (nullite_plm(j, nt, k, np, base) == 1) {
00265
00266 systeme.annule_hard() ;
00267 sec_membre.annule_hard() ;
00268
00269 int column_courant = 0 ;
00270 int ligne_courant = 0 ;
00271
00272
00273
00274
00275
00276 nr = mapping.get_mg()->get_nr(0) ;
00277 alpha = mapping.get_alpha()[0] ;
00278 base.give_quant_numbers (0, k, j, m_quant, l_quant, base_r) ;
00279
00280 if (l_quant == 0) {
00281 for (int i=0 ; i<size ; i++)
00282 soluce.set(i) = 0 ;
00283 }
00284 else {
00285
00286 Diff_dsdx2 d2_n(base_r, nr) ;
00287 Diff_sxdsdx sxd_n(base_r, nr) ;
00288 Diff_sx2 sx2_n(base_r, nr) ;
00289 Diff_x2dsdx2 x2d2_n(base_r,nr) ;
00290 Diff_xdsdx xd_n(base_r,nr) ;
00291 Diff_id id_n(base_r,nr) ;
00292
00293 work = new Matrice( ac(0,0) * ( d2_n + 2.*sxd_n -l_quant*(l_quant+1)*sx2_n )
00294 + ac(0,2) * ( x2d2_n + 2.*xd_n -l_quant*(l_quant+1)*id_n )
00295 + alpha * bc(0,1) * xd_n ) ;
00296
00297
00298
00299
00300
00301 int nbr_cl = 0 ;
00302 if (l_quant > 1) {
00303 nbr_cl = 1 ;
00304 if (l_quant%2==0) {
00305
00306 for (int col=0 ; col<nr ; col++)
00307 if (col%2==0)
00308 systeme.set(ligne_courant, col+column_courant) = 1 ;
00309 else
00310 systeme.set(ligne_courant, col+column_courant) = -1 ;
00311 }
00312 else {
00313
00314 for (int col=0 ; col<nr ; col++)
00315 if (col%2==0)
00316 systeme.set(ligne_courant, col+column_courant) = 2*col+1 ;
00317 else
00318 systeme.set(ligne_courant, col+column_courant) = -(2*col+1) ;
00319 }
00320 ligne_courant ++ ;
00321 }
00322
00323
00324 for (int lig=0 ; lig<nr-1-nbr_cl ; lig++) {
00325 for (int col=0 ; col<nr ; col++)
00326 systeme.set(lig+ligne_courant,col+column_courant) = (*work)(lig,col) ;
00327 sec_membre.set(lig+ligne_courant) = alpha*alpha*source(0, k, j, lig) ;
00328 }
00329
00330 delete work ;
00331 ligne_courant += nr-1-nbr_cl ;
00332
00333
00334 for (int col=0 ; col<nr ; col++) {
00335
00336 systeme.set(ligne_courant, col+column_courant) = 1 ;
00337
00338 if (l_quant%2==0)
00339 systeme.set(ligne_courant+1, col+column_courant) = 4*col*col/alpha ;
00340 else
00341 systeme.set(ligne_courant+1, col+column_courant) = (2*col+1)*(2*col+1)/alpha ;
00342 }
00343 column_courant += nr ;
00344
00345
00346
00347
00348
00349 for (int l=1 ; l<nzet ; l++) {
00350
00351 nr = mapping.get_mg()->get_nr(l) ;
00352 alpha = mapping.get_alpha()[l] ;
00353 beta = mapping.get_beta()[l] ;
00354 echelle = beta/alpha ;
00355 double bsa = echelle ;
00356 double bsa2 = bsa*bsa ;
00357
00358 base.give_quant_numbers (l, k, j, m_quant, l_quant, base_r) ;
00359
00360 Diff_dsdx dx(base_r, nr) ;
00361 Diff_xdsdx xdx(base_r, nr) ;
00362 Diff_x2dsdx x2dx(base_r, nr) ;
00363 Diff_x3dsdx x3dx(base_r, nr) ;
00364 Diff_dsdx2 dx2(base_r, nr) ;
00365 Diff_xdsdx2 xdx2(base_r, nr) ;
00366 Diff_x2dsdx2 x2dx2(base_r, nr) ;
00367 Diff_x3dsdx2 x3dx2(base_r, nr) ;
00368 Diff_id id(base_r,nr) ;
00369 Diff_mx mx(base_r,nr) ;
00370
00371 work = new Matrice ( ac(l,0) * ( x2dx2 + 2.*bsa*xdx2 + bsa2*dx2 + 2.*xdx
00372 + 2.*bsa*dx - l_quant*(l_quant+1)*id )
00373 + ac(l,1) * ( x3dx2 + 2.*bsa*x2dx2 + bsa2*xdx2 + 2.*x2dx
00374 + 2.*bsa*xdx - l_quant*(l_quant+1) *mx )
00375 + alpha * ( bc(l,0) * ( x2dx + 2.*bsa*xdx + bsa2*dx )
00376 + bc(l,1) * ( x3dx + 2.*bsa*x2dx + bsa2*xdx ) ) ) ;
00377
00378
00379 for (int col=0 ; col<nr ; col++) {
00380
00381 if (col%2==0)
00382 systeme.set(ligne_courant, col+column_courant) = -1 ;
00383 else
00384 systeme.set(ligne_courant, col+column_courant) = 1 ;
00385
00386 if (col%2==0)
00387 systeme.set(ligne_courant+1, col+column_courant) = col*col/alpha ;
00388 else
00389 systeme.set(ligne_courant+1, col+column_courant) = -col*col/alpha ;
00390 }
00391 ligne_courant += 2 ;
00392
00393
00394 Tbl source_aux(nr) ;
00395 source_aux.set_etat_qcq() ;
00396 for (int i=0 ; i<nr ; i++)
00397 source_aux.set(i) = source(l,k,j,i)*alpha*alpha ;
00398 Tbl xso(source_aux) ;
00399 Tbl xxso(source_aux) ;
00400 multx_1d(nr, &xso.t, R_CHEB) ;
00401 multx_1d(nr, &xxso.t, R_CHEB) ;
00402 multx_1d(nr, &xxso.t, R_CHEB) ;
00403 source_aux = beta*beta/alpha/alpha*source_aux+2*beta/alpha*xso+xxso ;
00404
00405
00406
00407 for (int lig=0 ; lig<nr-1 ; lig++) {
00408 for (int col=0 ; col<nr ; col++)
00409 systeme.set(lig+ligne_courant,col+column_courant) = (*work)(lig,col) ;
00410 sec_membre.set(lig+ligne_courant) = source_aux(lig) ;
00411 }
00412
00413
00414
00415
00416 delete work ;
00417 ligne_courant += nr-2 ;
00418
00419 if (l<nzet-1) {
00420
00421 for (int col=0 ; col<nr ; col++) {
00422
00423 systeme.set(ligne_courant, col+column_courant) = 1 ;
00424
00425 systeme.set(ligne_courant+1, col+column_courant) = col*col/alpha ;
00426 }
00427 }
00428
00429 column_courant += nr ;
00430
00431 }
00432
00433
00434
00435
00436
00437
00438 systeme.set_band (size, size) ;
00439 systeme.set_lu() ;
00440
00441
00442
00443
00444 soluce = systeme.inverse(sec_membre) ;
00445
00446 }
00447
00448
00449
00450
00451
00452 int conte = 0 ;
00453 for (int l=0 ; l<nzet ; l++) {
00454 nr = mapping.get_mg()->get_nr(l) ;
00455 for (int i=0 ; i<nr ; i++) {
00456 resultat.set(l,k,j,i) = soluce(conte) ;
00457 conte++ ;
00458 }
00459 }
00460
00461 }
00462
00463 return resultat ;
00464
00465 }
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480