poisson_vect_frontiere.C

00001 /*
00002  *   Copyright (c) 2000-2001 Philippe Grandclement
00003  *
00004  *   This file is part of LORENE.
00005  *
00006  *   LORENE is free software; you can redistribute it and/or modify
00007  *   it under the terms of the GNU General Public License as published by
00008  *   the Free Software Foundation; either version 2 of the License, or
00009  *   (at your option) any later version.
00010  *
00011  *   LORENE is distributed in the hope that it will be useful,
00012  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  *   GNU General Public License for more details.
00015  *
00016  *   You should have received a copy of the GNU General Public License
00017  *   along with LORENE; if not, write to the Free Software
00018  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019  *
00020  */
00021 
00022 
00023 char poisson_vect_frontiere_C[] = "$Header: /cvsroot/Lorene/C++/Source/Non_class_members/PDE/poisson_vect_frontiere.C,v 1.7 2005/03/11 11:20:26 f_limousin Exp $" ;
00024 
00025 /*
00026  * $Id: poisson_vect_frontiere.C,v 1.7 2005/03/11 11:20:26 f_limousin Exp $
00027  * $Log: poisson_vect_frontiere.C,v $
00028  * Revision 1.7  2005/03/11 11:20:26  f_limousin
00029  * Minor modif
00030  *
00031  * Revision 1.6  2005/02/22 18:00:32  f_limousin
00032  * Correction of an error in the function poisson_vect_binaire(...).
00033  * Confusion between cartesian and spherical triad for the solution.
00034  *
00035  * Revision 1.5  2005/02/08 10:07:07  f_limousin
00036  * Implementation of poisson_vect_binaire(...) with Vectors (instead of
00037  * Tenseur) in argument.
00038  *
00039  * Revision 1.4  2004/09/28 16:00:15  f_limousin
00040  * Add function poisson_vect_boundary which is the same as
00041  * poisson_vect_frontiere but for the new classes Tensor and Scalar.
00042  *
00043  * Revision 1.3  2003/10/03 15:58:50  j_novak
00044  * Cleaning of some headers
00045  *
00046  * Revision 1.2  2003/02/13 16:40:25  p_grandclement
00047  * Addition of various things for the Bin_ns_bh project, non of them being
00048  * completely tested
00049  *
00050  * Revision 1.1.1.1  2001/11/20 15:19:28  e_gourgoulhon
00051  * LORENE
00052  *
00053  * Revision 2.2  2000/10/26  09:08:06  phil
00054  * *** empty log message ***
00055  *
00056  * Revision 2.1  2000/10/26  09:01:18  phil
00057  * *** empty log message ***
00058  *
00059  * Revision 2.0  2000/10/19  09:36:36  phil
00060  * *** empty log message ***
00061  *
00062  *
00063  * $Header: /cvsroot/Lorene/C++/Source/Non_class_members/PDE/poisson_vect_frontiere.C,v 1.7 2005/03/11 11:20:26 f_limousin Exp $
00064  *
00065  */
00066 
00067 // Header C : 
00068 #include <stdlib.h>
00069 #include <math.h>
00070 
00071 // Headers Lorene :
00072 #include "proto.h"
00073 #include "tenseur.h"
00074 #include "tensor.h"
00075 #include "metric.h"
00076 
00077     // USING OOhara
00078 void poisson_vect_frontiere (double lambda, const Tenseur& source, Tenseur& shift, 
00079         const Valeur& lim_x, const Valeur& lim_y, const Valeur& lim_z, 
00080         int num_front, double precision, int itermax) {
00081     
00082     // METTRE TOUT PLEIN D'ASSERT
00083    
00084     // Confort
00085     int nt = lim_x.get_mg()->get_nt(num_front+1) ;
00086     int np = lim_x.get_mg()->get_np(num_front+1) ;
00087     int nz = lim_x.get_mg()->get_nzone() ;
00088     
00089    if (shift.get_etat() == ETATZERO) {
00090     shift.set_etat_qcq() ;
00091     for (int i=0 ; i<3 ; i++)
00092         shift.set(i).annule_hard() ;
00093     shift.set_std_base() ;
00094     }
00095     
00096     Tenseur so (source) ;
00097     
00098     // La source scalaire :
00099     Tenseur cop_so (so) ;
00100     cop_so.dec2_dzpuis() ;
00101     cop_so.dec2_dzpuis() ;
00102     
00103     Tenseur scal (*so.get_mp()) ;
00104     scal.set_etat_qcq() ;
00105     
00106     Cmp source_scal (contract(cop_so.gradient(), 0, 1)()/(lambda+1)) ;
00107     source_scal.inc2_dzpuis() ;
00108     if (source_scal.get_etat()== ETATZERO) {
00109     source_scal.annule_hard() ;
00110     source_scal.std_base_scal() ;
00111     source_scal.set_dzpuis(4) ;
00112     }
00113 
00114     Tenseur copie_so (so) ;
00115     copie_so.dec_dzpuis() ;
00116      
00117     Tenseur source_vect (*so.get_mp(), 1, CON, *source.get_triad()) ;
00118     Tenseur auxi (*so.get_mp(), 1, COV, *source.get_triad()) ;
00119     Cmp grad_shift (source_scal.get_mp()) ;
00120     
00121     // La condition sur la derivee du scalaire :
00122     Valeur lim_scal (lim_x.get_mg()) ;
00123     Tenseur shift_old (*shift.get_mp(), 1, CON, shift.get_mp()->get_bvect_cart()) ;
00124     
00125     int conte = 0 ;
00126     int indic = 1 ;
00127    
00128     while (indic ==1) {
00129     
00130     shift_old = shift ;
00131     
00132     grad_shift = contract(shift.gradient(), 0, 1)() ;
00133     grad_shift.dec2_dzpuis() ;
00134     grad_shift.va.coef_i() ;
00135        
00136    
00137   
00138     lim_scal = 1 ; // Permet d'affecter les trucs qui vont bien !
00139     for (int k=0 ; k<np ; k++)
00140         for (int j=0 ; j<nt ; j++)
00141         lim_scal.set(num_front, k, j, 0) = 
00142             grad_shift.va (num_front+1, k, j, 0) ;
00143     lim_scal.std_base_scal() ;
00144    
00145     // On resout la scalaire :
00146     scal.set() = source_scal.poisson_dirichlet (lim_scal, num_front) ;
00147     
00148     // La source vectorielle :
00149     source_vect.set_etat_qcq() ;
00150     auxi = scal.gradient() ;
00151     auxi.inc_dzpuis() ;
00152     for (int i=0 ; i<3 ; i++)
00153         source_vect.set(i) = copie_so(i) - lambda * auxi(i) ;
00154     
00155     indic = 0;
00156     for (int i=0 ; i<3 ; i++)
00157         if (source_vect(i).get_etat()==ETATQCQ)
00158         indic = 1 ;
00159     if (indic==0) {
00160         for (int i=0 ; i<3 ; i++)
00161         source_vect.set(i).annule_hard() ;
00162         source_vect.set_std_base() ;
00163     }
00164    
00165     // On resout les equations de poisson sur le shift :
00166     shift.set(0) = source_vect(0).poisson_dirichlet (lim_x, num_front) ;
00167     shift.set(1) = source_vect(1).poisson_dirichlet (lim_y, num_front) ;
00168     shift.set(2) = source_vect(2).poisson_dirichlet (lim_z, num_front) ;
00169     
00170     double erreur = 0 ;
00171     for (int i=0 ; i<3 ; i++) 
00172         if (max(norme(shift(i))) > precision) {
00173         Tbl diff (diffrelmax (shift(i), shift_old(i))) ;
00174         for (int j=num_front+1 ; j<nz ; j++)
00175         if (diff(j)> erreur)
00176             erreur = diff(j) ;
00177         }
00178     
00179     cout << "Pas " << conte << " : Difference " << erreur << endl ;
00180     conte ++ ;
00181     
00182     if ((erreur <precision) || (conte > itermax))
00183         indic = -1 ;
00184     }
00185 }
00186 
00187 
00188 
00189     // USING OOhara
00190 void poisson_vect_boundary (double lambda, const Vector& source,Vector& shift, 
00191         const Valeur& lim_x, const Valeur& lim_y, const Valeur& lim_z, 
00192         int num_front, double precision, int itermax) {
00193     
00194     // On travaille en composantes cartesiennes
00195     assert(source.get_mp().get_bvect_spher() == *(source.get_triad())) ;
00196     assert(source.get_mp().get_bvect_spher() == *(shift.get_triad())) ;
00197 
00198  
00199     // Confort
00200     int nt = lim_x.get_mg()->get_nt(num_front+1) ;
00201     int np = lim_x.get_mg()->get_np(num_front+1) ;
00202     int nz = lim_x.get_mg()->get_nzone() ;
00203     
00204     Metric_flat ff(source.get_mp(), source.get_mp().get_bvect_spher()) ;
00205     
00206     Vector so (source) ;
00207     
00208     // La source scalaire :
00209     Vector cop_so (so) ;
00210     cop_so.dec_dzpuis(2) ;
00211     cop_so.dec_dzpuis(2) ;
00212     
00213     Scalar scal (so.get_mp()) ;
00214     
00215     Scalar source_scal (contract(cop_so.derive_cov(ff), 0, 1)/(lambda+1)) ;
00216     source_scal.inc_dzpuis(2) ;
00217     if (source_scal.get_etat()== ETATZERO) {
00218     source_scal.annule_hard() ;
00219     source_scal.std_spectral_base() ;
00220     source_scal.set_dzpuis(4) ;
00221     }
00222 
00223     Vector copie_so (so) ;
00224     copie_so.dec_dzpuis() ;
00225      
00226     Vector source_vect (so.get_mp(), CON, *source.get_triad()) ;
00227     Vector auxi (so.get_mp(), COV, *source.get_triad()) ;
00228     Scalar grad_shift (source_scal.get_mp()) ;
00229     
00230     // La condition sur la derivee du scalaire :
00231     Valeur lim_scal (lim_x.get_mg()) ;
00232     Vector shift_old (shift.get_mp(), CON, shift.get_mp().get_bvect_cart()) ;
00233     
00234     int conte = 0 ;
00235     int indic = 1 ;
00236    
00237     while (indic ==1) {
00238     
00239     shift_old = shift ;
00240     
00241     grad_shift = contract(shift.derive_cov(ff), 0, 1) ;
00242     grad_shift.dec_dzpuis(2) ;
00243     grad_shift.set_spectral_va().coef_i() ;
00244        
00245      
00246     lim_scal = 1 ; // Permet d'affecter les trucs qui vont bien !
00247     for (int k=0 ; k<np ; k++)
00248         for (int j=0 ; j<nt ; j++)
00249         lim_scal.set(num_front, k, j, 0) = 
00250             grad_shift.get_spectral_va() (num_front+1, k, j, 0) ;
00251     lim_scal.std_base_scal() ;
00252    
00253     // On resout la scalaire :
00254     
00255     source_scal.filtre(4) ;
00256     scal = source_scal.poisson_dirichlet (lim_scal, num_front) ;
00257     
00258     // La source vectorielle :
00259     source_vect.set_etat_qcq() ;
00260     auxi = scal.derive_cov(ff) ;
00261     auxi.inc_dzpuis() ;
00262     for (int i=1 ; i<=3 ; i++)
00263         source_vect.set(i) = copie_so(i) - lambda * auxi(i) ;
00264     
00265     indic = 0;
00266     for (int i=1 ; i<=3 ; i++)
00267         if (source_vect(i).get_etat()==ETATQCQ)
00268         indic = 1 ;
00269     if (indic==0) {
00270         for (int i=1 ; i<=3 ; i++)
00271         source_vect.set(i).annule_hard() ;
00272         source_vect.std_spectral_base() ;
00273     }
00274 
00275     shift.change_triad(source.get_mp().get_bvect_cart()) ;
00276     source_vect.change_triad(source.get_mp().get_bvect_cart()) ;
00277 
00278     for (int i=1 ; i<=3 ; i++) 
00279         source_vect.set(i).filtre(4) ;
00280 
00281     // On resout les equations de poisson sur le shift :
00282     shift.set(1) = source_vect(1).poisson_dirichlet (lim_x, num_front) ;
00283     shift.set(2) = source_vect(2).poisson_dirichlet (lim_y, num_front) ;
00284     shift.set(3) = source_vect(3).poisson_dirichlet (lim_z, num_front) ;
00285     
00286     shift.change_triad(source.get_mp().get_bvect_spher()) ;
00287     source_vect.change_triad(source.get_mp().get_bvect_spher()) ;
00288 
00289     double erreur = 0 ;
00290     for (int i=1 ; i<=3 ; i++) 
00291         if (max(norme(shift(i))) > precision) {
00292         Tbl diff (diffrelmax (shift(i), shift_old(i))) ;
00293         for (int j=num_front+1 ; j<nz ; j++)
00294         if (diff(j)> erreur)
00295             erreur = diff(j) ;
00296         }
00297     
00298     cout << "Pas " << conte << " : Difference " << erreur << endl ;
00299     conte ++ ;
00300     
00301     if ((erreur <precision) || (conte > itermax))
00302         indic = -1 ;
00303     }
00304 }
00305 
00306 
00307 
00308 
00309 void poisson_vect_binaire ( double lambda, 
00310         const Tenseur& source_un, const Tenseur& source_deux, 
00311         const Valeur& bound_x_un, const Valeur& bound_y_un, 
00312         const Valeur& bound_z_un, const Valeur& bound_x_deux, 
00313         const Valeur& bound_y_deux, const Valeur& bound_z_deux, 
00314         Tenseur& sol_un, Tenseur& sol_deux, int num_front, double precision) {
00315             
00316     // METTRE DES ASSERT
00317     assert (sol_un.get_etat() != ETATNONDEF) ;
00318     assert (sol_deux.get_etat() != ETATNONDEF) ;
00319     
00320     // Les bases des deux vecteurs doivent etre alignees ou non alignees :
00321      
00322     assert (sol_un.get_mp() == source_un.get_mp()) ;
00323     assert (sol_deux.get_mp() == source_deux.get_mp()) ;
00324     
00325     double orientation_un = sol_un.get_mp()->get_rot_phi() ;
00326     assert ((orientation_un==0) || (orientation_un==M_PI)) ;
00327     
00328     double orientation_deux = sol_deux.get_mp()->get_rot_phi() ;
00329     assert ((orientation_deux==0) || (orientation_deux==M_PI)) ;
00330     
00331     int same_orient = (orientation_un == orientation_deux) ? 1 : -1 ;
00332     
00333     
00334     if (sol_un.get_etat() == ETATZERO) {
00335     sol_un.set_etat_qcq() ;
00336     for (int i=0 ; i<3 ; i++)
00337         sol_un.set(i).annule_hard() ;
00338     sol_un.set_std_base() ;
00339     }
00340     
00341      if (sol_deux.get_etat() == ETATZERO) {
00342     sol_deux.set_etat_qcq() ;
00343     for (int i=0 ; i<3 ; i++)
00344         sol_deux.set(i).annule_hard() ;
00345     sol_deux.set_std_base() ;
00346     }
00347     
00348     Valeur limite_x_un (bound_x_un.get_mg()) ;
00349     limite_x_un = bound_x_un ;
00350     Valeur limite_y_un (bound_y_un.get_mg()) ;
00351     limite_y_un = bound_y_un ;
00352     Valeur limite_z_un (bound_z_un.get_mg()) ;
00353     limite_z_un = bound_z_un ;
00354       
00355     Valeur limite_x_deux (bound_x_deux.get_mg()) ;
00356     limite_x_deux = bound_x_deux ;
00357     Valeur limite_y_deux (bound_y_deux.get_mg()) ;
00358     limite_y_deux = bound_y_deux ;
00359     Valeur limite_z_deux (bound_z_deux.get_mg()) ;
00360     limite_z_deux = bound_z_deux ;
00361     
00362     Valeur limite_chi_un (bound_x_un.get_mg()) ;
00363     limite_chi_un = 0 ;
00364     limite_chi_un.std_base_scal() ;
00365     
00366     Valeur limite_chi_deux (bound_x_deux.get_mg()) ;
00367     limite_chi_deux = 0 ;
00368     limite_chi_deux.std_base_scal() ;
00369     
00370     Mtbl xa_mtbl_un (source_un.get_mp()->get_mg()) ;
00371     xa_mtbl_un.set_etat_qcq() ;
00372     Mtbl ya_mtbl_un (source_un.get_mp()->get_mg()) ;
00373     ya_mtbl_un.set_etat_qcq() ;
00374     Mtbl za_mtbl_un (source_un.get_mp()->get_mg()) ;
00375     za_mtbl_un.set_etat_qcq() ;
00376     Mtbl xa_mtbl_deux (source_deux.get_mp()->get_mg()) ;
00377     xa_mtbl_deux.set_etat_qcq() ;
00378     Mtbl ya_mtbl_deux (source_deux.get_mp()->get_mg()) ;
00379     ya_mtbl_deux.set_etat_qcq() ;
00380     Mtbl za_mtbl_deux (source_deux.get_mp()->get_mg()) ;
00381     za_mtbl_deux.set_etat_qcq() ;
00382     
00383     xa_mtbl_un = source_un.get_mp()->xa ;
00384     ya_mtbl_un = source_un.get_mp()->ya ;
00385     za_mtbl_un = source_un.get_mp()->za ;
00386     
00387     xa_mtbl_deux = source_deux.get_mp()->xa ;
00388     ya_mtbl_deux = source_deux.get_mp()->ya ;
00389     za_mtbl_deux = source_deux.get_mp()->za ;
00390     
00391     double xabs, yabs, zabs ;
00392     double air,  theta,  phi ;
00393     double valeur ;
00394     
00395     int nbrep_un = bound_x_un.get_mg()->get_np(num_front) ;
00396     int nbret_un = bound_x_un.get_mg()->get_nt(num_front) ;
00397     int nbrep_deux = bound_x_deux.get_mg()->get_np(num_front) ;
00398     int nbret_deux = bound_x_deux.get_mg()->get_nt(num_front) ;
00399     int nz_un = bound_x_un.get_mg()->get_nzone() ;
00400     int nz_deux = bound_x_deux.get_mg()->get_nzone() ;
00401     
00402     // La source de l'equation scalaire sur 1
00403     Tenseur cop_so_un (source_un) ;
00404     cop_so_un.dec2_dzpuis() ;
00405     cop_so_un.dec2_dzpuis() ;
00406     
00407     Cmp source_scal_un (contract (cop_so_un.gradient(), 0, 1)()/(lambda+1)) ;
00408     if (source_scal_un.get_etat() == ETATZERO) {
00409     source_scal_un.annule_hard() ;
00410     source_scal_un.std_base_scal() ;
00411     }
00412     source_scal_un.inc2_dzpuis() ;
00413     
00414     // La source de l'equation scalaire sur 2
00415     Tenseur cop_so_deux (source_deux) ;
00416     cop_so_deux.dec2_dzpuis() ;
00417     cop_so_deux.dec2_dzpuis() ;
00418     
00419     Cmp source_scal_deux (contract (cop_so_deux.gradient(), 0, 1)()/(lambda+1)) ;
00420     if (source_scal_deux.get_etat() == ETATZERO) {
00421     source_scal_deux.annule_hard() ;
00422     source_scal_deux.std_base_scal() ;
00423     }
00424     source_scal_deux.inc2_dzpuis() ;
00425     
00426     // Les copies :
00427     Tenseur copie_so_un (source_un) ;
00428     copie_so_un.dec_dzpuis() ;
00429     
00430     Tenseur copie_so_deux (source_deux) ;
00431     copie_so_deux.dec_dzpuis() ;
00432     
00433     // ON COMMENCE LA BOUCLE :
00434     Tenseur sol_un_old (sol_un) ;
00435     Tenseur sol_deux_old (sol_deux) ;
00436     
00437     int indic = 1 ;
00438     int conte = 0 ;
00439     
00440     while (indic == 1) {
00441     
00442     // On resout les deux equations scalaires :
00443     Tenseur chi_un (source_scal_un.poisson_dirichlet (limite_chi_un, num_front)) ;
00444     Tenseur chi_deux (source_scal_deux.poisson_dirichlet (limite_chi_deux, num_front)) ;
00445     
00446     // On calcul les source pour les equation vectorielles :
00447     Tenseur source_vect_un (copie_so_un) ;
00448     if (source_vect_un.get_etat() == ETATZERO) {
00449         source_vect_un.set_etat_qcq() ;
00450         for (int i=0 ; i<3 ; i++) {
00451         source_vect_un.set(i).annule_hard() ;
00452         source_vect_un.set(i).set_dzpuis(3) ;
00453         }
00454         source_vect_un.set_std_base() ;
00455         }
00456     Tenseur grad_chi_un (chi_un.gradient()) ;
00457     grad_chi_un.inc_dzpuis() ;
00458     for (int i=0 ; i<3 ; i++)
00459         source_vect_un.set(i) = source_vect_un(i)-lambda*grad_chi_un(i) ;
00460     
00461     Tenseur source_vect_deux (copie_so_deux) ;
00462     if (source_vect_deux.get_etat() == ETATZERO) {
00463         source_vect_deux.set_etat_qcq() ;
00464         for (int i=0 ; i<3 ; i++) {
00465         source_vect_deux.set(i).annule_hard() ;
00466         source_vect_deux.set(i).set_dzpuis(3) ;
00467         }
00468         source_vect_deux.set_std_base() ;
00469         }
00470     Tenseur grad_chi_deux (chi_deux.gradient()) ;
00471     grad_chi_deux.inc_dzpuis() ;
00472     for (int i=0 ; i<3 ; i++)
00473         source_vect_deux.set(i) = source_vect_deux(i)-lambda*grad_chi_deux(i) ;
00474     
00475     
00476     sol_un_old = sol_un ;
00477     sol_deux_old = sol_deux ;
00478     
00479     // On resout les equation vectorielles :
00480     sol_un.set(0) = source_vect_un(0).poisson_dirichlet (limite_x_un, num_front) ;
00481     sol_un.set(1) = source_vect_un(1).poisson_dirichlet (limite_y_un, num_front) ;
00482     sol_un.set(2) = source_vect_un(2).poisson_dirichlet (limite_z_un, num_front) ;
00483     sol_deux.set(0) = source_vect_deux(0).poisson_dirichlet (limite_x_deux, num_front) ;
00484     sol_deux.set(1) = source_vect_deux(1).poisson_dirichlet (limite_y_deux, num_front) ;
00485     sol_deux.set(2) = source_vect_deux(2).poisson_dirichlet (limite_z_deux, num_front) ;
00486     
00487     
00488     // On modifie les Cl sur chi :
00489     Cmp div_shift_un (contract(sol_un.gradient(), 0, 1)()) ;
00490     div_shift_un.dec2_dzpuis() ;
00491     div_shift_un.va.coef_i() ;
00492     
00493     limite_chi_un = 1 ; // Affectation
00494     for (int k=0 ; k<nbrep_un ; k++)
00495         for (int j=0 ; j<nbret_un ; j++)
00496         limite_chi_un.set(num_front, k, j, 0) =
00497             div_shift_un.va (num_front+1, k, j, 0) ;
00498     limite_chi_un.std_base_scal() ;
00499     
00500     Cmp div_shift_deux (contract(sol_deux.gradient(), 0, 1)()) ;
00501     div_shift_deux.dec2_dzpuis() ;
00502     div_shift_deux.va.coef_i() ;
00503     
00504     limite_chi_deux = 1 ; // Affectation
00505     for (int k=0 ; k<nbrep_deux ; k++)
00506         for (int j=0 ; j<nbret_deux ; j++)
00507         limite_chi_deux.set(num_front, k, j, 0) =
00508             div_shift_deux.va (num_front+1, k, j, 0) ;
00509     limite_chi_deux.std_base_scal() ;
00510     
00511     
00512     // On modifie les Cl sur sol_un :
00513     for (int k=0 ; k<nbrep_un ; k++)
00514         for (int j=0 ; j<nbret_un ; j++) {
00515         xabs = xa_mtbl_un (num_front+1, k, j, 0) ;
00516         yabs = ya_mtbl_un (num_front+1, k, j, 0) ;
00517         zabs = za_mtbl_un (num_front+1, k, j, 0) ;
00518         
00519         source_deux.get_mp()->convert_absolute 
00520                 (xabs, yabs, zabs, air, theta, phi) ;
00521         
00522         valeur = sol_deux(0).val_point(air, theta, phi) ;
00523         limite_x_un.set(num_front, k, j, 0) = 
00524             bound_x_un(num_front, k, j, 0) - same_orient*valeur ;
00525         
00526         valeur = sol_deux(1).val_point(air, theta, phi) ;
00527         limite_y_un.set(num_front, k, j, 0) = 
00528             bound_y_un(num_front, k, j, 0) - same_orient*valeur ;
00529         
00530         valeur = sol_deux(2).val_point(air, theta, phi) ;
00531         limite_z_un.set(num_front, k, j, 0) = 
00532             bound_z_un(num_front, k, j, 0) - valeur ;
00533         }
00534         
00535     // On modifie les Cl sur sol_deux :
00536     for (int k=0 ; k<nbrep_deux ; k++)
00537         for (int j=0 ; j<nbret_deux ; j++) {
00538         xabs = xa_mtbl_deux (num_front+1, k, j, 0) ;
00539         yabs = ya_mtbl_deux (num_front+1, k, j, 0) ;
00540         zabs = za_mtbl_deux (num_front+1, k, j, 0) ;
00541         
00542         source_un.get_mp()->convert_absolute 
00543                 (xabs, yabs, zabs, air, theta, phi) ;
00544         
00545         valeur = sol_un(0).val_point(air, theta, phi) ;
00546         limite_x_deux.set(num_front, k, j, 0) = 
00547             bound_x_deux(num_front, k, j, 0) - same_orient*valeur ;
00548         
00549         valeur = sol_un(1).val_point(air, theta, phi) ;
00550         limite_y_deux.set(num_front, k, j, 0) = 
00551             bound_y_deux(num_front, k, j, 0) - same_orient*valeur ;
00552         
00553         valeur = sol_un(2).val_point(air, theta, phi) ;
00554         limite_z_deux.set(num_front, k, j, 0) = 
00555             bound_z_deux(num_front, k, j, 0) - valeur ;
00556         }
00557         
00558     double erreur = 0 ;
00559     
00560     for (int i=0 ; i<3 ; i++) {
00561         Tbl diff_un (diffrelmax (sol_un_old(i), sol_un(i))) ;
00562         for (int j=num_front+1 ; j<nz_un ; j++)
00563         if (erreur<diff_un(j))
00564             erreur = diff_un(j) ;
00565     }
00566     
00567     for (int i=0 ; i<3 ; i++) {
00568         Tbl diff_deux (diffrelmax (sol_deux_old(i), sol_deux(i))) ;
00569         for (int j=num_front+1 ; j<nz_deux ; j++)
00570         if (erreur<diff_deux(j))
00571             erreur = diff_deux(j) ;
00572     }
00573     
00574     cout << "Pas " << conte << " : Difference " << erreur << endl ;
00575     
00576     if (erreur < precision)
00577         indic = -1 ;
00578     conte ++ ;
00579     }
00580 }
00581 void poisson_vect_binaire ( double lambda, 
00582         const Vector& source_un, const Vector& source_deux, 
00583         const Valeur& bound_x_un, const Valeur& bound_y_un, 
00584         const Valeur& bound_z_un, const Valeur& bound_x_deux, 
00585         const Valeur& bound_y_deux, const Valeur& bound_z_deux, 
00586         Vector& sol_un, Vector& sol_deux, int num_front, double precision) {
00587             
00588     sol_un.change_triad(source_un.get_mp().get_bvect_cart()) ;
00589     sol_deux.change_triad(source_deux.get_mp().get_bvect_cart()) ;
00590     
00591     // Les bases des deux vecteurs doivent etre alignees ou non alignees :
00592      
00593     assert (sol_un.get_mp() == source_un.get_mp()) ;
00594     assert (sol_deux.get_mp() == source_deux.get_mp()) ;
00595     
00596     double orientation_un = sol_un.get_mp().get_rot_phi() ;
00597     assert ((orientation_un==0) || (orientation_un==M_PI)) ;
00598     
00599     double orientation_deux = sol_deux.get_mp().get_rot_phi() ;
00600     assert ((orientation_deux==0) || (orientation_deux==M_PI)) ;
00601     
00602     int same_orient = (orientation_un == orientation_deux) ? 1 : -1 ;
00603     
00604     Valeur limite_x_un (bound_x_un.get_mg()) ;
00605     limite_x_un = bound_x_un ;
00606     Valeur limite_y_un (bound_y_un.get_mg()) ;
00607     limite_y_un = bound_y_un ;
00608     Valeur limite_z_un (bound_z_un.get_mg()) ;
00609     limite_z_un = bound_z_un ;
00610       
00611     Valeur limite_x_deux (bound_x_deux.get_mg()) ;
00612     limite_x_deux = bound_x_deux ;
00613     Valeur limite_y_deux (bound_y_deux.get_mg()) ;
00614     limite_y_deux = bound_y_deux ;
00615     Valeur limite_z_deux (bound_z_deux.get_mg()) ;
00616     limite_z_deux = bound_z_deux ;
00617     
00618     Valeur limite_chi_un (bound_x_un.get_mg()) ;
00619     limite_chi_un = 0 ;
00620     limite_chi_un.std_base_scal() ;
00621     
00622     Valeur limite_chi_deux (bound_x_deux.get_mg()) ;
00623     limite_chi_deux = 0 ;
00624     limite_chi_deux.std_base_scal() ;
00625     
00626     Mtbl xa_mtbl_un (source_un.get_mp().get_mg()) ;
00627     xa_mtbl_un.set_etat_qcq() ;
00628     Mtbl ya_mtbl_un (source_un.get_mp().get_mg()) ;
00629     ya_mtbl_un.set_etat_qcq() ;
00630     Mtbl za_mtbl_un (source_un.get_mp().get_mg()) ;
00631     za_mtbl_un.set_etat_qcq() ;
00632     Mtbl xa_mtbl_deux (source_deux.get_mp().get_mg()) ;
00633     xa_mtbl_deux.set_etat_qcq() ;
00634     Mtbl ya_mtbl_deux (source_deux.get_mp().get_mg()) ;
00635     ya_mtbl_deux.set_etat_qcq() ;
00636     Mtbl za_mtbl_deux (source_deux.get_mp().get_mg()) ;
00637     za_mtbl_deux.set_etat_qcq() ;
00638     
00639     xa_mtbl_un = source_un.get_mp().xa ;
00640     ya_mtbl_un = source_un.get_mp().ya ;
00641     za_mtbl_un = source_un.get_mp().za ;
00642     
00643     xa_mtbl_deux = source_deux.get_mp().xa ;
00644     ya_mtbl_deux = source_deux.get_mp().ya ;
00645     za_mtbl_deux = source_deux.get_mp().za ;
00646     
00647     double xabs, yabs, zabs ;
00648     double air,  theta,  phi ;
00649     double valeur ;
00650     
00651     int nbrep_un = bound_x_un.get_mg()->get_np(num_front) ;
00652     int nbret_un = bound_x_un.get_mg()->get_nt(num_front) ;
00653     int nbrep_deux = bound_x_deux.get_mg()->get_np(num_front) ;
00654     int nbret_deux = bound_x_deux.get_mg()->get_nt(num_front) ;
00655     int nz_un = bound_x_un.get_mg()->get_nzone() ;
00656     int nz_deux = bound_x_deux.get_mg()->get_nzone() ;
00657     
00658     const Metric_flat& ff_un (source_un.get_mp().flat_met_cart()) ;
00659     const Metric_flat& ff_deux (source_deux.get_mp().flat_met_cart()) ;
00660 
00661     // La source de l'equation scalaire sur 1
00662     Vector cop_so_un (source_un) ;
00663     cop_so_un.dec_dzpuis(2) ;
00664     cop_so_un.dec_dzpuis(2) ;
00665     cop_so_un.change_triad(source_un.get_mp().get_bvect_cart()) ;
00666 
00667     
00668     Scalar source_scal_un (contract (cop_so_un.derive_cov(ff_un), 0, 1)/(lambda+1)) ;
00669     if (source_scal_un.get_etat() == ETATZERO) {
00670     source_scal_un.annule_hard() ;
00671     source_scal_un.std_spectral_base() ;
00672     }
00673     source_scal_un.inc_dzpuis(2) ;
00674     
00675     // La source de l'equation scalaire sur 2
00676     Vector cop_so_deux (source_deux) ;
00677     cop_so_deux.dec_dzpuis(2) ;
00678     cop_so_deux.dec_dzpuis(2) ;
00679     cop_so_deux.change_triad(source_deux.get_mp().get_bvect_cart()) ;
00680    
00681     Scalar source_scal_deux (contract (cop_so_deux.derive_cov(ff_deux), 0, 1)/(lambda+1)) ;
00682     if (source_scal_deux.get_etat() == ETATZERO) {
00683     source_scal_deux.annule_hard() ;
00684     source_scal_deux.std_spectral_base() ;
00685     }
00686     source_scal_deux.inc_dzpuis(2) ;
00687     
00688     // Les copies :
00689     Vector copie_so_un (source_un) ;
00690     copie_so_un.dec_dzpuis() ;
00691     copie_so_un.change_triad(source_un.get_mp().get_bvect_cart()) ;
00692 
00693     Vector copie_so_deux (source_deux) ;
00694     copie_so_deux.dec_dzpuis() ;
00695     copie_so_deux.change_triad(source_deux.get_mp().get_bvect_cart()) ;
00696     
00697     // ON COMMENCE LA BOUCLE :
00698     Vector sol_un_old (sol_un) ;
00699     Vector sol_deux_old (sol_deux) ;
00700     
00701     int indic = 1 ;
00702     int conte = 0 ;
00703     
00704     while (indic == 1) {
00705     
00706     // On resout les deux equations scalaires :
00707     Scalar chi_un (source_scal_un.poisson_dirichlet (limite_chi_un, num_front)) ;
00708     Scalar chi_deux (source_scal_deux.poisson_dirichlet (limite_chi_deux, num_front)) ;
00709     
00710 
00711     // On calcule les sources pour les equations vectorielles :
00712     Vector source_vect_un (copie_so_un) ;
00713     Vector grad_chi_un (chi_un.derive_con(ff_un)) ;
00714     grad_chi_un.inc_dzpuis() ;
00715     source_vect_un = source_vect_un - lambda*grad_chi_un ;
00716     
00717 
00718     Vector source_vect_deux (copie_so_deux) ;
00719     Vector grad_chi_deux (chi_deux.derive_con(ff_deux)) ;
00720     grad_chi_deux.inc_dzpuis() ;
00721     source_vect_deux = source_vect_deux - lambda*grad_chi_deux ;
00722     
00723     sol_un_old = sol_un ;
00724     sol_deux_old = sol_deux ;
00725 
00726     // On resout les equations vectorielles :
00727     sol_un.set(1) = source_vect_un(1).poisson_dirichlet (limite_x_un, num_front) ;
00728     sol_un.set(2) = source_vect_un(2).poisson_dirichlet (limite_y_un, num_front) ;
00729     sol_un.set(3) = source_vect_un(3).poisson_dirichlet (limite_z_un, num_front) ;
00730     sol_deux.set(1) = source_vect_deux(1).poisson_dirichlet (limite_x_deux, num_front) ;
00731     sol_deux.set(2) = source_vect_deux(2).poisson_dirichlet (limite_y_deux, num_front) ;
00732     sol_deux.set(3) = source_vect_deux(3).poisson_dirichlet (limite_z_deux, num_front) ;
00733     
00734     
00735     // On modifie les Cl sur chi :
00736     Scalar div_shift_un (contract(sol_un.derive_cov(ff_un), 0, 1)) ;
00737     div_shift_un.dec_dzpuis(2) ;
00738     div_shift_un.get_spectral_va().coef_i() ;
00739     
00740     limite_chi_un = 1 ; // Affectation
00741     for (int k=0 ; k<nbrep_un ; k++)
00742         for (int j=0 ; j<nbret_un ; j++)
00743         limite_chi_un.set(num_front, k, j, 0) =
00744             div_shift_un.get_spectral_va() (num_front+1, k, j, 0) ;
00745     limite_chi_un.std_base_scal() ;
00746     
00747     Scalar div_shift_deux (contract(sol_deux.derive_cov(ff_deux), 0, 1)) ;
00748     div_shift_deux.dec_dzpuis(2) ;
00749     div_shift_deux.get_spectral_va().coef_i() ;
00750     
00751     limite_chi_deux = 1 ; // Affectation
00752     for (int k=0 ; k<nbrep_deux ; k++)
00753         for (int j=0 ; j<nbret_deux ; j++)
00754         limite_chi_deux.set(num_front, k, j, 0) =
00755             div_shift_deux.get_spectral_va() (num_front+1, k, j, 0) ;
00756     limite_chi_deux.std_base_scal() ;
00757     
00758     
00759     // On modifie les Cl sur sol_un :
00760     for (int k=0 ; k<nbrep_un ; k++)
00761         for (int j=0 ; j<nbret_un ; j++) {
00762         xabs = xa_mtbl_un (num_front+1, k, j, 0) ;
00763         yabs = ya_mtbl_un (num_front+1, k, j, 0) ;
00764         zabs = za_mtbl_un (num_front+1, k, j, 0) ;
00765         
00766         source_deux.get_mp().convert_absolute 
00767                 (xabs, yabs, zabs, air, theta, phi) ;
00768         
00769         valeur = sol_deux(1).val_point(air, theta, phi) ;
00770         limite_x_un.set(num_front, k, j, 0) = 
00771             bound_x_un(num_front, k, j, 0) - same_orient*valeur ;
00772         
00773         valeur = sol_deux(2).val_point(air, theta, phi) ;
00774         limite_y_un.set(num_front, k, j, 0) = 
00775             bound_y_un(num_front, k, j, 0) - same_orient*valeur ;
00776         
00777         valeur = sol_deux(3).val_point(air, theta, phi) ;
00778         limite_z_un.set(num_front, k, j, 0) = 
00779             bound_z_un(num_front, k, j, 0) - valeur ;
00780         }
00781         
00782     // On modifie les Cl sur sol_deux :
00783     for (int k=0 ; k<nbrep_deux ; k++)
00784         for (int j=0 ; j<nbret_deux ; j++) {
00785         xabs = xa_mtbl_deux (num_front+1, k, j, 0) ;
00786         yabs = ya_mtbl_deux (num_front+1, k, j, 0) ;
00787         zabs = za_mtbl_deux (num_front+1, k, j, 0) ;
00788         
00789         source_un.get_mp().convert_absolute 
00790                 (xabs, yabs, zabs, air, theta, phi) ;
00791         
00792         valeur = sol_un(1).val_point(air, theta, phi) ;
00793         limite_x_deux.set(num_front, k, j, 0) = 
00794             bound_x_deux(num_front, k, j, 0) - same_orient*valeur ;
00795         
00796         valeur = sol_un(2).val_point(air, theta, phi) ;
00797         limite_y_deux.set(num_front, k, j, 0) = 
00798             bound_y_deux(num_front, k, j, 0) - same_orient*valeur ;
00799         
00800         valeur = sol_un(3).val_point(air, theta, phi) ;
00801         limite_z_deux.set(num_front, k, j, 0) = 
00802             bound_z_deux(num_front, k, j, 0) - valeur ;
00803         }
00804         
00805     double erreur = 0 ;
00806     
00807     for (int i=1 ; i<=3 ; i++) {
00808         Tbl diff_un (diffrelmax (sol_un_old(i), sol_un(i))) ;
00809         for (int j=num_front+1 ; j<nz_un ; j++)
00810         if (erreur<diff_un(j))
00811             erreur = diff_un(j) ;
00812     }
00813     
00814     for (int i=1 ; i<=3 ; i++) {
00815         Tbl diff_deux (diffrelmax (sol_deux_old(i), sol_deux(i))) ;
00816         for (int j=num_front+1 ; j<nz_deux ; j++)
00817         if (erreur<diff_deux(j))
00818             erreur = diff_deux(j) ;
00819     }
00820     
00821     cout << "Pas " << conte << " : Difference " << erreur << endl ;
00822     
00823 
00824 
00825 /*
00826     maxabs(sol_un.derive_con(ff_un).divergence(ff_un) + lambda * sol_un.divergence(ff_un).derive_con(ff_un) - source_un,
00827            "Absolute error in the resolution of the equation for beta") ;  
00828     cout << endl ;
00829 */
00830     
00831 
00832     if (erreur < precision)
00833         indic = -1 ;
00834     conte ++ ;
00835     }
00836 }

Generated on Tue Feb 7 01:35:19 2012 for LORENE by  doxygen 1.4.6