vcs_internal.h

Go to the documentation of this file.
00001 /**
00002  *  @file vcs_internal.h
00003  *      Internal declarations for the VCSnonideal package
00004  */
00005 /*
00006  * $Id: vcs_internal.h 368 2010-01-04 00:46:26Z hkmoffa $
00007  */
00008 
00009 /*
00010  * Copywrite (2005) Sandia Corporation. Under the terms of 
00011  * Contract DE-AC04-94AL85000 with Sandia Corporation, the
00012  * U.S. Government retains certain rights in this software.
00013  */
00014 
00015 #ifndef _VCS_INTERNAL_H
00016 #define _VCS_INTERNAL_H
00017 
00018 #include <cstring>
00019 
00020 #include "vcs_defs.h"
00021 #include "vcs_DoubleStarStar.h"
00022 #include "vcs_Exception.h"
00023 
00024 #include "global.h"
00025 
00026 namespace VCSnonideal {
00027 
00028   //! Points to the data in a std::vector<> object
00029 #define VCS_DATA_PTR(vvv) (&(vvv[0]))
00030 
00031   //! define this Cantera function to replace printf
00032   /*!
00033    * We can replace this with printf easily
00034    */
00035 #define plogf  Cantera::writelogf
00036 
00037   //! define this Cantera function to replace cout << endl;
00038   /*!
00039    * We use this to place an endl in the log file, and
00040    * ensure that the IO buffers are flushed.
00041    */
00042 #define plogendl() Cantera::writelogendl()
00043 
00044   //! Global hook for turning on and off time printing.
00045   /*!
00046    * Default is to allow printing. But, you can assign this to zero
00047    * globally to turn off all time printing.
00048    * This is helpful for test suite purposes where you are interested
00049    * in differences in text files.
00050    */
00051   extern int vcs_timing_print_lvl;
00052 
00053   /*
00054    * Forward references
00055    */
00056   class VCS_SPECIES_THERMO;
00057   class VCS_PROB;
00058 
00059   //!  Amount of extra printing that is done while in debug mode.
00060   /*!
00061    *                     0 -> none
00062    *                     1 -> some    
00063    *                     2 -> alot      (default)
00064    *                     3 -> everything
00065    */
00066 
00067   //! Class to keep track of time and iterations
00068   /*!
00069    * class keeps all of the counters together.
00070    */
00071   class VCS_COUNTERS {
00072   public:
00073     //! Total number of iterations in the main loop 
00074     //! of vcs_TP() to solve for thermo equilibrium 
00075     int T_Its;
00076  
00077     //!  Current number of iterations in the main loop 
00078     //!   of vcs_TP() to solve for thermo equilibrium 
00079     int Its;
00080 
00081     //! Total number of optimizations of the 
00082     //! components basis set done 
00083     int T_Basis_Opts;
00084 
00085     //! number of optimizations of the components basis set done 
00086     int Basis_Opts;
00087  
00088     //! Current number of times the initial thermo
00089     //! equilibrium estimator has been called 
00090     int T_Calls_Inest; 
00091  
00092     //! Current number of calls to vcs_TP 
00093     int T_Calls_vcs_TP;     
00094 
00095     //! Current time spent in vcs_TP 
00096     double T_Time_vcs_TP;
00097 
00098     //! Current time spent in vcs_TP 
00099     double Time_vcs_TP;
00100   
00101     //! Total Time spent in basopt 
00102     double T_Time_basopt;  
00103 
00104     //! Current Time spent in basopt
00105     double Time_basopt;
00106 
00107     //! Time spent in initial estimator 
00108     double T_Time_inest;
00109 
00110     //! Time spent in the vcs suite of programs
00111     double T_Time_vcs;      
00112   };
00113 
00114   //!  Returns the value of the gas constant in the units specified by parameter
00115   /*!
00116    *  @param mu_units Specifies the units. 
00117    *           -  VCS_UNITS_KCALMOL: kcal gmol-1 K-1
00118    *           -  VCS_UNITS_UNITLESS:  1.0 K-1
00119    *           -  VCS_UNITS_KJMOL:   kJ gmol-1 K-1
00120    *           -  VCS_UNITS_KELVIN:    1.0 K-1
00121    *           -  VCS_UNITS_MKS:   joules  kmol-1 K-1 =  kg m2 s-2 kmol-1 K-1 
00122    */
00123   double vcsUtil_gasConstant(int mu_units);
00124 
00125   //! Invert an n x n matrix and solve m rhs's
00126   /*!
00127    * Solve a square matrix with multiple right hand sides
00128    *
00129    * \f[
00130    *     C X + B = 0;
00131    * \f]
00132    *
00133    * This routine uses Gauss elimination and is optimized for the solution
00134    * of lots of rhs's. A crude form of row pivoting is used here. 
00135    * The matrix C is destroyed during the solve.
00136    *
00137    * @return  The solution x[] is returned in the matrix <I>B</I>.
00138    *          Routine returns an integer representing success:
00139    *     -   1 : Matrix is singluar
00140    *     -   0 : solution is OK
00141    *   
00142    *
00143    *  @param c  Matrix to be inverted. c is in fortran format, i.e., rows
00144    *            are the inner loop. Row  numbers equal to idem.
00145    *            c[i+j*idem] = c_i_j = Matrix to be inverted:
00146    *                   -  i = row number
00147    *                   -  j = column number
00148    *
00149    *  @param idem number of row dimensions in c
00150    *  @param n  Number of rows and columns in c
00151    *  @param b  Multiple RHS. Note, b is actually the negative of 
00152    *            most formulations.  Row  numbers equal to idem.
00153    *             b[i+j*idem] = b_i_j = vectors of rhs's:
00154    *                   -  i = row number
00155    *                   -  j = column number
00156    *            (each column is a new rhs)
00157    *  @param m  number of rhs's
00158    */
00159   int  vcsUtil_mlequ(double *c, int idem, int n, double *b, int m);
00160 
00161   //! Swap values in vector of doubles
00162   /*!
00163    * Switches the value of x[i1] with x[i2]
00164    * 
00165    * @param x  Vector of doubles
00166    * @param i1 first index
00167    * @param i2 second index
00168    */
00169   void vcsUtil_dsw(double x[], int i1, int i2);
00170 
00171   //! Swap values in an integer array
00172   /*!
00173    * Switches the value of x[i1] with x[i2]
00174    * 
00175    * @param x  Vector of integers
00176    * @param i1 first index
00177    * @param i2 second index
00178    */
00179   void   vcsUtil_isw(int x[], int i1, int i2);
00180 
00181   //! Swap values in a std vector string
00182   /*!
00183    * Switches the value of vecStrings[i1] with vecStrings[i2]
00184    * 
00185    * @param vecStrings  Vector of integers
00186    * @param i1 first index
00187    * @param i2 second index
00188    */
00189   void vcsUtil_stsw(std::vector<std::string> & vecStrings, 
00190                     int i1, int i2); 
00191 
00192   //! Definition of the function pointer for the root finder
00193   /*!
00194    *  see vcsUtil_root1d for a definition of how to use this.
00195    */
00196   typedef double (*VCS_FUNC_PTR)(double xval, double Vtarget, 
00197                                  int varID, void *fptrPassthrough,
00198                                  int *err);
00199 
00200   //! One dimensional root finder
00201   /*!
00202    *
00203    *  This root finder will find the root of a one dimensional
00204    *  equation
00205    *
00206    *  \f[
00207    *     f(x) = 0
00208    *  \f]
00209    *  where x is a bounded quantity: \f$ x_{min} < x < x_max \f$ 
00210    *
00211    *  The functional to be minimized must have the following call
00212    *  structure:
00213    *
00214    *    @verbatim
00215            typedef double (*VCS_FUNC_PTR)(double xval, double Vtarget,
00216                                           int varID, void *fptrPassthrough, 
00217                                           int *err);  @endverbatim
00218    *
00219    *    xval is the current value of the x variable. Vtarget is the
00220    *    requested value of f(x), usually 0. varID is an integer
00221    *    that is passed through. fptrPassthrough is a void pointer
00222    *    that is passed through. err is a return error indicator.
00223    *    err = 0 is the norm. anything else is considered a fatal
00224    *    error.
00225    *    The return value of the function is the current value of
00226    *    f(xval).
00227    *
00228    *  @param xmin  Minimum permissible value of the x variable
00229    *  @param xmax  Maximum permissible value of the x paramerer
00230    *  @param itmax Maximum number of iterations
00231    *  @param func  function pointer, pointing to the function to be
00232    *               minimized
00233    *  @param fptrPassthrough Pointer to void that gets passed through
00234    *                         the rootfinder, unchanged, to the func.
00235    *  @param FuncTargVal Target value of the function. This is usually set
00236    *                     to zero.
00237    *  @param varID       Variable ID. This is usually set to zero.
00238    *  @param xbest Pointer to the initial value of x on input. On output
00239    *               This contains the root value.
00240    *  @param printLvl Print level of the routine.
00241    * 
00242    *
00243    * Following is a nontrial example for vcs_root1d() in which the position of a 
00244    * cylinder floating on the water is calculated.
00245    *
00246    *    @verbatim
00247      #include <cmath>
00248      #include <cstdlib>
00249     
00250      #include "Cantera.h"
00251      #include "kernel/vcs_internal.h"
00252      using namespace Cantera;
00253      using namespace VCSnonideal;
00254 
00255      const double g_cgs = 980.;
00256      const double mass_cyl = 0.066;
00257      const double diam_cyl = 0.048;
00258      const double rad_cyl = diam_cyl / 2.0; 
00259      const double len_cyl  = 5.46;
00260      const double vol_cyl  = Pi * diam_cyl * diam_cyl / 4 * len_cyl;
00261      const double rho_cyl = mass_cyl / vol_cyl; 
00262      const double rho_gas = 0.0;
00263      const double rho_liq = 1.0;
00264      const double sigma = 72.88;
00265      // Contact angle in radians
00266      const double alpha1 = 40.0 / 180. * Pi;
00267       
00268      double func_vert(double theta1, double h_2, double rho_c) {
00269        double f_grav = - Pi * rad_cyl * rad_cyl * rho_c * g_cgs;
00270        double tmp = rad_cyl * rad_cyl * g_cgs;
00271        double tmp1 = theta1 + sin(theta1) * cos(theta1) - 2.0 * h_2 / rad_cyl * sin(theta1);
00272        double f_buoy = tmp * (Pi * rho_gas + (rho_liq - rho_gas) * tmp1);
00273        double f_sten = 2 * sigma * sin(theta1 + alpha1 - Pi);
00274        double f_net =  f_grav +  f_buoy +  f_sten;
00275        return f_net;
00276      }
00277      double calc_h2_farfield(double theta1) {
00278        double rhs = sigma * (1.0 + cos(alpha1 + theta1));
00279        rhs *= 2.0;
00280        rhs = rhs / (rho_liq - rho_gas) / g_cgs;
00281        double sign = -1.0;
00282        if (alpha1 + theta1 < Pi) sign = 1.0;
00283        double res = sign * sqrt(rhs);
00284        double h2 = res + rad_cyl * cos(theta1);
00285        return h2;
00286      }
00287      double funcZero(double xval, double Vtarget, int varID, void *fptrPassthrough, int *err) {
00288        double theta = xval;
00289        double h2 = calc_h2_farfield(theta);
00290        double fv = func_vert(theta, h2, rho_cyl);
00291        return fv;
00292      }
00293      int main () {
00294        double thetamax = Pi;
00295        double thetamin = 0.0;
00296        int maxit = 1000;
00297        int iconv;
00298        double thetaR = Pi/2.0;
00299        int printLvl = 4;
00300    
00301        iconv =  VCSnonideal::vcsUtil_root1d(thetamin, thetamax, maxit, 
00302                                             funcZero,
00303                                             (void *) 0, 0.0, 0, 
00304                                             &thetaR, printLvl);
00305        printf("theta = %g\n", thetaR);
00306        double h2Final = calc_h2_farfield(thetaR);
00307        printf("h2Final = %g\n", h2Final);
00308        return 0;
00309      }   @endverbatim
00310    *
00311    */
00312   int vcsUtil_root1d(double xmin, double xmax, int itmax, VCS_FUNC_PTR func,
00313                      void *fptrPassthrough, 
00314                      double FuncTargVal, int varID, double *xbest,
00315                      int printLvl = 0);
00316 
00317   //! Returns the system wall clock time in seconds
00318   /*!
00319    * @return time in seconds.
00320    */
00321   double vcs_second();
00322 
00323   //! This define turns on using memset and memcpy. I have not run into
00324   //! any systems where this is a problem. It's the fastest way to do 
00325   //! low lvl operations where applicable. There are alternative routines
00326   //! available if this ever fails.
00327 #define USE_MEMSET
00328 #ifdef USE_MEMSET
00329 
00330   //! Zero a double vector
00331   /*!
00332    * @param vec_to vector of doubles
00333    * @param length length of the vector to zero.
00334    */
00335   inline void vcs_dzero(double * const vec_to, const int length) {
00336     (void) memset((void *) vec_to, 0, length * sizeof(double));
00337   }
00338 
00339   //! Zero an int vector
00340   /*!
00341    * @param vec_to vector of ints
00342    * @param length length of the vector to zero.
00343    */
00344   inline void vcs_izero(int * const vec_to, const int length) {
00345     (void) memset((void *) vec_to, 0, length * sizeof(int));
00346   }
00347 
00348   //! Copy a double vector
00349   /*!
00350    * @param vec_to    Vector to copy into. This vector must be dimensioned
00351    *                  at least as large as the vec_from vector.
00352    * @param vec_from  Vector to copy from
00353    * @param length    Number of doubles to copy.
00354    */
00355   inline void vcs_dcopy(double * const vec_to, 
00356                         const double * const vec_from, const int length) {
00357     (void) memcpy((void *) vec_to, (const void *) vec_from, 
00358                   (length) * sizeof(double));
00359   }
00360 
00361 
00362   //! Copy an int vector
00363   /*!
00364    * @param vec_to    Vector to copy into. This vector must be dimensioned
00365    *                  at least as large as the vec_from vector.
00366    * @param vec_from  Vector to copy from
00367    * @param length    Number of int to copy.
00368    */
00369   inline void vcs_icopy(int * const vec_to, 
00370                         const int * const vec_from, const int length) {
00371     (void) memcpy((void *) vec_to, (const void *) vec_from, 
00372                   (length) * sizeof(int));
00373   }
00374 
00375   //! Zero a std double vector
00376   /*!
00377    * @param vec_to vector of doubles
00378    * @param length length of the vector to zero.
00379    */
00380   inline void vcs_vdzero(std::vector<double> &vec_to, const int length) {
00381     (void) memset((void *)VCS_DATA_PTR(vec_to), 0, (length) * sizeof(double));
00382   }
00383   
00384   //! Zero a std int vector
00385   /*!
00386    * @param vec_to vector of ints
00387    * @param length length of the vector to zero.
00388    */
00389   inline void vcs_vizero(std::vector<int> &vec_to, const int length) {
00390     (void) memset((void *)VCS_DATA_PTR(vec_to), 0, (length) * sizeof(int));
00391   }
00392 
00393   //! Copy one std double vector into another
00394   /*!
00395    * This is an inlined function that uses memcpy. memcpy is probably
00396    * the fastest way to do this. This routine requires the vectors to be
00397    * previously dimensioned appropriately. No error checking is done.
00398    *
00399    * @param vec_to  Vector to copy into. This vector must be dimensioned
00400    *                at least as large as the vec_from vector.
00401    * @param vec_from Vector to copy from
00402    * @param length  Number of doubles to copy.
00403    */
00404   inline void vcs_vdcopy(std::vector<double> & vec_to, 
00405                          const std::vector<double> & vec_from, int length) {
00406     (void) memcpy((void *)&(vec_to[0]), (const void *) &(vec_from[0]), 
00407                   (length) * sizeof(double));
00408   }
00409 
00410   //! Copy one std integer vector into another
00411   /*!
00412    * This is an inlined function that uses memcpy. memcpy is probably
00413    * the fastest way to do this. This routine requires the 
00414    *
00415    * @param vec_to  Vector to copy into. This vector must be dimensioned
00416    *                at least as large as the vec_from vector.
00417    * @param vec_from Vector to copy from
00418    * @param length  Number of integers to copy.
00419    */
00420   inline void vcs_vicopy(std::vector<int> & vec_to, 
00421                          const std::vector<int> & vec_from, const int length) {
00422     (void) memcpy((void *)&(vec_to[0]), (const void *) &(vec_from[0]), 
00423                   (length) * sizeof(int));
00424   }
00425 #else
00426   extern void vcs_dzero(double * const, const int);
00427   extern void vcs_izero(int * const , const int);
00428   extern void vcs_dcopy(double * const, const double * const, const int);
00429   extern void vcs_icopy(int * const, const int * const, const int);
00430   extern void vcs_vdzero(std::vector<double> &vvv, const int len = -1);
00431   extern void vcs_vizero(std::vector<double> &vvv, const int len = -1);
00432   void vcs_vdcopy(std::vector<double> &vec_to, 
00433                   const std::vector<double> vec_from, const int len = -1);
00434   void vcs_vicopy(std::vector<int> &vec_to, 
00435                   const std::vector<int> vec_from, const int len = -1);
00436 #endif
00437 
00438   //! determine the l2 norm of a vector of doubles
00439   /*!
00440    * @param vec vector of doubles
00441    *
00442    * @return  Returns the l2 norm of the vector
00443    */
00444   double vcs_l2norm(const std::vector<double> vec);
00445 
00446   //! Finds the location of the maximum component in a double vector
00447   /*!
00448    * @param x pointer to a vector of doubles
00449    * @param xSize pointer to a vector of doubles used as a multiplier
00450    *              to x[]
00451    * @param j lowest index to search from 
00452    * @param n highest index to search from 
00453    * @return  Return index of the greatest value on X(i) searched
00454    *             j <= i < n
00455    */
00456   int vcs_optMax(const double *x, const double *xSize, int j, int n);
00457 
00458   //! Returns the maximum integer in a list
00459   /*!
00460    *  @param vector pointer to a vector of ints
00461    *  @param length length of the integer vector
00462    *
00463    * @return returns the max integer value in the list
00464    */
00465   int vcs_max_int(const int *vector, int length);
00466 
00467   //! Prints a line consisting of mutliple occurances of the same string
00468   /*!
00469    *  This prints a string num times, and then terminate with a
00470    *  end of line character
00471    *
00472    * @param str C string that is null terminated
00473    * @param num number of times the string is to be printed
00474    */
00475   void vcs_print_line(const char *str, int num);
00476 
00477   //! Returns a const char string representing the type of the
00478   //! species given by the first argument
00479   /*!
00480    * @param speciesStatus  Species status integer representing the type
00481    *                       of the species.
00482    * @param length         Maximum length of the string to be returned.
00483    *                       Shorter values will yield abbreviated strings.
00484    *                       Defaults to a value of 100.
00485    */
00486   const char *vcs_speciesType_string(int speciesStatus, int length = 100);
00487 
00488   //! Print a string within a given space limit
00489   /*!
00490    *   This routine limits the amount of the string that will be printed to a
00491    *   maximum of "space" characters. Printing is done to
00492    *   to Cantera's writelog() function.
00493    *
00494    *     @param str  String, which must be null terminated.
00495    *     @param space   space limit for the printing.
00496    *     @param alignment Alignment of string within the space:
00497    *                     -  0 centered
00498    *                     -  1 right aligned
00499    *                     -  2 left aligned
00500    */
00501   void vcs_print_stringTrunc(const char *str, int space, int alignment);
00502 
00503   //! Simple routine to check whether two doubles are equal up to
00504   //! roundoff error
00505   /*!
00506    *  Currently it's set to check for 10 digits of
00507    *  relative accuracy.
00508    *
00509    * @param d1 first double
00510    * @param d2 second double
00511    *
00512    * @return returns true if the doubles are "equal" and false otherwise
00513    */
00514   bool vcs_doubleEqual(double d1, double d2);
00515 
00516 }
00517 
00518 #endif
Generated by  doxygen 1.6.3