const XC::Matrix &XC::MFreedom_Joint2D::getConstraint(void) const { if(constraintMatrix.isEmpty()) { std::cerr << getClassName() << "::" << __FUNCTION__ << "; no matrix was set\n"; exit(-1); } // Length correction // to correct the trial displacement if(LargeDisplacement == 2 ) { // get the coordinates of the two nodes - check dimensions are the same FOR THE MOMENT const Vector &crdR = RetainedNode->getCrds(); const Vector &crdC = ConstrainedNode->getCrds(); // get committed displacements of nodes to get updated coordinates const Vector &dispR = RetainedNode->getTrialDisp(); const Vector &dispC = ConstrainedNode->getTrialDisp(); double deltaX = dispC(0) + crdC(0) - dispR(0) - crdR(0); double deltaY = dispC(1) + crdC(1) - dispR(1) - crdR(1); Vector Direction(2); Direction(0) = deltaX; Direction(1) = deltaY; double NewLength = Direction.Norm(); if(NewLength < 1e-12) std::cerr << "XC::MFreedom_Joint2D::applyConstraint : length of rigid link is too small or zero"; Direction = Direction * (Length0/NewLength); // correct the length // find new displacements of the constrainted node Vector NewLocation(3); NewLocation(0) = Direction(0) + dispR(0) + crdR(0) - crdC(0); NewLocation(1) = Direction(1) + dispR(1) + crdR(1) - crdC(1); NewLocation(2) = dispC(2); ConstrainedNode->setTrialDisp(NewLocation); } // end of length correction procedure // return the constraint matrix Ccr return constraintMatrix; }
const Matrix &MP_Joint2D::getConstraint(void) { if (constraint == 0) { opserr << "MP_Joint2D::getConstraint - no Matrix was set\n"; exit(-1); } // Length correction // to correct the trial displacement if ( LargeDisplacement == 2 ) { // get the coordinates of the two nodes - check dimensions are the same FOR THE MOMENT const Vector &crdR = RetainedNode->getCrds(); const Vector &crdC = ConstrainedNode->getCrds(); // get commited displacements of nodes to get updated coordinates const Vector &dispR = RetainedNode->getTrialDisp(); const Vector &dispC = ConstrainedNode->getTrialDisp(); double deltaX = dispC(0) + crdC(0) - dispR(0) - crdR(0); double deltaY = dispC(1) + crdC(1) - dispR(1) - crdR(1); Vector Direction(2); Direction(0) = deltaX; Direction(1) = deltaY; double NewLength = Direction.Norm(); if ( NewLength < 1e-12 ) opserr << "MP_Joint2D::applyConstraint : length of rigid link is too small or zero"; Direction = Direction * (Length0/NewLength); // correct the length // find new displacements of the constrainted node Vector NewLocation(3); NewLocation(0) = Direction(0) + dispR(0) + crdR(0) - crdC(0); NewLocation(1) = Direction(1) + dispR(1) + crdR(1) - crdC(1); NewLocation(2) = dispC(2); int dummy = ConstrainedNode->setTrialDisp( NewLocation ); } // end of length correction procedure // return the constraint matrix Ccr return (*constraint); }
int MP_Joint2D::applyConstraint(double timeStamp) { if ( LargeDisplacement != 0 ) { // calculate the constraint at this moment // get the coordinates of the two nodes - check dimensions are the same FOR THE MOMENT const Vector &crdR = RetainedNode->getCrds(); const Vector &crdC = ConstrainedNode->getCrds(); // get commited displacements of nodes to get updated coordinates const Vector &dispR = RetainedNode->getDisp(); const Vector &dispC = ConstrainedNode->getDisp(); double deltaX = dispC(0) + crdC(0) - dispR(0) - crdR(0); double deltaY = dispC(1) + crdC(1) - dispR(1) - crdR(1); constraint->Zero(); if ( FixedEnd == 0 ) { // the end is released (*constraint) (0,0) = 1.0 ; (*constraint) (0,2) = -deltaY ; (*constraint) (1,1) = 1.0 ; (*constraint) (1,2) = deltaX ; } else { // the end is fixed (*constraint) (0,0) = 1.0 ; (*constraint) (0,MainDOF) = -deltaY ; (*constraint) (1,1) = 1.0 ; (*constraint) (1,MainDOF) = deltaX ; (*constraint) (2,AuxDOF) = 1.0 ; } } return 0; }
// general constructor for ModelBuilder MP_Joint2D::MP_Joint2D(Domain *theDomain, int nodeRetain, int nodeConstr, int Maindof, int fixedend, int LrgDsp ) :MP_Constraint(CNSTRNT_TAG_MP_Joint2D ), thisDomain(theDomain), nodeRetained(nodeRetain), nodeConstrained(nodeConstr), MainDOF(Maindof), AuxDOF(0), FixedEnd(fixedend), constraint(0), constrDOF(0), retainDOF(0), dbTag1(0), dbTag2(0), dbTag3(0), RetainedNode(0), ConstrainedNode(0), LargeDisplacement( LrgDsp ), Length0(0.0) { if( thisDomain == NULL ) { opserr << "WARNING MP_Joint2D(): Specified domain does not exist"; opserr << "Domain = 0\n"; return; } // get node pointers of constrainted and retained nodes ConstrainedNode = theDomain->getNode(nodeConstrained); if (ConstrainedNode == NULL) { opserr << "MP_Joint2D::MP_Joint2D: nodeConstrained: "; opserr << nodeConstrained << "does not exist in model\n"; exit(0); } RetainedNode = theDomain->getNode(nodeRetained); if (RetainedNode == NULL) { opserr << "MP_Joint2D::MP_Joint2D: nodeRetained: "; opserr << nodeRetained << "does not exist in model\n"; exit(0); } // check for proper degrees of freedom int RnumDOF = RetainedNode->getNumberDOF(); int CnumDOF = ConstrainedNode->getNumberDOF(); if (RnumDOF != 4 || CnumDOF != 3 ){ opserr << "MP_Joint2D::MP_Joint2D - mismatch in numDOF\n DOF not supported by this type of constraint"; return; } // check the main degree of freedom. Assign auxilary DOF if ( MainDOF!= 2 && MainDOF!=3 ) { opserr << "MP_Joint2D::MP_Joint2D - Wrong main degree of freedom" ; return; } if ( MainDOF == 2 ) AuxDOF = 3; if ( MainDOF == 3 ) AuxDOF = 2; // check the fixed end flag if ( FixedEnd!= 0 && FixedEnd!=1 ) { opserr << "MP_Joint2D::MP_Joint2D - Wrong fixed end flag"; return; } // check for proper dimensions of coordinate space const Vector &crdR = RetainedNode->getCrds(); int dimR = crdR.Size(); const Vector &crdC = ConstrainedNode->getCrds(); int dimC = crdC.Size(); if (dimR != 2 || dimC != 2 ){ opserr << "MP_Joint2D::MP_Joint2D - mismatch in dimnesion\n dimension not supported by this type of constraint"; return; } // calculate the initial length of the rigid link double deltaX = crdC(0) - crdR(0); double deltaY = crdC(1) - crdR(1); Length0 = sqrt( deltaX*deltaX + deltaY*deltaY ); if ( Length0 <= 1.0e-12 ) { opserr << "MP_Joint2D::MP_Joint2D - The constraint length is zero\n"; } // allocate and set up the constranted and retained id's // allocate and set up the constraint matrix if ( FixedEnd == 0 ) { // the end is released constrDOF = new ID(CnumDOF-1); retainDOF = new ID(RnumDOF-1); (*constrDOF)(0) = 0; (*constrDOF)(1) = 1; (*retainDOF)(0) = 0; (*retainDOF)(1) = 1; (*retainDOF)(2) = MainDOF; constraint = new Matrix( CnumDOF-1 , RnumDOF-1 ); (*constraint) (0,0) = 1.0 ; (*constraint) (0,2) = -deltaY ; (*constraint) (1,1) = 1.0 ; (*constraint) (1,2) = deltaX ; } else { // the end is fixed constrDOF = new ID(CnumDOF); retainDOF = new ID(RnumDOF); (*constrDOF)(0) = 0; (*constrDOF)(1) = 1; (*constrDOF)(2) = 2; (*retainDOF)(0) = 0; (*retainDOF)(1) = 1; (*retainDOF)(2) = 2; (*retainDOF)(3) = 3; constraint = new Matrix( CnumDOF , RnumDOF ); (*constraint) (0,0) = 1.0 ; (*constraint) (0,MainDOF) = -deltaY ; (*constraint) (1,1) = 1.0 ; (*constraint) (1,MainDOF) = deltaX ; (*constraint) (2,AuxDOF) = 1.0 ; } if (constrDOF == NULL || retainDOF == NULL ) { opserr << "MP_Joint2D::MP_Joint2D - ran out of memory \ncan not generate ID for nodes\n"; exit(-1); } if (constraint == NULL ) { opserr << "MP_Joint2D::MP_Joint2D - ran out of memory \ncan not generate the constraint matrix"; exit(-1); } }
RigidBeam::RigidBeam(Domain &theDomain, int nR, int nC) { // get a pointer to the retained and constrained nodes - make sure they exist Node *nodeR = theDomain.getNode(nR); if (nodeR == 0) { opserr << "RigidBeam::RigidBeam - retained Node" << nR << "not in domain\n"; return; } Node *nodeC = theDomain.getNode(nC); if (nodeR == 0) { opserr << "RigidBeam::RigidBeam - constrained Node" << nC << "not in domain\n"; return; } // get the coordinates of the two nodes - check dimensions are the same FOR THE MOMENT const Vector &crdR = nodeR->getCrds(); const Vector &crdC = nodeC->getCrds(); int dimR = crdR.Size(); int dimC = crdC.Size(); if (dimR != dimC) { opserr << "RigidBeam::RigidBeam - mismatch in dimension " << "between constrained Node " << nC << " and Retained node" << nR << endln; return; } // check the number of dof at each node is the same int numDOF = nodeR->getNumberDOF(); if (numDOF != nodeC->getNumberDOF()) { opserr << "RigidBeam::RigidBeam - mismatch in numDOF " << "between constrained Node " << nC << " and Retained node" << nR << endln; return; } // check the number of dof at the nodes >= dimension of problem if(numDOF < dimR) { opserr << "RigidBeam::RigidBeam - numDOF at nodes " << nR << " and " << nC << "must be >= dimension of problem\n"; return; } // create the ID to identify the constrained dof ID id(numDOF); // construct the tranformation matrix Ccr, where Uc = Ccr Ur & set the diag, Ccr = I Matrix mat(numDOF,numDOF); mat.Zero(); // set the values for (int i=0; i<numDOF; i++) { mat(i,i) = 1.0; id(i) = i; } // if there are rotational dof - we must modify Ccr DONE ASSUMING SMALL ROTATIONS if (dimR != numDOF) { if (dimR == 2 && numDOF == 3) { double deltaX = crdC(0) - crdR(0); double deltaY = crdC(1) - crdR(1); mat(0,2) = -deltaY; mat(1,2) = deltaX; } else if (dimR == 3 && numDOF == 6) { double deltaX = crdC(0) - crdR(0); double deltaY = crdC(1) - crdR(1); double deltaZ = crdC(2) - crdR(2); // rotation about z/3 axis mat(0,5) = -deltaY; mat(1,5) = deltaX; // rotation about y/2 axis mat(0,4) = deltaZ; mat(2,4) = -deltaX; // rotation about x/1 axis mat(1,3) = -deltaZ; mat(2,3) = deltaY; } else { // not valid opserr << "RigidBeam::RigidBeam - for nodes " << nR << "and " << nC << "nodes do not have valid numDOF for their dimension\n"; return; } } // create the MP_Constraint MP_Constraint *newC = new MP_Constraint(nR, nC, mat, id, id); if (newC == 0) { opserr << "RigidBeam::RigidBeam - for nodes " << nC << " and " << nR << ", out of memory\n"; } else { // add the constraint to the domain if (theDomain.addMP_Constraint(newC) == false) { opserr << "RigidBeam::RigidBeam - for nodes " << nC << " and " << nR << ", could not add to domain\n"; delete newC; } } }
//! @brief Constructor. //! @param theDomain: domain where the constraint is defined. //! @param tag: tag for the multi-freedom constraint. //! @param nodeRetain: identifier of the retained node. //! @param nodeConstr: identifier of the constrained node. //! @param LrgDsp: true if large displacement (geometric non-linearity) must be expected: 0 for constant constraint matrix(small deformations), 1 for time varying constraint matrix(large deformations), 2 for large deformations with length correction. XC::MFreedom_Joint2D::MFreedom_Joint2D(Domain *domain, int tag, int nodeRetain, int nodeConstr,int Maindof, int fixedend, int LrgDsp ) : MFreedom_Joint(domain,tag,CNSTRNT_TAG_MFreedom_Joint2D,nodeRetain,nodeConstr,LrgDsp), MainDOF(Maindof), AuxDOF(0), FixedEnd(fixedend) { setDomain(domain); // check for proper degrees of freedom int RnumDOF = RetainedNode->getNumberDOF(); int CnumDOF = ConstrainedNode->getNumberDOF(); if(RnumDOF != 4 || CnumDOF != 3 ) { std::cerr << "MFreedom_Joint2D::MFreedom_Joint2D - mismatch in numDOF\n DOF not supported by this type of constraint"; return; } // check the XC::main degree of freedom. Assign auxilary DOF if( MainDOF!= 2 && MainDOF!=3 ) { std::cerr << "MFreedom_Joint2D::MFreedom_Joint2D - Wrong main degree of freedom" ; return; } if(MainDOF == 2 ) AuxDOF = 3; if(MainDOF == 3 ) AuxDOF = 2; // check the fixed end flag if( FixedEnd!= 0 && FixedEnd!=1 ) { std::cerr << "XC::MFreedom_Joint2D::MFreedom_Joint2D - Wrong fixed end flag"; return; } // check for proper dimensions of coordinate space const Vector &crdR = RetainedNode->getCrds(); int dimR = crdR.Size(); const Vector &crdC = ConstrainedNode->getCrds(); int dimC = crdC.Size(); if(dimR != 2 || dimC != 2 ) { std::cerr << "MFreedom_Joint2D::MFreedom_Joint2D - mismatch in dimnesion\n dimension not supported by this type of constraint"; return; } // calculate the initial length of the rigid link double deltaX = crdC(0) - crdR(0); double deltaY = crdC(1) - crdR(1); Length0 = sqrt( deltaX*deltaX + deltaY*deltaY ); if( Length0 <= 1.0e-12 ) { std::cerr << "XC::MFreedom_Joint2D::MFreedom_Joint2D - The constraint length is zero\n"; } // allocate and set up the constranted and retained id's // allocate and set up the constraint matrix if( FixedEnd == 0 ) { // the end is released set_constrained_dofs(ID(CnumDOF-1)); set_retained_dofs(ID(RnumDOF-1)); constrDOF(0) = 0; constrDOF(1) = 1; retainDOF(0) = 0; retainDOF(1) = 1; retainDOF(2) = MainDOF; set_constraint(Matrix( CnumDOF-1 , RnumDOF-1 )); constraintMatrix(0,0) = 1.0 ; constraintMatrix(0,2) = -deltaY ; constraintMatrix(1,1) = 1.0 ; constraintMatrix(1,2) = deltaX ; } else { // the end is fixed constrDOF = ID(CnumDOF); retainDOF = ID(RnumDOF); constrDOF(0) = 0; constrDOF(1) = 1; constrDOF(2) = 2; retainDOF(0) = 0; retainDOF(1) = 1; retainDOF(2) = 2; retainDOF(3) = 3; constraintMatrix= Matrix(CnumDOF,RnumDOF); constraintMatrix(0,0) = 1.0 ; constraintMatrix(0,MainDOF) = -deltaY ; constraintMatrix(1,1) = 1.0 ; constraintMatrix(1,MainDOF) = deltaX ; constraintMatrix(2,AuxDOF) = 1.0 ; } if(constraintMatrix.isEmpty()) { std::cerr << getClassName() << "::" << __FUNCTION__ << "; ran out of memory \ncan not generate the constraint matrix"; exit(-1); } }