ope_sec_order_r2_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_r2_solh_C[] = "$Header: /cvsroot/Lorene/C++/Source/Ope_elementary/Ope_sec_order_r2/ope_sec_order_r2_solh.C,v 1.2 2004/03/09 09:15:12 p_grandclement Exp $" ;
00022 
00023 /*
00024  * $Id: ope_sec_order_r2_solh.C,v 1.2 2004/03/09 09:15:12 p_grandclement Exp $
00025  * $Header: /cvsroot/Lorene/C++/Source/Ope_elementary/Ope_sec_order_r2/ope_sec_order_r2_solh.C,v 1.2 2004/03/09 09:15:12 p_grandclement 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_r2_pas_prevu (int, double, double,double,double,double,Tbl&) {
00038 
00039   cout << "Homogeneous solution not implemented in Sec_order_r2 : "<< 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_r2_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* air = new double[n] ;
00066   for (int i=0 ; i<n ; i++)
00067     air[i] = alpha*(-cos(M_PI*i/(n-1))) + beta ;
00068 
00069   double r_minus = beta-alpha ;
00070   double r_plus = beta+alpha ;
00071 
00072   // Determinant :
00073   double delta = (b-a)*(b-a)-4*a*c ;
00074   int signe ;
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 = ((a-b) + sqrt(delta)) / 2./a ;
00087     double lambda_two = ((a-b) - sqrt(delta)) / 2./a ;
00088 
00089     // First SH
00090     for (int i=0 ; i<n ; i++)
00091       coloc[i] = pow(air[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] = pow(air[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) = pow(r_minus, lambda_one) ;
00105     val_lim.set(0,1) = lambda_one*pow(r_minus, lambda_one-1) ;
00106     val_lim.set(0,2) = pow(r_plus, lambda_one) ;
00107     val_lim.set(0,3) = lambda_one*pow(r_plus, lambda_one-1) ;
00108 
00109     val_lim.set(1,0) = pow(r_minus, lambda_two) ;
00110     val_lim.set(1,1) = lambda_two*pow(r_minus, lambda_two-1) ;
00111     val_lim.set(1,2) = pow(r_plus, lambda_two) ;
00112     val_lim.set(1,3) = lambda_two*pow(r_plus, lambda_two-1) ;
00113     val_lim /= sqrt(double(2)) ;
00114     break ;
00115   }
00116   case 0: {
00117     // Only one solution :
00118     double lambda = (a-b)/2./a ;
00119     // First SH
00120     for (int i=0 ; i<n ; i++)
00121       coloc[i] = pow(air[i], lambda) ;
00122     cfrcheb(deg, deg, coloc, deg, coloc) ;
00123     for (int i=0 ; i<n ;i++)
00124       res.set(0,i) = coloc[i] ;
00125 
00126     // Second SH
00127     for (int i=0 ; i<n ; i++)
00128       coloc[i] = log(air[i])*pow(air[i], lambda) ;
00129     cfrcheb(deg, deg, coloc, deg, coloc) ;
00130     for (int i=0 ; i<n ;i++)
00131       res.set(1,i) = coloc[i] ; 
00132 
00133     // Limit on the boundaries :
00134     val_lim.set(0,0) = pow(r_minus, lambda) ;
00135     val_lim.set(0,1) = lambda*pow(r_minus, lambda-1) ;
00136     val_lim.set(0,2) = pow(r_plus, lambda) ;
00137     val_lim.set(0,3) = lambda*pow(r_plus, lambda-1) ;
00138 
00139     val_lim.set(1,0) = log(r_minus)*pow(r_minus, lambda) ;
00140     val_lim.set(1,1) = (1+lambda*log(r_minus))*pow(r_minus, lambda-1) ;
00141     val_lim.set(1,2) = log(r_plus)*pow(r_plus, lambda) ;
00142     val_lim.set(1,3) = (1+lambda*log(r_plus))*pow(r_plus, lambda-1) ;
00143     val_lim /= sqrt(double(2)) ;
00144     break ;
00145   }
00146   case -1:{
00147     // Two imaginary solutions :
00148     double real_part = (a-b)/2./a ;
00149     double imag_part = sqrt(-delta)/2./a ;
00150 
00151     // First SH
00152     for (int i=0 ; i<n ; i++)
00153       coloc[i] = pow(air[i], real_part)*cos(imag_part*log(air[i])) ;
00154     cfrcheb(deg, deg, coloc, deg, coloc) ;
00155     for (int i=0 ; i<n ;i++)
00156       res.set(0,i) = coloc[i] ;
00157     
00158     // Second SH
00159     for (int i=0 ; i<n ; i++)
00160       coloc[i] = pow(air[i], real_part)*sin(imag_part*log(air[i])) ;
00161     cfrcheb(deg, deg, coloc, deg, coloc) ;
00162     for (int i=0 ; i<n ;i++)
00163       res.set(1,i) = coloc[i] ;
00164 
00165     // Limit on the boundaries :
00166     val_lim.set(0,0) = pow(r_minus, real_part)*cos(imag_part*log(r_minus)) ;
00167     val_lim.set(0,1) =  (real_part*cos(imag_part*log(r_minus)) - 
00168              imag_part*sin(imag_part*log(r_minus))) * 
00169       pow(r_minus, real_part-1) ;
00170     val_lim.set(0,2) = pow(r_plus, real_part)*cos(imag_part*log(r_plus)) ;
00171     val_lim.set(0,3) = (real_part*cos(imag_part*log(r_plus)) - 
00172              imag_part*sin(imag_part*log(r_plus))) * 
00173       pow(r_plus, real_part-1) ;
00174 
00175     val_lim.set(1,0) = pow(r_minus, real_part)*sin(imag_part*log(r_minus)) ;
00176     val_lim.set(1,1) = (real_part*sin(imag_part*log(r_minus)) + 
00177              imag_part*cos(imag_part*log(r_minus))) * 
00178       pow(r_minus, real_part-1) ;
00179     val_lim.set(1,2) = pow(r_plus, real_part)*sin(imag_part*log(r_plus)) ;
00180     val_lim.set(1,3) = (real_part*sin(imag_part*log(r_plus)) + 
00181              imag_part*cos(imag_part*log(r_plus))) * 
00182       pow(r_plus, real_part-1) ;
00183     val_lim /= sqrt(double(2)) ;
00184     break ;
00185   }
00186   default:
00187     cout << "What are you doing here ? Get out or I call the police !" << endl;
00188     abort() ;
00189     break ;
00190   }
00191 
00192   delete [] deg ;
00193   delete [] coloc ;
00194   delete [] air ;
00195 
00196   return res ;
00197 }
00198 
00199 
00200 Tbl Ope_sec_order_r2::get_solh () const {
00201 
00202   // Routines de derivation
00203   static Tbl (*solh_sec_order_r2[MAX_BASE]) (int, double, double,
00204                          double, double, double, Tbl&) ;
00205   static int nap = 0 ;
00206   
00207   // Premier appel
00208   if (nap==0) {
00209     nap = 1 ;
00210     for (int i=0 ; i<MAX_BASE ; i++) {
00211       solh_sec_order_r2[i] = _solh_sec_order_r2_pas_prevu ;
00212     }
00213     // Les routines existantes
00214     solh_sec_order_r2[R_CHEB >> TRA_R] = _solh_sec_order_r2_r_cheb ;
00215   }
00216   
00217   Tbl val_lim (2,4) ;
00218   val_lim.set_etat_qcq() ;
00219   Tbl res(solh_sec_order_r2[base_r](nr,alpha,beta,a_param,b_param,c_param, 
00220                     val_lim)) ;
00221 
00222   s_one_minus  = val_lim(0,0) ;
00223   ds_one_minus = val_lim(0,1) ;
00224   s_one_plus   = val_lim(0,2) ;
00225   ds_one_plus  = val_lim(0,3) ;
00226 
00227   s_two_minus  = val_lim(1,0) ;
00228   ds_two_minus = val_lim(1,1) ;
00229   s_two_plus   = val_lim(1,2) ;
00230   ds_two_plus  = val_lim(1,3) ;
00231 
00232   return res ;
00233 }

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