evolution.C

00001 /*
00002  *  Methods of template class Evolution
00003  *
00004  *    (see file evolution.h for documentation).
00005  *
00006  */
00007 
00008 /*
00009  *   Copyright (c) 2004  Eric Gourgoulhon & Jerome Novak
00010  *
00011  *   This file is part of LORENE.
00012  *
00013  *   LORENE is free software; you can redistribute it and/or modify
00014  *   it under the terms of the GNU General Public License version 2
00015  *   as published by the Free Software Foundation.
00016  *
00017  *   LORENE is distributed in the hope that it will be useful,
00018  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00019  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00020  *   GNU General Public License for more details.
00021  *
00022  *   You should have received a copy of the GNU General Public License
00023  *   along with LORENE; if not, write to the Free Software
00024  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00025  *
00026  */
00027 
00028 /*
00029  * $Id: evolution.C,v 1.15 2008/09/19 13:24:29 j_novak Exp $
00030  * $Log: evolution.C,v $
00031  * Revision 1.15  2008/09/19 13:24:29  j_novak
00032  * Added the third-order scheme for the time derivativre computation.
00033  *
00034  * Revision 1.14  2004/05/14 08:51:01  p_grandclement
00035  * *** empty log message ***
00036  *
00037  * Revision 1.13  2004/05/14 08:41:05  e_gourgoulhon
00038  * Added declaration "class Tbl ;" before the declarations of
00039  * write_formatted.
00040  *
00041  * Revision 1.12  2004/05/13 21:30:32  e_gourgoulhon
00042  * Use of function write_formatted in method save( ).
00043  *
00044  * Revision 1.11  2004/05/11 20:12:49  e_gourgoulhon
00045  * Added methods j_min, j_max and save.
00046  *
00047  * Revision 1.10  2004/05/03 15:23:22  e_gourgoulhon
00048  * Method downdate: changed the order of conditions (pos_jtop>=0)
00049  * and (val[pos_jtop] == 0x0) in the while(...) test.
00050  *
00051  * Revision 1.9  2004/03/31 20:24:04  e_gourgoulhon
00052  * Method time_derive: result object created by the copy constructor of
00053  * class TyT, since the arithmetics may not return an object of exactly
00054  * class TyT.
00055  *
00056  * Revision 1.8  2004/03/26 13:31:09  j_novak
00057  * Definition of the macro UNDEF_STEP for non-defined time-steps.
00058  * Changes in the way the time derivative is calculated.
00059  *
00060  * Revision 1.7  2004/03/26 08:22:13  e_gourgoulhon
00061  * *** Full reorganization of class Evolution ***
00062  * Introduction of the notion of absoluteuniversal time steps,
00063  * stored in the new array 'step'.
00064  * The new function position(int j) makes a correspondence
00065  * between a universal time step j and the position in the
00066  * arrays step, the_time and val.
00067  * Only method update is now virtual.
00068  * Methods operator[], position, is_known, downdate belong to
00069  * the base class.
00070  *
00071  * Revision 1.6  2004/03/24 14:55:47  e_gourgoulhon
00072  * Added method last_value().
00073  *
00074  * Revision 1.5  2004/03/23 14:50:41  e_gourgoulhon
00075  * Added methods is_updated, downdate, get_jlast, get_size,
00076  * as well as constructors without any initial value.
00077  * Formatted documentation for Doxygen.
00078  *
00079  * Revision 1.4  2004/03/06 21:13:15  e_gourgoulhon
00080  * Added time derivation (method time_derive).
00081  *
00082  * Revision 1.3  2004/02/17 22:13:34  e_gourgoulhon
00083  * Suppressed declaration of global char[] evolution_C = ...
00084  *
00085  * Revision 1.2  2004/02/15 21:55:33  e_gourgoulhon
00086  * Introduced derived classes Evolution_full and Evolution_std.
00087  * Evolution is now an abstract base class.
00088  *
00089  * Revision 1.1  2004/02/13 15:53:20  e_gourgoulhon
00090  * New (template) class for time evolution.
00091  *
00092  *
00093  * $Header: /cvsroot/Lorene/C++/Include/Template/evolution.C,v 1.15 2008/09/19 13:24:29 j_novak Exp $
00094  *
00095  */
00096 
00097 // C++ headers
00098 #include "headcpp.h" 
00099 
00100 // C headers
00101 #include <stdlib.h>
00102 #include <assert.h>
00103 #include <math.h>
00104 #include <time.h>
00105 
00106 class Tbl ;
00107 
00108 void write_formatted(const double&, ostream& ) ; 
00109 void write_formatted(const Tbl&, ostream& ) ; 
00110 
00111 
00112                     //-------------------------//
00113                     //      Constructors       //
00114                     //-------------------------//
00115 
00116                     
00117 template<typename TyT> 
00118 Evolution<TyT>::Evolution(const TyT& initial_value, int initial_step,
00119                           double initial_time, int size_i)
00120       : size(size_i),
00121         pos_jtop(0) {
00122 
00123     step = new int[size] ; 
00124     step[0] = initial_step ; 
00125     for (int j=1; j<size; j++) {
00126         step[j] = UNDEF_STEP ; 
00127     }
00128     
00129     the_time = new double[size] ; 
00130     the_time[0] = initial_time ; 
00131     for (int j=1; j<size; j++) {
00132         the_time[j] = -1e20 ; 
00133     }
00134     
00135     val = new TyT*[size] ; 
00136     val[0] = new TyT(initial_value) ; 
00137     for (int j=1; j<size; j++) {
00138         val[j] = 0x0 ; 
00139     }
00140         
00141 }                    
00142 
00143                     
00144 template<typename TyT> 
00145 Evolution<TyT>::Evolution(int size_i)
00146       : size(size_i),
00147         pos_jtop(-1) {
00148 
00149     step = new int[size] ; 
00150     for (int j=0; j<size; j++) {
00151         step[j] = UNDEF_STEP ; 
00152     }
00153     
00154     the_time = new double[size] ; 
00155     for (int j=0; j<size; j++) {
00156         the_time[j] = -1e20 ; 
00157     }
00158     
00159     val = new TyT*[size] ; 
00160     for (int j=0; j<size; j++) {
00161         val[j] = 0x0 ; 
00162     }    
00163     
00164 }                    
00165                     
00166 
00167 
00168 template<typename TyT> 
00169 Evolution<TyT>::Evolution(const Evolution<TyT>& evo)
00170       : size(evo.size),
00171         pos_jtop(evo.pos_jtop) {
00172 
00173     step = new int[size] ; 
00174     for (int j=0; j<size; j++) {
00175         step[j] = evo.step[j] ; 
00176     }
00177     
00178     the_time = new double[size] ; 
00179     for (int j=0; j<size; j++) {
00180         the_time[j] = evo.the_time[j] ; 
00181     }
00182     
00183     val = new TyT*[size] ; 
00184     for (int j=0; j<size; j++) {
00185         if (evo.val[j] != 0x0) {
00186             val[j] = new TyT( *(evo.val[j]) ) ; 
00187         }
00188         else {
00189             val[j] = 0x0 ; 
00190         }
00191     }
00192     
00193     
00194 }                    
00195                     
00196 
00197                     
00198                     
00199                     //-----------------------//
00200                     //      Destructor       //
00201                     //-----------------------//
00202 
00203                     
00204 template<typename TyT> 
00205 Evolution<TyT>::~Evolution(){
00206 
00207     delete [] step ; 
00208     delete [] the_time ; 
00209 
00210     for (int j=0; j<size; j++) {
00211         if (val[j] != 0x0) delete val[j] ; 
00212     }
00213     
00214     delete [] val ;
00215     
00216 }
00217                     
00218                     
00219 
00220                     //-----------------------//
00221                     //      Mutators         //
00222                     //-----------------------//
00223 
00224                     
00225 template<typename TyT> 
00226 void Evolution<TyT>::operator=(const Evolution<TyT>& ) {
00227 
00228     cerr << "void Evolution<TyT>::operator= : not implemented yet ! \n" ; 
00229     abort() ; 
00230 
00231 }
00232 
00233 
00234 template<typename TyT> 
00235 void Evolution<TyT>::downdate(int j) {
00236 
00237     if ( !(is_known(j)) ) return ;  // a never updated step cannot
00238                                     // be downdated
00239     
00240     int pos = position(j) ; 
00241     
00242     assert( val[pos] != 0x0) ; 
00243 
00244     delete val[pos] ; 
00245     val[pos] = 0x0 ; 
00246     step[pos] = UNDEF_STEP ; 
00247     the_time[pos] = -1e20 ; 
00248 
00249     if (pos == pos_jtop) {  // pos_jtop must be decreased
00250         pos_jtop-- ; 
00251         while ( (pos_jtop>=0) && (val[pos_jtop] == 0x0) ) pos_jtop-- ;
00252     }
00253     
00254 }
00255 
00256 
00257                     
00258                     
00259                         //------------//
00260                         // Accessors  //
00261                         //------------//
00262 
00263 template<typename TyT> 
00264 int Evolution<TyT>::position(int j) const {
00265     
00266     assert(pos_jtop >= 0) ; 
00267     int jmax = step[pos_jtop] ; 
00268     
00269     if (j == jmax) return pos_jtop ;   // for efficiency purpose
00270     
00271     int pos = - 1 ; 
00272 
00273     if ( (j>=step[0]) && (j<jmax) ) {
00274 
00275         for (int i=pos_jtop-1; i>=0; i--) {  // cas i=pos_jtop treated above
00276             if (step[i] == j) {
00277                 pos = i ;
00278                 break ; 
00279             }
00280         }
00281     }
00282     
00283     if (pos == -1) {
00284         cerr << "Evolution<TyT>::position: time step j = " <<
00285             j << " not found !" << endl ; 
00286         abort() ; 
00287     }
00288     
00289     return pos ; 
00290 }
00291                  
00292                     
00293 template<typename TyT> 
00294 bool Evolution<TyT>::is_known(int j) const {
00295 
00296     if (pos_jtop == -1) return false ; 
00297     
00298     assert(pos_jtop >= 0) ; 
00299     
00300     int jmax = step[pos_jtop] ; 
00301     
00302     if (j == jmax) {
00303         return ( val[pos_jtop] != 0x0 ) ; 
00304     }
00305 
00306     if ( (j>=step[0]) && (j<jmax) ) {
00307 
00308         for (int i=pos_jtop-1; i>=0; i--) {  // cas i=pos_jtop treated above
00309 
00310             if (step[i] == j) return ( val[i] != 0x0 ) ; 
00311         }
00312     }
00313     
00314     return false ; 
00315 }                  
00316                     
00317 
00318 template<typename TyT> 
00319 const TyT& Evolution<TyT>::operator[](int j) const {
00320 
00321     TyT* pval = val[position(j)] ; 
00322     assert(pval != 0x0) ; 
00323     return *pval ; 
00324 
00325 }
00326 
00327 
00328 template<typename TyT> 
00329 TyT Evolution<TyT>::operator()(double ) const {
00330 
00331     cerr << 
00332     "Evolution<TyT>::operator()(double ) const : not implemented yet !"
00333         << endl ; 
00334     abort() ; 
00335 
00336 }                  
00337  
00338 template<typename TyT> 
00339 int Evolution<TyT>::j_min() const {
00340 
00341     int resu = UNDEF_STEP ; 
00342     for (int i=0; i<=pos_jtop; i++) {
00343         if (step[i] != UNDEF_STEP) {
00344             resu = step[i] ; 
00345             break ; 
00346         }
00347     }
00348     
00349     if (resu == UNDEF_STEP) {
00350         cerr << "Evolution<TyT>::j_min() : no valid time step found !" << endl ; 
00351         abort() ; 
00352     }
00353     
00354     return resu ; 
00355 }
00356 
00357 template<typename TyT> 
00358 int Evolution<TyT>::j_max() const {
00359     
00360     if (pos_jtop == -1) {
00361         cerr << "Evolution<TyT>::j_max() : no valid time step found !" << endl ; 
00362         abort() ; 
00363     }
00364     
00365     assert(pos_jtop >=0) ; 
00366     int jmax = step[pos_jtop] ; 
00367     assert(jmax != UNDEF_STEP) ; 
00368     return jmax ; 
00369 }
00370 
00371 
00372 
00373 
00374 
00375                     //-----------------------//
00376                     //   Time derivative     //
00377                     //-----------------------//
00378 
00379 template<typename TyT> 
00380 TyT Evolution<TyT>::time_derive(int j, int n) const {
00381 
00382   if (n == 0) { 
00383     TyT resu ( operator[](j) ) ;
00384     resu = 0 * resu ;
00385 
00386     return resu ;
00387 
00388   }
00389   
00390   else { 
00391     
00392     int pos = position(j) ;
00393     assert ( pos > 0 ) ;
00394     assert ( step[pos-1] != UNDEF_STEP ) ;
00395 
00396     switch (n) {
00397     
00398         case 1 : {
00399 
00400             double dt = the_time[pos] - the_time[pos-1] ; 
00401 
00402             return ( (*val[pos]) - (*val[pos-1]) ) / dt  ;
00403             break ;
00404         } 
00405            
00406         case 2 : {
00407       
00408       assert ( pos > 1 ) ;
00409       assert ( step[pos-2] != UNDEF_STEP ) ;
00410       double dt = the_time[pos] - the_time[pos-1] ;
00411 #ifndef NDEBUG
00412       double dt2 = the_time[pos-1] - the_time[pos-2] ;
00413       if (fabs(dt2 -dt) > 1.e-13) {
00414           cerr << 
00415           "Evolution<TyT>::time_derive: the current version is"
00416            << " valid only for \n"
00417            << " a constant time step !" << endl ; 
00418           abort() ;
00419       }
00420 #endif
00421       return ( 1.5* (*val[pos]) - 2.* (*val[pos-1]) + 0.5* (*val[pos-2]) ) / dt ;  
00422       break ;
00423         } 
00424         
00425         case 3 : {
00426         
00427         assert ( pos > 2 ) ;
00428         assert ( step[pos-2] != UNDEF_STEP ) ;
00429         assert ( step[pos-3] != UNDEF_STEP ) ;
00430         double dt = the_time[pos] - the_time[pos-1] ;
00431 #ifndef NDEBUG
00432         double dt2 = the_time[pos-1] - the_time[pos-2] ;
00433         double dt3 = the_time[pos-2] - the_time[pos-3] ;
00434             if ((fabs(dt2 -dt) > 1.e-13)||(fabs(dt3 -dt2) > 1.e-13)) {
00435                 cerr << 
00436   "Evolution<TyT>::time_derive: the current version is  valid only for \n"
00437     << " a constant time step !" << endl ; 
00438                 abort() ;
00439             }
00440 #endif
00441         return ( 11.*(*val[pos]) - 18.*(*val[pos-1]) + 9.*(*val[pos-2])
00442              - 2.*(*val[pos-3])) / (6.*dt) ;
00443         break ;
00444     }
00445         default : {
00446             cerr << "Evolution<TyT>::time_derive: the case n = " << n 
00447                  << "  is not implemented !" << endl ; 
00448             abort() ;
00449             break ;
00450         }    
00451     }
00452 
00453   }
00454   return operator[](j) ;
00455 }                    
00456  
00457                    
00458 
00459                     //-----------------------//
00460                     //        Outputs        //
00461                     //-----------------------//
00462 
00463                    
00464 template<typename TyT> 
00465 void Evolution<TyT>::save(const char* filename) const {
00466 
00467     ofstream fich(filename) ; 
00468 
00469     time_t temps = time(0x0) ; 
00470     
00471     fich << "# " << filename << "    " << ctime(&temps) ; 
00472     fich << "# " << size << "  size" << '\n' ; 
00473     fich << "# " << pos_jtop << "  pos_jtop" << '\n' ; 
00474     fich << "#         t                  value...                   \n" ; 
00475     
00476     fich.precision(14) ; 
00477     fich.setf(ios::scientific) ; 
00478     fich.width(20) ; 
00479     for (int i=0; i<=pos_jtop; i++) {
00480         if (step[i] != UNDEF_STEP) {
00481             fich << the_time[i] ; fich.width(23) ; 
00482             assert(val[i] != 0x0) ;
00483             write_formatted(*(val[i]), fich) ;  
00484             fich << '\n' ; 
00485         }
00486     }
00487         
00488     fich.close() ; 
00489 }
00490 
00491 
00492 
00493 
00494 
00495 
00496 
00497 
00498 
00499 
00500 
00501 
00502 
00503 
00504 
00505 
00506 
00507 

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