Diana  0.8.3
IDASolver.hpp
00001 /* -----------------------------------------------------------------------------
00002  *  Diana process modelling, simulation and analysis software
00003  *  Copyright (c) 2005, Michael Krasnyk
00004  *  All rights reserved.
00005 
00006  *  This file is a part of Diana process modelling, simulation and analysis software
00007  *
00008  *  Diana is free software; you can redistribute it and/or modify it
00009  *  under the terms of the GNU General Public License as published
00010  *  by the Free Software Foundation (see accompanying file LICENSE)
00011  * -----------------------------------------------------------------------------
00012  *  $Id: IDASolver.hpp 9727 2014-06-05 10:57:22Z andriushchenko $
00013  * -----------------------------------------------------------------------------
00014  *  Description:
00015  */
00016  
00017 #ifndef IDA_SOLVER_H
00018 #define IDA_SOLVER_H
00019 
00020 #ifdef HAVE_CONFIG_H
00021 #include <config.h>
00022 #endif
00023 
00024 #include <CapeOpen.hpp>
00025 #include <Diana.hpp>
00026 
00027 #ifdef HAVE_HSL
00028 #include <DianaHslSolver.hpp>
00029 #else
00030 #include <DianaSparseSolver.hpp>
00031 #endif
00032 
00033 extern "C" {
00034 #if HAVE_SUNDIALS == 1
00035 #include "sundials/sundials_types.h"
00036 #include "sundials/sundials_math.h"
00037 #include "nvector_serial.h"
00038 #include "ida.h"
00039 #include "ida/ida_dense.h"
00040 #include "ida/ida_impl.h"
00041 #elif HAVE_SUNDIALS >= 2
00042 #include "sundials/sundials_types.h"
00043 #include "sundials/sundials_math.h"
00044 #include "nvector/nvector_serial.h"
00045 #include "ida/ida.h"
00046 #include "ida/ida_dense.h"
00047 #include "ida/ida_impl.h"
00048 #else
00049 #error "Unknown internal SUNDIALS version!"
00050 #endif
00051 }
00052 
00053 #include <string.h>
00054 
00055 namespace Diana {
00057   class IDASolver : public Diana::IDianaNumericDAESolver,
00058                     public Diana::DianaNumericSolver {
00059     typedef struct {
00060       IDASolver* solver;
00061     }IDALASolverMemRec;
00062   public:
00064     IDASolver(Numeric::Solvers::Model::ICapeNumericModel* model)
00065       throw (Common::Error::ECapeUnknown);
00066     ~IDASolver();
00067   
00069     const Common::Types::CapeString& GetComponentName() const
00070       throw (Common::Error::ECapeUnknown);
00071 
00074     void SetComponentName(const Common::Types::CapeString& _name)
00075       throw (Common::Error::ECapeUnknown, Common::Error::ECapeInvalidArgument);
00076 
00078     const Common::Types::CapeString& GetComponentDescription() const
00079       throw (Common::Error::ECapeUnknown);
00080 
00083     void SetComponentDescription(const Common::Types::CapeString& _description)
00084       throw (Common::Error::ECapeUnknown, Common::Error::ECapeInvalidArgument);
00085 
00095     Common::Collection::ICapeCollection* GetParameters()
00096       throw (Common::Error::ECapeUnknown, Common::Error::ECapeFailedInitialisation,
00097              Common::Error::ECapeNoImpl);
00098       
00112     void SetSimulationContext(Common::Identification::ICapeIdentification* simContextManager)
00113       throw (Common::Error::ECapeUnknown, Common::Error::ECapeInvalidArgument,
00114              Common::Error::ECapeFailedInitialisation, Common::Error::ECapeNoImpl);
00115 
00128     void Initialize()
00129       throw (Common::Error::ECapeUnknown, Common::Error::ECapeFailedInitialisation,
00130              Common::Error::ECapeOutOfResources, Common::Error::ECapeLicenceError,
00131              Common::Error::ECapeBadInvOrder);
00132 
00141     void Terminate()
00142       throw (Common::Error::ECapeUnknown, Common::Error::ECapeOutOfResources,
00143              Common::Error::ECapeBadInvOrder);
00144   
00160     Numeric::Solvers::Solver::SolveReturn Solve()
00161       throw (Common::Error::ECapeUnknown, Common::Error::ECapeBadInvOrder,
00162              Common::Error::ECapeSolvingError, Common::Error::ECapeOutOfResources);
00163 
00165     Common::Types::CapeArrayDouble GetSolution()
00166       throw (Common::Error::ECapeUnknown, Common::Error::ECapeBadInvOrder);
00167 
00170     void Destroy()
00171       throw (Common::Error::ECapeUnknown);
00172 
00180     void SetRelTolerance(const Common::Types::CapeArrayDouble& relTolValue)
00181       throw (Common::Error::ECapeUnknown, Common::Error::ECapeInvalidArgument,
00182              Common::Error::ECapeOutOfBounds);
00183 
00191     Common::Types::CapeArrayDouble GetRelTolerance()
00192       throw (Common::Error::ECapeUnknown, Common::Error::ECapeBadInvOrder);
00193 
00200     void SetAbsTolerance(const Common::Types::CapeArrayDouble& absTolValues)
00201       throw (Common::Error::ECapeUnknown, Common::Error::ECapeInvalidArgument,
00202              Common::Error::ECapeOutOfBounds);
00203 
00210     Common::Types::CapeArrayDouble GetAbsTolerance()
00211       throw (Common::Error::ECapeUnknown, Common::Error::ECapeBadInvOrder);
00212 
00227     Numeric::Solvers::Model::CapeArrayNumericEventInfo*
00228     AdvanceToNextEvent(Numeric::Solvers::Model::CapeArrayNumericEventInfo endConditions,
00229                        Common::Types::CapeDouble& timeBefore,
00230                        Common::Types::CapeDouble& timeAfter)
00231       throw (Common::Error::ECapeUnknown, Common::Error::ECapeInvalidArgument,
00232              Common::Error::ECapeOutOfBounds, Common::Error::ECapeBadInvOrder,
00233              Common::Error::ECapeSolvingError, Common::Error::ECapeOutOfResources,
00234              Common::Error::ECapeNoImpl);
00235 
00236   protected:
00237 
00239     static int errHandler(int error_code, const char *module, const char *function, char *msg, IDASolver* rdata);
00240 
00242     static int calculateResiduals(Common::Types::CapeDouble Tres, N_Vector Y, N_Vector Yp,
00243                                   N_Vector R, IDASolver* solver);
00244 #if HAVE_SUNDIALS >= 3
00245 
00246     static int calculateJacobainDense(Common::Types::CapeLong Neq, Common::Types::CapeDouble T, Common::Types::CapeDouble cj, 
00247                                       N_Vector Y, N_Vector Yp, N_Vector Res, 
00248                                       DlsMat JJ, IDASolver* solver, 
00249                                       N_Vector tempv1, N_Vector tempv2, N_Vector tempv3);
00250 #else
00251 
00252     static int calculateJacobainDense(Common::Types::CapeLong Neq, Common::Types::CapeDouble T, N_Vector Y, N_Vector Yp,
00253                                       N_Vector Res, Common::Types::CapeDouble cj, IDASolver* solver, DenseMat JJ,
00254                                       N_Vector tempv1, N_Vector tempv2, N_Vector tempv3);
00255 #endif
00256 
00257     static int IDASparseSetup(IDAMem IDA_mem, N_Vector yyp, N_Vector ypp, N_Vector rrp,
00258                               N_Vector tmp1, N_Vector tmp2, N_Vector tmp3);
00259       
00260     static int IDASparseSolve(IDAMem IDA_mem, N_Vector b, N_Vector weight,
00261                               N_Vector ycur, N_Vector ypcur, N_Vector rrcur);
00262     
00269     int  calculateStructuralRank(const Diana::DianaSparseArray& dsa);
00270 
00272     void setValuesFromESO(bool bUpdateAbsTol=true);
00273   
00275     void startIntegrator();
00276 
00277     void printStep();
00278 
00279   protected:
00280     Common::Types::CapeString                    strName;
00281     Common::Types::CapeString                    strDescription;
00282     Numeric::Solvers::Model::ICapeNumericModel*  pModel; 
00283     Numeric::Solvers::Eso::ICapeNumericDAESO*    pESO;   
00284     Diana::DianaCollection                       collParameters; 
00285     Common::Parameter::ICapeParameter*           prmLASolver;
00286 
00287     void*                                        memIDA; 
00288 
00289     Common::Types::CapeBoolean                   bStartSimulation; 
00290 
00291     Common::Types::CapeBoolean                   bIntermediateResults;
00292     Common::Types::CapeBoolean                   bCalculateConsistentIC; 
00293 
00294     Common::Types::CapeLong                      nVerboseLevel;
00295     Common::Types::CapeLong                                      nParamVisual;
00296     Common::Types::CapeLong                      nStructRankLHS; 
00297   
00298     Common::Types::CapeLong                      nVars; 
00299     Common::Types::CapeLong                      nEqns; 
00300 
00301     // IDA internal variables
00302     N_Vector                                     vecStates; 
00303     N_Vector                                     vecDerivs; 
00304     N_Vector                                     vecId; 
00305 
00306 
00307     N_Vector                                     vecAbsTol; 
00308   
00309     Common::Types::CapeDouble                    dblT; 
00310     Common::Types::CapeDouble                    dblT0; 
00311     Common::Types::CapeDouble                    dblTend; 
00312     Common::Types::CapeDouble                    dblTout; 
00313     Common::Types::CapeDouble                    dblRTol; 
00314     Common::Types::CapeLong                      nMaxInternalSteps; 
00315 
00316     Common::Types::CapeBoolean                   bSingleStepping; 
00317     Common::Types::CapeDouble                    dblMaxStepSize; 
00318 
00319     Common::Types::CapeLong                      nMaxOrd; 
00320   private:
00321       Common::Types::CapeBoolean                 bIDAInitialized; 
00322       Common::Types::CapeBoolean                 bIDAInterruption; 
00323       Diana::DianaSparseArray                    dsaJacoDiff;
00324 #ifdef HAVE_HSL
00325       Diana::DianaHslSolver                      dssJacoDiff;
00326 #else
00327       Diana::DianaSparseSolver                   dssJacoDiff;
00328 #endif
00329       IDALASolverMemRec                          stIDALASolverMem;
00330   };
00331 };
00332 
00333 #endif // IDA_SOLVER_H