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: 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