int CentralDifferenceAlternative::newStep(double _deltaT) { updateCount = 0; deltaT = _deltaT; if (deltaT <= 0.0) { opserr << "CentralDifference::newStep() - error in variable\n"; opserr << "dT = " << deltaT << endln; return -2; } AnalysisModel *theModel = this->getAnalysisModel(); double time = theModel->getCurrentDomainTime(); theModel->applyLoadDomain(time); return 0; }
int AlphaOS::commit(void) { AnalysisModel *theModel = this->getAnalysisModel(); if (theModel == 0) { opserr << "WARNING AlphaOS::commit() - no AnalysisModel set\n"; return -1; } // set the time to be t+deltaT double time = theModel->getCurrentDomainTime(); time += (1.0-alpha)*deltaT; theModel->setCurrentDomainTime(time); // update the displacements in the elements if (updElemDisp == true) theModel->updateDomain(); return theModel->commitDomain(); }
int CentralDifferenceAlternative::commit(void) { AnalysisModel *theModel = this->getAnalysisModel(); if (theModel == 0) { opserr << "WARNING CentralDifferenceAlternative::commit() - no AnalysisModel set\n"; return -1; } *Ut = *Utp1; // update time in Domain to T + deltaT & commit the domain double time = theModel->getCurrentDomainTime() + deltaT; theModel->setCurrentDomainTime(time); return theModel->commitDomain(); return 0; }
int TransientIntegrator::formTangent(int statFlag) { int result = 0; statusFlag = statFlag; LinearSOE *theLinSOE = this->getLinearSOE(); AnalysisModel *theModel = this->getAnalysisModel(); if (theLinSOE == 0 || theModel == 0) { opserr << "WARNING TransientIntegrator::formTangent() "; opserr << "no LinearSOE or AnalysisModel has been set\n"; return -1; } // the loops to form and add the tangents are broken into two for // efficiency when performing parallel computations theLinSOE->zeroA(); // loop through the DOF_Groups and add the unbalance DOF_GrpIter &theDOFs = theModel->getDOFs(); DOF_Group *dofPtr; while ((dofPtr = theDOFs()) != 0) { if (theLinSOE->addA(dofPtr->getTangent(this),dofPtr->getID()) <0) { opserr << "TransientIntegrator::formTangent() - failed to addA:dof\n"; result = -1; } } // loop through the FE_Elements getting them to add the tangent FE_EleIter &theEles2 = theModel->getFEs(); FE_Element *elePtr; while((elePtr = theEles2()) != 0) { if (theLinSOE->addA(elePtr->getTangent(this),elePtr->getID()) < 0) { opserr << "TransientIntegrator::formTangent() - failed to addA:ele\n"; result = -2; } } return result; }
int TRBDF2::update(const Vector &deltaU) { AnalysisModel *theModel = this->getAnalysisModel(); if (theModel == 0) { opserr << "WARNING TRBDF2::update() - no AnalysisModel set\n"; return -1; } // check domainChanged() has been called, i.e. Ut will not be zero if (Ut == 0) { opserr << "WARNING TRBDF2::update() - domainChange() failed or not called\n"; return -2; } // check deltaU is of correct size if (deltaU.Size() != U->Size()) { opserr << "WARNING TRBDF2::update() - Vectors of incompatible size "; opserr << " expecting " << U->Size() << " obtained " << deltaU.Size() << endln; return -3; } // determine the response at t+deltaT if (step == 0) { (*U) += deltaU; Udot->addVector(1.0, deltaU, c2); Udotdot->addVector(1.0, deltaU, c3); } else { (*U) += deltaU; Udot->addVector(1.0, deltaU, c2); Udotdot->addVector(1.0, deltaU, c3); } // update the response at the DOFs theModel->setResponse(*U,*Udot,*Udotdot); if (theModel->updateDomain() < 0) { opserr << "TRBDF2::update() - failed to update the domain\n"; return -4; } return 0; }
int PFEMIntegrator::newStep(double deltaT) { if (deltaT <= 0.0) { opserr << "PFEMIntegrator::newStep() - error in variable\n"; opserr << "dT = " << deltaT << endln; return -2; } // get a pointer to the AnalysisModel and Domain AnalysisModel *theModel = this->getAnalysisModel(); if(theModel == 0) { opserr << "Analysis model has not been linked - PFEMIntegrator::newStep()\n"; return -1; } Domain* theDomain = theModel->getDomainPtr(); if(theDomain == 0) { opserr<<"WARNING: no domain is set for the model"; opserr<<" -- PFEMIntegrator::newStep()\n"; return -1; } // set the constants c1 = deltaT; c2 = 1.0; c3 = 1.0/deltaT; c4 = deltaT*deltaT; c5 = deltaT; c6 = 1.0; // check if domainchange() is called if (U == 0) { opserr << "PFEMIntegrator::newStep() - domainChange() failed or hasn't been called\n"; return -3; } // set response at t to be that at t+deltaT of previous step (*Ut) = *U; (*Utdot) = *Udot; (*Utdotdot) = *Udotdot; // determinte new disps and accels U->addVector(1.0, *Utdot, deltaT); Udotdot->Zero(); // set states theModel->setDisp(*U); theModel->setAccel(*Udotdot); // increment the time to t+deltaT and apply the load double time = theModel->getCurrentDomainTime(); time += deltaT; if (theModel->updateDomain(time, deltaT) < 0) { opserr << "PFEMIntegrator::newStep() - failed to update the domain\n"; return -4; } return 0; }
int CollocationHSIncrReduct::update(const Vector &deltaU) { AnalysisModel *theModel = this->getAnalysisModel(); if (theModel == 0) { opserr << "WARNING CollocationHSIncrReduct::update() - no AnalysisModel set\n"; return -1; } // check domainChanged() has been called, i.e. Ut will not be zero if (Ut == 0) { opserr << "WARNING CollocationHSIncrReduct::update() - domainChange() failed or not called\n"; return -2; } // check deltaU is of correct size if (deltaU.Size() != U->Size()) { opserr << "WARNING CollocationHSIncrReduct::update() - Vectors of incompatible size "; opserr << " expecting " << U->Size() << " obtained " << deltaU.Size() << endln; return -3; } // get scaled increment (*scaledDeltaU) = reduct*deltaU; // determine the response at t+theta*deltaT U->addVector(1.0, *scaledDeltaU, c1); Udot->addVector(1.0, *scaledDeltaU, c2); Udotdot->addVector(1.0, *scaledDeltaU, c3); // update the response at the DOFs theModel->setResponse(*U, *Udot, *Udotdot); if (theModel->updateDomain() < 0) { opserr << "CollocationHSIncrReduct::update() - failed to update the domain\n"; return -4; } return 0; }
int NewmarkHSFixedNumIter::commit(void) { AnalysisModel *theModel = this->getAnalysisModel(); if (theModel == 0) { opserr << "WARNING NewmarkHSFixedNumIter::commit() - no AnalysisModel set\n"; return -1; } LinearSOE *theSOE = this->getLinearSOE(); if (theSOE == 0) { opserr << "WARNING NewmarkHSFixedNumIter::commit() - no LinearSOE set\n"; return -2; } if (this->formTangent(statusFlag) < 0) { opserr << "WARNING NewmarkHSFixedNumIter::commit() - " << "the Integrator failed in formTangent()\n"; return -3; } if (theSOE->solve() < 0) { opserr << "WARNING NewmarkHSFixedNumIter::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); return theModel->commitDomain(); }
int XC::Collocation::commit(void) { AnalysisModel *theModel = this->getAnalysisModelPtr(); if (theModel == 0) { std::cerr << "WARNING XC::Collocation::commit() - no XC::AnalysisModel set\n"; return -1; } // determine response quantities at t+deltaT U.getDotDot().addVector(1.0/theta, Ut.getDotDot(), (theta-1.0)/theta); (U.getDot()) = Ut.getDot(); double a1 = deltaT*(1.0 - gamma); double a2 = deltaT*gamma; U.getDot().addVector(1.0, Ut.getDotDot(), a1); U.getDot().addVector(1.0, U.getDotDot(), a2); U.get()= Ut.get(); U.get().addVector(1.0, Ut.getDot(), deltaT); double a3 = deltaT*deltaT*(0.5 - beta); double a4 = deltaT*deltaT*beta; U.get().addVector(1.0, Ut.getDotDot(), a3); U.get().addVector(1.0, U.getDotDot(), a4); // update the response at the DOFs theModel->setResponse(U.get(),U.getDot(),U.getDotDot()); // if (theModel->updateDomain() < 0) { // std::cerr << "XC::Collocation::commit() - failed to update the domain\n"; // return -4; // } // set the time to be t+delta t double time= getCurrentModelTime(); time += (1.0-theta)*deltaT; setCurrentModelTime(time); return commitModel(); }
int XC::HHTHybridSimulation::commit(void) { AnalysisModel *theModel = this->getAnalysisModelPtr(); if(theModel == 0) { std::cerr << "WARNING XC::HHTHybridSimulation::commit() - no XC::AnalysisModel set\n"; return -1; } // update the response at the DOFs theModel->setResponse(U.get(),U.getDot(),U.getDotDot()); // if (theModel->updateDomain() < 0) { // std::cerr << "XC::HHTHybridSimulation::commit() - failed to update the domain\n"; // return -4; // } // set the time to be t+deltaT double time = getCurrentModelTime(); time+= (1.0-alphaF)*deltaT; setCurrentModelTime(time); return commitModel(); }
int XC::Collocation::update(const Vector &deltaU) { AnalysisModel *theModel = this->getAnalysisModelPtr(); if (theModel == 0) { std::cerr << "WARNING XC::Collocation::update() - no XC::AnalysisModel set\n"; return -1; } // check domainChanged() has been called, i.e. Ut will not be zero if (Ut.get().Size() == 0) { std::cerr << "WARNING XC::Collocation::update() - domainChange() failed or not called\n"; return -2; } // check deltaU is of correct size if (deltaU.Size() != U.get().Size()) { std::cerr << "WARNING XC::Collocation::update() - Vectors of incompatible size "; std::cerr << " expecting " << U.get().Size() << " obtained " << deltaU.Size() << std::endl; return -3; } // determine the response at t+theta*deltaT (U.get()) += deltaU; U.getDot().addVector(1.0, deltaU, c2); U.getDotDot().addVector(1.0, deltaU, c3); // update the response at the DOFs theModel->setResponse(U.get(),U.getDot(),U.getDotDot()); if(updateModel() < 0) { std::cerr << "XC::Collocation::update() - failed to update the domain\n"; return -4; } return 0; }
int LoadControl::update(const Vector &deltaU) { AnalysisModel *myModel = this->getAnalysisModel(); LinearSOE *theSOE = this->getLinearSOE(); if (myModel == 0 || theSOE == 0) { opserr << "WARNING LoadControl::update() "; opserr << "No AnalysisModel or LinearSOE has been set\n"; return -1; } myModel->incrDisp(deltaU); if (myModel->updateDomain() < 0) { opserr << "LoadControl::update - model failed to update for new dU\n"; return -1; } // Set deltaU for the convergence test theSOE->setX(deltaU); numIncrLastStep++; return 0; }
//! @brief Constructor. //! //! The constructor is responsible for constructing the graph given {\em //! theModel}. It creates the vertices of the graph, one for every //! equation (each DOF that has not been constrained out by the //! constraint handler) in the model and adds all edges based on the //! FE\_Element connectivity. For this reason the model must be fully //! populated with the DOF\_Group and FE\_Element objects before // the constructor is called. XC::DOF_GroupGraph::DOF_GroupGraph(const AnalysisModel &theModel) :ModelGraph(theModel.getNumDOF_Groups()+START_VERTEX_NUM,theModel) { assert(myModel); const int numVertex= myModel->getNumDOF_Groups(); if(numVertex>0) { const DOF_Group *dofGroupPtr= nullptr; // now create the vertices with a reference equal to the DOF_Group number. // and a tag which ranges from 0 through numVertex-1 DOF_GrpConstIter &dofIter2 = myModel->getConstDOFs(); while((dofGroupPtr = dofIter2()) != 0) { const int DOF_GroupTag = dofGroupPtr->getTag(); const int DOF_GroupNodeTag = dofGroupPtr->getNodeTag(); const int numDOF = dofGroupPtr->getNumFreeDOF(); Vertex vrt(DOF_GroupTag, DOF_GroupNodeTag, 0, numDOF); this->addVertex(vrt); } // now add the edges, by looping over the Elements, getting their // IDs and adding edges between DOFs for equation numbers >= START_EQN_NUM const FE_Element *elePtr= nullptr; FE_EleConstIter &eleIter = myModel->getConstFEs(); while((elePtr = eleIter()) != 0) { const ID &id= elePtr->getDOFtags(); const int size = id.Size(); for(int i=0; i<size; i++) { int dof1 = id(i); for(int j=0; j<size; j++) if(i != j) { const int dof2 = id(j); this->addEdge(dof1,dof2); } } } } }
int GeneralizedAlpha::commit(void) { AnalysisModel *theModel = this->getAnalysisModel(); if (theModel == 0) { opserr << "WARNING GeneralizedAlpha::commit() - no AnalysisModel set\n"; return -1; } // update the response at the DOFs theModel->setResponse(*U,*Udot,*Udotdot); if (theModel->updateDomain() < 0) { opserr << "GeneralizedAlpha::commit() - failed to update the domain\n"; return -4; } // set the time to be t+deltaT double time = theModel->getCurrentDomainTime(); time += (1.0-alphaF)*deltaT; theModel->setCurrentDomainTime(time); return theModel->commitDomain(); }
//! @brief Handle the constraints. //! //! Determines the number of FE\_Elements and DOF\_Groups needed from the //! Domain (a one to one mapping between Elements and FE\_Elements and //! Nodes and DOF\_Groups) Creates two arrays of pointers to store the //! FE\_elements and DOF\_Groups, returning a warning message and a \f$-2\f$ //! or \f$-3\f$ if not enough memory is available for these arrays. Then the //! object will iterate through the Nodes of the Domain, creating a //! DOF\_Group for each node and setting the initial id for each dof to //! \f$-2\f$ if no SFreedom\_Constraint exists for the dof, or \f$-1\f$ if a //! SFreedom\_Constraint exists or \f$-3\f$ if the node identifier is in {\em //! nodesToBeNumberedLast}. The object then iterates through the Elements //! of the Domain creating a FE\_Element for each Element, if the Element //! is a Subdomain setFE\_ElementPtr() is invoked on the Subdomain //! with the new FE\_Element as the argument. If not enough memory is //! available for any DOF\_Group or FE\_element a warning message is //! printed and a \f$-4\f$ or \f$-5\f$ is returned. If any MFreedom\_Constraint //! objects exist in the Domain a warning message is printed and \f$-6\f$ is //! returned. If all is successful, the method returns the number of //! degrees-of-freedom associated with the DOF\_Groups in {\em //! nodesToBeNumberedLast}. int XC::PlainHandler::handle(const ID *nodesLast) { // first check links exist to a Domain and an AnalysisModel object Domain *theDomain = this->getDomainPtr(); AnalysisModel *theModel = this->getAnalysisModelPtr(); Integrator *theIntegrator = this->getIntegratorPtr(); if((!theDomain) || (!theModel) || (!theIntegrator)) { std::cerr << getClassName() << "::" << __FUNCTION__ << "; domain, model or integrator was not set.\n"; return -1; } // initialse the DOF_Groups and add them to the AnalysisModel. // : must of course set the initial IDs NodeIter &theNod= theDomain->getNodes(); Node *nodPtr= nullptr; SFreedom_Constraint *spPtr= nullptr; DOF_Group *dofPtr= nullptr; int numDOF = 0; int count3 = 0; int countDOF =0; while((nodPtr = theNod()) != nullptr) { dofPtr= theModel->createDOF_Group(numDOF++, nodPtr); // initially set all the ID value to -2 countDOF+= dofPtr->inicID(-2); // loop through the SFreedom_Constraints to see if any of the // DOFs are constrained, if so set initial XC::ID value to -1 int nodeID = nodPtr->getTag(); SFreedom_ConstraintIter &theSPs = theDomain->getConstraints().getDomainAndLoadPatternSPs(); while((spPtr = theSPs()) != 0) if(spPtr->getNodeTag() == nodeID) { if(spPtr->isHomogeneous() == false) std::cerr << getClassName() << "::" << __FUNCTION__ << "; non-homogeneos constraint" << " for node " << spPtr->getNodeTag() << " h**o assumed\n"; const ID &id = dofPtr->getID(); int dof = spPtr->getDOF_Number(); if(id(dof) == -2) { dofPtr->setID(spPtr->getDOF_Number(),-1); countDOF--; } else std::cerr << getClassName() << "::" << __FUNCTION__ << "; multiple single pointconstraints at DOF " << dof << " for node " << spPtr->getNodeTag() << std::endl; } // loop through the MFreedom_Constraints to see if any of the // DOFs are constrained, note constraint matrix must be diagonal // with 1's on the diagonal MFreedom_ConstraintIter &theMPs = theDomain->getConstraints().getMPs(); MFreedom_Constraint *mpPtr; while((mpPtr = theMPs()) != 0) { if(mpPtr->getNodeConstrained() == nodeID) { if(mpPtr->isTimeVarying() == true) std::cerr << getClassName() << "::" << __FUNCTION__ << "; time-varying constraint" << " for node " << nodeID << " non-varying assumed\n"; const Matrix &C = mpPtr->getConstraint(); int numRows = C.noRows(); int numCols = C.noCols(); if(numRows != numCols) std::cerr << getClassName() << "::" << __FUNCTION__ << " constraint matrix not diagonal," << " ignoring constraint for node " << nodeID << std::endl; else { int ok = 0; for(int i=0; i<numRows; i++) { if(C(i,i) != 1.0) ok = 1; for(int j=0; j<numRows; j++) if(i != j) if(C(i,j) != 0.0) ok = 1; } if(ok != 0) std::cerr << getClassName() << "::" << __FUNCTION__ << "; constraint matrix not identity," << " ignoring constraint for node " << nodeID << std::endl; else { const ID &dofs = mpPtr->getConstrainedDOFs(); const ID &id = dofPtr->getID(); for(int i=0; i<dofs.Size(); i++) { int dof = dofs(i); if(id(dof) == -2) { dofPtr->setID(dof,-4); countDOF--; } else std::cerr << getClassName() << "::" << __FUNCTION__ << "; constraint at dof " << dof << " already specified for constrained node" << " in MFreedom_Constraint at node " << nodeID << std::endl; } } } } } // loop through the MFreedom_Constraints to see if any of the // DOFs are constrained, note constraint matrix must be diagonal // with 1's on the diagonal MRMFreedom_ConstraintIter &theMRMPs = theDomain->getConstraints().getMRMPs(); MRMFreedom_Constraint *mrmpPtr; while((mrmpPtr = theMRMPs()) != 0) { std::cerr << getClassName() << "::" << __FUNCTION__ << "; loop through the MRMFreedom_Constraints." << std::endl; } } // set the number of eqn in the model theModel->setNumEqn(countDOF); // now see if we have to set any of the dof's to -3 // int numLast = 0; if(nodesLast != 0) for(int i=0; i<nodesLast->Size(); i++) { int nodeID = (*nodesLast)(i); Node *nodPtr = theDomain->getNode(nodeID); if(nodPtr != 0) { dofPtr = nodPtr->getDOF_GroupPtr(); const ID &id = dofPtr->getID(); // set all the dof values to -3 for (int j=0; j < id.Size(); j++) if(id(j) == -2) { dofPtr->setID(j,-3); count3++; } else std::cerr << getClassName() << "::" << __FUNCTION__ << "; boundary sp constraint in subdomain" << " this should not be - results suspect \n"; } } // initialise the FE_Elements and add to the XC::AnalysisModel. ElementIter &theEle = theDomain->getElements(); Element *elePtr; int numFe = 0; FE_Element *fePtr; while((elePtr = theEle()) != 0) { fePtr= theModel->createFE_Element(numFe++, elePtr); } return count3; }
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 HHT1::newStep(double deltaT) { if (beta == 0 || gamma == 0 ) { opserr << "HHT1::newStep() - error in variable\n"; opserr << "gamma = " << gamma << " beta= " << beta << endln; return -1; } if (deltaT <= 0.0) { opserr << "HHT1::newStep() - error in variable\n"; opserr << "dT = " << deltaT << endln; return -2; } c1 = 1.0; c2 = gamma/(beta*deltaT); c3 = 1.0/(beta*deltaT*deltaT); AnalysisModel *theModel = this->getAnalysisModel(); if (U == 0) { opserr << "HHT1::newStep() - domainChange() failed or hasn't been called\n"; return -3; } // set response at t to be that at t+delta t of previous step (*Ut) = *U; (*Utdot) = *Udot; (*Utdotdot) = *Udotdot; // set new velocity and accelerations at t + delta t double a1 = (1.0 - gamma/beta); double a2 = (deltaT)*(1.0 - 0.5*gamma/beta); // (*Udot) *= a1; Udot->addVector(a1, *Utdotdot,a2); double a3 = -1.0/(beta*deltaT); double a4 = 1 - 0.5/beta; // (*Udotdot) *= a4; Udotdot->addVector(a4, *Utdot,a3); (*Ualpha) = *Ut; (*Udotalpha) = *Utdot; // (*Udotalpha) *= (1 - alpha); Udotalpha->addVector((1-alpha), *Udot, alpha); // set the new trial response quantities theModel->setResponse(*Ualpha,*Udotalpha,*Udotdot); // increment the time and apply the load double time = theModel->getCurrentDomainTime(); time +=deltaT; if (theModel->updateDomain(time, deltaT) < 0) { opserr << "HHT::newStep() - failed to update the domain\n"; return -4; } return 0; }
int TRBDF2::newStep(double deltaT) { // check the vectors have been created if (U == 0) { opserr << "TRBDF2::newStep() - domainChange() failed or hasn't been called\n"; return -3; } // mark step as Trapezoidal (=0) or Backward Euler (=1) if (deltaT != dt || step == 1) { step = 0; } else step = 1; // get a pointer to the AnalysisModel AnalysisModel *theModel = this->getAnalysisModel(); // set response at t to be that at t+deltaT of previous step dt = deltaT; (*Utm1) = *Ut; (*Utm1dot) = *Utdot; (*Ut) = *U; (*Utdot) = *Udot; (*Utdotdot) = *Udotdot; // set the constants if (step == 0) { // trapezoidal c1 = 1.0; c2 = 2.0/deltaT; c3 = 4.0/(deltaT*deltaT); (*Udot) *= -1.0; double a3 = -4.0/deltaT; double a4 = -1; Udotdot->addVector(a4, *Utdot, a3); // set the trial response quantities theModel->setVel(*Udot); theModel->setAccel(*Udotdot); } else { // backward euler c1 = 1.0; c2 = 1.5/deltaT; c3 = 2.25/(deltaT*deltaT); (*Udot) = *Utm1; Udot->addVector(0.5/deltaT, *Ut, -1/(2.0*deltaT)); (*Udotdot) = *Utm1dot; Udotdot->addVector(0.5/deltaT, *Utdot, -4.0/(2.0*deltaT)); Udotdot->addVector(1.0, *Udot, 3.0/(2.0*deltaT)); // set the trial response quantities theModel->setVel(*Udot); theModel->setAccel(*Udotdot); } // increment the time to t+deltaT and apply the load double time = theModel->getCurrentDomainTime(); time += deltaT; if (theModel->updateDomain(time, deltaT) < 0) { opserr << "TRBDF2::newStep() - failed to update the domain\n"; return -4; } return 0; }
int LagrangeConstraintHandler::handle(const ID *nodesLast) { // first check links exist to a Domain and an AnalysisModel object Domain *theDomain = this->getDomainPtr(); AnalysisModel *theModel = this->getAnalysisModelPtr(); Integrator *theIntegrator = this->getIntegratorPtr(); if ((theDomain == 0) || (theModel == 0) || (theIntegrator == 0)) { opserr << "WARNING LagrangeConstraintHandler::handle() - "; opserr << " setLinks() has not been called\n"; return -1; } // get number ofelements and nodes in the domain // and init the theFEs and theDOFs arrays int numConstraints = 0; SP_ConstraintIter &theSPss = theDomain->getDomainAndLoadPatternSPs(); SP_Constraint *spPtr; while ((spPtr = theSPss()) != 0) numConstraints++; numConstraints += theDomain->getNumMPs(); //create a DOF_Group for each Node and add it to the AnalysisModel. // : must of course set the initial IDs NodeIter &theNod = theDomain->getNodes(); Node *nodPtr; MP_Constraint *mpPtr; DOF_Group *dofPtr; int numDofGrp = 0; int count3 = 0; int countDOF =0; while ((nodPtr = theNod()) != 0) { if ((dofPtr = new DOF_Group(numDofGrp++, nodPtr)) == 0) { opserr << "WARNING LagrangeConstraintHandler::handle() "; opserr << "- ran out of memory"; opserr << " creating DOF_Group " << numDofGrp++ << endln; return -4; } // initially set all the ID value to -2 const ID &id = dofPtr->getID(); for (int j=0; j < id.Size(); j++) { dofPtr->setID(j,-2); countDOF++; } nodPtr->setDOF_GroupPtr(dofPtr); theModel->addDOF_Group(dofPtr); } // create the FE_Elements for the Elements and add to the AnalysisModel ElementIter &theEle = theDomain->getElements(); Element *elePtr; int numFeEle = 0; FE_Element *fePtr; while ((elePtr = theEle()) != 0) { // only create an FE_Element for a subdomain element if it does not // do independent analysis .. then subdomain part of this analysis so create // an FE_element & set subdomain to point to it. if (elePtr->isSubdomain() == true) { Subdomain *theSub = (Subdomain *)elePtr; if (theSub->doesIndependentAnalysis() == false) { if ((fePtr = new FE_Element(numFeEle++, elePtr)) == 0) { opserr << "WARNING PlainHandler::handle() - ran out of memory"; opserr << " creating FE_Element " << elePtr->getTag() << endln; return -5; } theModel->addFE_Element(fePtr); theSub->setFE_ElementPtr(fePtr); } // if (theSub->doesIndependentAnalysis() == false) { } else { // just a regular element .. create an FE_Element for it & add to AnalysisModel if ((fePtr = new FE_Element(numFeEle++, elePtr)) == 0) { opserr << "WARNING PlainHandler::handle() - ran out of memory"; opserr << " creating FE_Element " << elePtr->getTag() << endln; return -5; } theModel->addFE_Element(fePtr); } } // create the LagrangeSP_FE for the SP_Constraints and // add to the AnalysisModel SP_ConstraintIter &theSPs = theDomain->getDomainAndLoadPatternSPs(); while ((spPtr = theSPs()) != 0) { if ((dofPtr = new LagrangeDOF_Group(numDofGrp++, *spPtr)) == 0) { opserr << "WARNING LagrangeConstraintHandler::handle()"; opserr << " - ran out of memory"; opserr << " creating LagrangeDOFGroup " << endln; return -5; } const ID &id = dofPtr->getID(); for (int j=0; j < id.Size(); j++) { dofPtr->setID(j,-2); countDOF++; } theModel->addDOF_Group(dofPtr); if ((fePtr = new LagrangeSP_FE(numFeEle++, *theDomain, *spPtr, *dofPtr, alphaSP)) == 0) { opserr << "WARNING LagrangeConstraintHandler::handle()"; opserr << " - ran out of memory"; opserr << " creating LagrangeSP_FE " << endln; return -5; } theModel->addFE_Element(fePtr); } // create the LagrangeMP_FE for the MP_Constraints and // add to the AnalysisModel MP_ConstraintIter &theMPs = theDomain->getMPs(); while ((mpPtr = theMPs()) != 0) { if ((dofPtr = new LagrangeDOF_Group(numDofGrp++, *mpPtr)) == 0) { opserr << "WARNING LagrangeConstraintHandler::handle()"; opserr << " - ran out of memory"; opserr << " creating LagrangeDOFGroup " << endln; return -5; } const ID &id = dofPtr->getID(); for (int j=0; j < id.Size(); j++) { dofPtr->setID(j,-2); countDOF++; } theModel->addDOF_Group(dofPtr); if ((fePtr = new LagrangeMP_FE(numFeEle++, *theDomain, *mpPtr, *dofPtr, alphaMP)) == 0) { opserr << "WARNING LagrangeConstraintHandler::handle()"; opserr << " - ran out of memory"; opserr << " creating LagrangeMP_FE " << endln; return -5; } theModel->addFE_Element(fePtr); } theModel->setNumEqn(countDOF); // set the number of eqn in the model // now see if we have to set any of the dof's to -3 // int numLast = 0; if (nodesLast != 0) for (int i=0; i<nodesLast->Size(); i++) { int nodeID = (*nodesLast)(i); Node *nodPtr = theDomain->getNode(nodeID); if (nodPtr != 0) { dofPtr = nodPtr->getDOF_GroupPtr(); const ID &id = dofPtr->getID(); // set all the dof values to -3 for (int j=0; j < id.Size(); j++) if (id(j) == -2) { dofPtr->setID(j,-3); count3++; } else { opserr << "WARNING LagrangeConstraintHandler::handle() "; opserr << " - boundary sp constraint in subdomain"; opserr << " this should not be - results suspect \n"; } } } return count3; }
int PlainNumberer::numberDOF(int lastDOF) { int eqnNumber = 0; // start equation number = 0 // get a pointer to the model & check its not null AnalysisModel *theModel = this->getAnalysisModelPtr(); Domain *theDomain = 0; if (theModel != 0) theDomain = theModel->getDomainPtr(); if (theModel == 0 || theDomain == 0) { opserr << "WARNING PlainNumberer::numberDOF(int) -"; opserr << " - no AnalysisModel - has setLinks() been invoked?\n"; return -1; } if (lastDOF != -1) { opserr << "WARNING PlainNumberer::numberDOF(int lastDOF):"; opserr << " does not use the lastDOF as requested\n"; } // iterate throgh the DOFs first time setting -2 values DOF_GrpIter &theDOFs = theModel->getDOFs(); DOF_Group *dofPtr; while ((dofPtr = theDOFs()) != 0) { const ID &theID = dofPtr->getID(); for (int i=0; i<theID.Size(); i++) if (theID(i) == -2) dofPtr->setID(i,eqnNumber++); } // iterate throgh the DOFs second time setting -3 values DOF_GrpIter &moreDOFs = theModel->getDOFs(); while ((dofPtr = moreDOFs()) != 0) { const ID &theID = dofPtr->getID(); for (int i=0; i<theID.Size(); i++) if (theID(i) == -3) dofPtr->setID(i,eqnNumber++); } // iterate through the DOFs one last time setting any -4 values DOF_GrpIter &tDOFs = theModel->getDOFs(); while ((dofPtr = tDOFs()) != 0) { const ID &theID = dofPtr->getID(); int have4s = 0; for (int i=0; i<theID.Size(); i++) if (theID(i) == -4) have4s = 1; if (have4s == 1) { int nodeID = dofPtr->getNodeTag(); // loop through the MP_Constraints to see if any of the // DOFs are constrained, note constraint matrix must be diagonal // with 1's on the diagonal MP_ConstraintIter &theMPs = theDomain->getMPs(); MP_Constraint *mpPtr; while ((mpPtr = theMPs()) != 0 ) { // note keep looping over all in case multiple constraints // are used to constrain a node -- can't assume intelli user if (mpPtr->getNodeConstrained() == nodeID) { int nodeRetained = mpPtr->getNodeRetained(); Node *nodeRetainedPtr = theDomain->getNode(nodeRetained); DOF_Group *retainedDOF = nodeRetainedPtr->getDOF_GroupPtr(); const ID&retainedDOFIDs = retainedDOF->getID(); const ID&constrainedDOFs = mpPtr->getConstrainedDOFs(); const ID&retainedDOFs = mpPtr->getRetainedDOFs(); for (int i=0; i<constrainedDOFs.Size(); i++) { int dofC = constrainedDOFs(i); int dofR = retainedDOFs(i); int dofID = retainedDOFIDs(dofR); dofPtr->setID(dofC, dofID); } } } } } eqnNumber--; int numEqn = eqnNumber - START_EQN_NUMBER +1; // iterate through the FE_Element getting them to set their IDs FE_EleIter &theEle = theModel->getFEs(); FE_Element *elePtr; while ((elePtr = theEle()) != 0) elePtr->setID(); // set the numOfEquation in the Model theModel->setNumEqn(numEqn); return numEqn; }
int TransformationConstraintHandler::handle(const ID *nodesLast) { // first check links exist to a Domain and an AnalysisModel object Domain *theDomain = this->getDomainPtr(); AnalysisModel *theModel = this->getAnalysisModelPtr(); Integrator *theIntegrator = this->getIntegratorPtr(); if ((theDomain == 0) || (theModel == 0) || (theIntegrator == 0)) { opserr << "WARNING TransformationConstraintHandler::handle() - "; opserr << " setLinks() has not been called\n"; return -1; } // get number ofelements and nodes in the domain // and init the theFEs and theDOFs arrays int numMPConstraints = theDomain->getNumMPs(); // int numSPConstraints = theDomain->getNumSPs(); int numSPConstraints = 0; SP_ConstraintIter &theSP1s = theDomain->getDomainAndLoadPatternSPs(); SP_Constraint *theSP1; while ((theSP1 = theSP1s()) != 0) numSPConstraints++; numDOF = 0; ID transformedNode(0, 64); int i; // create an ID of constrained node tags in MP_Constraints ID constrainedNodesMP(0, numMPConstraints); MP_Constraint **mps =0; if (numMPConstraints != 0) { mps = new MP_Constraint *[numMPConstraints]; if (mps == 0) { opserr << "WARNING TransformationConstraintHandler::handle() - "; opserr << "ran out of memory for MP_Constraints"; opserr << " array of size " << numMPConstraints << endln; return -3; } MP_ConstraintIter &theMPs = theDomain->getMPs(); MP_Constraint *theMP; int index = 0; while ((theMP = theMPs()) != 0) { int nodeConstrained = theMP->getNodeConstrained(); if (transformedNode.getLocation(nodeConstrained) < 0) transformedNode[numDOF++] = nodeConstrained; constrainedNodesMP[index] = nodeConstrained; mps[index] = theMP; index++; } } // create an ID of constrained node tags in SP_Constraints ID constrainedNodesSP(0, numSPConstraints);; SP_Constraint **sps =0; if (numSPConstraints != 0) { sps = new SP_Constraint *[numSPConstraints]; if (sps == 0) { opserr << "WARNING TransformationConstraintHandler::handle() - "; opserr << "ran out of memory for SP_Constraints"; opserr << " array of size " << numSPConstraints << endln; if (mps != 0) delete [] mps; if (sps != 0) delete [] sps; return -3; } SP_ConstraintIter &theSPs = theDomain->getDomainAndLoadPatternSPs(); SP_Constraint *theSP; int index = 0; while ((theSP = theSPs()) != 0) { int constrainedNode = theSP->getNodeTag(); if (transformedNode.getLocation(constrainedNode) < 0) transformedNode[numDOF++] = constrainedNode; constrainedNodesSP[index] = constrainedNode; sps[index] = theSP; index++; } } // create an array for the DOF_Groups and zero it if ((numDOF != 0) && ((theDOFs = new DOF_Group *[numDOF]) == 0)) { opserr << "WARNING TransformationConstraintHandler::handle() - "; opserr << "ran out of memory for DOF_Groups"; opserr << " array of size " << numDOF << endln; return -3; } for (i=0; i<numDOF; i++) theDOFs[i] = 0; //create a DOF_Group for each Node and add it to the AnalysisModel. // :must of course set the initial IDs NodeIter &theNod = theDomain->getNodes(); Node *nodPtr; int numDofGrp = 0; int count3 = 0; int countDOF =0; numConstrainedNodes = 0; numDOF = 0; while ((nodPtr = theNod()) != 0) { DOF_Group *dofPtr = 0; int nodeTag = nodPtr->getTag(); int numNodalDOF = nodPtr->getNumberDOF(); int loc = -1; int createdDOF = 0; loc = constrainedNodesMP.getLocation(nodeTag); if (loc >= 0) { TransformationDOF_Group *tDofPtr = new TransformationDOF_Group(numDofGrp++, nodPtr, mps[loc], this); createdDOF = 1; dofPtr = tDofPtr; // add any SPs if (numSPConstraints != 0) { loc = constrainedNodesSP.getLocation(nodeTag); if (loc >= 0) { tDofPtr->addSP_Constraint(*(sps[loc])); for (int i = loc+1; i<numSPConstraints; i++) { if (constrainedNodesSP(i) == nodeTag) tDofPtr->addSP_Constraint(*(sps[i])); } } // add the DOF to the array theDOFs[numDOF++] = dofPtr; numConstrainedNodes++; } } if (createdDOF == 0) { loc = constrainedNodesSP.getLocation(nodeTag); if (loc >= 0) { TransformationDOF_Group *tDofPtr = new TransformationDOF_Group(numDofGrp++, nodPtr, this); int numSPs = 1; createdDOF = 1; dofPtr = tDofPtr; tDofPtr->addSP_Constraint(*(sps[loc])); // check for more SP_constraints acting on node and add them for (int i = loc+1; i<numSPConstraints; i++) { if (constrainedNodesSP(i) == nodeTag) { tDofPtr->addSP_Constraint(*(sps[i])); numSPs++; } } // add the DOF to the array theDOFs[numDOF++] = dofPtr; numConstrainedNodes++; countDOF+= numNodalDOF - numSPs; } } // create an ordinary DOF_Group object if no dof constrained if (createdDOF == 0) { if ((dofPtr = new DOF_Group(numDofGrp++, nodPtr)) == 0) { opserr << "WARNING TransformationConstraintHandler::handle() "; opserr << "- ran out of memory"; opserr << " creating DOF_Group " << i << endln; if (mps != 0) delete [] mps; if (sps != 0) delete [] sps; return -4; } countDOF+= numNodalDOF; } if (dofPtr == 0) opserr << "TransformationConstraintHandler::handle() - error in logic\n"; nodPtr->setDOF_GroupPtr(dofPtr); theModel->addDOF_Group(dofPtr); } // create the FE_Elements for the Elements and add to the AnalysisModel ElementIter &theEle = theDomain->getElements(); Element *elePtr; FE_Element *fePtr; numFE = 0; ID transformedEle(0, 64); while ((elePtr = theEle()) != 0) { int flag = 0; if (elePtr->isSubdomain() == true) { Subdomain *theSub = (Subdomain *)elePtr; if (theSub->doesIndependentAnalysis() == true) flag = 1; } if (flag == 0) { const ID &nodes = elePtr->getExternalNodes(); int nodesSize = nodes.Size(); int isConstrainedNode = 0; for (int i=0; i<nodesSize; i++) { int nodeTag = nodes(i); if (numMPConstraints != 0) { int loc = constrainedNodesMP.getLocation(nodeTag); if (loc >= 0) { isConstrainedNode = 1; i = nodesSize; } } if (numSPConstraints != 0 && isConstrainedNode == 0) { int loc = constrainedNodesSP.getLocation(nodeTag); if (loc >= 0) { isConstrainedNode = 1; i = nodesSize; } } } if (isConstrainedNode == 1) { transformedEle[numFE++] = elePtr->getTag(); } } } // create an array for the FE_elements and zero it if ((numFE != 0) && ((theFEs = new FE_Element *[numFE]) == 0)) { opserr << "WARNING TransformationConstraintHandler::handle() - "; opserr << "ran out of memory for FE_elements"; opserr << " array of size " << numFE << endln; return -2; } for (i=0; i<numFE; i++) theFEs[i] = 0; ElementIter &theEle1 = theDomain->getElements(); // int numConstraints = numMPConstraints+numSPConstraints; int numFeEle = 0; int numFE = 0; while ((elePtr = theEle1()) != 0) { int tag = elePtr->getTag(); if (elePtr->isSubdomain() == true) { Subdomain *theSub = (Subdomain *)elePtr; if (theSub->doesIndependentAnalysis() == false) { if (transformedEle.getLocation(tag) < 0) { if ((fePtr = new FE_Element(numFeEle, elePtr)) == 0) { opserr << "WARNING TransformationConstraintHandler::handle()"; opserr << " - ran out of memory"; opserr << " creating FE_Element " << elePtr->getTag() << endln; if (mps != 0) delete [] mps; if (sps != 0) delete [] sps; return -5; } } else { if ((fePtr = new TransformationFE(numFeEle, elePtr)) == 0) { opserr << "WARNING TransformationConstraintHandler::handle()"; opserr << " - ran out of memory"; opserr << " creating TransformationFE " << elePtr->getTag() << endln; if (mps != 0) delete [] mps; if (sps != 0) delete [] sps; return -6; } theFEs[numFE++] = fePtr; } numFeEle++; theModel->addFE_Element(fePtr); theSub->setFE_ElementPtr(fePtr); } } else { if (transformedEle.getLocation(tag) < 0) { if ((fePtr = new FE_Element(numFeEle, elePtr)) == 0) { opserr << "WARNING TransformationConstraintHandler::handle()"; opserr << " - ran out of memory"; opserr << " creating FE_Element " << elePtr->getTag() << endln; if (mps != 0) delete [] mps; if (sps != 0) delete [] sps; return -5; } } else { if ((fePtr = new TransformationFE(numFeEle, elePtr)) == 0) { opserr << "WARNING TransformationConstraintHandler::handle()"; opserr << " - ran out of memory"; opserr << " creating TransformationFE " << elePtr->getTag() << endln; if (mps != 0) delete [] mps; if (sps != 0) delete [] sps; return -6; } theFEs[numFE++] = fePtr; } numFeEle++; theModel->addFE_Element(fePtr); } } theModel->setNumEqn(countDOF); // set the number of eqn in the model // now see if we have to set any of the dof's to -3 // int numLast = 0; if (nodesLast != 0) for (i=0; i<nodesLast->Size(); i++) { int nodeID = (*nodesLast)(i); Node *nodPtr = theDomain->getNode(nodeID); if (nodPtr != 0) { DOF_Group *dofPtr = nodPtr->getDOF_GroupPtr(); const ID &id = dofPtr->getID(); // set all the dof values to -3 for (int j=0; j < id.Size(); j++) { if (id(j) == -2) { dofPtr->setID(j,-3); count3++; } else { opserr << "WARNING TransformationConstraintHandler::handle() "; opserr << " - boundary sp constraint in subdomain"; opserr << " this should not be - results suspect \n"; if (mps != 0) delete [] mps; if (sps != 0) delete [] sps; } } } } if (mps != 0) delete [] mps; if (sps != 0) delete [] sps; return count3; }
int HHTHSFixedNumIter::update(const Vector &deltaU) { AnalysisModel *theModel = this->getAnalysisModel(); if (theModel == 0) { opserr << "WARNING HHTHSFixedNumIter::update() - no AnalysisModel set\n"; return -1; } ConvergenceTest *theTest = this->getConvergenceTest(); if (theTest == 0) { opserr << "WARNING HHTHSFixedNumIter::update() - no ConvergenceTest set\n"; return -2; } // check domainChanged() has been called, i.e. Ut will not be zero if (Ut == 0) { opserr << "WARNING HHTHSFixedNumIter::update() - domainChange() failed or not called\n"; return -3; } // check deltaU is of correct size if (deltaU.Size() != U->Size()) { opserr << "WARNING HHTHSFixedNumIter::update() - Vectors of incompatible size "; opserr << " expecting " << U->Size() << " obtained " << deltaU.Size() << endln; return -4; } // get interpolation location and scale displacement increment x = (double) theTest->getNumTests()/theTest->getMaxNumTests(); if (polyOrder == 1) { (*scaledDeltaU) = x*((*U)+deltaU) - (x-1.0)*(*Ut) - (*U); } else if (polyOrder == 2) { (*scaledDeltaU) = x*(x+1.0)/2.0*((*U)+deltaU) - (x-1.0)*(x+1.0)*(*Ut) + (x-1.0)*x/2.0*(*Utm1) - (*U); } else if (polyOrder == 3) { (*scaledDeltaU) = x*(x+1.0)*(x+2.0)/6.0*((*U)+deltaU) - (x-1.0)*(x+1.0)*(x+2.0)/2.0*(*Ut) + (x-1.0)*x*(x+2.0)/2.0*(*Utm1) - (x-1.0)*x*(x+1.0)/6.0*(*Utm2) - (*U); } else { opserr << "WARNING HHTHSFixedNumIter::update() - polyOrder > 3 not supported\n"; } // determine the response at t+deltaT U->addVector(1.0, *scaledDeltaU, c1); Udot->addVector(1.0, *scaledDeltaU, c2); Udotdot->addVector(1.0, *scaledDeltaU, c3); // determine response at t+alpha*deltaT (*Ualpha) = *Ut; Ualpha->addVector((1.0-alphaF), *U, alphaF); (*Ualphadot) = *Utdot; Ualphadot->addVector((1.0-alphaF), *Udot, alphaF); (*Ualphadotdot) = *Utdotdot; Ualphadotdot->addVector((1.0-alphaI), *Udotdot, alphaI); // update the response at the DOFs theModel->setResponse(*Ualpha,*Ualphadot,*Ualphadotdot); if (theModel->updateDomain() < 0) { opserr << "HHTHSFixedNumIter::update() - failed to update the domain\n"; return -5; } 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 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; }
void ArpackSolver::myMv(int n, double *v, double *result) { Vector x(v, n); Vector y(result,n); bool mDiagonal = theArpackSOE->mDiagonal; if (mDiagonal == true) { int Msize = theArpackSOE->Msize; double *M = theArpackSOE->M; /* for output DataFileStream dataStream("M.txt"); dataStream.open(); for (int i=0; i<n; i++) dataStream << M[i] << endln; dataStream.close(); */ if (n <= Msize) { for (int i=0; i<n; i++) result[i] = M[i]*v[i]; } else { opserr << "ArpackSolver::myMv() n > Msize!\n"; return; } } else { y.Zero(); AnalysisModel *theAnalysisModel = theArpackSOE->theModel; // loop over the FE_Elements FE_Element *elePtr; FE_EleIter &theEles = theAnalysisModel->getFEs(); while((elePtr = theEles()) != 0) { const Vector &b = elePtr->getM_Force(x, 1.0); y.Assemble(b, elePtr->getID(), 1.0); } // loop over the DOF_Groups DOF_Group *dofPtr; DOF_GrpIter &theDofs = theAnalysisModel->getDOFs(); while ((dofPtr = theDofs()) != 0) { const Vector &a = dofPtr->getM_Force(x,1.0); y.Assemble(a, dofPtr->getID(), 1.0); } } // if paallel we have to merge the results int processID = theArpackSOE->processID; if (processID != -1) { Channel **theChannels = theArpackSOE->theChannels; int numChannels = theArpackSOE->numChannels; if (processID != 0) { theChannels[0]->sendVector(0, 0, y); theChannels[0]->recvVector(0, 0, y); } else { Vector other(workArea, n); // recv contribution from remote & add for (int i=0; i<numChannels; i++) { theChannels[i]->recvVector(0,0,other); y += other; } // send result back for (int i=0; i<numChannels; i++) { theChannels[i]->sendVector(0,0,y); } } } }
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 Newmark::newStep(double deltaT) { if (beta == 0 || gamma == 0) { opserr << "Newmark::newStep() - error in variable\n"; opserr << "gamma = " << gamma << " beta = " << beta << endln; return -1; } if (deltaT <= 0.0) { opserr << "Newmark::newStep() - error in variable\n"; opserr << "dT = " << deltaT << endln; return -2; } // get a pointer to the AnalysisModel AnalysisModel *theModel = this->getAnalysisModel(); // set the constants if (displ == true) { c1 = 1.0; c2 = gamma/(beta*deltaT); c3 = 1.0/(beta*deltaT*deltaT); } else { c1 = beta*deltaT*deltaT; c2 = gamma*deltaT; c3 = 1.0; } if (U == 0) { opserr << "Newmark::newStep() - domainChange() failed or hasn't been called\n"; return -3; } // set response at t to be that at t+deltaT of previous step (*Ut) = *U; (*Utdot) = *Udot; (*Utdotdot) = *Udotdot; if (displ == true) { // determine new velocities and accelerations at t+deltaT double a1 = (1.0 - gamma/beta); double a2 = (deltaT)*(1.0 - 0.5*gamma/beta); Udot->addVector(a1, *Utdotdot, a2); double a3 = -1.0/(beta*deltaT); double a4 = 1.0 - 0.5/beta; Udotdot->addVector(a4, *Utdot, a3); // set the trial response quantities theModel->setVel(*Udot); theModel->setAccel(*Udotdot); } else { // determine new displacements and velocities at t+deltaT double a1 = (deltaT*deltaT/2.0); U->addVector(1.0, *Utdot, deltaT); U->addVector(1.0, *Utdotdot, a1); Udot->addVector(1.0, *Utdotdot, deltaT); // set the trial response quantities theModel->setDisp(*U); theModel->setVel(*Udot); } // increment the time to t+deltaT and apply the load double time = theModel->getCurrentDomainTime(); time += deltaT; if (theModel->updateDomain(time, deltaT) < 0) { opserr << "Newmark::newStep() - failed to update the domain\n"; return -4; } return 0; }
int XC::ParallelNumberer::numberDOF(int lastDOF) { int result = 0; // get a pointer to the model & check its not null AnalysisModel *theModel = this->getAnalysisModelPtr(); Domain *theDomain = 0; if(theModel) theDomain = theModel->getDomainPtr(); if(theModel == 0 || theDomain == 0) { std::cerr << "WARNING XC::ParallelNumberer::numberDOF(int) -"; std::cerr << " - no AnalysisModel.\n"; return -1; } if(lastDOF != -1) { std::cerr << "WARNING XC::ParallelNumberer::numberDOF(int lastDOF):"; std::cerr << " does not use the lastDOF as requested\n"; } Graph &theGraph= theModel->getDOFGroupGraph(); // if subdomain, collect graph, send it off, get // ID back containing dof tags & start id numbers. if(processID != 0) { CommParameters cp(0,*theChannels[0]); const int numVertex = theGraph.getNumVertex(); /* static XC::ID test(2); test(0) = processID; test(1) = 25; theChannel->recvID(0, 0, test); */ cp.sendMovable(theGraph,DistributedObj::getDbTagData(),CommMetaData(1)); // recv iD ID theID(2*numVertex); cp.receiveID(theID,DistributedObj::getDbTagData(),CommMetaData(2)); // set vertex numbering based on ID received for(int i=0; i<numVertex; i ++) { const int vertexTag= theID(i); int startID= theID(i+numVertex); //Vertex *vertexPtr = theGraph.getVertexPtr(vertexTag); const int dofTag= vertexTag; DOF_Group *dofPtr= theModel->getDOF_GroupPtr(dofTag); if(!dofPtr) { std::cerr << "WARNING ParallelNumberer::numberDOF - "; std::cerr << "DOF_Group " << dofTag << "not in XC::AnalysisModel!\n"; result= -4; } else { const ID &theDOFID= dofPtr->getID(); //std::cerr << "P: " << processID << " dofTag: " << dofTag << " " << "start: " << startID << " " << theDOFID; const int idSize= theDOFID.Size(); for(int j=0; j<idSize; j++) if(theDOFID(j) == -2 || theDOFID(j) == -3) dofPtr->setID(j, startID++); } //const ID &theDOFID= dofPtr->getID(); } cp.sendID(theID,DistributedObj::getDbTagData(),CommMetaData(2)); } else { // if XC::main domain, collect graphs from all subdomains, // merge into 1, number this one, send to subdomains the // id containing dof tags & start id's. // for P0 domain determine original vertex and ref tags const int numVertex= theGraph.getNumVertex(); const int numVertexP0= numVertex; ID vertexTags(numVertex); ID vertexRefs(numVertex); Vertex *vertexPtr; int loc= 0; VertexIter &theVertices= theGraph.getVertices(); while((vertexPtr= theVertices()) != 0) { vertexTags[loc]= vertexPtr->getTag(); vertexRefs[loc]= vertexPtr->getRef(); loc++; } const int numChannels= theChannels.size(); std::vector<ID> theSubdomainIDs(numChannels); FEM_ObjectBroker theBroker; // for each subdomain we receive graph, create an XC::ID (to store // subdomain graph to merged graph vertex mapping and the final // subdoain graph vertex to startDOF mapping) and finally merge the // subdomain graph for(int j=0; j<numChannels; j++) { CommParameters cp(0,*theChannels[j]); Graph theSubGraph; /* static XC::ID test(2); test(0)= processID; test(1)= 25; theChannel->sendID(0, 0, test); */ cp.receiveMovable(theSubGraph,DistributedObj::getDbTagData(),CommMetaData(3)); theSubdomainIDs[j]= ID(theSubGraph.getNumVertex()*2); this->mergeSubGraph(theGraph, theSubGraph, vertexTags, vertexRefs, theSubdomainIDs[j]); } // we use graph numberer if one was provided in constructor, // otherwise we number based on subdomains (all in subdomain 1 numbered first, // then those in 2 not in 1 and so on till done. // GraphNumberer *theNumberer= this->getGraphNumbererPtr(); ID theOrderedRefs(theGraph.getNumVertex()); if(theNumberer) { // use the supplied graph numberer to number the merged graph theOrderedRefs= theNumberer->number(theGraph, lastDOF); } else { // assign numbers based on the subdomains int loc= 0; for(int l=0; l<numChannels; l++) { const ID &theSubdomain= theSubdomainIDs[l]; int numVertexSubdomain= theSubdomain.Size()/2; for(int i=0; i<numVertexSubdomain; i++) { const int vertexTagMerged= theSubdomain(i+numVertexSubdomain); // int refTag= vertexRefs[vertexTags.getLocation(vertexTagMerged)]; if(theOrderedRefs.getLocation(vertexTagMerged) == -1) theOrderedRefs[loc++]= vertexTagMerged; } } // now order those not yet ordered in p0 for(int j=0; j<numVertexP0; j++) { int refTagP0= vertexTags[j]; if(theOrderedRefs.getLocation(refTagP0) == -1) theOrderedRefs[loc++]= refTagP0; } } int count= 0; for(int i=0; i<theOrderedRefs.Size(); i++) { int vertexTag= theOrderedRefs(i); // int vertexTag= vertexTags[vertexRefs.getLocation(tag)]; Vertex *vertexPtr= theGraph.getVertexPtr(vertexTag); int numDOF= vertexPtr->getColor(); vertexPtr->setTmp(count); count += numDOF; } // number own dof's for(int i=0; i<numVertexP0; i++ ) { int vertexTag= vertexTags(i); Vertex *vertexPtr= theGraph.getVertexPtr(vertexTag); int startID= vertexPtr->getTmp(); int dofTag= vertexTag; DOF_Group *dofPtr; dofPtr= theModel->getDOF_GroupPtr(dofTag); if(dofPtr == 0) { std::cerr << "WARNING XC::ParallelNumberer::numberDOF - "; std::cerr << "DOF_Group (P0) " << dofTag << "not in XC::AnalysisModel!\n"; result= -4; } else { const ID &theDOFID= dofPtr->getID(); int idSize= theDOFID.Size(); for(int j=0; j<idSize; j++) if(theDOFID(j) == -2 || theDOFID(j) == -3) dofPtr->setID(j, startID++); } } // now given the ordered refs we determine the mapping for each subdomain // and send the id with the information back to the subdomain, which it uses to order // it's own graph for(int k=0; k<numChannels; k++) { CommParameters cp(0,*theChannels[k]); ID &theSubdomain= theSubdomainIDs[k]; int numVertexSubdomain= theSubdomain.Size()/2; for(int i=0; i<numVertexSubdomain; i++) { int vertexTagMerged= theSubdomain[numVertexSubdomain+i]; Vertex *vertexPtr= theGraph.getVertexPtr(vertexTagMerged); int startDOF= vertexPtr->getTmp(); theSubdomain[i+numVertexSubdomain]= startDOF; } cp.sendID(theSubdomain,DistributedObj::getDbTagData(),CommMetaData(4)); cp.receiveID(theSubdomain,DistributedObj::getDbTagData(),CommMetaData(4)); } } // iterate through the XC::FE_Element getting them to set their IDs FE_EleIter &theEle= theModel->getFEs(); FE_Element *elePtr; while ((elePtr= theEle()) != 0) elePtr->setID(); return result; }
int ArcLength::domainChanged(void) { // we first create the Vectors needed 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; } int size = theModel->getNumEqn(); // ask model in case N+1 space if (deltaUhat == 0 || deltaUhat->Size() != size) { // create new Vector if (deltaUhat != 0) delete deltaUhat; // delete the old deltaUhat = new Vector(size); if (deltaUhat == 0 || deltaUhat->Size() != size) { // check got it opserr << "FATAL ArcLength::domainChanged() - ran out of memory for"; opserr << " deltaUhat Vector of size " << size << endln; exit(-1); } } if (deltaUbar == 0 || deltaUbar->Size() != size) { // create new Vector if (deltaUbar != 0) delete deltaUbar; // delete the old deltaUbar = new Vector(size); if (deltaUbar == 0 || deltaUbar->Size() != size) { // check got it opserr << "FATAL ArcLength::domainChanged() - ran out of memory for"; opserr << " deltaUbar Vector of size " << size << endln; exit(-1); } } if (deltaU == 0 || deltaU->Size() != size) { // create new Vector if (deltaU != 0) delete deltaU; // delete the old deltaU = new Vector(size); if (deltaU == 0 || deltaU->Size() != size) { // check got it opserr << "FATAL ArcLength::domainChanged() - ran out of memory for"; opserr << " deltaU Vector of size " << size << endln; exit(-1); } } if (deltaUstep == 0 || deltaUstep->Size() != size) { if (deltaUstep != 0) delete deltaUstep; deltaUstep = new Vector(size); if (deltaUstep == 0 || deltaUstep->Size() != size) { opserr << "FATAL ArcLength::domainChanged() - ran out of memory for"; opserr << " deltaUstep Vector of size " << size << endln; exit(-1); } } if (phat == 0 || phat->Size() != size) { if (phat != 0) delete phat; phat = new Vector(size); if (phat == 0 || phat->Size() != size) { opserr << "FATAL ArcLength::domainChanged() - ran out of memory for"; opserr << " phat Vector of size " << size << endln; exit(-1); } } // now we have to determine phat // do this by incrementing lambda by 1, applying load // and getting phat from unbalance. currentLambda = theModel->getCurrentDomainTime(); currentLambda += 1.0; theModel->applyLoadDomain(currentLambda); this->formUnbalance(); // NOTE: this assumes unbalance at last was 0 (*phat) = theLinSOE->getB(); currentLambda -= 1.0; theModel->setCurrentDomainTime(currentLambda); // check there is a reference load int haveLoad = 0; for (int i=0; i<size; i++) if ( (*phat)(i) != 0.0 ) { haveLoad = 1; i = size; } if (haveLoad == 0) { opserr << "WARNING ArcLength::domainChanged() - zero reference load"; return -1; } return 0; }
int HHTHSFixedNumIter::newStep(double _deltaT) { deltaT = _deltaT; if (beta == 0 || gamma == 0 ) { opserr << "HHTHSFixedNumIter::newStep() - error in variable\n"; opserr << "gamma = " << gamma << " beta = " << beta << endln; return -1; } if (deltaT <= 0.0) { opserr << "HHTHSFixedNumIter::newStep() - error in variable\n"; opserr << "dT = " << deltaT << endln; return -2; } // get a pointer to the AnalysisModel AnalysisModel *theModel = this->getAnalysisModel(); // set the constants c1 = 1.0; c2 = gamma/(beta*deltaT); c3 = 1.0/(beta*deltaT*deltaT); if (U == 0) { opserr << "HHTHSFixedNumIter::newStep() - domainChange() failed or hasn't been called\n"; return -3; } // set response at t to be that at t+deltaT of previous step (*Utm2) = *Utm1; (*Utm1) = *Ut; (*Ut) = *U; (*Utdot) = *Udot; (*Utdotdot) = *Udotdot; // determine new velocities and accelerations at t+deltaT double a1 = (1.0 - gamma/beta); double a2 = deltaT*(1.0 - 0.5*gamma/beta); Udot->addVector(a1, *Utdotdot, a2); double a3 = -1.0/(beta*deltaT); double a4 = 1.0 - 0.5/beta; Udotdot->addVector(a4, *Utdot, a3); // determine the velocities and accelerations at t+alpha*deltaT (*Ualphadot) = *Utdot; Ualphadot->addVector((1.0-alphaF), *Udot, alphaF); (*Ualphadotdot) = *Utdotdot; Ualphadotdot->addVector((1.0-alphaI), *Udotdot, alphaI); // set the trial response quantities theModel->setVel(*Ualphadot); theModel->setAccel(*Ualphadotdot); // increment the time to t+alpha*deltaT and apply the load double time = theModel->getCurrentDomainTime(); time += alphaF*deltaT; theModel->applyLoadDomain(time); return 0; }