Diana  0.8.3
DianaContinuation.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: DianaContinuation.hpp 8959 2009-12-10 12:46:22Z miha $
00013  * -----------------------------------------------------------------------------
00014  *  Description:
00015  */
00016 
00017 #ifndef DIANA_CONTINUATION__HPP
00018 #define DIANA_CONTINUATION__HPP
00019 
00020 #ifdef HAVE_CONFIG_H
00021 #include <config.h>
00022 #endif
00023 
00024 #include <Diana.hpp>
00025 #include <DianaSparseSolver.hpp>
00026 #include <Diana/DianaSignals.hpp>
00027 
00028 #ifdef USE_NLEQ1S
00029 #include "NLEQ1S.hpp"
00030 #endif // USE_NLEQ1S
00031 
00032 namespace Diana {
00033 
00034   enum ResidualType{
00035     NoneParameterisationResidual,
00036     LocalParameterisationResidual,
00037     PseudoParameterisationResidual,
00038   };
00039 
00040   enum ParameterisationType{
00041     ParameterisationLocal,
00042     ParameterisationPseudoArclength,
00043     ParameterisationsNumber,
00044   };
00045 
00046   enum PredictorType{
00047     PredictorTangent,
00048     PredictorChord,
00049     PredictorsNumber,
00050   };
00051 
00059   char* complex2str(double real, double imag, char* strbuf);
00060   
00065   class DianaContinuation : virtual public IDianaContinuation,
00066                             virtual public DianaNumericSolver {
00067 
00068   public:
00073     DianaContinuation(Numeric::Solvers::Model::ICapeNumericModel* _pModel);
00074 
00078     virtual ~DianaContinuation();
00079 
00081     const Common::Types::CapeString& GetComponentName() const
00082       throw (Common::Error::ECapeUnknown);
00083 
00086     void SetComponentName(const Common::Types::CapeString& _name)
00087       throw (Common::Error::ECapeUnknown, Common::Error::ECapeInvalidArgument);
00088 
00090     const Common::Types::CapeString& GetComponentDescription() const
00091       throw (Common::Error::ECapeUnknown);
00092 
00095     void SetComponentDescription(const Common::Types::CapeString& _description)
00096       throw (Common::Error::ECapeUnknown, Common::Error::ECapeInvalidArgument);
00097 
00107     Common::Collection::ICapeCollection* GetParameters()
00108       throw (Common::Error::ECapeUnknown, Common::Error::ECapeFailedInitialisation,
00109              Common::Error::ECapeNoImpl);
00110 
00124     void SetSimulationContext(Common::Identification::ICapeIdentification* simContextManager)
00125       throw (Common::Error::ECapeUnknown, Common::Error::ECapeInvalidArgument,
00126              Common::Error::ECapeFailedInitialisation, Common::Error::ECapeNoImpl);
00127 
00140     void Initialize()
00141       throw (Common::Error::ECapeUnknown, Common::Error::ECapeFailedInitialisation,
00142              Common::Error::ECapeOutOfResources, Common::Error::ECapeLicenceError,
00143              Common::Error::ECapeBadInvOrder);
00144 
00153     void Terminate()
00154       throw (Common::Error::ECapeUnknown, Common::Error::ECapeOutOfResources,
00155              Common::Error::ECapeBadInvOrder);
00156 
00159     Common::Types::CapeArrayDouble GetSolution()
00160       throw (Common::Error::ECapeUnknown, Common::Error::ECapeBadInvOrder);
00161 
00164     void Destroy()
00165       throw (Common::Error::ECapeUnknown);
00166 
00174     Numeric::Solvers::Solver::SolveReturn Solve()
00175       throw (Common::Error::ECapeUnknown, Common::Error::ECapeBadInvOrder,
00176              Common::Error::ECapeSolvingError, Common::Error::ECapeOutOfResources);
00177 
00182     ContiReturn Continuate()
00183       throw (Common::Error::ECapeUnknown, Common::Error::ECapeSolvingError);
00184 
00193     void AddFreeParameter(const Common::Types::CapeString& strParName,
00194                           Common::Types::CapeDouble minValue=0.0,
00195                           Common::Types::CapeDouble maxValue=0.0)
00196       throw (Common::Error::ECapeUnknown, Common::Error::ECapeInvalidArgument);
00197 
00202     void RemoveFreeParameter(const Common::Types::CapeString& strParName)
00203       throw (Common::Error::ECapeUnknown, Common::Error::ECapeInvalidArgument);
00204 
00208     Common::Types::CapeString GetVariableName(Common::Types::CapeLong index)
00209       throw (Common::Error::ECapeUnknown, Common::Error::ECapeInvalidArgument);
00210 
00211 #ifdef DEBUG
00212     double TestJacobian();
00213 #endif
00214 
00215   protected:
00217     void             initSystemVariables();
00219     void             destroySystemVariables();
00220 
00221   protected:
00222     ContiReturn makeContinuation(const Common::Types::CapeArrayDouble& vecYI,
00223                                                     Common::Types::CapeDouble initialDirection)
00224       throw (Common::Error::ECapeUnknown, Common::Error::ECapeSolvingError);
00225 
00237     Numeric::Solvers::Solver::SolveReturn doNewtonSolve(Common::Types::CapeArrayDouble& Y, int nMaxIterations,
00238                                                         const DianaINTSignalHandler& inthandler)
00239                         throw (Common::Error::ECapeUnknown, Common::Error::ECapeSolvingError);
00240 
00241     Numeric::Solvers::Solver::SolveReturn doNewtonSolve_(Common::Types::CapeArrayDouble& Y, int nMaxIterations,
00242                                                          const DianaINTSignalHandler& inthandler)
00243       throw (Common::Error::ECapeUnknown, Common::Error::ECapeSolvingError);
00244     
00246     void restoreInitialValues()
00247       throw (Common::Error::ECapeUnknown);
00248 
00250     virtual int getModelEquations() = 0;
00251 
00253     virtual int getModelVariables() = 0;
00254 
00257     virtual CapeBoolean calcTestCondition(CapeBoolean bFirstCall=false);
00258 
00259     CapeBoolean checkIsolaCondition(const CapeArrayDouble& vecY0, const CapeArrayDouble& vecY1,
00260                              const CapeArrayDouble& vecY2);
00261 
00267     void formFunction(const Common::Types::CapeArrayDouble& Y, Common::Types::CapeArrayDouble& Res);
00268 
00269   private:
00271     void packVector(Common::Types::CapeArrayDouble& work_vector);
00272 
00274     void unpackVector(const Common::Types::CapeArrayDouble& work_vector);
00275 
00277     void packFreeParameters(int nFreeParamsPos, Common::Types::CapeArrayDouble& modelVector);
00278 
00280     void unpackFreeParameters(int nFreeParamsPos, const Common::Types::CapeArrayDouble& modelVector);
00281 
00283     void getParameterBoundaries(Common::Parameter::ICapeParameter* param,
00284                                 Common::Types::CapeDouble& dblMin,
00285                                 Common::Types::CapeDouble& dblMax);
00286 
00287   protected:
00288 
00290     virtual void packModelVector(Common::Types::CapeArrayDouble& modelVector) = 0;
00291 
00294     virtual void packModelBoundaries(Common::Types::CapeArrayDouble& arrMinY,
00295                                      Common::Types::CapeArrayDouble& arrMaxY) = 0;
00296 
00298     virtual void unpackModelVector(const Common::Types::CapeArrayDouble& modelVector) = 0;
00299 
00301     virtual void packModelResidual(Common::Types::CapeArrayDouble& modelResidual) = 0;
00302 
00304     virtual void packModelJacobian(Diana::DianaSparseArray& Jaco);
00305 
00309     virtual void addDerivativeByParameter(Diana::DianaSparseArray& Jaco, int nJacCol, int nParamIndex);
00310 
00311 #ifdef USE_NLEQ1S
00312   private:
00317     Numeric::Solvers::Solver::SolveReturn doNewtonSolve_NLEQ1S(Common::Types::CapeArrayDouble& Y, int nMaxIterations,
00318                                                                const DianaINTSignalHandler& inthandler)
00319       throw (Common::Error::ECapeUnknown, Common::Error::ECapeSolvingError);
00320     static void NLEQ1SRes(fortrani& n, fortrand* x, fortrand* f, fortrani& ifail, DianaContinuation* param);
00321     static void NLEQ1SJac(fortrani& n, fortrand* x, fortrand* dfdx, fortrani* irow, fortrani* icol, fortrani& nfill, 
00322                           fortrani& ifail, DianaContinuation* param);
00323 #endif // USE_NLEQ1S
00324 
00325   protected:
00330     int              checkVariableFiniteness(const Common::Types::CapeArrayDouble& Y);
00331 
00337     void             calcTangentVector(const Common::Types::CapeArrayDouble& Y, Common::Types::CapeArrayDouble& T,
00338                                        PredictorType type);
00339 
00344     CapeBoolean      checkVariableBoundaries(const Common::Types::CapeArrayDouble& Y);
00345 
00355     int              makeBoundaryCorrection(Common::Types::CapeArrayDouble& Y, const DianaINTSignalHandler& inthandler);
00356 
00357   private:
00358     /* parametrisation methods */
00360     void             setNoneParameterisation();
00361 
00362     /* local parameterisation */
00364     void             setLocalParameterisation(CapeLong idx, CapeDouble val, CapeDouble sign);
00366     Common::Types::CapeDouble calcLocalParameterisation(const Common::Types::CapeArrayDouble& dblY);
00368     void             addLocalParameterisationJacRow(Diana::DianaSparseArray& Jaco, int nRow);
00369 
00370     /* pseudo-arclength parameterisation */
00372     void             setPseudoParameterisation();
00374     Common::Types::CapeDouble calcPseudoParameterisation(const Common::Types::CapeArrayDouble& dblY);
00376     void             addPseudoParameterisationJacRow(Diana::DianaSparseArray& Jaco, int nRow);
00377 
00378   private:
00379     // Linear algebra
00380     void             formJacobianMatrix(const Common::Types::CapeArrayDouble& Y);
00381 
00382   protected:
00383     Common::Types::CapeDouble  vecNorm2(const Common::Types::CapeArrayDouble& dblY);
00384     Common::Types::CapeBoolean isZeroValue(Common::Types::CapeDouble value);
00385     Common::Types::CapeDouble  calcCosAngle(const Common::Types::CapeArrayDouble& Y1, const Common::Types::CapeArrayDouble& Y0,
00386                                             const Common::Types::CapeArrayDouble& Ym1);
00387 
00388     void printVector(const Common::Types::CapeString& name, const Common::Types::CapeArrayDouble& vec);
00389 
00390     void calcArpackSMEigenpair(Diana::DianaSparseArray&        dsaA,
00391                                Common::Types::CapeArrayDouble& arrEigenvector);
00392 
00393     std::vector<std::complex<Common::Types::CapeDouble> > GetEigenvalues()
00394       throw (Common::Error::ECapeUnknown);
00395 
00396     ContiReturn init(const Common::Types::CapeArrayDouble& vecYI,
00397                      Common::Types::CapeDouble initialDirection,
00398                      const int nInitialCorrectionDir,
00399                      const DianaINTSignalHandler& inthandler);
00400     ContiReturn one_step(const DianaINTSignalHandler& inthandler);
00401 
00402   protected:
00403     Common::Types::CapeString                   strName;
00404     Common::Types::CapeString                   strDescription;
00405     Numeric::Solvers::Model::ICapeNumericModel* pModel;               
00406     Diana::IDianaDAESO*                         pESO;                 
00407     Diana::DianaCollection*                     pESORealParameters;
00408     Diana::DianaCollection                      collSolverParameters; 
00409     CapeBoolean                                 bInitialized;         
00410 
00411     CapeBoolean                                 bstart;
00412     CapeBoolean                                 bintermediate;
00413 
00414 
00415   protected:
00416     // parameters lists
00417     Common::Types::CapeArrayLong          arrFreeParams;     
00418     Common::Types::CapeArrayDouble        arrFreeParamsMin;  
00419     Common::Types::CapeArrayDouble        arrFreeParamsMax;  
00420 
00421   protected:
00422     Common::Types::CapeArrayDouble        dblMinY;      
00423     Common::Types::CapeArrayDouble        dblMaxY;      
00424   private:
00425     Common::Types::CapeArrayDouble        dblScaleY;    
00426 
00427   private:
00428     // model variables
00429     int                            nVars;               
00430     int                            nModelVars;          
00431     int                            nModelEqns;          
00432     Common::Types::CapeArrayDouble vecY;                
00433     Common::Types::CapeArrayDouble vecYBC;              
00434     Common::Types::CapeArrayDouble vecRes;              
00435     Common::Types::CapeArrayDouble vecEye;              
00436     Common::Types::CapeArrayDouble vecY0;               
00437     Common::Types::CapeArrayDouble vecT0;               
00438     Common::Types::CapeArrayDouble vecYm1;              
00439     Common::Types::CapeArrayDouble vecYStart;           
00440     Diana::DianaSparseArray        matJacobian;         
00441 
00442     Diana::DianaSparseSolver       spmNewton;
00443 
00444   private:
00445     // variables for predictor and parameterisation functions
00446     ResidualType                nResidualType;          
00447 
00448     Common::Types::CapeLong     nParameterisationType;  
00449     Common::Types::CapeLong     nPredictorType;         
00450     Common::Parameter::ICapeParameter* prmParameterisationType;
00451     Common::Parameter::ICapeParameter* prmPredictorType;
00452     Common::Parameter::ICapeParameter* prmInitialCorrection;
00453 
00454     // local parameterisation internal parameters
00455     CapeDouble                  dblLocalXk;             
00456     CapeLong                    indLocalXk;             
00457 
00458   protected:
00459     // continuation paramameters (access with help of GetParameters method)
00460     Common::Types::CapeLong     nVerboseLevel;          
00461     Common::Types::CapeBoolean  bBidirectional;         
00462     Common::Types::CapeDouble   dblInitialDirection;    
00463 
00464     Common::Types::CapeDouble   dblStepSize;            
00465     Common::Types::CapeDouble   dblInitialStepSize;     
00466     Common::Types::CapeDouble   dblFailedStepScale;     
00467     Common::Types::CapeDouble   dblSucceededStepScale;  
00468     Common::Types::CapeDouble   dblMinStepSize;         
00469     Common::Types::CapeDouble   dblMaxStepSize;         
00470     Common::Types::CapeLong     nMaxStepsAmount;        
00471     Common::Types::CapeLong     nStepNumber;            
00472     Common::Types::CapeLong     nMaxNewtonIts;          
00473     Common::Types::CapeDouble   dblTol;                 
00474     Common::Types::CapeDouble   dblTolF;                
00475     Common::Types::CapeLong     nSuccessIts;            
00476 
00480     Common::Types::CapeLong     nBoundaryVariableIdx;
00481 
00482     Common::Types::CapeDouble   dblFDEpsilon;           
00483     Common::Types::CapeDouble   dblUround;              
00484     Common::Types::CapeDouble   dblIsolaTrustInterval;  
00485 
00486     Common::Types::CapeBoolean  bOrthogonalBranch;
00487     Common::Types::CapeBoolean  bCheckVariablesBoundaries; 
00488   };
00489 };
00490 
00491 #endif // DIANA_CONTINUATION__HPP