ope_sec_order_solh.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 ope_sec_order_solh_C[] = "$Header: /cvsroot/Lorene/C++/Source/Ope_elementary/Ope_sec_order/ope_sec_order_solh.C,v 1.2 2005/02/18 13:14:18 j_novak Exp $" ;
00022 
00023 /*
00024  * $Id: ope_sec_order_solh.C,v 1.2 2005/02/18 13:14:18 j_novak Exp $
00025  * $Header: /cvsroot/Lorene/C++/Source/Ope_elementary/Ope_sec_order/ope_sec_order_solh.C,v 1.2 2005/02/18 13:14:18 j_novak Exp $
00026  *
00027  */
00028 #include <math.h>
00029 #include <stdlib.h>
00030 
00031 #include "proto.h"
00032 #include "ope_elementary.h"
00033 
00034             //------------------------------------
00035         // Routine pour les cas non prevus --
00036         //------------------------------------
00037 Tbl _solh_sec_order_pas_prevu (int, double, double,double,double,double,Tbl&) {
00038 
00039   cout << "Homogeneous solution not implemented in Sec_order : "<< endl ;
00040   abort() ;
00041   exit(-1) ;
00042   Tbl res(1) ;
00043   return res;
00044 }
00045 
00046     
00047         //-------------------
00048            //--  R_CHEB   ------
00049           //-------------------
00050 
00051 Tbl _solh_sec_order_r_cheb (int n, double alpha, double beta, 
00052                    double a, double b, double c, Tbl& val_lim) {
00053 
00054   // Stuff to compute the coefs...
00055   Tbl res(2,n) ;
00056   res.set_etat_qcq() ;
00057   double* coloc = new double[n] ;
00058     
00059   int * deg = new int[3] ;
00060   deg[0] = 1 ; 
00061   deg[1] = 1 ;
00062   deg[2] = n ;
00063   
00064   // Array on the radius 
00065   double* sigma = new double[n] ;
00066   for (int i=0 ; i<n ; i++)
00067     sigma[i] = alpha*(-cos(M_PI*i/(n-1))) + beta ;
00068 
00069   double sigma_minus = beta-alpha ;
00070   double sigma_plus  = beta+alpha ;
00071 
00072   // Determinant :
00073   double delta = b*b-4*a*c ;
00074   int signe = 0 ;
00075   if (delta > 0)
00076     signe = + 1 ;
00077   if (delta < 0)
00078     signe = -1 ;
00079   if (fabs(delta) < 1e-14)
00080     signe = 0 ;
00081 
00082   switch (signe) {
00083     
00084   case 1: {
00085     // Two real solutions
00086     double lambda_one = (-b + sqrt(delta)) / 2./a ;
00087     double lambda_two = (-b - sqrt(delta)) / 2./a ;
00088 
00089     // First SH
00090     for (int i=0 ; i<n ; i++)
00091       coloc[i] = exp(sigma[i]*lambda_one) ;
00092     cfrcheb(deg, deg, coloc, deg, coloc) ;
00093     for (int i=0 ; i<n ;i++)
00094       res.set(0,i) = coloc[i] ;
00095 
00096     // Second SH
00097     for (int i=0 ; i<n ; i++)
00098       coloc[i] = exp(sigma[i]*lambda_two) ;
00099     cfrcheb(deg, deg, coloc, deg, coloc) ;
00100     for (int i=0 ; i<n ;i++)
00101       res.set(1,i) = coloc[i] ;
00102     
00103     // Limit on the boundaries :
00104     val_lim.set(0,0) = exp(sigma_minus*lambda_one) ;
00105     val_lim.set(0,1) = lambda_one*exp(sigma_minus*lambda_one)
00106       /exp(sigma_minus) ;
00107     val_lim.set(0,2) = exp(sigma_plus*lambda_one) ;
00108     val_lim.set(0,3) = lambda_one*exp(sigma_plus*lambda_one)
00109       /exp(sigma_plus) ;
00110 
00111     val_lim.set(1,0) = exp(sigma_minus*lambda_two) ;
00112     val_lim.set(1,1) = lambda_two*exp(sigma_minus*lambda_two)/
00113       exp(sigma_minus);
00114     val_lim.set(1,2) = exp(sigma_plus*lambda_two) ;
00115     val_lim.set(1,3) = lambda_two*exp(sigma_plus*lambda_two)
00116       /exp(sigma_plus) ;
00117     val_lim /= sqrt(double(2)) ;
00118     break ;
00119   }
00120   case 0: {
00121     // Only one solution :
00122     double lambda = -b/2./a ;
00123     // First SH
00124     for (int i=0 ; i<n ; i++)
00125       coloc[i] = exp(sigma[i]*lambda) ;
00126     cfrcheb(deg, deg, coloc, deg, coloc) ;
00127     for (int i=0 ; i<n ;i++)
00128       res.set(0,i) = coloc[i] ;
00129 
00130     // Second SH
00131     for (int i=0 ; i<n ; i++)
00132       coloc[i] = sigma[i]*exp(sigma[i]*lambda) ;
00133     cfrcheb(deg, deg, coloc, deg, coloc) ;
00134     for (int i=0 ; i<n ;i++)
00135       res.set(1,i) = coloc[i] ; 
00136 
00137     // Limit on the boundaries :
00138     val_lim.set(0,0) = exp(sigma_minus*lambda) ;
00139     val_lim.set(0,1) = lambda*exp(sigma_minus*lambda)/exp(sigma_minus) ;
00140     val_lim.set(0,2) = exp(sigma_plus*lambda) ;
00141     val_lim.set(0,3) = lambda*exp(sigma_plus*lambda)/exp(sigma_plus) ;
00142 
00143     val_lim.set(1,0) = sigma_minus*exp(sigma_minus*lambda) ;
00144     val_lim.set(1,1) = exp(sigma_minus*lambda)* (lambda*sigma_minus+1)
00145       /exp(sigma_minus);
00146     val_lim.set(1,2) = sigma_plus*exp(sigma_plus*lambda) ;
00147     val_lim.set(1,3) =  exp(sigma_plus*lambda)* (lambda*sigma_plus+1)/ 
00148       exp(sigma_plus) ;
00149     val_lim /= sqrt(double(2)) ;
00150     break ;
00151   }
00152   case -1:{
00153     // Two imaginary solutions :
00154     double real_part = -b/2./a ;
00155     double imag_part = sqrt(-delta)/2./a ;
00156 
00157     // First SH
00158     for (int i=0 ; i<n ; i++)
00159       coloc[i] = exp(sigma[i]*real_part)*cos(imag_part*sigma[i]) ;
00160     cfrcheb(deg, deg, coloc, deg, coloc) ;
00161     for (int i=0 ; i<n ;i++)
00162       res.set(0,i) = coloc[i] ;
00163     
00164     // Second SH
00165     for (int i=0 ; i<n ; i++)
00166       coloc[i] = exp(sigma[i]*real_part)*sin(imag_part*sigma[i]) ;
00167     cfrcheb(deg, deg, coloc, deg, coloc) ;
00168     for (int i=0 ; i<n ;i++)
00169       res.set(1,i) = coloc[i] ;
00170 
00171     // Limit on the boundaries :
00172     val_lim.set(0,0) = exp(sigma_minus*real_part)*cos(imag_part*sigma_minus) ;
00173     val_lim.set(0,1) =  (real_part*cos(imag_part*sigma_minus) - 
00174              imag_part*sin(imag_part*sigma_minus)) * exp(real_part*sigma_minus)
00175       /exp(sigma_minus);
00176     val_lim.set(0,2) = exp(sigma_plus*real_part)*cos(imag_part*sigma_plus) ;
00177     val_lim.set(0,3) = (real_part*cos(imag_part*sigma_plus) - 
00178              imag_part*sin(imag_part*sigma_plus)) * exp(real_part*sigma_plus)
00179       /exp(sigma_plus) ;
00180 
00181     val_lim.set(1,0) = exp(sigma_minus*real_part)*sin(imag_part*sigma_minus) ;
00182     val_lim.set(1,1) = (real_part*sin(imag_part*sigma_minus) + 
00183              imag_part*cos(imag_part*sigma_minus)) * exp(real_part*sigma_minus)
00184       /exp(sigma_minus);
00185     val_lim.set(1,2) = exp(sigma_plus*real_part)*sin(imag_part*sigma_plus);
00186     val_lim.set(1,3) = (real_part*sin(imag_part*sigma_plus) + 
00187             imag_part*cos(imag_part*sigma_plus)) * exp(real_part*sigma_plus)
00188       /exp(sigma_plus) ;
00189     val_lim /= sqrt(double(2)) ;
00190     break ;
00191   }
00192   default:
00193     cout << "What are you doing here ? Get out or I call the police !" << endl;
00194     abort() ;
00195     break ;
00196   }
00197 
00198   delete [] deg ;
00199   delete [] coloc ;
00200   delete [] sigma ;
00201 
00202   return res ;
00203 }
00204 
00205 
00206 Tbl Ope_sec_order::get_solh () const {
00207 
00208   // Routines de derivation
00209   static Tbl (*solh_sec_order[MAX_BASE]) (int, double, double,
00210                          double, double, double, Tbl&) ;
00211   static int nap = 0 ;
00212   
00213   // Premier appel
00214   if (nap==0) {
00215     nap = 1 ;
00216     for (int i=0 ; i<MAX_BASE ; i++) {
00217       solh_sec_order[i] = _solh_sec_order_pas_prevu ;
00218     }
00219     // Les routines existantes
00220     solh_sec_order[R_CHEB >> TRA_R] = _solh_sec_order_r_cheb ;
00221   }
00222   
00223   Tbl val_lim (2,4) ;
00224   val_lim.set_etat_qcq() ;
00225   Tbl res(solh_sec_order[base_r](nr,alpha,beta,a_param,b_param,c_param, 
00226                     val_lim)) ;
00227 
00228   s_one_minus  = val_lim(0,0) ;
00229   ds_one_minus = val_lim(0,1) ;
00230   s_one_plus   = val_lim(0,2) ;
00231   ds_one_plus  = val_lim(0,3) ;
00232 
00233   s_two_minus  = val_lim(1,0) ;
00234   ds_two_minus = val_lim(1,1) ;
00235   s_two_plus   = val_lim(1,2) ;
00236   ds_two_plus  = val_lim(1,3) ;
00237 
00238   return res ;
00239 }

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