sol_elliptic.C

00001 /*
00002  *   Copyright (c) 2003 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 version 2
00008  *   as published by the Free Software Foundation.
00009  *
00010  *   LORENE is distributed in the hope that it will be useful,
00011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  *   GNU General Public License for more details.
00014  *
00015  *   You should have received a copy of the GNU General Public License
00016  *   along with LORENE; if not, write to the Free Software
00017  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00018  *
00019  */
00020 
00021 char sol_elliptic_C[] = "$Header: /cvsroot/Lorene/C++/Source/Non_class_members/PDE/sol_elliptic.C,v 1.8 2008/07/10 11:20:33 p_grandclement Exp $" ;
00022 
00023 /*
00024  * $Id: sol_elliptic.C,v 1.8 2008/07/10 11:20:33 p_grandclement Exp $
00025  * $Log: sol_elliptic.C,v $
00026  * Revision 1.8  2008/07/10 11:20:33  p_grandclement
00027  * mistake fixed in solh_helmholtz_minus
00028  *
00029  * Revision 1.7  2008/07/09 06:51:58  p_grandclement
00030  * some corrections to helmholtz minus in the nucleus
00031  *
00032  * Revision 1.6  2005/01/25 15:44:20  j_novak
00033  * Fixed a problem in the definition of nr at the end.
00034  *
00035  * Revision 1.5  2004/11/25 08:14:56  j_novak
00036  * Modifs. comments
00037  *
00038  * Revision 1.4  2004/08/24 09:14:44  p_grandclement
00039  * Addition of some new operators, like Poisson in 2d... It now requieres the
00040  * GSL library to work.
00041  *
00042  * Also, the way a variable change is stored by a Param_elliptic is changed and
00043  * no longer uses Change_var but rather 2 Scalars. The codes using that feature
00044  * will requiere some modification. (It should concern only the ones about monopoles)
00045  *
00046  * Revision 1.3  2004/05/26 20:32:44  p_grandclement
00047  * utilisation of val_r_jk
00048  *
00049  * Revision 1.2  2003/12/19 16:21:49  j_novak
00050  * Shadow hunt
00051  *
00052  * Revision 1.1  2003/12/11 14:48:49  p_grandclement
00053  * Addition of ALL (and that is a lot !) the files needed for the general elliptic solver ... UNDER DEVELOPEMENT...
00054  *
00055  * 
00056  * $Header: /cvsroot/Lorene/C++/Source/Non_class_members/PDE/sol_elliptic.C,v 1.8 2008/07/10 11:20:33 p_grandclement Exp $
00057  *
00058  */
00059 
00060 // Header C : 
00061 #include <stdlib.h>
00062 #include <math.h>
00063 
00064 // Headers Lorene :
00065 #include "param_elliptic.h"
00066 #include "tbl.h"
00067 #include "mtbl_cf.h"
00068 #include "map.h"
00069           
00070  
00071         //----------------------------------------------
00072        //       Version Mtbl_cf
00073       //----------------------------------------------
00074 
00075 
00076 
00077 Mtbl_cf elliptic_solver  (const Param_elliptic& ope_var, const Mtbl_cf& source) {
00078   // Verifications d'usage sur les zones
00079   int nz = source.get_mg()->get_nzone() ;
00080   assert (nz>1) ;
00081   assert (source.get_mg()->get_type_r(0) == RARE) ;
00082   assert (source.get_mg()->get_type_r(nz-1) == UNSURR) ;
00083   for (int l=1 ; l<nz-1 ; l++)
00084     assert(source.get_mg()->get_type_r(l) == FIN) ;
00085    
00086   // donnees sur la zone
00087   int nr, nt, np ;
00088   
00089   //Rangement des valeurs intermediaires 
00090   Tbl *so ;
00091   Tbl *sol_hom ;
00092   Tbl *sol_part ;
00093    
00094   
00095   // Rangement des solutions, avant raccordement
00096   Mtbl_cf solution_part(source.get_mg(), source.base) ;
00097   Mtbl_cf solution_hom_un(source.get_mg(), source.base) ;
00098   Mtbl_cf solution_hom_deux(source.get_mg(), source.base) ;
00099   Mtbl_cf resultat(source.get_mg(), source.base) ;
00100 
00101   solution_part.annule_hard() ;
00102   solution_hom_un.annule_hard() ;
00103   solution_hom_deux.annule_hard() ;
00104   resultat.annule_hard() ;
00105 
00106   // Computation of the SP and SH's in every domain ...
00107   int conte = 0 ;
00108   for (int zone=0 ; zone<nz ; zone++) {
00109 
00110     nr = source.get_mg()->get_nr(zone) ;
00111     nt = source.get_mg()->get_nt(zone) ;
00112     np = source.get_mg()->get_np(zone) ;
00113 
00114     for (int k=0 ; k<np+1 ; k++)
00115       for (int j=0 ; j<nt ; j++) {
00116 
00117     if (ope_var.operateurs[conte] != 0x0) {
00118 
00119       // Calcul de la SH
00120       sol_hom = new Tbl(ope_var.operateurs[conte]->get_solh()) ;
00121       
00122       //Calcul de la SP
00123       so = new Tbl(nr) ;
00124       so->set_etat_qcq() ;
00125       for (int i=0 ; i<nr ; i++)
00126         so->set(i) = source(zone, k, j, i) ;
00127       
00128       sol_part = new Tbl(ope_var.operateurs[conte]->get_solp(*so)) ;
00129       
00130       // Rangement dans les tableaux globaux ;
00131       for (int i=0 ; i<nr ; i++) {
00132         solution_part.set(zone, k, j, i) = (*sol_part)(i) ;
00133         if (sol_hom->get_ndim()==1)
00134           solution_hom_un.set(zone, k, j, i) = (*sol_hom)(i) ;
00135         else
00136           {
00137         solution_hom_un.set(zone, k, j, i) = (*sol_hom)(0,i) ;
00138         solution_hom_deux.set(zone, k, j, i) = (*sol_hom)(1,i) ;
00139           }
00140       }
00141       
00142       delete so ;
00143       delete sol_hom ;
00144       delete sol_part ;
00145       
00146     }
00147     conte ++ ;
00148       }
00149   }
00150 
00151 
00152   //-------------------------------------------------
00153   // ON EST PARTI POUR LE RACCORD (Be carefull ....)
00154   //-------------------------------------------------
00155   
00156   // C'est pas simple toute cette sombre affaire...
00157   // Que le cas meme nombre de points dans chaque domaines...
00158 
00159   int start = 0 ;
00160   for (int k=0 ; k<source.get_mg()->get_np(0)+1 ; k++)
00161     for (int j=0 ; j<source.get_mg()->get_nt(0) ; j++) {
00162       if (ope_var.operateurs[start] != 0x0) {
00163     
00164     int taille = 2*nz - 2 ;
00165     Matrice systeme (taille, taille) ;
00166     systeme.set_etat_qcq() ;
00167     for (int i=0 ; i<taille ; i++)
00168       for (int j2=0 ; j2<taille ; j2++)
00169         systeme.set(i,j2) = 0 ;
00170     Tbl sec_membre (taille) ;
00171     sec_membre.set_etat_qcq() ;
00172     for (int i=0 ; i<taille ; i++)
00173       sec_membre.set(i) = 0 ;
00174     
00175     //---------
00176     //  Noyau :
00177     //---------
00178     conte = start ;
00179 
00180     systeme.set(0,0) = ope_var.G_plus(0) * 
00181       ope_var.operateurs[conte]->val_sh_one_plus() ;
00182     systeme.set(1,0) = 
00183       ope_var.dG_plus(0) * ope_var.operateurs[conte]->val_sh_one_plus() +  
00184       ope_var.G_plus(0) * ope_var.operateurs[conte]->der_sh_one_plus() ;
00185     
00186     sec_membre.set(0) -= ope_var.F_plus(0,k,j) + 
00187       ope_var.G_plus(0) * ope_var.operateurs[conte]->val_sp_plus() ;
00188     sec_membre.set(1) -= ope_var.dF_plus(0,k,j) + 
00189       ope_var.dG_plus(0) * ope_var.operateurs[conte]->val_sp_plus() + 
00190       ope_var.G_plus(0) * ope_var.operateurs[conte]->der_sp_plus() ;
00191     
00192     //----------
00193     // SHELLS :
00194     //----------
00195     
00196     for (int l=1 ; l<nz-1 ; l++) {
00197       
00198       // On se met au bon endroit :
00199       int np_prec = source.get_mg()->get_np(l-1) ;
00200       int nt_prec = source.get_mg()->get_nt(l-1) ;
00201       conte += (np_prec+1)*nt_prec ;
00202          
00203       systeme.set(2*l-2, 2*l-1) = -ope_var.G_minus(l) * 
00204         ope_var.operateurs[conte]->val_sh_one_minus() ;
00205       systeme.set(2*l-2, 2*l) = - ope_var.G_minus(l) * 
00206         ope_var.operateurs[conte]->val_sh_two_minus() ;
00207       systeme.set(2*l-1, 2*l-1) = 
00208         -ope_var.dG_minus(l)*ope_var.operateurs[conte]->val_sh_one_minus()-  
00209         ope_var.G_minus(l)*ope_var.operateurs[conte]->der_sh_one_minus() ;
00210       systeme.set(2*l-1, 2*l) =
00211         -ope_var.dG_minus(l)*ope_var.operateurs[conte]->val_sh_two_minus()-  
00212         ope_var.G_minus(l)*ope_var.operateurs[conte]->der_sh_two_minus() ;
00213       
00214       sec_membre.set(2*l-2) += ope_var.F_minus(l,k,j) + 
00215         ope_var.G_minus(l) * ope_var.operateurs[conte]->val_sp_minus() ;
00216       sec_membre.set(2*l-1) += ope_var.dF_minus(l,k,j) + 
00217         ope_var.dG_minus(l) * ope_var.operateurs[conte]->val_sp_minus() + 
00218         ope_var.G_minus(l) * ope_var.operateurs[conte]->der_sp_minus() ;
00219       
00220       // Valeurs en +1 :
00221       systeme.set(2*l, 2*l-1) = ope_var.G_plus(l) * 
00222         ope_var.operateurs[conte]->val_sh_one_plus() ;
00223       systeme.set(2*l, 2*l) = ope_var.G_plus(l) * 
00224         ope_var.operateurs[conte]->val_sh_two_plus() ;
00225       systeme.set(2*l+1, 2*l-1) = 
00226         ope_var.dG_plus(l)*ope_var.operateurs[conte]->val_sh_one_plus()+  
00227         ope_var.G_plus(l)*ope_var.operateurs[conte]->der_sh_one_plus() ;
00228       systeme.set(2*l+1, 2*l) =
00229         ope_var.dG_plus(l)*ope_var.operateurs[conte]->val_sh_two_plus()+
00230         ope_var.G_plus(l)*ope_var.operateurs[conte]->der_sh_two_plus() ;
00231       
00232       sec_membre.set(2*l) -=  ope_var.F_plus(l,k,j) + 
00233         ope_var.G_plus(l) * ope_var.operateurs[conte]->val_sp_plus();
00234       sec_membre.set(2*l+1) -=  ope_var.dF_plus(l,k,j) + 
00235         ope_var.dG_plus(l) * ope_var.operateurs[conte]->val_sp_plus() + 
00236         ope_var.G_plus(l) * ope_var.operateurs[conte]->der_sp_plus() ;
00237     }
00238     
00239     //-------
00240     // ZEC :
00241     //-------
00242     int np_prec = source.get_mg()->get_np(nz-2) ;
00243     int nt_prec = source.get_mg()->get_nt(nz-2) ;
00244     conte += (np_prec+1)*nt_prec ;
00245     
00246     systeme.set(taille-2, taille-1) = -ope_var.G_minus(nz-1) * 
00247       ope_var.operateurs[conte]->val_sh_one_minus() ;
00248     systeme.set(taille-1, taille-1) = 
00249       -ope_var.dG_minus(nz-1)*ope_var.operateurs[conte]->val_sh_one_minus()-  
00250       ope_var.G_minus(nz-1)*ope_var.operateurs[conte]->der_sh_one_minus()  ;
00251     
00252     sec_membre.set(taille-2) += ope_var.F_minus(nz-1,k,j) + 
00253       ope_var.G_minus(nz-1)*ope_var.operateurs[conte]->val_sp_minus() ;
00254     sec_membre.set(taille-1) += ope_var.dF_minus(nz-1,k,j) + 
00255       ope_var.dG_minus(nz-1) * ope_var.operateurs[conte]->val_sp_minus() + 
00256       ope_var.G_minus(nz-1) * ope_var.operateurs[conte]->der_sp_minus() ;
00257     
00258     // On resout le systeme ...
00259     if (taille > 2)
00260       systeme.set_band(2,2) ;
00261     else
00262       systeme.set_band(1,1) ;
00263     
00264     systeme.set_lu() ;
00265     Tbl facteur (systeme.inverse(sec_membre)) ;
00266 
00267     // On range tout ca :
00268     // Noyau 
00269     nr = source.get_mg()->get_nr(0) ;
00270     for (int i=0 ; i<nr ; i++)
00271       resultat.set(0,k,j,i) = solution_part(0,k,j,i) +facteur(0)*solution_hom_un(0,k,j,i) ;
00272 
00273     // Shells
00274     for (int l=1 ; l<nz-1 ; l++) {
00275       nr = source.get_mg()->get_nr(l) ;
00276       for (int i=0 ; i<nr ; i++)
00277         resultat.set(l,k,j,i) = solution_part(l,k,j,i) + 
00278           facteur(2*l-1)*solution_hom_un(l,k,j,i) +
00279           facteur(2*l)*solution_hom_deux(l,k,j,i) ;
00280     }
00281     
00282     // Zec
00283     nr = source.get_mg()->get_nr(nz-1) ;
00284     for (int i=0 ; i<nr ; i++)
00285       resultat.set(nz-1,k,j,i) = solution_part(nz-1,k,j,i) + 
00286         facteur(taille-1)*solution_hom_un(nz-1,k,j,i) ;
00287       }
00288     start ++ ;
00289       }
00290     
00291   return resultat;
00292 }
00293 

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