SimTKcpodes.h

Go to the documentation of this file.
00001 #ifndef SimTK_CPODES_H_
00002 #define SimTK_CPODES_H_
00003 
00004 /* -------------------------------------------------------------------------- *
00005  *                      SimTK Core: SimTK CPodes                              *
00006  * -------------------------------------------------------------------------- *
00007  * This is part of the SimTK Core biosimulation toolkit originating from      *
00008  * Simbios, the NIH National Center for Physics-Based Simulation of           *
00009  * Biological Structures at Stanford, funded under the NIH Roadmap for        *
00010  * Medical Research, grant U54 GM072970. See https://simtk.org.               *
00011  *                                                                            *
00012  * Portions copyright (c) 2006-7 Stanford University and the Authors.         *
00013  * Authors: Michael Sherman                                                   *
00014  * Contributors:                                                              *
00015  *                                                                            *
00016  * Permission is hereby granted, free of charge, to any person obtaining a    *
00017  * copy of this software and associated documentation files (the "Software"), *
00018  * to deal in the Software without restriction, including without limitation  *
00019  * the rights to use, copy, modify, merge, publish, distribute, sublicense,   *
00020  * and/or sell copies of the Software, and to permit persons to whom the      *
00021  * Software is furnished to do so, subject to the following conditions:       *
00022  *                                                                            *
00023  * The above copyright notice and this permission notice shall be included in *
00024  * all copies or substantial portions of the Software.                        *
00025  *                                                                            *
00026  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
00027  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,   *
00028  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL    *
00029  * THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,    *
00030  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR      *
00031  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE  *
00032  * USE OR OTHER DEALINGS IN THE SOFTWARE.                                     *
00033  * -------------------------------------------------------------------------- */
00034 
00041 #include "SimTKcommon.h"
00042 
00043 #include <cstdio> // Needed for "FILE".
00044 
00045 /* Shared libraries are messy in Visual Studio. We have to distinguish three
00046  * cases:
00047  *   (1) this header is being used to build the SimTKcpodes shared library (dllexport)
00048  *   (2) this header is being used by a *client* of the SimTKcpodes shared
00049  *       library (dllimport)
00050  *   (3) we are building the SimTKcpodes static library, or the client is
00051  *       being compiled with the expectation of linking with the
00052  *       SimTKcpodes static library (nothing special needed)
00053  * In the CMake script for building this library, we define one of the symbols
00054  *     SimTK_CPODES_BUILDING_{SHARED|STATIC}_LIBRARY
00055  * Client code normally has no special symbol defined, in which case we'll
00056  * assume it wants to use the shared library. However, if the client defines
00057  * the symbol SimTK_USE_STATIC_LIBRARIES we'll suppress the dllimport so
00058  * that the client code can be linked with static libraries. Note that
00059  * the client symbol is not library dependent, while the library symbols
00060  * affect only the SimTKcpodes library, meaning that other libraries can
00061  * be clients of this one. However, we are assuming all-static or all-shared.
00062 */
00063 
00064 #ifdef _WIN32
00065     #if defined(SimTK_CPODES_BUILDING_SHARED_LIBRARY)
00066         #define SimTK_CPODES_EXPORT __declspec(dllexport)
00067     #elif defined(SimTK_CPODES_BUILDING_STATIC_LIBRARY) || defined(SimTK_USE_STATIC_LIBRARIES)
00068         #define SimTK_CPODES_EXPORT
00069     #else
00070         /* i.e., a client of a shared library */
00071         #define SimTK_CPODES_EXPORT __declspec(dllimport)
00072     #endif
00073 #else
00074     /* Linux, Mac */
00075     #define SimTK_CPODES_EXPORT
00076 #endif
00077 
00078 /* Every SimTK Core library must provide these two routines, with the library
00079  * name appearing after the "version_" and "about_".
00080  */
00081 #ifdef __cplusplus
00082 extern "C" {
00083 #endif
00084     SimTK_CPODES_EXPORT void SimTK_version_SimTKcpodes(int* major, int* minor, int* build);
00085     SimTK_CPODES_EXPORT void SimTK_about_SimTKcpodes(const char* key, int maxlen, char* value);
00086 #ifdef __cplusplus
00087 }
00088 #endif
00089 
00090 namespace SimTK {
00091 
00101 class SimTK_CPODES_EXPORT CPodesSystem {
00102 public:
00103     virtual ~CPodesSystem() {}
00104     // The default implementations of these virtual functions
00105     // just throw an "unimplemented virtual function" exception. 
00106 
00107     // At least one of these two must be supplied by the concrete class.
00108     virtual int  explicitODE(Real t, const Vector& y, Vector& fout) const;
00109     virtual int  implicitODE(Real t, const Vector& y, const Vector& yp, 
00110                              Vector& fout) const;
00111 
00112     virtual int  constraint(Real t, const Vector& y, 
00113                             Vector& cout) const;
00114     virtual int  project(Real t, const Vector& ycur, Vector& corr,
00115                          Real epsProj, Vector& err) const; // err is in/out
00116     virtual int  quadrature(Real t, const Vector& y, 
00117                             Vector& qout) const;
00118     virtual int  root(Real t, const Vector& y, const Vector& yp,
00119                       Vector& gout) const;
00120     virtual int  weight(const Vector& y, Vector& weights) const;
00121     virtual void errorHandler(int error_code, const char* module,
00122                               const char* function, char* msg) const;
00123 
00124     //TODO: Jacobian functions
00125 };
00126 
00127 
00128 // These static functions are private to the current (client-side) compilation
00129 // unit. They are used to navigate the client-side CPodesSystem virtual function
00130 // table, which cannot be done on the library side. Note that these are defined
00131 // in the SimTK namespace so don't need "SimTK" in their names.
00132 static int explicitODE_static(const CPodesSystem& sys, 
00133                               Real t, const Vector& y, Vector& fout) 
00134   { return sys.explicitODE(t,y,fout); }
00135 
00136 static int implicitODE_static(const CPodesSystem& sys, 
00137                               Real t, const Vector& y, const Vector& yp, Vector& fout)
00138   { return sys.implicitODE(t,y,yp,fout); }
00139 
00140 static int constraint_static(const CPodesSystem& sys, 
00141                              Real t, const Vector& y, Vector& cout)
00142   { return sys.constraint(t,y,cout); }
00143 
00144 static int project_static(const CPodesSystem& sys, 
00145                           Real t, const Vector& ycur, Vector& corr,
00146                           Real epsProj, Vector& err)
00147   { return sys.project(t,ycur,corr,epsProj,err); }
00148 
00149 static int quadrature_static(const CPodesSystem& sys, 
00150                              Real t, const Vector& y, Vector& qout)
00151   { return sys.quadrature(t,y,qout); }
00152 
00153 static int root_static(const CPodesSystem& sys, 
00154                        Real t, const Vector& y, const Vector& yp, Vector& gout)
00155   { return sys.root(t,y,yp,gout); }
00156 
00157 static int weight_static(const CPodesSystem& sys, 
00158                          const Vector& y, Vector& weights)
00159   { return sys.weight(y,weights); }
00160 
00161 static void errorHandler_static(const CPodesSystem& sys, 
00162                                 int error_code, const char* module, 
00163                                 const char* function, char* msg)
00164   { sys.errorHandler(error_code,module,function,msg); }
00165 
00174 class SimTK_CPODES_EXPORT CPodes {
00175 public:
00176     // no default constructor
00177     // copy constructor and default assignment are suppressed
00178 
00179     enum ODEType {
00180         UnspecifiedODEType=0,
00181         ExplicitODE,
00182         ImplicitODE
00183     };
00184 
00185     enum LinearMultistepMethod {
00186         UnspecifiedLinearMultistepMethod=0,
00187         BDF,
00188         Adams
00189     };
00190 
00191     enum NonlinearSystemIterationType {
00192         UnspecifiedNonlinearSystemIterationType=0,
00193         Newton,
00194         Functional
00195     };
00196 
00197     enum ToleranceType {
00198         UnspecifiedToleranceType=0,
00199         ScalarScalar,
00200         ScalarVector,
00201         WeightFunction
00202     };
00203 
00204     enum ProjectionNorm {
00205         UnspecifiedProjectionNorm=0,
00206         L2Norm,
00207         ErrorNorm
00208     };
00209 
00210     enum ConstraintLinearity {
00211         UnspecifiedConstraintLinearity=0,
00212         Linear,
00213         Nonlinear
00214     };
00215 
00216     enum ProjectionFactorizationType {
00217         UnspecifiedProjectionFactorizationType=0,
00218         ProjectWithLU,
00219         ProjectWithQR,
00220         ProjectWithSchurComplement,
00221         ProjectWithQRPivot  // for handling redundancy
00222     };
00223 
00224     enum StepMode {
00225         UnspecifiedStepMode=0,
00226         Normal,
00227         OneStep,
00228         NormalTstop,
00229         OneStepTstop
00230     };
00231 
00232     explicit CPodes
00233        (ODEType                      ode=UnspecifiedODEType, 
00234         LinearMultistepMethod        lmm=UnspecifiedLinearMultistepMethod, 
00235         NonlinearSystemIterationType nls=UnspecifiedNonlinearSystemIterationType)
00236     {
00237         // Perform construction of the CPodesRep on the library side.
00238         librarySideCPodesConstructor(ode, lmm, nls);
00239         // But fill in function pointers from the client side.
00240         clientSideCPodesConstructor();
00241     }
00242 
00243     // Values for 'flag' return values. These are just the "normal" return
00244     // values; there are many more which are all negative and represent
00245     // error conditions.
00246     static const int Success     = 0;
00247     static const int TstopReturn = 1;
00248     static const int RootReturn  = 2;
00249     static const int Warning     = 99;
00250     static const int TooMuchWork = -1;
00251     static const int TooClose    = -27;
00252 
00253     // These values should be used by user routines. "Success" is the
00254     // same as above. A positive return value means "recoverable error",
00255     // i.e., CPodes should cut the step size and try again, while a
00256     // negative number means "unrecoverable error" which will kill
00257     // CPODES altogether with a CP_xxx_FAIL error. The particular numerical
00258     // values here have no significance, just + vs. -.
00259     static const int RecoverableError = 9999;
00260     static const int UnrecoverableError = -9999;
00261 
00262     ~CPodes();
00263 
00264     // Depending on the setting of ode_type at construction, init()
00265     // and reInit() will tell CPodes to use either the explicitODE()
00266     // or implicitODE() function from the CPodesSystem, so the user
00267     // MUST have overridden at least one of those virtual methods.
00268     int init(CPodesSystem& sys,
00269              Real t0, const Vector& y0, const Vector& yp0,
00270              ToleranceType tt, Real reltol, void* abstol);
00271 
00272     int reInit(CPodesSystem& sys,
00273                Real t0, const Vector& y0, const Vector& yp0,
00274                ToleranceType tt, Real reltol, void* abstol);
00275 
00276     // This tells CPodes to make use of the user's constraint()
00277     // method from CPodesSystem, and perform projection internally.
00278     int projInit(ProjectionNorm, ConstraintLinearity,
00279                  const Vector& ctol);
00280 
00281     // This tells CPodes to make use of the user's project()
00282     // method from CPodesSystem.
00283     int projDefine();
00284 
00285     // These tell CPodes to make use of the user's quadrature()
00286     // method from CPodesSystem.
00287     int quadInit(const Vector& q0);
00288     int quadReInit(const Vector& q0);
00289 
00290     // This tells CPodes to make use of the user's root() method
00291     // from CPodesSystem.
00292     int rootInit(int nrtfn);
00293 
00294     // This tells CPodes to make use of the user's errorHandler() 
00295     // method from CPodesSystem.
00296     int setErrHandlerFn();
00297 
00298     // These tells CPodes to make use of the user's weight() 
00299     // method from CPodesSystem.
00300     int setEwtFn();
00301 
00302     // TODO: these routines should enable methods that are defined
00303     // in the CPodesSystem, but a proper interface to the Jacobian
00304     // routines hasn't been implemented yet.
00305     int dlsSetJacFn(void* jac, void* jac_data);
00306     int dlsProjSetJacFn(void* jacP, void* jacP_data);
00307 
00308 
00309     int step(Real tout, Real* tret, 
00310              Vector& y_inout, Vector& yp_inout, StepMode=Normal);
00311 
00312     int setErrFile(FILE* errfp);
00313     int setMaxOrd(int maxord);
00314     int setMaxNumSteps(int mxsteps);
00315     int setMaxHnilWarns(int mxhnil);
00316     int setStabLimDet(bool stldet) ;
00317     int setInitStep(Real hin);
00318     int setMinStep(Real hmin);
00319     int setMaxStep(Real hmax);
00320     int setStopTime(Real tstop);
00321     int setMaxErrTestFails(int maxnef);
00322 
00323     int setMaxNonlinIters(int maxcor);
00324     int setMaxConvFails(int maxncf);
00325     int setNonlinConvCoef(Real nlscoef);
00326 
00327     int setProjUpdateErrEst(bool proj_err);
00328     int setProjFrequency(int proj_freq);
00329     int setProjTestCnstr(bool test_cnstr);
00330     int setProjLsetupFreq(int proj_lset_freq);
00331     int setProjNonlinConvCoef(Real prjcoef);
00332 
00333     int setQuadErrCon(bool errconQ, 
00334                       int tol_typeQ, Real reltolQ, void* abstolQ);
00335 
00336     int setTolerances(int tol_type, Real reltol, void* abstol);
00337     
00338     int setRootDirection(Array_<int>& rootdir);
00339 
00340     int getDky(Real t, int k, Vector& dky);
00341 
00342     int getQuad(Real t, Vector& yQout);
00343     int getQuadDky(Real t, int k, Vector& dky);
00344 
00345     int getWorkSpace(int* lenrw, int* leniw);
00346     int getNumSteps(int* nsteps);
00347     int getNumFctEvals(int* nfevals);
00348     int getNumLinSolvSetups(int* nlinsetups);
00349     int getNumErrTestFails(int* netfails);
00350     int getLastOrder(int* qlast);
00351     int getCurrentOrder(int* qcur);
00352     int getNumStabLimOrderReds(int* nslred);
00353     int getActualInitStep(Real* hinused);
00354     int getLastStep(Real* hlast);
00355     int getCurrentStep(Real* hcur);
00356     int getCurrentTime(Real* tcur);
00357     int getTolScaleFactor(Real* tolsfac);
00358     int getErrWeights(Vector& eweight);
00359     int getEstLocalErrors(Vector& ele) ;
00360     int getNumGEvals(int* ngevals);
00361     int getRootInfo(int* rootsfound);
00362     int getIntegratorStats(int* nsteps,
00363                            int* nfevals, int* nlinsetups,
00364                            int* netfails, int* qlast,
00365                            int* qcur, Real* hinused, Real* hlast,
00366                            Real* hcur, Real* tcur);
00367 
00368     int getNumNonlinSolvIters(int* nniters);
00369     int getNumNonlinSolvConvFails(int* nncfails);
00370     int getNonlinSolvStats(int* nniters, int* nncfails);
00371     int getProjNumProj(int* nproj);
00372     int getProjNumCnstrEvals(int* nce);
00373     int getProjNumLinSolvSetups(int* nsetupsP);
00374     int getProjNumFailures(int* nprf) ;
00375     int getProjStats(int* nproj,
00376                      int* nce, int* nsetupsP,
00377                      int* nprf);
00378     int getQuadNumFunEvals(int* nqevals);
00379     int getQuadErrWeights(Vector& eQweight);
00380     char* getReturnFlagName(int flag);
00381 
00382 
00383     int dlsGetWorkSpace(int* lenrwLS, int* leniwLS);
00384     int dlsGetNumJacEvals(int* njevals);
00385     int dlsGetNumFctEvals(int* nfevalsLS);
00386     int dlsGetLastFlag(int* flag);
00387     char* dlsGetReturnFlagName(int flag);
00388 
00389     int dlsProjGetNumJacEvals(int* njPevals);
00390     int dlsProjGetNumFctEvals(int* ncevalsLS);
00391 
00392     int lapackDense(int N);
00393     int lapackBand(int N, int mupper, int mlower);
00394     int lapackDenseProj(int Nc, int Ny, ProjectionFactorizationType);
00395 
00396 private:
00397     // This is how we get the client-side virtual functions to
00398     // be callable from library-side code while maintaining binary
00399     // compatibility.
00400     typedef int (*ExplicitODEFunc)(const CPodesSystem&, 
00401                                    Real t, const Vector& y, Vector& fout);
00402     typedef int (*ImplicitODEFunc)(const CPodesSystem&, 
00403                                    Real t, const Vector& y, const Vector& yp,
00404                                    Vector& fout);
00405     typedef int (*ConstraintFunc) (const CPodesSystem&, 
00406                                    Real t, const Vector& y, Vector& cout);
00407     typedef int (*ProjectFunc)    (const CPodesSystem&, 
00408                                    Real t, const Vector& ycur, Vector& corr,
00409                                    Real epsProj, Vector& err);
00410     typedef int (*QuadratureFunc) (const CPodesSystem&, 
00411                                    Real t, const Vector& y, Vector& qout);
00412     typedef int (*RootFunc)       (const CPodesSystem&, 
00413                                    Real t, const Vector& y, const Vector& yp, 
00414                                    Vector& gout);
00415     typedef int (*WeightFunc)     (const CPodesSystem&, 
00416                                    const Vector& y, Vector& weights);
00417     typedef void (*ErrorHandlerFunc)(const CPodesSystem&, 
00418                                      int error_code, const char* module, 
00419                                      const char* function, char* msg);
00420 
00421     // Note that these routines do not tell CPodes to use the supplied
00422     // functions. They merely provide the client-side addresses of functions
00423     // which understand how to find the user's virtual functions, should those
00424     // actually be provided. Control over whether to actually call any of these
00425     // is handled elsewhere, with user-visible methods. These private methods
00426     // are to be called only upon construction of the CPodes object here. They
00427     // are not even dependent on which user-supplied concrete CPodesSystem is
00428     // being used.
00429     void registerExplicitODEFunc(ExplicitODEFunc);
00430     void registerImplicitODEFunc(ImplicitODEFunc);
00431     void registerConstraintFunc(ConstraintFunc);
00432     void registerProjectFunc(ProjectFunc);
00433     void registerQuadratureFunc(QuadratureFunc);
00434     void registerRootFunc(RootFunc);
00435     void registerWeightFunc(WeightFunc);
00436     void registerErrorHandlerFunc(ErrorHandlerFunc);
00437 
00438 
00439     // This is the library-side part of the CPodes constructor. This must
00440     // be done prior to the client side construction.
00441     void librarySideCPodesConstructor(ODEType, LinearMultistepMethod, NonlinearSystemIterationType);
00442 
00443     // Note that this routine MUST be called from client-side code so that
00444     // it picks up exactly the static routines above which will agree with
00445     // the client about the layout of the CPodesSystem virtual function table.
00446     void clientSideCPodesConstructor() {
00447         registerExplicitODEFunc(explicitODE_static);
00448         registerImplicitODEFunc(implicitODE_static);
00449         registerConstraintFunc(constraint_static);
00450         registerProjectFunc(project_static);
00451         registerQuadratureFunc(quadrature_static);
00452         registerRootFunc(root_static);
00453         registerWeightFunc(weight_static);
00454         registerErrorHandlerFunc(errorHandler_static);
00455     }
00456 
00457     // FOR INTERNAL USE ONLY
00458 private:
00459     class CPodesRep* rep;
00460     friend class CPodesRep;
00461 
00462     const CPodesRep& getRep() const {assert(rep); return *rep;}
00463     CPodesRep&       updRep()       {assert(rep); return *rep;}
00464 
00465     // Suppress copy constructor and default assigment operator.
00466     CPodes(const CPodes&);
00467     CPodes& operator=(const CPodes&);
00468 };
00469 
00470 } // namespace SimTK
00471 
00472 #endif // SimTK_CPODES_H_

Generated on Thu Aug 12 16:37:14 2010 for SimTKcore by  doxygen 1.6.1