pde_frontiere_bin.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 pde_frontiere_bin_C[] = "$Header: /cvsroot/Lorene/C++/Source/Non_class_members/PDE/pde_frontiere_bin.C,v 1.5 2006/05/11 14:16:37 f_limousin Exp $" ;
00024 
00025 /*
00026  * $Id: pde_frontiere_bin.C,v 1.5 2006/05/11 14:16:37 f_limousin Exp $
00027  * $Log: pde_frontiere_bin.C,v $
00028  * Revision 1.5  2006/05/11 14:16:37  f_limousin
00029  * Minor modifs.
00030  *
00031  * Revision 1.4  2005/04/29 14:06:18  f_limousin
00032  * Improve the resolution for Neumann_binaire(Scalars).
00033  *
00034  * Revision 1.3  2005/02/08 10:05:53  f_limousin
00035  * Implementation of neumann_binaire(...) and dirichlet_binaire(...)
00036  * with Scalars (instead of Cmps) in arguments.
00037  *
00038  * Revision 1.2  2003/10/03 15:58:50  j_novak
00039  * Cleaning of some headers
00040  *
00041  * Revision 1.1.1.1  2001/11/20 15:19:28  e_gourgoulhon
00042  * LORENE
00043  *
00044  * Revision 2.3  2000/12/04  14:30:16  phil
00045  * correction CL.
00046  *
00047  * Revision 2.2  2000/12/01  15:18:26  phil
00048  * vire trucs inutiles
00049  *
00050  * Revision 2.1  2000/12/01  15:16:49  phil
00051  * correction version Neumann
00052  *
00053  * Revision 2.0  2000/10/19  09:36:07  phil
00054  * *** empty log message ***
00055  *
00056  *
00057  * $Header: /cvsroot/Lorene/C++/Source/Non_class_members/PDE/pde_frontiere_bin.C,v 1.5 2006/05/11 14:16:37 f_limousin Exp $
00058  *
00059  */
00060 
00061 //standard
00062 #include <stdlib.h>
00063 #include <math.h>
00064 
00065 // LORENE
00066 #include "tensor.h"
00067 #include "tenseur.h"
00068 #include "proto.h"
00069 #include "metric.h"
00070 
00071 // Version avec une fonction de theta, phi.
00072 
00073 void dirichlet_binaire (const Cmp& source_un, const Cmp& source_deux, 
00074             const Valeur& boundary_un, const Valeur& boundary_deux, 
00075                 Cmp& sol_un, Cmp& sol_deux, int num_front, 
00076                 double precision) {
00077     
00078     // Les verifs sur le mapping :
00079     assert (source_un.get_mp() == sol_un.get_mp()) ;
00080     assert (source_deux.get_mp() == sol_deux.get_mp()) ;
00081     
00082     Valeur limite_un (boundary_un.get_mg()) ;
00083     Valeur limite_deux (boundary_deux.get_mg()) ;
00084     
00085     Cmp sol_un_old (sol_un.get_mp()) ;
00086     Cmp sol_deux_old (sol_deux.get_mp()) ;
00087     
00088     Mtbl xa_mtbl_un (source_un.get_mp()->xa) ;
00089     Mtbl ya_mtbl_un (source_un.get_mp()->ya) ;
00090     Mtbl za_mtbl_un (source_un.get_mp()->za) ;
00091     Mtbl xa_mtbl_deux (source_deux.get_mp()->xa) ;
00092     Mtbl ya_mtbl_deux (source_deux.get_mp()->ya) ;
00093     Mtbl za_mtbl_deux (source_deux.get_mp()->za) ;
00094     
00095     double xabs, yabs, zabs ;
00096     double air,  theta,  phi ;
00097     double valeur ;
00098     
00099     int nbrep_un = boundary_un.get_mg()->get_np(num_front) ;
00100     int nbret_un = boundary_un.get_mg()->get_nt(num_front) ;
00101     int nbrep_deux = boundary_deux.get_mg()->get_np(num_front) ;
00102     int nbret_deux = boundary_deux.get_mg()->get_nt(num_front) ;
00103     
00104     int nz_un = boundary_un.get_mg()->get_nzone() ;
00105     int nz_deux = boundary_deux.get_mg()->get_nzone() ;
00106     
00107     // Initialisation valeur limite avant iteration !
00108    limite_un = 1 ; //Pour initialiser les tableaux
00109    for (int k=0 ; k<nbrep_un ; k++)
00110     for (int j=0 ; j<nbret_un ; j++)
00111     limite_un.set(num_front, k, j, 0) =
00112         sol_un.va.val_point_jk(num_front+1, -1, j, k) ;
00113     limite_un.set_base (boundary_un.base) ;
00114 
00115     limite_deux = 1 ;
00116     for (int k=0 ; k<nbrep_deux ; k++)
00117     for (int j=0 ; j<nbret_deux ; j++)
00118       limite_deux.set(num_front, k, j, 0) =
00119         sol_deux.va.val_point_jk(num_front+1, -1, j, k) ;
00120     limite_deux.set_base (boundary_deux.base) ;
00121 
00122 
00123     int conte = 0 ;
00124     int indic = 1 ;
00125     
00126     while (indic==1) {
00127     
00128     sol_un_old = sol_un ;
00129     sol_deux_old = sol_deux ;
00130     
00131     sol_un = source_un.poisson_dirichlet(limite_un, num_front) ;
00132     sol_deux = source_deux.poisson_dirichlet(limite_deux, num_front) ;
00133     
00134     xa_mtbl_deux = source_deux.get_mp()->xa ;
00135     ya_mtbl_deux = source_deux.get_mp()->ya ;
00136     za_mtbl_deux = source_deux.get_mp()->za ;
00137     
00138     
00139     for (int k=0 ; k<nbrep_deux ; k++)
00140         for (int j=0 ; j<nbret_deux ; j++) {
00141         xabs = xa_mtbl_deux (num_front+1, k, j, 0) ;
00142         yabs = ya_mtbl_deux (num_front+1, k, j, 0) ;
00143         zabs = za_mtbl_deux (num_front+1, k, j, 0) ;
00144         
00145         source_un.get_mp()->convert_absolute 
00146                 (xabs, yabs, zabs, air, theta, phi) ;
00147         valeur = sol_un.val_point(air, theta, phi) ;
00148         
00149         limite_deux.set(num_front, k, j, 0) = 
00150             boundary_deux(num_front, k, j, 0) - valeur ;
00151         }
00152        
00153     xa_mtbl_un = source_un.get_mp()->xa ;
00154     ya_mtbl_un = source_un.get_mp()->ya ;
00155     za_mtbl_un = source_un.get_mp()->za ;
00156     
00157     for (int k=0 ; k<nbrep_un ; k++)
00158         for (int j=0 ; j<nbret_un ; j++) {
00159         xabs = xa_mtbl_un (num_front+1, k, j, 0) ;
00160         yabs = ya_mtbl_un (num_front+1, k, j, 0) ;
00161         zabs = za_mtbl_un (num_front+1, k, j, 0) ;
00162         
00163         source_deux.get_mp()->convert_absolute 
00164             (xabs, yabs, zabs, air, theta, phi) ;
00165         valeur = sol_deux.val_point(air, theta, phi) ;
00166         
00167         limite_un.set(num_front, k, j, 0) = 
00168             boundary_un(num_front, k, j, 0) - valeur ;
00169         }
00170     
00171     double erreur = 0 ;
00172     Tbl diff_un (diffrelmax(sol_un, sol_un_old)) ;
00173     for (int i=num_front+1 ; i<nz_un ; i++)
00174         if (diff_un(i) > erreur)
00175         erreur = diff_un(i) ;
00176     
00177     Tbl diff_deux (diffrelmax(sol_deux, sol_deux_old)) ;
00178     for (int i=num_front+1 ; i<nz_deux ; i++)
00179         if (diff_deux(i) > erreur)
00180         erreur = diff_deux(i) ;
00181     
00182     cout << "Pas " << conte << " : Difference " << erreur << endl ;
00183     
00184     conte ++ ;
00185     if (erreur < precision)
00186         indic = -1 ;
00187     }
00188                     
00189 }
00190 
00191 // Version avec des doubles :
00192 void dirichlet_binaire (const Cmp& source_un, const Cmp& source_deux, 
00193             double bound_un, double bound_deux, 
00194                 Cmp& sol_un, Cmp& sol_deux, int num_front, 
00195                 double precision) {
00196                 
00197     Valeur boundary_un (source_un.get_mp()->get_mg()->get_angu()) ;
00198     if (bound_un == 0)
00199     boundary_un.annule_hard() ;
00200     else
00201     boundary_un = bound_un ;
00202     boundary_un.std_base_scal() ;
00203     
00204     Valeur boundary_deux (source_deux.get_mp()->get_mg()->get_angu()) ;
00205     if (bound_deux == 0)
00206     boundary_deux.annule_hard() ;
00207     else
00208     boundary_deux = bound_deux ;
00209     boundary_deux.std_base_scal() ;
00210     
00211     dirichlet_binaire (source_un, source_deux, boundary_un, boundary_deux, 
00212             sol_un, sol_deux, num_front, precision) ;
00213 }
00214 
00215 
00216 // Version with Scalar :
00217 void dirichlet_binaire (const Scalar& source_un, const Scalar& source_deux, 
00218             const Valeur& boundary_un, const Valeur& boundary_deux,
00219             Scalar& sol_un, Scalar& sol_deux, int num_front, 
00220                 double precision) {
00221     
00222     // Les verifs sur le mapping :
00223     assert (source_un.get_mp() == sol_un.get_mp()) ;
00224     assert (source_deux.get_mp() == sol_deux.get_mp()) ;
00225     
00226     Valeur limite_un (boundary_un.get_mg()) ;
00227     Valeur limite_deux (boundary_deux.get_mg()) ;
00228     
00229     Scalar sol_un_old (sol_un.get_mp()) ;
00230     Scalar sol_deux_old (sol_deux.get_mp()) ;
00231     
00232     Mtbl xa_mtbl_un (source_un.get_mp().xa) ;
00233     Mtbl ya_mtbl_un (source_un.get_mp().ya) ;
00234     Mtbl za_mtbl_un (source_un.get_mp().za) ;
00235     Mtbl xa_mtbl_deux (source_deux.get_mp().xa) ;
00236     Mtbl ya_mtbl_deux (source_deux.get_mp().ya) ;
00237     Mtbl za_mtbl_deux (source_deux.get_mp().za) ;
00238     
00239     double xabs, yabs, zabs ;
00240     double air,  theta,  phi ;
00241     double valeur ;
00242     
00243     int nbrep_un = boundary_un.get_mg()->get_np(num_front) ;
00244     int nbret_un = boundary_un.get_mg()->get_nt(num_front) ;
00245     int nbrep_deux = boundary_deux.get_mg()->get_np(num_front) ;
00246     int nbret_deux = boundary_deux.get_mg()->get_nt(num_front) ;
00247     
00248     int nz_un = boundary_un.get_mg()->get_nzone() ;
00249     int nz_deux = boundary_deux.get_mg()->get_nzone() ;
00250     
00251     // Initialisation valeur limite avant iteration !
00252    limite_un = 1 ; //Pour initialiser les tableaux
00253    for (int k=0 ; k<nbrep_un ; k++)
00254     for (int j=0 ; j<nbret_un ; j++)
00255     limite_un.set(num_front, k, j, 0) =
00256         sol_un.get_spectral_va().val_point_jk(num_front+1, -1, j, k) ;
00257     limite_un.set_base (boundary_un.base) ;
00258 
00259     limite_deux = 1 ;
00260     for (int k=0 ; k<nbrep_deux ; k++)
00261     for (int j=0 ; j<nbret_deux ; j++)
00262       limite_deux.set(num_front, k, j, 0) =
00263         sol_deux.get_spectral_va().val_point_jk(num_front+1, -1, j, k) ;
00264     limite_deux.set_base (boundary_deux.base) ;
00265 
00266 
00267     int conte = 0 ;
00268     int indic = 1 ;
00269     
00270     while (indic==1) {
00271     
00272     sol_un_old = sol_un ;
00273     sol_deux_old = sol_deux ;
00274     
00275     sol_un = source_un.poisson_dirichlet(limite_un, num_front) ;
00276     sol_deux = source_deux.poisson_dirichlet(limite_deux, num_front) ;
00277     
00278     xa_mtbl_deux = source_deux.get_mp().xa ;
00279     ya_mtbl_deux = source_deux.get_mp().ya ;
00280     za_mtbl_deux = source_deux.get_mp().za ;
00281     
00282     
00283     for (int k=0 ; k<nbrep_deux ; k++)
00284         for (int j=0 ; j<nbret_deux ; j++) {
00285         xabs = xa_mtbl_deux (num_front+1, k, j, 0) ;
00286         yabs = ya_mtbl_deux (num_front+1, k, j, 0) ;
00287         zabs = za_mtbl_deux (num_front+1, k, j, 0) ;
00288         
00289         source_un.get_mp().convert_absolute 
00290                 (xabs, yabs, zabs, air, theta, phi) ;
00291         valeur = sol_un.val_point(air, theta, phi) ;
00292         
00293         limite_deux.set(num_front, k, j, 0) = 
00294             boundary_deux(num_front, k, j, 0) - valeur ;
00295         }
00296        
00297     xa_mtbl_un = source_un.get_mp().xa ;
00298     ya_mtbl_un = source_un.get_mp().ya ;
00299     za_mtbl_un = source_un.get_mp().za ;
00300     
00301     for (int k=0 ; k<nbrep_un ; k++)
00302         for (int j=0 ; j<nbret_un ; j++) {
00303         xabs = xa_mtbl_un (num_front+1, k, j, 0) ;
00304         yabs = ya_mtbl_un (num_front+1, k, j, 0) ;
00305         zabs = za_mtbl_un (num_front+1, k, j, 0) ;
00306         
00307         source_deux.get_mp().convert_absolute 
00308             (xabs, yabs, zabs, air, theta, phi) ;
00309         valeur = sol_deux.val_point(air, theta, phi) ;
00310         
00311         limite_un.set(num_front, k, j, 0) = 
00312             boundary_un(num_front, k, j, 0) - valeur ;     
00313 //      cout << 0.3  << " " << valeur+(sol_un+1.).val_grid_point(1, k, j, 0) << " " << (0.3 - (sol_un+1.)).val_grid_point(1, k, j, 0)-valeur  << endl ;
00314         }
00315 
00316     double erreur = 0 ;
00317     Tbl diff_un (diffrelmax(sol_un, sol_un_old)) ;
00318     for (int i=num_front+1 ; i<nz_un ; i++)
00319         if (diff_un(i) > erreur)
00320         erreur = diff_un(i) ;
00321     
00322     Tbl diff_deux (diffrelmax(sol_deux, sol_deux_old)) ;
00323     for (int i=num_front+1 ; i<nz_deux ; i++)
00324         if (diff_deux(i) > erreur)
00325         erreur = diff_deux(i) ;
00326     
00327     cout << "Pas " << conte << " : Difference " << erreur << endl ;
00328     
00329     conte ++ ;
00330     if (erreur < precision)
00331         indic = -1 ;
00332     }
00333 
00334 }
00335 
00336 
00337 
00338 // Version avec une fonction de theta, phi.
00339 
00340 void neumann_binaire (const Cmp& source_un, const Cmp& source_deux, 
00341               const Valeur& boundary_un, const Valeur& boundary_deux,
00342               Cmp& sol_un, Cmp& sol_deux, int num_front, 
00343               double precision) {
00344     
00345     // Les verifs sur le mapping :
00346     assert (source_un.get_mp() == sol_un.get_mp()) ;
00347     assert (source_deux.get_mp() == sol_deux.get_mp()) ;
00348     
00349     // Alignes ou non ?
00350     double orient_un = source_un.get_mp()->get_rot_phi() ;
00351     assert ((orient_un==0) || (orient_un==M_PI)) ;
00352     double orient_deux = source_deux.get_mp()->get_rot_phi() ;
00353     assert ((orient_deux==0) || (orient_deux==M_PI)) ;
00354     int same_orient = (orient_un==orient_deux) ? 1 : -1 ;
00355     
00356     Valeur limite_un (boundary_un.get_mg()) ;
00357     Valeur limite_deux (boundary_deux.get_mg()) ;
00358     
00359     Cmp sol_un_old (sol_un.get_mp()) ;
00360     Cmp sol_deux_old (sol_deux.get_mp()) ;
00361     
00362     Mtbl xa_mtbl_un (source_un.get_mp()->xa) ;
00363     Mtbl ya_mtbl_un (source_un.get_mp()->ya) ;
00364     Mtbl za_mtbl_un (source_un.get_mp()->za) ;
00365     
00366     Mtbl cost_mtbl_un (source_un.get_mp()->cost) ;
00367     Mtbl sint_mtbl_un (source_un.get_mp()->sint) ;
00368     Mtbl cosp_mtbl_un (source_un.get_mp()->cosp) ;
00369     Mtbl sinp_mtbl_un (source_un.get_mp()->sinp) ;
00370     
00371     
00372     Mtbl xa_mtbl_deux (source_deux.get_mp()->xa) ;
00373     Mtbl ya_mtbl_deux (source_deux.get_mp()->ya) ;
00374     Mtbl za_mtbl_deux (source_deux.get_mp()->za) ;
00375     
00376     Mtbl cost_mtbl_deux (source_deux.get_mp()->cost) ;
00377     Mtbl sint_mtbl_deux (source_deux.get_mp()->sint) ;
00378     Mtbl cosp_mtbl_deux (source_deux.get_mp()->cosp) ;
00379     Mtbl sinp_mtbl_deux (source_deux.get_mp()->sinp) ;
00380     
00381     double xabs, yabs, zabs ;
00382     double air,  theta,  phi ;
00383     double valeur ;
00384      
00385     int nbrep_un = boundary_un.get_mg()->get_np(num_front) ;
00386     int nbret_un = boundary_un.get_mg()->get_nt(num_front) ;
00387     int nbrep_deux = boundary_deux.get_mg()->get_np(num_front) ;
00388     int nbret_deux = boundary_deux.get_mg()->get_nt(num_front) ;
00389     
00390     int nz_un = boundary_un.get_mg()->get_nzone() ;
00391     int nz_deux = boundary_deux.get_mg()->get_nzone() ;
00392     
00393     // Initialisation des CL :
00394     limite_un = 1 ;
00395     limite_deux = 2 ;
00396     Cmp der_un (sol_un.dsdr()) ;
00397     Cmp der_deux (sol_deux.dsdr()) ;
00398     
00399     for (int k=0 ; k<nbrep_un ; k++)
00400     for (int j=0 ; j<nbret_un ; j++)
00401         limite_un.set(num_front, k, j, 0) =
00402         der_un.va.val_point_jk(num_front+1, -1, j, k) ;
00403     limite_un.set_base (boundary_un.base) ;
00404 
00405     for (int k=0 ; k<nbrep_deux ; k++)
00406     for (int j=0 ; j<nbret_deux ; j++)
00407       limite_deux.set(num_front, k, j, 0) =
00408         der_deux.va.val_point_jk(num_front+1, -1, j, k) ;
00409     limite_deux.set_base (boundary_deux.base) ;
00410     
00411     int conte = 0 ;
00412     int indic = 1 ;
00413     
00414     while (indic==1) {
00415 
00416     sol_un_old = sol_un ;
00417     sol_deux_old = sol_deux ;
00418     
00419     sol_un = source_un.poisson_neumann(limite_un, num_front) ;
00420     sol_deux = source_deux.poisson_neumann(limite_deux, num_front) ;
00421     
00422     // On veut les derivees de l'un sur l'autre :
00423     Tenseur copie_un (sol_un) ;
00424     Tenseur grad_sol_un (copie_un.gradient()) ;
00425     grad_sol_un.dec2_dzpuis() ;
00426     grad_sol_un.set(0) = grad_sol_un(0)*same_orient ;
00427     grad_sol_un.set(1) = grad_sol_un(1)*same_orient ;
00428     
00429     for (int k=0 ; k<nbrep_deux ; k++)
00430         for (int j=0 ; j<nbret_deux ; j++) {
00431         xabs = xa_mtbl_deux (num_front+1, k, j, 0) ;
00432         yabs = ya_mtbl_deux (num_front+1, k, j, 0) ;
00433         zabs = za_mtbl_deux (num_front+1, k, j, 0) ;
00434         
00435         source_un.get_mp()->convert_absolute 
00436                 (xabs, yabs, zabs, air, theta, phi) ;
00437                 
00438         valeur = sint_mtbl_deux (num_front+1, k, j, 0) * (
00439 cosp_mtbl_deux(num_front+1, k, j, 0)*grad_sol_un(0).val_point(air, theta, phi)+
00440 sinp_mtbl_deux(num_front+1, k, j, 0)*grad_sol_un(1).val_point(air, theta, phi))+
00441 cost_mtbl_deux(num_front+1, k, j, 0)*grad_sol_un(2).val_point(air, theta, phi);
00442 
00443         limite_deux.set(num_front, k, j, 0) = 
00444             boundary_deux(num_front, k, j, 0) - valeur ;
00445         }
00446     
00447     Tenseur copie_deux (sol_deux) ;
00448     Tenseur grad_sol_deux (copie_deux.gradient()) ;
00449     grad_sol_deux.dec2_dzpuis() ;
00450     grad_sol_deux.set(0) = grad_sol_deux(0)*same_orient ;
00451     grad_sol_deux.set(1) = grad_sol_deux(1)*same_orient ;
00452     
00453     for (int k=0 ; k<nbrep_un ; k++)
00454         for (int j=0 ; j<nbret_un ; j++) {
00455         xabs = xa_mtbl_un (num_front+1, k, j, 0) ;
00456         yabs = ya_mtbl_un (num_front+1, k, j, 0) ;
00457         zabs = za_mtbl_un (num_front+1, k, j, 0) ;
00458         
00459         source_deux.get_mp()->convert_absolute 
00460                 (xabs, yabs, zabs, air, theta, phi) ;
00461                 
00462         valeur = sint_mtbl_un (num_front+1, k, j, 0) * (
00463 cosp_mtbl_un(num_front+1, k, j, 0)*grad_sol_deux(0).val_point(air, theta, phi)+
00464 sinp_mtbl_un(num_front+1, k, j, 0)*grad_sol_deux(1).val_point(air, theta, phi))+
00465 cost_mtbl_un(num_front+1, k, j, 0)*grad_sol_deux(2).val_point(air, theta, phi);
00466 
00467         limite_un.set(num_front, k, j, 0) = 
00468             boundary_un(num_front, k, j, 0) - valeur ;
00469         }
00470         
00471     double erreur = 0 ;
00472     Tbl diff_un (diffrelmax(sol_un, sol_un_old)) ;
00473     for (int i=num_front+1 ; i<nz_un ; i++)
00474         if (diff_un(i) > erreur)
00475         erreur = diff_un(i) ;
00476     
00477     Tbl diff_deux (diffrelmax(sol_deux, sol_deux_old)) ;
00478     for (int i=num_front+1 ; i<nz_deux ; i++)
00479         if (diff_deux(i) > erreur)
00480         erreur = diff_deux(i) ;
00481     
00482     cout << "Pas " << conte << " : Difference " << erreur << endl ;
00483     conte ++ ;
00484 
00485     if (erreur < precision)
00486         indic = -1 ;
00487     }                   
00488 }
00489 
00490 // Version avec des doubles :
00491 void neumann_binaire (const Cmp& source_un, const Cmp& source_deux, 
00492             double bound_un, double bound_deux, 
00493                 Cmp& sol_un, Cmp& sol_deux, int num_front, 
00494                 double precision) {
00495                 
00496     Valeur boundary_un (source_un.get_mp()->get_mg()->get_angu()) ;
00497     if (bound_un == 0)
00498     boundary_un.annule_hard () ;
00499     else 
00500     boundary_un = bound_un ;
00501     boundary_un.std_base_scal() ;
00502     
00503     Valeur boundary_deux (source_deux.get_mp()->get_mg()->get_angu()) ;
00504     if (bound_deux == 0)
00505     boundary_deux.annule_hard() ;
00506     else
00507     boundary_deux = bound_deux ;
00508     boundary_deux.std_base_scal() ;
00509     
00510     neumann_binaire (source_un, source_deux, boundary_un, boundary_deux, 
00511             sol_un, sol_deux, num_front, precision) ;
00512 }           
00513 void neumann_binaire (const Scalar& source_un, const Scalar& source_deux, 
00514               const Valeur& boundary_un, const Valeur& boundary_deux,
00515               Scalar& sol_un, Scalar& sol_deux, int num_front, 
00516               double precision) {
00517     
00518     // Les verifs sur le mapping :
00519     assert (source_un.get_mp() == sol_un.get_mp()) ;
00520     assert (source_deux.get_mp() == sol_deux.get_mp()) ;
00521 
00522     // Alignement
00523     double orient_un = source_un.get_mp().get_rot_phi() ;
00524     assert ((orient_un==0) || (orient_un==M_PI)) ;
00525     double orient_deux = source_deux.get_mp().get_rot_phi() ;
00526     assert ((orient_deux==0) || (orient_deux==M_PI)) ;
00527     int same_orient = (orient_un==orient_deux) ? 1 : -1 ;
00528 
00529     Valeur limite_un (boundary_un.get_mg()) ;
00530     Valeur limite_deux (boundary_deux.get_mg()) ;
00531     
00532     Scalar sol_un_old (sol_un.get_mp()) ;
00533     Scalar sol_deux_old (sol_deux.get_mp()) ;
00534     
00535     Mtbl xa_mtbl_un (source_un.get_mp().xa) ;
00536     Mtbl ya_mtbl_un (source_un.get_mp().ya) ;
00537     Mtbl za_mtbl_un (source_un.get_mp().za) ;
00538     
00539     Mtbl cost_mtbl_un (source_un.get_mp().cost) ;
00540     Mtbl sint_mtbl_un (source_un.get_mp().sint) ;
00541     Mtbl cosp_mtbl_un (source_un.get_mp().cosp) ;
00542     Mtbl sinp_mtbl_un (source_un.get_mp().sinp) ;
00543 
00544     Mtbl xa_mtbl_deux (source_deux.get_mp().xa) ;
00545     Mtbl ya_mtbl_deux (source_deux.get_mp().ya) ;
00546     Mtbl za_mtbl_deux (source_deux.get_mp().za) ;
00547         
00548     Mtbl cost_mtbl_deux (source_deux.get_mp().cost) ;
00549     Mtbl sint_mtbl_deux (source_deux.get_mp().sint) ;
00550     Mtbl cosp_mtbl_deux (source_deux.get_mp().cosp) ;
00551     Mtbl sinp_mtbl_deux (source_deux.get_mp().sinp) ;
00552 
00553     double xabs, yabs, zabs ;
00554     double air,  theta,  phi ;
00555     double valeur ;
00556      
00557     const Metric_flat& ff_un (source_un.get_mp().flat_met_cart()) ;
00558     const Metric_flat& ff_deux (source_deux.get_mp().flat_met_cart()) ;
00559 
00560     int nbrep_un = boundary_un.get_mg()->get_np(num_front) ;
00561     int nbret_un = boundary_un.get_mg()->get_nt(num_front) ;
00562     int nbrep_deux = boundary_deux.get_mg()->get_np(num_front) ;
00563     int nbret_deux = boundary_deux.get_mg()->get_nt(num_front) ;
00564     
00565     int nz_un = boundary_un.get_mg()->get_nzone() ;
00566     int nz_deux = boundary_deux.get_mg()->get_nzone() ;
00567     
00568     // Initialisation des CL :
00569     limite_un = 1 ;
00570     limite_deux = 2 ;
00571     Scalar der_un (sol_un.dsdr()) ;
00572     Scalar der_deux (sol_deux.dsdr()) ;
00573     
00574     for (int k=0 ; k<nbrep_un ; k++)
00575     for (int j=0 ; j<nbret_un ; j++)
00576         limite_un.set(num_front, k, j, 0) =
00577         der_un.get_spectral_va().val_point_jk(num_front+1, -1, j, k) ;
00578     limite_un.set_base (boundary_un.base) ;
00579 
00580     for (int k=0 ; k<nbrep_deux ; k++)
00581     for (int j=0 ; j<nbret_deux ; j++)
00582       limite_deux.set(num_front, k, j, 0) =
00583         der_deux.get_spectral_va().val_point_jk(num_front+1, -1, j, k) ;
00584     limite_deux.set_base (boundary_deux.base) ;
00585     
00586     int conte = 0 ;
00587     int indic = 1 ;
00588     
00589     while (indic==1) {
00590 
00591     sol_un_old = sol_un ;
00592     sol_deux_old = sol_deux ;
00593     
00594     sol_un = source_un.poisson_neumann(limite_un, num_front) ;
00595     sol_deux = source_deux.poisson_neumann(limite_deux, num_front) ;
00596     
00597     // On veut les derivees de l'un sur l'autre :
00598     Scalar copie_un (sol_un) ;
00599     Vector grad_sol_un (copie_un.derive_cov(ff_un)) ;
00600     grad_sol_un.dec_dzpuis(2) ;
00601     grad_sol_un.set(1) = grad_sol_un(1)*same_orient ;
00602     grad_sol_un.set(2) = grad_sol_un(2)*same_orient ;
00603     
00604     
00605     for (int k=0 ; k<nbrep_deux ; k++)
00606         for (int j=0 ; j<nbret_deux ; j++) {
00607         xabs = xa_mtbl_deux (num_front+1, k, j, 0) ;
00608         yabs = ya_mtbl_deux (num_front+1, k, j, 0) ;
00609         zabs = za_mtbl_deux (num_front+1, k, j, 0) ;
00610         
00611         source_un.get_mp().convert_absolute 
00612                 (xabs, yabs, zabs, air, theta, phi) ;
00613                 
00614         valeur = sint_mtbl_deux (num_front+1, k, j, 0) * (
00615 cosp_mtbl_deux(num_front+1, k, j, 0)*grad_sol_un(1).val_point(air, theta, phi)+
00616 sinp_mtbl_deux(num_front+1, k, j, 0)*grad_sol_un(2).val_point(air, theta, phi))+
00617 cost_mtbl_deux(num_front+1, k, j, 0)*grad_sol_un(3).val_point(air, theta, phi);
00618 
00619         limite_deux.set(num_front, k, j, 0) = 
00620             boundary_deux(num_front, k, j, 0) - valeur ;
00621         }
00622      
00623     Scalar copie_deux (sol_deux) ;
00624     Vector grad_sol_deux (copie_deux.derive_cov(ff_deux)) ;
00625     grad_sol_deux.dec_dzpuis(2) ;
00626     grad_sol_deux.set(1) = grad_sol_deux(1)*same_orient ;
00627     grad_sol_deux.set(2) = grad_sol_deux(2)*same_orient ;
00628     
00629     for (int k=0 ; k<nbrep_un ; k++)
00630         for (int j=0 ; j<nbret_un ; j++) {
00631         xabs = xa_mtbl_un (num_front+1, k, j, 0) ;
00632         yabs = ya_mtbl_un (num_front+1, k, j, 0) ;
00633         zabs = za_mtbl_un (num_front+1, k, j, 0) ;
00634         
00635         source_deux.get_mp().convert_absolute 
00636                 (xabs, yabs, zabs, air, theta, phi) ;
00637                 
00638         valeur = sint_mtbl_un (num_front+1, k, j, 0) * (
00639 cosp_mtbl_un(num_front+1, k, j, 0)*grad_sol_deux(1).val_point(air, theta, phi)+
00640 sinp_mtbl_un(num_front+1, k, j, 0)*grad_sol_deux(2).val_point(air, theta, phi))+
00641 cost_mtbl_un(num_front+1, k, j, 0)*grad_sol_deux(3).val_point(air, theta, phi);
00642 
00643 
00644                 
00645         limite_un.set(num_front, k, j, 0) = 
00646             boundary_un(num_front, k, j, 0) - valeur ;
00647         }
00648         
00649     double erreur = 0 ;
00650     Tbl diff_un (diffrelmax(sol_un, sol_un_old)) ;
00651     for (int i=num_front+1 ; i<nz_un ; i++)
00652         if (diff_un(i) > erreur)
00653         erreur = diff_un(i) ;
00654     
00655     Tbl diff_deux (diffrelmax(sol_deux, sol_deux_old)) ;
00656     for (int i=num_front+1 ; i<nz_deux ; i++)
00657         if (diff_deux(i) > erreur)
00658         erreur = diff_deux(i) ;
00659     
00660     cout << "Pas " << conte << " : Difference " << erreur << endl ;
00661     conte ++ ;
00662     
00663     Scalar source1 (source_un) ;
00664     Scalar solution1 (sol_un) ;
00665 
00666 //  maxabs(solution1.laplacian() - source1,
00667 //         "Absolute error in the resolution of the equation for psi") ;  
00668 
00669     if (erreur < precision)
00670         indic = -1 ;
00671     }                   
00672 }

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