From 797b05ac3eba562fb425ca33d0b0b92e340dd571 Mon Sep 17 00:00:00 2001 From: Knut Morten Okstad Date: Tue, 24 Nov 2015 17:57:55 +0100 Subject: [PATCH] Added: Another MultiStepSIM::saveStep method taking the running block counter as argument. For use when this simulator is a component in a coupled simulator. Added: Option to save iteration results to the VTF file for a specified step. --- src/SIM/MultiStepSIM.C | 33 +++++++++++++++++++++++++++------ src/SIM/MultiStepSIM.h | 25 ++++++++++++++++++++----- src/SIM/NewmarkSIM.C | 12 ++++++++++++ src/SIM/NewmarkSIM.h | 1 + 4 files changed, 60 insertions(+), 11 deletions(-) diff --git a/src/SIM/MultiStepSIM.C b/src/SIM/MultiStepSIM.C index 5e19301b..0e9248ce 100644 --- a/src/SIM/MultiStepSIM.C +++ b/src/SIM/MultiStepSIM.C @@ -32,7 +32,7 @@ MultiStepSIM::MultiStepSIM (SIMbase& sim) nRHSvec = 1; rotUpd = false; - geoBlk = nBlock = 0; + geoBlk = nBlock = lastSt = 0; } @@ -82,22 +82,24 @@ bool MultiStepSIM::saveModel (char* fileName) } -bool MultiStepSIM::saveModel (int& gBlk, int& rBlk, char* fileName) +bool MultiStepSIM::saveModel (int& gBlock, int& rBlock, char* fileName) { PROFILE1("MultiStepSIM::saveModel"); // Write VTF-file with model geometry - if (!model.writeGlvG(gBlk,fileName,gBlk==0)) + if (!model.writeGlvG(gBlock,fileName,gBlock==0)) return false; // Write Dirichlet boundary conditions - return model.writeGlvBC(rBlk); + return model.writeGlvBC(rBlock); } bool MultiStepSIM::saveStep (int iStep, double time, bool psolOnly, const char* vecName) { + if (iStep <= lastSt) return true; // We have already saved this step + PROFILE1("MultiStepSIM::saveStep"); // Negative iStep means we are saving the initial state only @@ -105,6 +107,8 @@ bool MultiStepSIM::saveStep (int iStep, double time, return false; else if (iStep < 0) iStep = -iStep; + else + lastSt = iStep; // Write boundary tractions, if any if (!psolOnly) @@ -130,15 +134,32 @@ bool MultiStepSIM::saveStep (int iStep, double time, } +/*! + Use this method when other simulators write results to the same VTF-file. + The internal result block counter \a nBlock is syncronized with the + argument \a rBlock before the results of this simulator are written, + to avoid that multiple result blocks recieve the same result block ID. +*/ + +bool MultiStepSIM::saveStep (int iStep, int& rBlock, double time, + bool psolOnly, const char* vecName) +{ + if (rBlock > nBlock) nBlock = rBlock; + bool s = this->saveStep(iStep,time,psolOnly,vecName); + rBlock = nBlock; + return s; +} + + /*! This method only writes the primary solution vector as a vector field. It is mainly used when this simulator is a component in a coupled simulation, and where the secondary solution is of minor interest. */ -bool MultiStepSIM::saveStep (int iStep, int& nBlock, const char* vecName) +bool MultiStepSIM::saveStep (int iStep, int& rBlock, const char* vecName) { - return model.writeGlvV(solution.front(),vecName,iStep,nBlock); + return model.writeGlvV(solution.front(),vecName,iStep,rBlock); } diff --git a/src/SIM/MultiStepSIM.h b/src/SIM/MultiStepSIM.h index 1eee4ca3..d7d16446 100644 --- a/src/SIM/MultiStepSIM.h +++ b/src/SIM/MultiStepSIM.h @@ -79,6 +79,9 @@ protected: virtual bool solutionNorms(const TimeDomain&, double zero_tolerance = 1.0e-8, std::streamsize outPrec = 0); + //! \brief Returns the last step that was save to VTF + int getLastSavedStep() const { return lastSt; } + public: //! \brief Initializes the geometry block counter. void setStartGeo(int gID); @@ -88,10 +91,10 @@ public: bool saveModel(char* fileName); //! \brief Opens a new VTF-file and writes the model geometry to it. - //! \param geoBlk Running geometry block counter - //! \param nBlock Running result block counter + //! \param gBlock Running geometry block counter + //! \param rBlock Running result block counter //! \param[in] fileName File name used to construct the VTF-file name from - bool saveModel(int& geoBlk, int& nBlock, char* fileName = nullptr); + bool saveModel(int& gBlock, int& rBlock, char* fileName = nullptr); //! \brief Saves the converged results to VTF file of a given time step. //! \param[in] iStep Time/load step identifier @@ -101,11 +104,20 @@ public: bool saveStep(int iStep, double time, bool psolOnly = false, const char* vecName = nullptr); + //! \brief Saves the converged results to VTF file of a given time step. + //! \param[in] iStep Time/load step identifier + //! \param rBlock Running result block counter + //! \param[in] time Current time/load parameter + //! \param[in] psolOnly If \e true, skip secondary solution field output + //! \param[in] vecName Optional name of primary solution vector field + bool saveStep(int iStep, int& rBlock, double time, + bool psolOnly = false, const char* vecName = nullptr); + //! \brief Saves the converged solution to VTF file of a given time step. //! \param[in] iStep Time/load step identifier - //! \param nBlock Running result block counter + //! \param rBlock Running result block counter //! \param[in] vecName Name of primary solution vector field - bool saveStep(int iStep, int& nBlock, const char* vecName); + bool saveStep(int iStep, int& rBlock, const char* vecName); //! \brief Dumps the primary solution for inspection. //! \param[in] iStep Time/load step identifier @@ -163,6 +175,9 @@ protected: int geoBlk; //!< Running VTF geometry block counter int nBlock; //!< Running VTF result block counter + +private: + int lastSt; //!< The last step that was saved to VTF }; #endif diff --git a/src/SIM/NewmarkSIM.C b/src/SIM/NewmarkSIM.C index 3d6acc43..9f8b5ca3 100644 --- a/src/SIM/NewmarkSIM.C +++ b/src/SIM/NewmarkSIM.C @@ -36,6 +36,7 @@ NewmarkSIM::NewmarkSIM (SIMbase& sim) : MultiStepSIM(sim) maxit = 20; convTol = 0.000001; divgLim = 10.0; + saveIts = 0; } @@ -62,6 +63,8 @@ bool NewmarkSIM::parse (const TiXmlElement* elem) convTol = atof(value); else if ((value = utl::getValue(child,"dtol"))) divgLim = atof(value); + else if ((value = utl::getValue(child,"saveiterations"))) + saveIts = atoi(value); else if ((value = utl::getValue(child,"referencenorm"))) { if (!strcasecmp(value,"all")) @@ -351,6 +354,15 @@ SIM::ConvStatus NewmarkSIM::solveStep (TimeStep& param, SIM::SolutionMode, if (!this->correctStep(param)) return SIM::FAILURE; + if (param.step == saveIts) + { + double time = param.time.t + (param.time.dt*param.iter)/maxit; + if (!this->saveStep(this->getLastSavedStep()+1,time)) + return SIM::FAILURE; + else if (!model.setMode(SIM::DYNAMIC)) + return SIM::FAILURE; + } + if (subiter&FIRST && param.iter == 1 && !model.updateDirichlet()) return SIM::FAILURE; diff --git a/src/SIM/NewmarkSIM.h b/src/SIM/NewmarkSIM.h index edd72a11..bafb363a 100644 --- a/src/SIM/NewmarkSIM.h +++ b/src/SIM/NewmarkSIM.h @@ -92,6 +92,7 @@ protected: // Solution algorithm parameters char predictor; //!< Predictor type flag int maxit; //!< Maximum number of iterations in a time step + int saveIts; //!< Time step for which iteration result should be saved double convTol; //!< Convergence tolerance double divgLim; //!< Relative divergence limit unsigned short int cNorm; //!< Option for which convergence norm to use