helmholtz_minus_mat.C

00001 /*
00002  *   Copyright (c) 1999-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 helmholtz_minus_mat_C[] = "$$" ;
00024 
00025 /*
00026  * $Id: helmholtz_minus_mat.C,v 1.6 2008/07/09 06:51:58 p_grandclement Exp $
00027  * $Log: helmholtz_minus_mat.C,v $
00028  * Revision 1.6  2008/07/09 06:51:58  p_grandclement
00029  * some corrections to helmholtz minus in the nucleus
00030  *
00031  * Revision 1.5  2008/07/08 11:45:28  p_grandclement
00032  * Add helmholtz_minus in the nucleus
00033  *
00034  * Revision 1.4  2004/08/24 09:14:44  p_grandclement
00035  * Addition of some new operators, like Poisson in 2d... It now requieres the
00036  * GSL library to work.
00037  *
00038  * Also, the way a variable change is stored by a Param_elliptic is changed and
00039  * no longer uses Change_var but rather 2 Scalars. The codes using that feature
00040  * will requiere some modification. (It should concern only the ones about monopoles)
00041  *
00042  * Revision 1.3  2004/01/15 09:15:37  p_grandclement
00043  * Modification and addition of the Helmholtz operators
00044  *
00045  * Revision 1.2  2003/12/11 15:57:26  p_grandclement
00046  * include stdlib.h encore ...
00047  *
00048  * Revision 1.1  2003/12/11 14:48:49  p_grandclement
00049  * Addition of ALL (and that is a lot !) the files needed for the general elliptic solver ... UNDER DEVELOPEMENT...
00050  *
00051  * 
00052  * $Header: /cvsroot/Lorene/C++/Source/Non_class_members/PDE/helmholtz_minus_mat.C,v 1.6 2008/07/09 06:51:58 p_grandclement Exp $
00053  *
00054  */
00055 #include <stdlib.h>
00056 
00057 #include "matrice.h"
00058 #include "type_parite.h"
00059 #include "proto.h"
00060 #include "diff.h"
00061 
00062                      //-----------------------------------
00063                      // Routine pour les cas non prevus -- 
00064                      //-----------------------------------
00065 
00066 Matrice _helmholtz_minus_mat_pas_prevu(int, int, double, double, double) {
00067   cout << "Helmholtz minus : base not implemented..." << endl ;
00068   abort() ;
00069   exit(-1) ;
00070   Matrice res(1, 1) ;
00071   return res;
00072 }
00073 
00074                     //-------------------------
00075             //--   CAS R_CHEBU    -----
00076             //------------------------
00077 
00078 Matrice _helmholtz_minus_mat_r_chebu (int n, int lq, double alpha, 
00079                       double, double masse) {
00080 
00081   assert (masse > 0) ;
00082 
00083   Matrice res(n-2, n-2) ;
00084   res.set_etat_qcq() ;
00085   
00086   double* vect = new double[n] ;
00087   double* vect_bis = new double[n] ;
00088   double* vect_dd = new double[n] ;
00089   
00090   for (int i=0 ; i<n-2 ; i++) {
00091     
00092     for (int j=0 ; j<n ; j++)
00093       vect[j] = 0 ;
00094     vect[i] = 2*i+3 ;
00095     vect[i+1] = -4*i-4 ;
00096     vect[i+2] = 2*i+1 ;
00097     
00098     for (int j=0 ; j<n ; j++)
00099       vect_bis[j] = vect[j] ;
00100     
00101     d2sdx2_1d (n, &vect_bis, R_CHEBU) ;  // appel dans le cas unsurr
00102     mult2_xm1_1d_cheb (n, vect_bis, vect_dd) ; // multiplication par (x-1)^2
00103    
00104     // Mass term
00105     for (int j=0 ; j<n ; j++)
00106       vect_bis[j] = vect[j] ;
00107     sx2_1d (n, &vect_bis, R_CHEBU) ;
00108     
00109     for (int j=0 ; j<n-2 ; j++)
00110       res.set(j,i) = vect_dd[j] - lq*(lq+1)*vect[j] 
00111     - masse*masse*vect_bis[j]/alpha/alpha ;
00112   }
00113   
00114   delete [] vect ;
00115   delete [] vect_bis ;
00116   delete [] vect_dd ;
00117 
00118   return res ;
00119 }
00120 
00121 
00122                     //-------------------------
00123             //--   CAS R_CHEB   -----
00124             //------------------------
00125 
00126 Matrice _helmholtz_minus_mat_r_cheb (int n, int lq, double alpha, double beta, 
00127                      double masse) {
00128 
00129   assert (masse > 0) ;
00130        
00131   double echelle = beta / alpha ;
00132     
00133   Matrice dd(n, n) ;
00134   dd.set_etat_qcq() ;
00135   Matrice xd(n, n) ;
00136   xd.set_etat_qcq() ;  
00137   Matrice xx(n, n) ;
00138   xx.set_etat_qcq() ;
00139   
00140   double* vect = new double[n] ;
00141   
00142   for (int i=0 ; i<n ; i++) {
00143     for (int j=0 ; j<n ; j++)
00144       vect[j] = 0 ;
00145     vect[i] = 1 ;
00146     d2sdx2_1d (n, &vect, R_CHEB) ;  // appel dans le cas fin
00147     vect[i] -= masse*masse*alpha*alpha ;
00148     for (int j=0 ; j<n ; j++)
00149       dd.set(j, i) = vect[j]*echelle*echelle ;
00150   }
00151   
00152   for (int i=0 ; i<n ; i++) {
00153     for (int j=0 ; j<n ; j++)
00154       vect[j] = 0 ;
00155     vect[i] = 1 ;
00156     d2sdx2_1d (n, &vect, R_CHEB) ;  // appel dans le cas fin
00157     vect[i] -= masse*masse*alpha*alpha ;
00158     multx_1d (n, &vect, R_CHEB) ;
00159     for (int j=0 ; j<n ; j++)
00160       dd.set(j, i) += 2*echelle*vect[j] ;
00161   }
00162   
00163   for (int i=0 ; i<n ; i++) {
00164     for (int j=0 ; j<n ; j++)
00165       vect[j] = 0 ;
00166     vect[i] = 1 ;
00167     d2sdx2_1d (n, &vect, R_CHEB) ;  // appel dans le cas fin
00168     vect[i] -= masse*masse*alpha*alpha ;
00169     multx_1d (n, &vect, R_CHEB) ;
00170     multx_1d (n, &vect, R_CHEB) ;
00171     for (int j=0 ; j<n ; j++)
00172       dd.set(j, i) += vect[j] ;
00173   }
00174   
00175   for (int i=0 ; i<n ; i++) {
00176     for (int j=0 ; j<n ; j++)
00177       vect[j] = 0 ;
00178     vect[i] = 1 ;
00179     sxdsdx_1d (n, &vect, R_CHEB) ;
00180     for (int j=0 ; j<n ; j++)
00181       xd.set(j, i) = vect[j]*echelle ;
00182   }
00183   
00184   for (int i=0 ; i<n ; i++) {
00185     for (int j=0 ; j<n ; j++)
00186       vect[j] = 0 ;
00187     vect[i] = 1 ;
00188     sxdsdx_1d (n, &vect, R_CHEB) ;
00189     multx_1d (n, &vect, R_CHEB) ;
00190     for (int j=0 ; j<n ; j++)
00191       xd.set(j, i) += vect[j] ;
00192   }
00193   
00194     for (int i=0 ; i<n ; i++) {
00195       for (int j=0 ; j<n ; j++)
00196     vect[j] = 0 ;
00197       vect[i] = 1 ;
00198       sx2_1d (n, &vect, R_CHEB) ;
00199       for (int j=0 ; j<n ; j++)
00200     xx.set(j, i) = vect[j] ;
00201     }
00202 
00203   delete [] vect ;
00204   
00205   Matrice res(n, n) ;
00206   res = dd+2*xd - lq*(lq+1)*xx; 
00207   
00208   return res ;
00209 }
00210 
00211 
00212            //-------------------------
00213            //--   CAS R_CHEBP    -----
00214            //--------------------------
00215             
00216 
00217 Matrice _helmholtz_minus_mat_r_chebp (int n, int lq, double alpha, double, double masse) {
00218    
00219     if (lq==0) {
00220     Diff_dsdx2 d2(R_CHEBP, n) ;
00221         Diff_sxdsdx sxd(R_CHEBP, n) ;
00222         Diff_id xx (R_CHEBP, n) ;
00223     
00224         return Matrice(d2 + 2.*sxd -masse*masse*alpha*alpha*xx) ;
00225     }
00226     else {
00227           Matrice res(n-1, n-1) ;
00228           res.set_etat_qcq() ;
00229   
00230               double* vect = new double[n] ;
00231  
00232               double* vect_sx2 = new double[n] ;
00233           double* vect_sxd = new double[n] ;
00234               double* vect_dd = new double[n] ;
00235   
00236          for (int i=0 ; i<n-1 ; i++) {
00237             for (int j=0 ; j<n ; j++)
00238                 vect[j] = 0 ;
00239             vect[i] = 1. ;
00240             vect[i+1] = 1. ;
00241     
00242         
00243             for (int j=0 ; j<n ; j++)
00244                  vect_dd[j] = vect[j] ;
00245             d2sdx2_1d (n, &vect_dd, R_CHEBP) ;  // appel dans le cas chebp
00246         for (int j=0 ; j<n ; j++)
00247                  vect_sxd[j] = vect[j] ;
00248             sxdsdx_1d (n, &vect_sxd, R_CHEBP) ;  // appel dans le cas chebp
00249         for (int j=0 ; j<n ; j++)
00250                  vect_sx2[j] = vect[j] ;
00251             sx2_1d (n, &vect_sx2, R_CHEBP) ;  // appel dans le cas chebp
00252         
00253      for (int j=0 ; j<n-1 ; j++)
00254         res.set(j,i) = vect_dd[j] +2*vect_sxd[j] - lq*(lq+1)*vect_sx2[j] - masse*masse*alpha*alpha*vect[j] ;
00255      }
00256         delete [] vect ;
00257         delete [] vect_sx2 ;
00258         delete [] vect_sxd ;
00259         delete [] vect_dd ;
00260 
00261       return res ;
00262     }
00263 }
00264 
00265 
00266 
00267            //------------------------
00268            //--   CAS R_CHEBI    ----
00269            //------------------------
00270             
00271 
00272 Matrice _helmholtz_minus_mat_r_chebi (int n, int lq, double alpha, double, double masse) {
00273    
00274   if (lq==1) {
00275     Diff_dsdx2 d2(R_CHEBI, n) ;
00276     Diff_sxdsdx sxd(R_CHEBI, n) ;
00277     Diff_sx2 sx2(R_CHEBI, n) ;
00278     Diff_id xx(R_CHEBI, n) ;
00279 
00280     return Matrice(d2 + 2.*sxd - (lq*(lq+1))*sx2- masse*masse*alpha*alpha*xx) ;
00281    }
00282     else {
00283           Matrice res(n-1, n-1) ;
00284           res.set_etat_qcq() ;
00285   
00286               double* vect = new double[n] ;
00287  
00288               double* vect_sx2 = new double[n] ;
00289           double* vect_sxd = new double[n] ;
00290               double* vect_dd = new double[n] ;
00291   
00292          for (int i=0 ; i<n-1 ; i++) {
00293             for (int j=0 ; j<n ; j++)
00294                 vect[j] = 0 ;
00295             vect[i] = (2*i+3) ;
00296             vect[i+1] = (2*i+1) ;
00297     
00298         
00299             for (int j=0 ; j<n ; j++)
00300                  vect_dd[j] = vect[j] ;
00301             d2sdx2_1d (n, &vect_dd, R_CHEBI) ;  // appel dans le cas chebi
00302         for (int j=0 ; j<n ; j++)
00303                  vect_sxd[j] = vect[j] ;
00304             sxdsdx_1d (n, &vect_sxd, R_CHEBI) ;  // appel dans le cas chebi
00305         for (int j=0 ; j<n ; j++)
00306                  vect_sx2[j] = vect[j] ;
00307             sx2_1d (n, &vect_sx2, R_CHEBI) ;  // appel dans le cas chebi
00308         
00309      for (int j=0 ; j<n-1 ; j++)
00310         res.set(j,i) = vect_dd[j] +2*vect_sxd[j] - lq*(lq+1)*vect_sx2[j] - masse*masse*alpha*alpha*vect[j] ;
00311      }
00312         delete [] vect ;
00313         delete [] vect_sx2 ;
00314         delete [] vect_sxd ;
00315         delete [] vect_dd ;
00316 
00317       return res ;
00318     }
00319 }
00320 
00321 
00322     
00323                 //--------------------------
00324         //- La routine a appeler  ---
00325             //----------------------------
00326 
00327 Matrice helmholtz_minus_mat(int n, int lq, 
00328                 double alpha, double beta, double masse, 
00329                 int base_r)
00330 {
00331   
00332   // Routines de derivation
00333   static Matrice (*helmholtz_minus_mat[MAX_BASE])(int, int, 
00334                           double, double, double);
00335   static int nap = 0 ;
00336   
00337   // Premier appel
00338   if (nap==0) {
00339     nap = 1 ;
00340     for (int i=0 ; i<MAX_BASE ; i++) {
00341       helmholtz_minus_mat[i] = _helmholtz_minus_mat_pas_prevu ;
00342     }
00343     // Les routines existantes
00344     helmholtz_minus_mat[R_CHEB >> TRA_R] = _helmholtz_minus_mat_r_cheb ;
00345     helmholtz_minus_mat[R_CHEBU >> TRA_R] = _helmholtz_minus_mat_r_chebu ;  
00346     helmholtz_minus_mat[R_CHEBP >> TRA_R] = _helmholtz_minus_mat_r_chebp ;
00347     helmholtz_minus_mat[R_CHEBI >> TRA_R] = _helmholtz_minus_mat_r_chebi ;
00348   }
00349   
00350   Matrice res(helmholtz_minus_mat[base_r](n, lq, alpha, beta, masse)) ;
00351   return res ;
00352 }
00353 

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