int XC::Collocation::domainChanged() { AnalysisModel *myModel = this->getAnalysisModelPtr(); LinearSOE *theLinSOE = this->getLinearSOEPtr(); const Vector &x = theLinSOE->getX(); int size = x.Size(); setRayleighDampingFactors(); if(Ut.get().Size() != size) { // create the new Ut.resize(size); U.resize(size); } // now go through and populate U, by iterating through // the DOF_Groups and getting the last committed velocity and accel DOF_GrpIter &theDOFGroups = myModel->getDOFGroups(); DOF_Group *dofGroupPtr= nullptr; while((dofGroupPtr = theDOFGroups()) != 0) { const XC::ID &id = dofGroupPtr->getID(); const Vector &disp = dofGroupPtr->getCommittedDisp(); U.setDisp(id,disp); const Vector &vel = dofGroupPtr->getCommittedVel(); U.setVel(id,vel); const Vector &accel = dofGroupPtr->getCommittedAccel(); U.setAccel(id,accel); // NOTE WE CAN't DO TOGETHER BECAUSE DOF_GROUPS USING SINGLE VECTOR } return 0; }
int DisplacementControl::update(const Vector &dU) { if (theDofID == -1) { opserr << "DisplacementControl::newStep() - domainChanged has not been called\n"; return -1; } AnalysisModel *theModel = this->getAnalysisModel(); LinearSOE *theLinSOE = this->getLinearSOE(); if (theModel == 0 || theLinSOE == 0) { opserr << "WARNING DisplacementControl::update() "; opserr << "No AnalysisModel or LinearSOE has been set\n"; return -1; } (*deltaUbar) = dU; // have to do this as the SOE is gonna change double dUabar = (*deltaUbar)(theDofID); // determine dUhat theLinSOE->setB(*phat); theLinSOE->solve(); (*deltaUhat) = theLinSOE->getX(); double dUahat = (*deltaUhat)(theDofID); if (dUahat == 0.0) { opserr << "WARNING DisplacementControl::update() "; opserr << "dUahat is zero -- zero reference displacement at control node DOF\n"; return -1; } // determine delta lambda(1) == dlambda double dLambda = -dUabar/dUahat; // determine delta U(i) (*deltaU) = (*deltaUbar); deltaU->addVector(1.0, *deltaUhat,dLambda); // update dU and dlambda (*deltaUstep) += *deltaU; deltaLambdaStep += dLambda; currentLambda += dLambda; // update the model theModel->incrDisp(*deltaU); theModel->applyLoadDomain(currentLambda); if (theModel->updateDomain() < 0) { opserr << "DisplacementControl::update - model failed to update for new dU\n"; return -1; } // set the X soln in linearSOE to be deltaU for convergence Test theLinSOE->setX(*deltaU); numIncrLastStep++; return 0; }
//! If the size of the LinearSOE has changed, the object deletes any old Vectors //! created and then creates \f$6\f$ new Vector objects of size equal to {\em //! theLinearSOE-\f$>\f$getNumEqn()}. There is a Vector object created to store //! the current displacement, velocity and accelerations at times \f$t\f$ and //! \f$t + \Delta t\f$. The response quantities at time \f$t + \Delta t\f$ are //! then set by iterating over the DOF\_Group objects in the model and //! obtaining their committed values. //! Returns \f$0\f$ if successful, otherwise a warning message and a negative //! number is returned: \f$-1\f$ if no memory was available for constructing //! the Vectors. int XC::CentralDifference::domainChanged(void) { AnalysisModel *myModel = this->getAnalysisModelPtr(); LinearSOE *theLinSOE = this->getLinearSOEPtr(); const XC::Vector &x = theLinSOE->getX(); int size = x.Size(); setRayleighDampingFactors(); if(Ut.get().Size() != size) { Utm1.resize(size); Ut.resize(size); U.resize(size); } // now go through and populate U, Udot and Udotdot by iterating through // the DOF_Groups and getting the last committed velocity and accel DOF_GrpIter &theDOFGroups = myModel->getDOFGroups(); DOF_Group *dofGroupPtr= nullptr; while((dofGroupPtr = theDOFGroups()) != 0) { const ID &id = dofGroupPtr->getID(); const int idSize = id.Size(); const Vector &disp = dofGroupPtr->getCommittedDisp(); for(int i=0;i<idSize;i++) { const int loc = id(i); if(loc >= 0) { Utm1(loc) = disp(i); } } Ut.setDisp(id,disp); const Vector &vel = dofGroupPtr->getCommittedVel(); U.setVel(id,vel); const XC::Vector &accel = dofGroupPtr->getCommittedAccel(); U.setAccel(id,accel); /** NOTE WE CAN't DO TOGETHER BECAUSE DOF_GROUPS USING SINGLE VECTOR ****** for (int i=0; i < id.Size(); i++) { int loc = id(i); if (loc >= 0) { (*U)(loc) = disp(i); (U.getDot())(loc) = vel(i); (U.getDotDot())(loc) = accel(i); } } ***/ } std::cerr << getClassName() << "::" << __FUNCTION__ << "; WARNING: assuming Ut-1 = Ut\n"; return 0; }
int CollocationHSFixedNumIter::commit(void) { AnalysisModel *theModel = this->getAnalysisModel(); if (theModel == 0) { opserr << "WARNING CollocationHSFixedNumIter::commit() - no AnalysisModel set\n"; return -1; } LinearSOE *theSOE = this->getLinearSOE(); if (theSOE == 0) { opserr << "WARNING CollocationHSFixedNumIter::commit() - no LinearSOE set\n"; return -2; } if (theSOE->solve() < 0) { opserr << "WARNING CollocationHSFixedNumIter::commit() - " << "the LinearSysOfEqn failed in solve()\n"; return -3; } const Vector &deltaU = theSOE->getX(); // determine the response at t+theta*deltaT U->addVector(1.0, deltaU, c1); Udot->addVector(1.0, deltaU, c2); Udotdot->addVector(1.0, deltaU, c3); // determine response quantities at t+deltaT Udotdot->addVector(1.0/theta, *Utdotdot, (theta-1.0)/theta); (*Udot) = *Utdot; double a1 = deltaT*(1.0 - gamma); double a2 = deltaT*gamma; Udot->addVector(1.0, *Utdotdot, a1); Udot->addVector(1.0, *Udotdot, a2); (*U) = *Ut; U->addVector(1.0, *Utdot, deltaT); double a3 = deltaT*deltaT*(0.5 - beta); double a4 = deltaT*deltaT*beta; U->addVector(1.0, *Utdotdot, a3); U->addVector(1.0, *Udotdot, a4); // update the response at the DOFs theModel->setResponse(*U,*Udot,*Udotdot); // set the time to be t+deltaT double time = theModel->getCurrentDomainTime(); time += (1.0-theta)*deltaT; theModel->setCurrentDomainTime(time); return theModel->commitDomain(); }
int ArcLength::newStep(void) { // get pointers to AnalysisModel and LinearSOE AnalysisModel *theModel = this->getAnalysisModel(); LinearSOE *theLinSOE = this->getLinearSOE(); if (theModel == 0 || theLinSOE == 0) { opserr << "WARNING ArcLength::newStep() "; opserr << "No AnalysisModel or LinearSOE has been set\n"; return -1; } // get the current load factor currentLambda = theModel->getCurrentDomainTime(); if (deltaLambdaStep < 0) signLastDeltaLambdaStep = -1; else signLastDeltaLambdaStep = +1; // determine dUhat this->formTangent(); theLinSOE->setB(*phat); if (theLinSOE->solve() < 0) { opserr << "ArcLength::newStep(void) - failed in solver\n"; return -1; } (*deltaUhat) = theLinSOE->getX(); Vector &dUhat = *deltaUhat; // determine delta lambda(1) == dlambda double dLambda = sqrt(arcLength2/((dUhat^dUhat)+alpha2)); dLambda *= signLastDeltaLambdaStep; // base sign of load change // on what was happening last step deltaLambdaStep = dLambda; currentLambda += dLambda; // determine delta U(1) == dU (*deltaU) = dUhat; (*deltaU) *= dLambda; (*deltaUstep) = (*deltaU); // update model with delta lambda and delta U theModel->incrDisp(*deltaU); theModel->applyLoadDomain(currentLambda); theModel->updateDomain(); return 0; }
int Linear::solveCurrentStep(void) { // set up some pointers and check they are valid // NOTE this could be taken away if we set Ptrs as protecetd in superclass AnalysisModel *theAnalysisModel = this->getAnalysisModelPtr(); LinearSOE *theSOE = this->getLinearSOEptr(); IncrementalIntegrator *theIncIntegrator = this->getIncrementalIntegratorPtr(); if ((theAnalysisModel == 0) || (theIncIntegrator ==0 ) || (theSOE == 0)) { opserr << "WARNING Linear::solveCurrentStep() -"; opserr << "setLinks() has not been called.\n"; return -5; } if (factorOnce != 2) { if (theIncIntegrator->formTangent(incrTangent) < 0) { opserr << "WARNING Linear::solveCurrentStep() -"; opserr << "the Integrator failed in formTangent()\n"; return -1; } if (factorOnce == 1) factorOnce = 2; } if (theIncIntegrator->formUnbalance() < 0) { opserr << "WARNING Linear::solveCurrentStep() -"; opserr << "the Integrator failed in formUnbalance()\n"; return -2; } if (theSOE->solve() < 0) { opserr << "WARNING Linear::solveCurrentStep() -"; opserr << "the LinearSOE failed in solve()\n"; return -3; } const Vector &deltaU = theSOE->getX(); if (theIncIntegrator->update(deltaU) < 0) { opserr << "WARNING Linear::solveCurrentStep() -"; opserr << "the Integrator failed in update()\n"; return -4; } return 0; }
int InitialInterpolatedLineSearch::newStep(LinearSOE &theSOE) { const Vector &dU = theSOE.getX(); if (x == 0) x = new Vector(dU); if (x->Size() != dU.Size()) { delete x; x = new Vector(dU); } return 0; }
int SecantLineSearch::newStep(LinearSOE &theSOE) { const Vector &dU = theSOE.getX(); if (x == 0) x = new Vector(dU); if (x->Size() != dU.Size()) { delete x; x = new Vector(dU); } return 0; }
int ArcLength1::update(const Vector &dU) { AnalysisModel *theModel = this->getAnalysisModel(); LinearSOE *theLinSOE = this->getLinearSOE(); if (theModel == 0 || theLinSOE == 0) { opserr << "WARNING ArcLength1::update() "; opserr << "No AnalysisModel or LinearSOE has been set\n"; return -1; } (*deltaUbar) = dU; // have to do this as the SOE is gonna change // determine dUhat theLinSOE->setB(*phat); theLinSOE->solve(); (*deltaUhat) = theLinSOE->getX(); // determine delta lambda(i) double a = (*deltaUstep)^(*deltaUbar); double b = (*deltaUstep)^(*deltaUhat) + alpha2*deltaLambdaStep; if (b == 0) { opserr << "ArcLength1::update() - zero denominator,"; opserr << " alpha was set to 0.0 and zero reference load\n"; return -1; } double dLambda = -a/b; // determine delta U(i) (*deltaU) = (*deltaUbar); deltaU->addVector(1.0, *deltaUhat,dLambda); // update dU and dlambda (*deltaUstep) += *deltaU; deltaLambdaStep += dLambda; currentLambda += dLambda; // update the model theModel->incrDisp(*deltaU); theModel->applyLoadDomain(currentLambda); theModel->updateDomain(); // set the X soln in linearSOE to be deltaU for convergence Test theLinSOE->setX(*deltaU); return 0; }
int ArcLengthw::update(const Vector &dU) { ofstream factor; factor.open("FS.dat",ios::app); factor<<"insideupdate"<<endln; //factor>>dU; factor<<"insideupdate1"<<endln; AnalysisModel *theModel = this->getAnalysisModel(); LinearSOE *theLinSOE = this->getLinearSOE(); if (theModel == 0 || theLinSOE == 0) { opserr << "WARNING ArcLengthw::update() "; opserr << "No AnalysisModel or LinearSOE has been set\n"; return -1; } (*deltaUbar) = dU; // have to do this as the SOE is gonna change // determine dUhat theLinSOE->setB(*phat); theLinSOE->solve(); (*deltaUhat) = theLinSOE->getX(); double dLambda = -((*phat)^(*deltaUbar))/((*phat)^(*deltaUhat)); (*deltaU) = (*deltaUbar); deltaU->addVector(1.0, *deltaUhat,dLambda); // update dU and dlambda (*deltaUstep) += *deltaU; deltaLambdaStep += dLambda; currentLambda += dLambda; // update the model theModel->incrDisp(*deltaU); theModel->applyLoadDomain(currentLambda); theModel->updateDomain(); // set the X soln in linearSOE to be deltaU for convergence Test theLinSOE->setX(*deltaU); return 0; }
int HHTHSFixedNumIter::commit(void) { AnalysisModel *theModel = this->getAnalysisModel(); if (theModel == 0) { opserr << "WARNING HHTHSFixedNumIter::commit() - no AnalysisModel set\n"; return -1; } LinearSOE *theSOE = this->getLinearSOE(); if (theSOE == 0) { opserr << "WARNING HHTHSFixedNumIter::commit() - no LinearSOE set\n"; return -2; } if (this->formTangent(statusFlag) < 0) { opserr << "WARNING HHTHSFixedNumIter::commit() - " << "the Integrator failed in formTangent()\n"; return -3; } if (theSOE->solve() < 0) { opserr << "WARNING HHTHSFixedNumIter::commit() - " << "the LinearSysOfEqn failed in solve()\n"; return -4; } const Vector &deltaU = theSOE->getX(); // determine the response at t+deltaT U->addVector(1.0, deltaU, c1); Udot->addVector(1.0, deltaU, c2); Udotdot->addVector(1.0, deltaU, c3); // update the response at the DOFs theModel->setResponse(*U,*Udot,*Udotdot); // set the time to be t+deltaT double time = theModel->getCurrentDomainTime(); time += (1.0-alphaF)*deltaT; theModel->setCurrentDomainTime(time); return theModel->commitDomain(); }
int AlgorithmIncrements::record(int cTag, double timeStamp) { LinearSOE *theSOE = theAlgo->getLinearSOEptr(); if (theSOE == 0) return 0; const Vector &B = theSOE->getB(); const Vector &X = theSOE->getX(); if (fileName != 0) { if (cTag == 0) { if (theFile) theFile.close(); numRecord = 0; theFile.open(fileName, ios::out); if (!theFile) { opserr << "WARNING - AlgorithmIncrements::record()"; opserr << " - could not open file " << fileName << endln; } } if (theFile) { numRecord ++; int i; for (i=0; X.Size(); i++) theFile << X(i); for (i=0; X.Size(); i++) theFile << B(i); } } if (displayRecord == true) return this->plotData(X, B); return 0; }
int HHTHSFixedNumIter::domainChanged() { AnalysisModel *myModel = this->getAnalysisModel(); LinearSOE *theLinSOE = this->getLinearSOE(); const Vector &x = theLinSOE->getX(); int size = x.Size(); // if damping factors exist set them in the ele & node of the domain if (alphaM != 0.0 || betaK != 0.0 || betaKi != 0.0 || betaKc != 0.0) myModel->setRayleighDampingFactors(alphaM, betaK, betaKi, betaKc); // create the new Vector objects if (Ut == 0 || Ut->Size() != size) { // delete the old if (Ut != 0) delete Ut; if (Utdot != 0) delete Utdot; if (Utdotdot != 0) delete Utdotdot; if (U != 0) delete U; if (Udot != 0) delete Udot; if (Udotdot != 0) delete Udotdot; if (Ualpha != 0) delete Ualpha; if (Ualphadot != 0) delete Ualphadot; if (Ualphadotdot != 0) delete Ualphadotdot; if (Utm1 != 0) delete Utm1; if (Utm2 != 0) delete Utm2; if (scaledDeltaU != 0) delete scaledDeltaU; // create the new Ut = new Vector(size); Utdot = new Vector(size); Utdotdot = new Vector(size); U = new Vector(size); Udot = new Vector(size); Udotdot = new Vector(size); Ualpha = new Vector(size); Ualphadot = new Vector(size); Ualphadotdot = new Vector(size); Utm1 = new Vector(size); Utm2 = new Vector(size); scaledDeltaU = new Vector(size); // check we obtained the new if (Ut == 0 || Ut->Size() != size || Utdot == 0 || Utdot->Size() != size || Utdotdot == 0 || Utdotdot->Size() != size || U == 0 || U->Size() != size || Udot == 0 || Udot->Size() != size || Udotdot == 0 || Udotdot->Size() != size || Ualpha == 0 || Ualpha->Size() != size || Ualphadot == 0 || Ualphadot->Size() != size || Ualphadotdot == 0 || Ualphadotdot->Size() != size || Utm1 == 0 || Utm1->Size() != size || Utm2 == 0 || Utm2->Size() != size || scaledDeltaU == 0 || scaledDeltaU->Size() != size) { opserr << "HHTHSFixedNumIter::domainChanged - ran out of memory\n"; // delete the old if (Ut != 0) delete Ut; if (Utdot != 0) delete Utdot; if (Utdotdot != 0) delete Utdotdot; if (U != 0) delete U; if (Udot != 0) delete Udot; if (Udotdot != 0) delete Udotdot; if (Ualpha != 0) delete Ualpha; if (Ualphadot != 0) delete Ualphadot; if (Ualphadotdot != 0) delete Ualphadotdot; if (Utm1 != 0) delete Utm1; if (Utm2 != 0) delete Utm2; if (scaledDeltaU != 0) delete scaledDeltaU; Ut = 0; Utdot = 0; Utdotdot = 0; U = 0; Udot = 0; Udotdot = 0; Ualpha = 0; Ualphadot = 0; Ualphadotdot = 0; Utm1 = 0; Utm2 = 0; scaledDeltaU = 0; return -1; } } // now go through and populate U, Udot and Udotdot by iterating through // the DOF_Groups and getting the last committed velocity and accel DOF_GrpIter &theDOFs = myModel->getDOFs(); DOF_Group *dofPtr; while ((dofPtr = theDOFs()) != 0) { const ID &id = dofPtr->getID(); int idSize = id.Size(); int i; const Vector &disp = dofPtr->getCommittedDisp(); for (i=0; i < idSize; i++) { int loc = id(i); if (loc >= 0) { (*Utm1)(loc) = disp(i); (*Ut)(loc) = disp(i); (*U)(loc) = disp(i); } } const Vector &vel = dofPtr->getCommittedVel(); for (i=0; i < idSize; i++) { int loc = id(i); if (loc >= 0) { (*Udot)(loc) = vel(i); } } const Vector &accel = dofPtr->getCommittedAccel(); for (i=0; i < idSize; i++) { int loc = id(i); if (loc >= 0) { (*Udotdot)(loc) = accel(i); } } } if (polyOrder == 2) opserr << "\nWARNING: HHTHSFixedNumIter::domainChanged() - assuming Ut-1 = Ut\n"; else if (polyOrder == 3) opserr << "\nWARNING: HHTHSFixedNumIter::domainChanged() - assuming Ut-2 = Ut-1 = Ut\n"; return 0; }
int NewtonLineSearch::solveCurrentStep(void) { // set up some pointers and check they are valid // NOTE this could be taken away if we set Ptrs as protecetd in superclass AnalysisModel *theAnaModel = this->getAnalysisModelPtr(); IncrementalIntegrator *theIntegrator = this->getIncrementalIntegratorPtr(); LinearSOE *theSOE = this->getLinearSOEptr(); if ((theAnaModel == 0) || (theIntegrator == 0) || (theSOE == 0) || (theTest == 0)){ opserr << "WARNING NewtonLineSearch::solveCurrentStep() - setLinks() has"; opserr << " not been called - or no ConvergenceTest has been set\n"; return -5; } theLineSearch->newStep(*theSOE); // set itself as the ConvergenceTest objects EquiSolnAlgo theTest->setEquiSolnAlgo(*this); if (theTest->start() < 0) { opserr << "NewtonLineSearch::solveCurrentStep() -"; opserr << "the ConvergenceTest object failed in start()\n"; return -3; } if (theIntegrator->formUnbalance() < 0) { opserr << "WARNING NewtonLineSearch::solveCurrentStep() -"; opserr << "the Integrator failed in formUnbalance()\n"; return -2; } int result = -1; do { //residual at this iteration before next solve const Vector &Resid0 = theSOE->getB() ; //form the tangent if (theIntegrator->formTangent() < 0){ opserr << "WARNING NewtonLineSearch::solveCurrentStep() -"; opserr << "the Integrator failed in formTangent()\n"; return -1; } //solve if (theSOE->solve() < 0) { opserr << "WARNING NewtonLineSearch::solveCurrentStep() -"; opserr << "the LinearSysOfEqn failed in solve()\n"; return -3; } //line search direction const Vector &dx0 = theSOE->getX() ; //intial value of s double s0 = - (dx0 ^ Resid0) ; if (theIntegrator->update(theSOE->getX()) < 0) { opserr << "WARNING NewtonLineSearch::solveCurrentStep() -"; opserr << "the Integrator failed in update()\n"; return -4; } if (theIntegrator->formUnbalance() < 0) { opserr << "WARNING NewtonLineSearch::solveCurrentStep() -"; opserr << "the Integrator failed in formUnbalance()\n"; return -2; } // do a line search only if convergence criteria not met theOtherTest->start(); result = theOtherTest->test(); if (result < 1) { //new residual const Vector &Resid = theSOE->getB() ; //new value of s double s = - ( dx0 ^ Resid ) ; if (theLineSearch != 0) theLineSearch->search(s0, s, *theSOE, *theIntegrator); } this->record(0); result = theTest->test(); } while (result == -1); if (result == -2) { opserr << "NewtonLineSearch::solveCurrentStep() -"; opserr << "the ConvergenceTest object failed in test()\n"; return -3; } // note - if postive result we are returning what the convergence test returned // which should be the number of iterations return result; }
int NewtonRaphson::solveCurrentStep(void) { // set up some pointers and check they are valid // NOTE this could be taken away if we set Ptrs as protecetd in superclass AnalysisModel *theAnaModel = this->getAnalysisModelPtr(); IncrementalIntegrator *theIntegrator = this->getIncrementalIntegratorPtr(); LinearSOE *theSOE = this->getLinearSOEptr(); if ((theAnaModel == 0) || (theIntegrator == 0) || (theSOE == 0) || (theTest == 0)){ opserr << "WARNING NewtonRaphson::solveCurrentStep() - setLinks() has"; opserr << " not been called - or no ConvergenceTest has been set\n"; return -5; } if (theIntegrator->formUnbalance() < 0) { opserr << "WARNING NewtonRaphson::solveCurrentStep() -"; opserr << "the Integrator failed in formUnbalance()\n"; return -2; } // set itself as the ConvergenceTest objects EquiSolnAlgo theTest->setEquiSolnAlgo(*this); if (theTest->start() < 0) { opserr << "NewtnRaphson::solveCurrentStep() -"; opserr << "the ConvergenceTest object failed in start()\n"; return -3; } int result = -1; int count = 0; do { if (tangent == INITIAL_THEN_CURRENT_TANGENT) { if (count == 0) { if (theIntegrator->formTangent(INITIAL_TANGENT) < 0){ opserr << "WARNING NewtonRaphson::solveCurrentStep() -"; opserr << "the Integrator failed in formTangent()\n"; return -1; } } else { if (theIntegrator->formTangent(CURRENT_TANGENT) < 0){ opserr << "WARNING NewtonRaphson::solveCurrentStep() -"; opserr << "the Integrator failed in formTangent()\n"; return -1; } } } else { if (theIntegrator->formTangent(tangent) < 0){ opserr << "WARNING NewtonRaphson::solveCurrentStep() -"; opserr << "the Integrator failed in formTangent()\n"; return -1; } } if (theSOE->solve() < 0) { opserr << "WARNING NewtonRaphson::solveCurrentStep() -"; opserr << "the LinearSysOfEqn failed in solve()\n"; return -3; } if (theIntegrator->update(theSOE->getX()) < 0) { opserr << "WARNING NewtonRaphson::solveCurrentStep() -"; opserr << "the Integrator failed in update()\n"; return -4; } if (theIntegrator->formUnbalance() < 0) { opserr << "WARNING NewtonRaphson::solveCurrentStep() -"; opserr << "the Integrator failed in formUnbalance()\n"; return -2; } result = theTest->test(); this->record(count++); } while (result == -1); if (result == -2) { opserr << "NewtnRaphson::solveCurrentStep() -"; opserr << "the ConvergenceTest object failed in test()\n"; return -3; } // note - if postive result we are returning what the convergence test returned // which should be the number of iterations return result; }
int ArcLengthw::newStep(void) { ofstream factor; factor.open("factor.dat",ios::app); // get pointers to AnalysisModel and LinearSOE AnalysisModel *theModel = this->getAnalysisModel(); LinearSOE *theLinSOE = this->getLinearSOE(); if (theModel == 0 || theLinSOE == 0) { opserr << "WARNING ArcLengthw::newStep() "; opserr << "No AnalysisModel or LinearSOE has been set\n"; return -1; } // get the current load factor currentLambda = theModel->getCurrentDomainTime(); factor<<"currentLambda"<<endln; factor<<currentLambda<<endln; // determine dUhat this->formTangent(); theLinSOE->setB(*phat); theLinSOE->solve(); (*deltaUhat) = theLinSOE->getX(); Vector &dUhat = *deltaUhat; factor<<"dUhat"<<endln; //factor>>dUhat; int size = dUhat.Size(); int i = 0; double sum = 0.0; int Ji_1 = 0; double dLambda = 0.0; factor<<"dWibefore"<<endln; factor<<dWi<<endln; factor<<"*phat"<<endln; //factor>>*phat; factor<<"dUhat"<<endln; //factor>>dUhat; factor<<"iFactor"<<endln; factor<<iFactor<<endln; factor<<"Jd"<<endln; factor<<Jd<<endln; factor<<"iflag"<<endln; factor<<iflag<<endln; double dJd = Jd; double dJi_1 = 1.0; if( iflag == 0 ){ dWi = ( (*phat) ^ dUhat ) * iFactor * iFactor; dLambda = iFactor; iflag = 1; } else if( iflag == 1 ){ Ji_1 = 10; //theAlgo->getNumIteration(); dJi_1 = Ji_1; dWi = dWi * pow(( dJd / dJi_1 ),0.01); dLambda = dWi / ( (*phat)^(dUhat) ); } if( Ji_1 >0){ factor<<"Jd/Ji-1"<<endln; factor<<dJd/dJi_1<<endln; } factor<<"iflag"<<endln; factor<<iflag<<endln; factor<<"Ji_1"<<endln; factor<<Ji_1<<endln; factor<<"dWi"<<endln; factor<<dWi<<endln; deltaLambdaStep = dLambda; currentLambda += dLambda; (*deltaU) = dUhat; (*deltaU) *= dLambda; (*deltaUstep) = (*deltaU); // update model with delta lambda and delta U theModel->incrDisp(*deltaU); theModel->applyLoadDomain(currentLambda); theModel->updateDomain(); return 0; }
int CollocationHSIncrReduct::domainChanged() { AnalysisModel *theModel = this->getAnalysisModel(); LinearSOE *theLinSOE = this->getLinearSOE(); const Vector &x = theLinSOE->getX(); int size = x.Size(); // create the new Vector objects if (Ut == 0 || Ut->Size() != size) { // delete the old if (Ut != 0) delete Ut; if (Utdot != 0) delete Utdot; if (Utdotdot != 0) delete Utdotdot; if (U != 0) delete U; if (Udot != 0) delete Udot; if (Udotdot != 0) delete Udotdot; if (scaledDeltaU != 0) delete scaledDeltaU; // create the new Ut = new Vector(size); Utdot = new Vector(size); Utdotdot = new Vector(size); U = new Vector(size); Udot = new Vector(size); Udotdot = new Vector(size); scaledDeltaU = new Vector(size); // check we obtained the new if (Ut == 0 || Ut->Size() != size || Utdot == 0 || Utdot->Size() != size || Utdotdot == 0 || Utdotdot->Size() != size || U == 0 || U->Size() != size || Udot == 0 || Udot->Size() != size || Udotdot == 0 || Udotdot->Size() != size || scaledDeltaU == 0 || scaledDeltaU->Size() != size) { opserr << "CollocationHSIncrReduct::domainChanged() - ran out of memory\n"; // delete the old if (Ut != 0) delete Ut; if (Utdot != 0) delete Utdot; if (Utdotdot != 0) delete Utdotdot; if (U != 0) delete U; if (Udot != 0) delete Udot; if (Udotdot != 0) delete Udotdot; if (scaledDeltaU != 0) delete scaledDeltaU; Ut = 0; Utdot = 0; Utdotdot = 0; U = 0; Udot = 0; Udotdot = 0; scaledDeltaU = 0; return -1; } } // now go through and populate U, Udot and Udotdot by iterating through // the DOF_Groups and getting the last committed velocity and accel DOF_GrpIter &theDOFs = theModel->getDOFs(); DOF_Group *dofPtr; while ((dofPtr = theDOFs()) != 0) { const ID &id = dofPtr->getID(); int idSize = id.Size(); int i; const Vector &disp = dofPtr->getCommittedDisp(); for (i=0; i < idSize; i++) { int loc = id(i); if (loc >= 0) { (*U)(loc) = disp(i); } } const Vector &vel = dofPtr->getCommittedVel(); for (i=0; i < idSize; i++) { int loc = id(i); if (loc >= 0) { (*Udot)(loc) = vel(i); } } const Vector &accel = dofPtr->getCommittedAccel(); for (i=0; i < idSize; i++) { int loc = id(i); if (loc >= 0) { (*Udotdot)(loc) = accel(i); } } } return 0; }
int HHT1::domainChanged() { AnalysisModel *myModel = this->getAnalysisModel(); LinearSOE *theLinSOE = this->getLinearSOE(); const Vector &x = theLinSOE->getX(); int size = x.Size(); // if damping factors exist set them in the ele & node of the domain if (alphaM != 0.0 || betaK != 0.0 || betaKi != 0.0 || betaKc != 0.0) myModel->setRayleighDampingFactors(alphaM, betaK, betaKi, betaKc); // create the new Vector objects if (Ut == 0 || Ut->Size() != size) { // delete the old if (Ut != 0) delete Ut; if (Utdot != 0) delete Utdot; if (Utdotdot != 0) delete Utdotdot; if (U != 0) delete U; if (Udot != 0) delete Udot; if (Udotdot != 0) delete Udotdot; if (Ualpha != 0) delete Ualpha; if (Udotalpha != 0) delete Udotalpha; // create the new Ut = new Vector(size); Utdot = new Vector(size); Utdotdot = new Vector(size); U = new Vector(size); Udot = new Vector(size); Udotdot = new Vector(size); Ualpha = new Vector(size); Udotalpha = new Vector(size); // check we obtained the new if (Ut == 0 || Ut->Size() != size || Utdot == 0 || Utdot->Size() != size || Utdotdot == 0 || Utdotdot->Size() != size || U == 0 || U->Size() != size || Udot == 0 || Udot->Size() != size || Udotdot == 0 || Udotdot->Size() != size || Ualpha == 0 || Ualpha->Size() != size || Udotalpha == 0 || Udotalpha->Size() != size) { opserr << "HHT1::domainChanged - ran out of memory\n"; // delete the old if (Ut != 0) delete Ut; if (Utdot != 0) delete Utdot; if (Utdotdot != 0) delete Utdotdot; if (U != 0) delete U; if (Udot != 0) delete Udot; if (Udotdot != 0) delete Udotdot; if (Ualpha != 0) delete Ualpha; if (Udotalpha != 0) delete Udotalpha; Ut = 0; Utdot = 0; Utdotdot = 0; U = 0; Udot = 0; Udotdot = 0; Udotalpha=0; Ualpha =0; return -1; } } // now go through and populate U, Udot and Udotdot by iterating through // the DOF_Groups and getting the last committed velocity and accel DOF_GrpIter &theDOFs = myModel->getDOFs(); DOF_Group *dofPtr; while ((dofPtr = theDOFs()) != 0) { const ID &id = dofPtr->getID(); int idSize = id.Size(); int i; const Vector &disp = dofPtr->getCommittedDisp(); for (i=0; i < idSize; i++) { int loc = id(i); if (loc >= 0) { (*U)(loc) = disp(i); } } const Vector &vel = dofPtr->getCommittedVel(); for (i=0; i < idSize; i++) { int loc = id(i); if (loc >= 0) { (*Udot)(loc) = vel(i); } } const Vector &accel = dofPtr->getCommittedAccel(); for (i=0; i < idSize; i++) { int loc = id(i); if (loc >= 0) { (*Udotdot)(loc) = accel(i); } } /** NOTE WE CAN't DO TOGETHER BECAUSE DOF_GROUPS USING SINGLE VECTOR ****** for (int i=0; i < id.Size(); i++) { int loc = id(i); if (loc >= 0) { (*U)(loc) = disp(i); (*Udot)(loc) = vel(i); (*Udotdot)(loc) = accel(i); } } *******************************************************************************/ } return 0; }
int CentralDifference::domainChanged() { AnalysisModel *myModel = this->getAnalysisModel(); LinearSOE *theLinSOE = this->getLinearSOE(); const Vector &x = theLinSOE->getX(); int size = x.Size(); // if damping factors exist set them in the element & node of the domain if (alphaM != 0.0 || betaK != 0.0 || betaKi != 0.0 || betaKc != 0.0) myModel->setRayleighDampingFactors(alphaM, betaK, betaKi, betaKc); // create the new Vector objects if (Ut == 0 || Ut->Size() != size) { if (Utm1 != 0) delete Utm1; if (Ut != 0) delete Ut; if (Utdot != 0) delete Utdot; if (Utdotdot != 0) delete Utdotdot; if (Udot != 0) delete Udot; if (Udotdot != 0) delete Udotdot; // create the new Utm1 = new Vector(size); Ut = new Vector(size); Utdot = new Vector(size); Utdotdot = new Vector(size); Udot = new Vector(size); Udotdot = new Vector(size); // check we obtained the new if (Utm1 == 0 || Utm1->Size() != size || Ut == 0 || Ut->Size() != size || Utdot == 0 || Utdot->Size() != size || Utdotdot == 0 || Utdotdot->Size() != size || Udot == 0 || Udot->Size() != size || Udotdot == 0 || Udotdot->Size() != size) { opserr << "CentralDifference::domainChanged - ran out of memory\n"; // delete the old if (Utm1 != 0) delete Utm1; if (Ut != 0) delete Ut; if (Utdot != 0) delete Utdot; if (Utdotdot != 0) delete Utdotdot; if (Udot != 0) delete Udot; if (Udotdot != 0) delete Udotdot; Utm1 = 0; Ut = 0; Utdot = 0; Utdotdot = 0; Udot = 0; Udotdot = 0; return -1; } } // now go through and populate U, Udot and Udotdot by iterating through // the DOF_Groups and getting the last committed velocity and accel DOF_GrpIter &theDOFs = myModel->getDOFs(); DOF_Group *dofPtr; while ((dofPtr = theDOFs()) != 0) { const ID &id = dofPtr->getID(); int idSize = id.Size(); int i; const Vector &disp = dofPtr->getCommittedDisp(); for (i=0; i < idSize; i++) { int loc = id(i); if (loc >= 0) { (*Utm1)(loc) = disp(i); (*Ut)(loc) = disp(i); } } const Vector &vel = dofPtr->getCommittedVel(); for (i=0; i < idSize; i++) { int loc = id(i); if (loc >= 0) { (*Udot)(loc) = vel(i); } } const Vector &accel = dofPtr->getCommittedAccel(); for (i=0; i < idSize; i++) { int loc = id(i); if (loc >= 0) { (*Udotdot)(loc) = accel(i); } } } opserr << "WARNING: CentralDifference::domainChanged() - assuming Ut-1 = Ut\n"; return 0; }
int DisplacementPath::newStep(void) { if (theDofID == -1) { opserr << "DisplacementPath::newStep() - domainChanged has not been called\n"; return -1; } // get pointers to AnalysisModel and LinearSOE AnalysisModel *theModel = this->getAnalysisModel(); LinearSOE *theLinSOE = this->getLinearSOE(); if (theModel == 0 || theLinSOE == 0) { opserr << "WARNING DisplacementPath::newStep() "; opserr << "No AnalysisModel or LinearSOE has been set\n"; return -1; } // check theIncrementVector Vector if ( theIncrementVector == 0 ) { opserr << "DisplacementPath::newStep() - no theIncrementVector associated with object\n"; return -2; } // determine increment for this iteration if (currentStep < theIncrementVector->Size()) { theCurrentIncrement = (*theIncrementVector)(currentStep); } else { theCurrentIncrement = 0.0; opserr << "DisplacementPath::newStep() - reach the end of specified load path\n"; opserr << " - setting theCurrentIncrement = 0.0\n"; } // get the current load factor currentLambda = theModel->getCurrentDomainTime(); // determine dUhat and dUabar this->formTangent(); this->formUnbalance(); (*deltaUbar) = theLinSOE->getX(); double dUabar = (*deltaUbar)(theDofID); theLinSOE->setB(*phat); if (theLinSOE->solve() < 0) { opserr << "DisplacementControl::newStep(void) - failed in solver\n"; return -1; } (*deltaUhat) = theLinSOE->getX(); Vector &dUhat = *deltaUhat; double dUahat = dUhat(theDofID); //opserr << " newStep( ) " << endln; //opserr << " theDofID = " << theDofID << endln; //opserr << "dUahat = " << dUahat << endln; if (dUahat == 0.0) { opserr << "WARNING DisplacementPath::newStep() "; opserr << "dUahat is zero -- zero reference displacement at control node DOF\n"; opserr << "currentStep = " << currentStep << endln; // add by zhong opserr << " theCurrentIncrement = " << theCurrentIncrement << endln; // zhong return -1; } // determine delta lambda(1) == dlambda double dLambda = (theCurrentIncrement-dUabar)/dUahat; deltaLambdaStep = dLambda; currentLambda += dLambda; // opserr << "DisplacementPath: " << dUahat << " " << theDofID << endln; // opserr << "DisplacementPath::newStep() : " << deltaLambdaStep << endln; // determine delta U(1) == dU (*deltaU) = dUhat; (*deltaU) *= dLambda; (*deltaUstep) = (*deltaU); // update model with delta lambda and delta U theModel->incrDisp(*deltaU); theModel->applyLoadDomain(currentLambda); if (theModel->updateDomain() < 0) { opserr << "DisplacementPath::newStep - model failed to update for new dU\n"; return -1; } currentStep++; return 0; }
int DisplacementPath::update(const Vector &dU) { // opserr << " update is invoked " << endln; if (theDofID == -1) { opserr << "DisplacementControl::newStep() - domainChanged has not been called\n"; return -1; } AnalysisModel *theModel = this->getAnalysisModel(); LinearSOE *theLinSOE = this->getLinearSOE(); if (theModel == 0 || theLinSOE == 0) { opserr << "WARNING DisplacementPath::update() "; opserr << "No AnalysisModel or LinearSOE has been set\n"; return -1; } (*deltaUbar) = dU; // have to do this as the SOE is gonna change double dUabar = (*deltaUbar)(theDofID); // determine dUhat theLinSOE->setB(*phat); theLinSOE->solve(); (*deltaUhat) = theLinSOE->getX(); // add by zhong for check purpose //int size = deltaUhat->Size(); //opserr << "\n size of deltaUhat = " << size << endln; //for (int i=0; i<size; i++) { // opserr << " dektaUhat(i) = " << (*deltaUhat)(i) << endln; //} // finish here double dUahat = (*deltaUhat)(theDofID); //opserr << " theDofID = " << theDofID << endln; //opserr << "update( ) " << endln; //opserr << "dUahat = " << dUahat << endln; if (dUahat == 0.0) { opserr << "WARNING DisplacementPath::update() "; opserr << "dUahat is zero -- zero reference displacement at control node DOF\n"; return -1; } // determine delta lambda(1) == dlambda double dLambda = -dUabar/dUahat; // add by zhong //opserr << "\n dUahat = " << dUahat << endln; //opserr << " dUabar = " << dUabar << endln; //opserr << " dLambda = " << dLambda << endln; // finish // determine delta U(i) (*deltaU) = (*deltaUbar); deltaU->addVector(1.0, *deltaUhat,dLambda); // update dU and dlambda (*deltaUstep) += *deltaU; deltaLambdaStep += dLambda; currentLambda += dLambda; // update the model theModel->incrDisp(*deltaU); theModel->applyLoadDomain(currentLambda); if (theModel->updateDomain() < 0) { opserr << "DisplacementPath::update - model failed to update for new dU\n"; return -1; } // set the X soln in linearSOE to be deltaU for convergence Test theLinSOE->setX(*deltaU); return 0; }
int CentralDifferenceNoDamping::domainChanged() { AnalysisModel *myModel = this->getAnalysisModel(); LinearSOE *theLinSOE = this->getLinearSOE(); const Vector &x = theLinSOE->getX(); int size = x.Size(); // create the new Vector objects if (U == 0 || U->Size() != size) { // delete the old if (U != 0) delete U; if (Udot != 0) delete Udot; if (Udotdot != 0) delete Udotdot; // create the new U = new Vector(size); Udot = new Vector(size); Udotdot = new Vector(size); // cheack we obtained the new if (U == 0 || U->Size() != size || Udot == 0 || Udot->Size() != size || Udotdot == 0 || Udotdot->Size() != size) { opserr << "CentralDifferenceNoDamping::domainChanged - ran out of memory\n"; // delete the old if (U != 0) delete U; if (Udot != 0) delete U; if (Udotdot != 0) delete Udot; U = 0; Udot = 0; Udotdot = 0; return -1; } } // now go through and populate U and Udot by iterating through // the DOF_Groups and getting the last committed velocity and accel DOF_GrpIter &theDOFs = myModel->getDOFs(); DOF_Group *dofPtr; while ((dofPtr = theDOFs()) != 0) { const ID &id = dofPtr->getID(); int idSize = id.Size(); int i; const Vector &disp = dofPtr->getCommittedDisp(); for (i=0; i < idSize; i++) { int loc = id(i); if (loc >= 0) { (*U)(loc) = disp(i); } } const Vector &vel = dofPtr->getCommittedVel(); for (i=0; i < idSize; i++) { int loc = id(i); if (loc >= 0) { (*Udot)(loc) = vel(i); } } } return 0; }
int KrylovAccelerator2::accelerate(Vector &vStar, LinearSOE &theSOE, IncrementalIntegrator &theIntegrator) { const Vector &R = theSOE.getB(); int k = dimension; // Store residual for differencing at next iteration *(Av[k]) = R; // If subspace is not empty if (dimension > 0) { // Compute Av_k = f(y_{k-1}) - f(y_k) = r_{k-1} - r_k Av[k-1]->addVector(1.0, R, -1.0); int i,j; // Put subspace vectors into AvData Matrix A(AvData, numEqns, k); for (i = 0; i < k; i++) { Vector &Ai = *(Av[i]); for (j = 0; j < numEqns; j++) A(j,i) = Ai(j); } for (i = 0; i < k; i++) { for (int j = i+1; j < k; j++) { double sum = 0.0; double sumi = 0.0; double sumj = 0.0; for (int ii = 0; ii < numEqns; ii++) { sum += A(ii,i)*A(ii,j); sumi += A(ii,i)*A(ii,i); sumj += A(ii,j)*A(ii,j); } sumi = sqrt(sumi); sumj = sqrt(sumj); sum = sum/(sumi*sumj); //if (fabs(sum) > 0.99) //opserr << sum << ' ' << i << ' ' << j << " "; } } // Put residual vector into rData (need to save r for later!) Vector B(rData, numEqns); B = R; // No transpose char *trans = "N"; // The number of right hand side vectors int nrhs = 1; // Leading dimension of the right hand side vector int ldb = (numEqns > k) ? numEqns : k; // Subroutine error flag int info = 0; // Call the LAPACK least squares subroutine #ifdef _WIN32 unsigned int sizeC = 1; DGELS(trans, &sizeC, &numEqns, &k, &nrhs, AvData, &numEqns, rData, &ldb, work, &lwork, &info); #else //SUBROUTINE DGELS( TRANS, M, N, NRHS, A, LDA, B, LDB, WORK, LWORK, // $ INFO ) dgels_(trans, &numEqns, &k, &nrhs, AvData, &numEqns, rData, &ldb, work, &lwork, &info); #endif // Check for error returned by subroutine if (info < 0) { opserr << "WARNING KrylovAccelerator2::accelerate() - \n"; opserr << "error code " << info << " returned by LAPACK dgels\n"; return info; } Vector Q(numEqns); Q = R; // Compute the correction vector double cj; for (j = 0; j < k; j++) { // Solution to least squares is written to rData cj = rData[j]; // Compute w_{k+1} = c_1 v_1 + ... + c_k v_k vStar.addVector(1.0, *(v[j]), cj); // Compute least squares residual // q_{k+1} = r_k - (c_1 Av_1 + ... + c_k Av_k) Q.addVector(1.0, *(Av[j]), -cj); } theSOE.setB(Q); //opserr << "Q: " << Q << endln; } theSOE.solve(); vStar.addVector(1.0, theSOE.getX(), 1.0); // Put accelerated vector into storage for next iteration *(v[k]) = vStar; dimension++; return 0; }
int DisplacementControl::newStep(void) { if (theDofID == -1) { opserr << "DisplacementControl::newStep() - domainChanged has not been called\n"; return -1; } // get pointers to AnalysisModel and LinearSOE AnalysisModel *theModel = this->getAnalysisModel(); LinearSOE *theLinSOE = this->getLinearSOE(); if (theModel == 0 || theLinSOE == 0) { opserr << "WARNING DisplacementControl::newStep() "; opserr << "No AnalysisModel or LinearSOE has been set\n"; return -1; } // determine increment for this iteration double factor = specNumIncrStep/numIncrLastStep; theIncrement *=factor; if (theIncrement < minIncrement) theIncrement = minIncrement; else if (theIncrement > maxIncrement) theIncrement = maxIncrement; // get the current load factor currentLambda = theModel->getCurrentDomainTime(); // determine dUhat this->formTangent(); theLinSOE->setB(*phat); if (theLinSOE->solve() < 0) { opserr << "DisplacementControl::newStep(void) - failed in solver\n"; return -1; } (*deltaUhat) = theLinSOE->getX(); Vector &dUhat = *deltaUhat; double dUahat = dUhat(theDofID); if (dUahat == 0.0) { opserr << "WARNING DisplacementControl::newStep() "; opserr << "dUahat is zero -- zero reference displacement at control node DOF\n"; return -1; } // determine delta lambda(1) == dlambda double dLambda = theIncrement/dUahat; deltaLambdaStep = dLambda; currentLambda += dLambda; // opserr << "DisplacementControl: " << dUahat << " " << theDofID << endln; // opserr << "DisplacementControl::newStep() : " << deltaLambdaStep << endln; // determine delta U(1) == dU (*deltaU) = dUhat; (*deltaU) *= dLambda; (*deltaUstep) = (*deltaU); // update model with delta lambda and delta U theModel->incrDisp(*deltaU); theModel->applyLoadDomain(currentLambda); if (theModel->updateDomain() < 0) { opserr << "DisplacementControl::newStep - model failed to update for new dU\n"; return -1; } numIncrLastStep = 0; return 0; }
int SecantLineSearch::search(double s0, double s1, LinearSOE &theSOE, IncrementalIntegrator &theIntegrator) { double r0 = 0.0; if ( s0 != 0.0 ) r0 = fabs( s1 / s0 ); if (r0 <= tolerance ) return 0; // Line Search Not Required Residual Decrease Less Than Tolerance if (s1 == s0) return 0; // Secant will have a divide-by-zero if continue // set some variables double eta = 1.0; double s = s1; double etaJ = 1.0; double etaJm1 = 0.0; double sJ = s1; double sJm1 = s0; double r = r0; const Vector &dU = theSOE.getX(); if (printFlag == 0) { opserr << "Secant Line Search - initial: " << " eta(0) : " << eta << " , Ratio |s/s0| = " << r0 << endln; } // perform the secant iterations: // // eta(j+1) = eta(j) - s(j) * (eta(j-1)-eta(j)) // ------------------------ // s(j-1) - s(j) int count = 0; //intial value of iteration counter while ( r > tolerance && count < maxIter ) { count++; eta = etaJ - sJ * (etaJm1-etaJ) / (sJm1 - sJ); //-- want to put limits on eta and stop solution blowing up if (eta > maxEta) eta = maxEta; if (r > r0 ) eta = 1.0; if (eta < minEta) eta = minEta; //update the incremental difference in response and determine new unbalance if (eta == etaJ) break; // no change in response *x = dU; *x *= eta-etaJ; if (theIntegrator.update(*x) < 0) { opserr << "WARNING SecantLineSearch::search() -"; opserr << "the Integrator failed in update()\n"; return -1; } if (theIntegrator.formUnbalance() < 0) { opserr << "WARNING SecantLineSearch::search() -"; opserr << "the Integrator failed in formUnbalance()\n"; return -2; } //new residual const Vector &ResidJ = theSOE.getB(); //new value of s s = dU ^ ResidJ; //new value of r r = fabs( s / s0 ); if (printFlag == 0) { opserr << "Secant Line Search - iteration: " << count << " , eta(j) : " << eta << " , Ratio |sj/s0| = " << r << endln; } if (etaJ == eta) count = maxIter; // set variables for next iteration etaJm1 = etaJ; etaJ = eta; sJm1 = sJ; sJ = s; if (sJm1 == sJ) count = maxIter; } //end while // set X in the SOE for the revised dU, needed for convergence tests *x = dU; if (eta != 0.0) *x *= eta; theSOE.setX(*x); return 0; }
int InitialInterpolatedLineSearch::search(double s0, double s1, LinearSOE &theSOE, IncrementalIntegrator &theIntegrator) { double s = s1; //intialize r = ratio of residuals double r0 = 0.0; if ( s0 != 0.0 ) r0 = fabs( s / s0 ); if (r0 <= tolerance ) return 0; // Line Search Not Required Residual Decrease Less Than Tolerance double eta = 1.0; //initial value of line search parameter double etaPrev = 1.0; double r = r0; const Vector &dU = theSOE.getX(); int count = 0; //intial value of iteration counter if (printFlag == 0) { opserr << "InitialInterpolated Line Search - initial " << " eta : " << eta << " , Ratio |s/s0| = " << r0 << endln; } // Solution procedure follows the one in Crissfields book. // (M.A. Crissfield, Nonlinear Finite Element Analysis of Solid and Structures, Wiley. 97). // NOTE: it is not quite linear interpolation/false-position/regula-falsi as eta(0) = 0.0 // does not change. uses eta(i) = eta(i-1)*s0 // ----------- // s0 - s(i-1) to compute eta(i) // opserr << "dU: " << dU; while ( r > tolerance && count < maxIter ) { count++; eta *= s0 / (s0 - s); //-- want to put limits on eta(i) if (eta > maxEta) eta = maxEta; if (r > r0 ) eta = 1.0; if (eta < minEta) eta = minEta; if (eta == etaPrev) break; // no change in response break //dx = ( eta * dx0 ); *x = dU; *x *= eta-etaPrev; if (theIntegrator.update(*x) < 0) { opserr << "WARNInG InitialInterpolatedLineSearch::search() -"; opserr << "the Integrator failed in update()\n"; return -1; } if (theIntegrator.formUnbalance() < 0) { opserr << "WARNInG InitialInterpolatedLineSearch::search() -"; opserr << "the Integrator failed in formUnbalance()\n"; return -2; } //new residual const Vector &ResidI = theSOE.getB(); //new value of s s = dU ^ ResidI; //new value of r r = fabs( s / s0 ); if (printFlag == 0) { opserr << "InitialInterpolated Line Search - iteration: " << count << " , eta(j) : " << eta << " , Ratio |sj/s0| = " << r << endln; } // reset the variables, also check not just hitting bounds over and over if (eta == etaPrev) count = maxIter; else etaPrev = eta; } //end while // set X in the SOE for the revised dU, needed for convergence tests *x = dU; if (eta != 0.0) *x *= eta; theSOE.setX(*x); return 0; }
int ArcLength::update(const Vector &dU) { AnalysisModel *theModel = this->getAnalysisModel(); LinearSOE *theLinSOE = this->getLinearSOE(); if (theModel == 0 || theLinSOE == 0) { opserr << "WARNING ArcLength::update() "; opserr << "No AnalysisModel or LinearSOE has been set\n"; return -1; } (*deltaUbar) = dU; // have to do this as the SOE is gonna change // determine dUhat theLinSOE->setB(*phat); theLinSOE->solve(); (*deltaUhat) = theLinSOE->getX(); // determine the coeeficients of our quadratic equation double a = alpha2 + ((*deltaUhat)^(*deltaUhat)); double b = alpha2*deltaLambdaStep + ((*deltaUhat)^(*deltaUbar)) + ((*deltaUstep)^(*deltaUhat)); b *= 2.0; double c = 2*((*deltaUstep)^(*deltaUbar)) + ((*deltaUbar)^(*deltaUbar)); // check for a solution to quadratic double b24ac = b*b - 4.0*a*c; if (b24ac < 0) { opserr << "ArcLength::update() - imaginary roots due to multiple instability"; opserr << " directions - initial load increment was too large\n"; opserr << "a: " << a << " b: " << b << " c: " << c << " b24ac: " << b24ac << endln; return -1; } double a2 = 2.0*a; if (a2 == 0.0) { opserr << "ArcLength::update() - zero denominator"; opserr << " alpha was set to 0.0 and zero reference load\n"; return -2; } // determine the roots of the quadratic double sqrtb24ac = sqrt(b24ac); double dlambda1 = (-b + sqrtb24ac)/a2; double dlambda2 = (-b - sqrtb24ac)/a2; double val = (*deltaUhat)^(*deltaUstep); double theta1 = ((*deltaUstep)^(*deltaUstep)) + ((*deltaUbar)^(*deltaUstep)); // double theta2 = theta1 + dlambda2*val; theta1 += dlambda1*val; // choose dLambda based on angle between incremental displacement before // and after this step -- want positive double dLambda; if (theta1 > 0) dLambda = dlambda1; else dLambda = dlambda2; // determine delta U(i) (*deltaU) = (*deltaUbar); deltaU->addVector(1.0, *deltaUhat,dLambda); // update dU and dlambda (*deltaUstep) += *deltaU; deltaLambdaStep += dLambda; currentLambda += dLambda; // update the model theModel->incrDisp(*deltaU); theModel->applyLoadDomain(currentLambda); theModel->updateDomain(); // set the X soln in linearSOE to be deltaU for convergence Test theLinSOE->setX(*deltaU); return 0; }
int PeriodicNewton::solveCurrentStep(void) { // set up some pointers and check they are valid // NOTE this could be taken away if we set Ptrs as protecetd in superclass AnalysisModel *theAnalysisModel = this->getAnalysisModelPtr(); IncrementalIntegrator *theIncIntegratorr = this->getIncrementalIntegratorPtr(); LinearSOE *theSOE = this->getLinearSOEptr(); if ((theAnalysisModel == 0) || (theIncIntegratorr == 0) || (theSOE == 0) || (theTest == 0)){ opserr << "WARNING PeriodicNewton::solveCurrentStep() - setLinks() has"; opserr << " not been called - or no ConvergenceTest has been set\n"; return -5; } // we form the tangent if (theIncIntegratorr->formUnbalance() < 0) { opserr << "WARNING PeriodicNewton::solveCurrentStep() -"; opserr << "the Integrator failed in formUnbalance()\n"; return -2; } if (theIncIntegratorr->formTangent(tangent) < 0){ opserr << "WARNING PeriodicNewton::solveCurrentStep() -"; opserr << "the Integrator failed in formTangent()\n"; return -1; } // set itself as the ConvergenceTest objects EquiSolnAlgo theTest->setEquiSolnAlgo(*this); if (theTest->start() < 0) { opserr << "PeriodicNewton::solveCurrentStep() -"; opserr << "the ConvergenceTest object failed in start()\n"; return -3; } // repeat until convergence is obtained or reach max num iterations int result = -1; int count = 0; int iter = 0; do { if (theSOE->solve() < 0) { opserr << "WARNING PeriodicNewton::solveCurrentStep() -"; opserr << "the LinearSysOfEqn failed in solve()\n"; return -3; } if (theIncIntegratorr->update(theSOE->getX()) < 0) { opserr << "WARNING PeriodicNewton::solveCurrentStep() -"; opserr << "the Integrator failed in update()\n"; return -4; } if (theIncIntegratorr->formUnbalance() < 0) { opserr << "WARNING PeriodicNewton::solveCurrentStep() -"; opserr << "the Integrator failed in formUnbalance()\n"; return -2; } this->record(count++); result = theTest->test(); iter++; if (iter > maxCount) { if (theIncIntegratorr->formTangent(tangent) < 0){ opserr << "WARNING PeriodicNewton::solveCurrentStep() -"; opserr << "the Integrator failed in formTangent()\n"; return -1; } iter = 0; } } while (result == -1); if (result == -2) { opserr << "PeriodicNewton::solveCurrentStep() -"; opserr << "the ConvergenceTest object failed in test()\n"; return -3; } return result; }
int BFGS::solveCurrentStep(void) { // set up some pointers and check they are valid // NOTE this could be taken away if we set Ptrs as protecetd in superclass AnalysisModel *theAnaModel = this->getAnalysisModelPtr(); IncrementalIntegrator *theIntegrator = this->getIncrementalIntegratorPtr(); LinearSOE *theSOE = this->getLinearSOEptr(); if ((theAnaModel == 0) || (theIntegrator == 0) || (theSOE == 0) || (theTest == 0)){ opserr << "WARNING BFGS::solveCurrentStep() - setLinks() has"; opserr << " not been called - or no ConvergenceTest has been set\n"; return -5; } // set itself as the ConvergenceTest objects EquiSolnAlgo theTest->setEquiSolnAlgo(*this); if (theTest->start() < 0) { opserr << "BFGS::solveCurrentStep() -"; opserr << "the ConvergenceTest object failed in start()\n"; return -3; } localTest->setEquiSolnAlgo(*this); if (rdotz == 0) rdotz = new double[numberLoops+3]; if (sdotr == 0) sdotr = new double[numberLoops+3]; int result = -1; int count = 0; do { // opserr << " BFGS -- Forming New Tangent" << endln; //form the initial tangent if (theIntegrator->formTangent(tangent) < 0){ opserr << "WARNING BFGS::solveCurrentStep() -"; opserr << "the Integrator failed in formTangent()\n"; return -1; } //form the initial residual if (theIntegrator->formUnbalance() < 0) { opserr << "WARNING BFGS::solveCurrentStep() -"; opserr << "the Integrator failed in formUnbalance()\n"; } //solve if (theSOE->solve() < 0) { opserr << "WARNING BFGS::solveCurrentStep() -"; opserr << "the LinearSysOfEqn failed in solve()\n"; return -3; } //update if ( theIntegrator->update(theSOE->getX() ) < 0) { opserr << "WARNING BFGS::solveCurrentStep() -"; opserr << "the Integrator failed in update()\n"; return -4; } // int systemSize = ( theSOE->getB() ).Size(); int systemSize = theSOE->getNumEqn( ); //temporary vector if (temp == 0 ) temp = new Vector(systemSize); //initial displacement increment if ( s[1] == 0 ) s[1] = new Vector(systemSize); *s[1] = theSOE->getX( ); if ( residOld == 0 ) residOld = new Vector(systemSize); *residOld = theSOE->getB( ) ; *residOld *= (-1.0 ); //form the residual again if (theIntegrator->formUnbalance() < 0) { opserr << "WARNING BFGS::solveCurrentStep() -"; opserr << "the Integrator failed in formUnbalance()\n"; } if ( residNew == 0 ) residNew = new Vector(systemSize); if ( du == 0 ) du = new Vector(systemSize); if ( b == 0 ) b = new Vector(systemSize); localTest->start(); int nBFGS = 1; do { //save residual *residNew = theSOE->getB( ); *residNew *= (-1.0 ); //solve if (theSOE->solve() < 0) { opserr << "WARNING BFGS::solveCurrentStep() -"; opserr << "the LinearSysOfEqn failed in solve()\n"; return -3; } //save right hand side *b = theSOE->getB( ); //save displacement increment *du = theSOE->getX( ); //BFGS modifications to du BFGSUpdate( theIntegrator, theSOE, *du, *b, nBFGS ) ; if ( theIntegrator->update( *du ) < 0 ) { opserr << "WARNING BFGS::solveCurrentStep() -"; opserr << "the Integrator failed in update()\n"; return -4; } /* opserr << " BFGS Iteration " << nBFGS << " Residual Norm = " << sqrt( (*residNew) ^ (*residNew) ) << endln; */ //increment broyden counter nBFGS += 1; //save displacement increment if ( s[nBFGS] == 0 ) s[nBFGS] = new Vector(systemSize); *s[nBFGS] = *du; //swap residuals *residOld = *residNew; //form the residual again if (theIntegrator->formUnbalance() < 0) { opserr << "WARNING BFGS::solveCurrentStep() -"; opserr << "the Integrator failed in formUnbalance()\n"; } result = localTest->test(); } while ( result == -1 && nBFGS <= numberLoops ); result = theTest->test(); this->record(count++); } while (result == -1); if (result == -2) { opserr << "BFGS::solveCurrentStep() -"; opserr << "the ConvergenceTest object failed in test()\n"; return -3; } // note - if postive result we are returning what the convergence test returned // which should be the number of iterations return result; }
int KRAlphaExplicit::domainChanged() { AnalysisModel *myModel = this->getAnalysisModel(); LinearSOE *theLinSOE = this->getLinearSOE(); const Vector &x = theLinSOE->getX(); int size = x.Size(); // create the new Matrix and Vector objects if (Ut == 0 || Ut->Size() != size) { // delete the old if (alpha1 != 0) delete alpha1; if (alpha3 != 0) delete alpha3; if (Mhat != 0) delete Mhat; if (Ut != 0) delete Ut; if (Utdot != 0) delete Utdot; if (Utdotdot != 0) delete Utdotdot; if (U != 0) delete U; if (Udot != 0) delete Udot; if (Udotdot != 0) delete Udotdot; if (Ualpha != 0) delete Ualpha; if (Ualphadot != 0) delete Ualphadot; if (Ualphadotdot != 0) delete Ualphadotdot; if (Utdothat != 0) delete Utdothat; // create the new alpha1 = new Matrix(size,size); alpha3 = new Matrix(size,size); Mhat = new Matrix(size,size); Ut = new Vector(size); Utdot = new Vector(size); Utdotdot = new Vector(size); U = new Vector(size); Udot = new Vector(size); Udotdot = new Vector(size); Ualpha = new Vector(size); Ualphadot = new Vector(size); Ualphadotdot = new Vector(size); Utdothat = new Vector(size); // check we obtained the new if (alpha1 == 0 || alpha1->noRows() != size || alpha1->noCols() != size || alpha3 == 0 || alpha3->noRows() != size || alpha3->noCols() != size || Mhat == 0 || Mhat->noRows() != size || Mhat->noCols() != size || Ut == 0 || Ut->Size() != size || Utdot == 0 || Utdot->Size() != size || Utdotdot == 0 || Utdotdot->Size() != size || U == 0 || U->Size() != size || Udot == 0 || Udot->Size() != size || Udotdot == 0 || Udotdot->Size() != size || Ualpha == 0 || Ualpha->Size() != size || Ualphadot == 0 || Ualphadot->Size() != size || Ualphadotdot == 0 || Ualphadotdot->Size() != size || Utdothat == 0 || Utdothat->Size() != size) { opserr << "WARNING KRAlphaExplicit::domainChanged() - "; opserr << "ran out of memory\n"; // delete the old if (alpha1 != 0) delete alpha1; if (alpha3 != 0) delete alpha3; if (Mhat != 0) delete Mhat; if (Ut != 0) delete Ut; if (Utdot != 0) delete Utdot; if (Utdotdot != 0) delete Utdotdot; if (U != 0) delete U; if (Udot != 0) delete Udot; if (Udotdot != 0) delete Udotdot; if (Ualpha != 0) delete Ualpha; if (Ualphadot != 0) delete Ualphadot; if (Ualphadotdot != 0) delete Ualphadotdot; if (Utdothat != 0) delete Utdothat; alpha1 = 0; alpha3 = 0; Mhat = 0; Ut = 0; Utdot = 0; Utdotdot = 0; U = 0; Udot = 0; Udotdot = 0; Ualpha = 0; Ualphadot = 0; Ualphadotdot = 0; Utdothat = 0; return -1; } } // now go through and populate U, Udot and Udotdot by iterating through // the DOF_Groups and getting the last committed velocity and accel DOF_GrpIter &theDOFs = myModel->getDOFs(); DOF_Group *dofPtr; while ((dofPtr = theDOFs()) != 0) { const ID &id = dofPtr->getID(); int idSize = id.Size(); int i; const Vector &disp = dofPtr->getCommittedDisp(); for (i=0; i < idSize; i++) { int loc = id(i); if (loc >= 0) { (*U)(loc) = disp(i); } } const Vector &vel = dofPtr->getCommittedVel(); for (i=0; i < idSize; i++) { int loc = id(i); if (loc >= 0) { (*Udot)(loc) = vel(i); } } const Vector &accel = dofPtr->getCommittedAccel(); for (i=0; i < idSize; i++) { int loc = id(i); if (loc >= 0) { (*Udotdot)(loc) = accel(i); } } } // recalculate integration parameter matrices b/c domain changed initAlphaMatrices = 1; return 0; }