Diana
0.8.3
|
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