Ejemplo n.º 1
0
PenaltyMP_FE::PenaltyMP_FE(int tag, Domain &theDomain, 
			   MP_Constraint &TheMP, double Alpha)
:FE_Element(tag, 2,(TheMP.getConstrainedDOFs()).Size()+
 (TheMP.getRetainedDOFs()).Size()),
 theMP(&TheMP), theConstrainedNode(0) , theRetainedNode(0),
 tang(0), resid(0), C(0), alpha(Alpha)
{
    
    int size;
    const ID &id1 = theMP->getConstrainedDOFs();
    size = id1.Size();
    const ID &id2 = theMP->getRetainedDOFs();    
    size += id2.Size();

    tang = new Matrix(size,size);
    resid = new Vector(size);
    C = new Matrix(id1.Size(),size);

    if (tang == 0 || resid == 0 || C == 0 ||
	tang->noCols() != size || C->noCols() != size || 
	resid->Size() != size) {
	opserr << "FATAL PenaltyMP_FE::PenaltyMP_FE() - out of memory\n";
	exit(-1);
    }
	    
    theRetainedNode = theDomain.getNode(theMP->getNodeRetained());    
    theConstrainedNode = theDomain.getNode(theMP->getNodeConstrained());

    if (theRetainedNode == 0 || theConstrainedNode == 0) {
	opserr << "FATAL PenaltyMP_FE::PenaltyMP_FE() - Constrained or Retained";
	opserr << " Node does not exist in Domain\n";
	opserr << theMP->getNodeRetained() << " " << theMP->getNodeConstrained() << endln;
	exit(-1);
    }	


    // set up the dof groups tags
    DOF_Group *dofGrpPtr = 0;
    dofGrpPtr = theRetainedNode->getDOF_GroupPtr();
    if (dofGrpPtr != 0) 
	myDOF_Groups(0) = dofGrpPtr->getTag();	    
    else 
	opserr << "WARNING PenaltyMP_FE::PenaltyMP_FE() - node no Group yet?\n"; 
    dofGrpPtr = theConstrainedNode->getDOF_GroupPtr();
    if (dofGrpPtr != 0) 
	myDOF_Groups(1) = dofGrpPtr->getTag();	        
    else
	opserr << "WARNING PenaltyMP_FE::PenaltyMP_FE() - node no Group yet?\n"; 
    
    
    if (theMP->isTimeVarying() == false) {
	this->determineTangent();
	// we can free up the space taken by C as it is no longer needed
	if (C != 0)
	    delete C;
	C = 0;
    }
}
Ejemplo n.º 2
0
int
MeshRegion::setRayleighDampingFactors(double alpham, double betak, double betak0, double betakc)
{
  alphaM = alpham;
  betaK  = betak;
  betaK0 = betak0;
  betaKc = betakc;

  // now set the damping factors at the nodes & elements
  Domain *theDomain = this->getDomain();
  if (theDomain == 0) {
    opserr << "MeshRegion::setRayleighDampingFactors() - no domain yet set\n";
    return -1;
  }
  if (theElements != 0) {
    for (int i=0; i<theElements->Size(); i++) {
      int eleTag = (*theElements)(i);
      Element *theEle = theDomain->getElement(eleTag);
      if (theEle != 0)
	theEle->setRayleighDampingFactors(alphaM, betaK, betaK0, betaKc);
    }
  }

  if (theNodes != 0) {
    for (int i=0; i<theNodes->Size(); i++) {
      int nodTag = (*theNodes)(i);
      Node *theNode = theDomain->getNode(nodTag);
      if (theNode != 0)
	theNode->setRayleighDampingFactor(alphaM);
    }
  }

  return 0;
}
Ejemplo n.º 3
0
int ExpControlSP::applyConstraint(double loadFactor)
{
    // on first call
    if (theNode == 0 || theNodeResponse == 0)  {
        Domain *theDomain = this->getDomain();
        
        theNode = theDomain->getNode(nodeTag);
        if (theNode == 0)
            return -1;
        
        theNodeResponse = new Vector(theNode->getNumberDOF());
        if (theNodeResponse == 0)
            return -2;
    }
    
    // set the responses at the node
    // disp response is the responsibility of constraint handler
    //*theNodeResponse = theNode->getTrialDisp();
    //(*theNodeResponse)(dofNumber) = dispFact * (*ctrlDisp);
    //theNode->setTrialDisp(*theNodeResponse);
    
    if (ctrlVel != 0 && velFact != 0.0)  {
        *theNodeResponse = theNode->getTrialVel();
        (*theNodeResponse)(dofNumber) = velFact * (*ctrlVel);
        theNode->setTrialVel(*theNodeResponse);
    }
    
    if (ctrlAccel != 0 && accelFact != 0.0)  {
        *theNodeResponse = theNode->getTrialAccel();
        (*theNodeResponse)(dofNumber) = accelFact * (*ctrlAccel);
        theNode->setTrialAccel(*theNodeResponse);
    }
    
    return 0;
}
Ejemplo n.º 4
0
Node*
Pressure_Constraint::getPressureNode()
{
    if(pval != 0) return 0;

    Domain* theDomain = this->getDomain();
    if(theDomain == 0) {
        opserr<<"WARNING: domain has not been set";
        opserr<<" -- Pressure_Constraint::getPressureNode\n";
        return 0;
    }
    return theDomain->getNode(pTag);
}
Ejemplo n.º 5
0
LagrangeSP_FE::LagrangeSP_FE(int tag, Domain &theDomain, SP_Constraint &TheSP,
			     DOF_Group &theGroup, double Alpha)
:FE_Element(tag, 2,2),
 alpha(Alpha), tang(0), resid(0), theSP(&TheSP), theDofGroup(&theGroup)
{
    // create a Matrix and a Vector for the tangent and residual
    tang = new Matrix(2,2);
    resid = new Vector(2);
    if ((tang == 0) || (tang->noCols() == 0) || (resid == 0) ||
	(resid->Size() == 0)) {
	opserr << "WARNING LagrangeSP_FE::LagrangeSP_FE()";
	opserr << "- ran out of memory\n";
	exit(-1);
    }

    // zero the Matrix and Vector
    resid->Zero();
    tang->Zero();

    theNode = theDomain.getNode(theSP->getNodeTag());    
    if (theNode == 0) {
	opserr << "WARNING LagrangeSP_FE::LagrangeSP_FE()";
	opserr << "- no asscoiated Node\n";
	exit(-1);
    }

    // set the tangent
    (*tang)(0,1) = alpha;
    (*tang)(1,0) = alpha;
    
    // set the myDOF_Groups tags indicating the attached id's of the
    // DOF_Group objects
    DOF_Group *theNodesDOFs = theNode->getDOF_GroupPtr();
    if (theNodesDOFs == 0) {
	opserr << "WARNING LagrangeSP_FE::LagrangeSP_FE()";
	opserr << " - no DOF_Group with Constrained Node\n";
	exit(-1);	
    }    

    myDOF_Groups(0) = theNodesDOFs->getTag();
    myDOF_Groups(1) = theDofGroup->getTag();
}
Ejemplo n.º 6
0
double
Pressure_Constraint::getPressure(int last)
{
    if (pval != 0) {
	return pval[0];
    }

    Domain* theDomain = this->getDomain();
    if(theDomain == 0) {
        opserr<<"WARNING: domain has not been set";
        opserr<<" -- Pressure_Constraint::getPressureNode\n";
        return 0;
    }
    Node* pNode = theDomain->getNode(pTag);
    if(pNode == 0) return 0.0;
    const Vector& vel = pNode->getVel();
    if(last == 1) {
        if(vel.Size()==0) return 0.0;
        return vel(0);
    }
    return 0.0;
}
Ejemplo n.º 7
0
//! @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;
  }
Ejemplo n.º 8
0
void *
OPS_RotationShearCurve(void)
{
  if (shearCurveCount == 0) {
    opserr << "RotationShearCurve limit curve - Written by MRL UT Austin Copyright 2012 -  Use at your Own Peril \n";
    shearCurveCount++;
  }

  int argc = OPS_GetNumRemainingInputArgs();

  if (!(argc == 9 || argc == 23)) { 
    opserr << "WARNING RotationShearCurve -- insufficient arguments\n";
    opserr << "For direct input of shear curve parameters and degrading slope want:\n\n";
    opserr << "limitCurve RotationShearCurve crvTag? eleTag? \n";
    opserr << "ndI? ndJ? rotAxis? Vn? Vr? Kdeg? rotLim? \n" << endln;
    
    opserr << "OR for calibrated shear curve and degrading slope want:\n\n";
    opserr << "limitCurve RotationShearCurve crvTag? eleTag?\n";
    opserr << "ndI? ndJ? rotAxis? Vn? Vr? Kdeg? defType?\n";
    opserr << "b? d? h? L? st? As? Acc? ld? db? rhot? f'c?\n";
    opserr << "fy? fyt? delta?\n" << endln;
    
    return 0;
  }

  int iTagData[2];	  
  int iNodeData[3];	  
  double dKdegData[3];  
  double dRotLimData[1];
  int iTypeData[1];	  
  double dPropData[14]; 
  
  int numData;
  numData = 2;
  if (OPS_GetIntInput(&numData, iTagData) != 0) {
    opserr << "WARNING RotationShearCurve -- invalid crvTag? eleTag?\n" << endln;
    return 0;
  }
  int eleTag = iTagData[1];
  Domain *theDomain = 0;
  theDomain = OPS_GetDomain();
  if (theDomain == 0) {
    opserr << "WARNING RotationShearCurve -- Pointer to Domain was not returned\n" << endln;
    return 0;
  }
  Element *theElement = 0;
  theElement = theDomain->getElement(eleTag);
  if (theElement == 0) {
    opserr << "WARNING RotationShearCurve -- Element with tag " << iTagData[1] << " does not exist for shear curve tag " << iTagData[0] << endln << endln;
    return 0;
  }
  numData = 3;
  if (OPS_GetIntInput(&numData, iNodeData) != 0) {
    opserr << "WARNING RotationShearCurve -- invalid ndI? ndJ? rotAxis?\n" << endln;
    return 0;
  }
  Node *theNodeI = 0;
  theNodeI = theDomain->getNode(iNodeData[0]);
  if (theNodeI == 0) {
    opserr << "WARNING RotationShearCurve -- Node with tag " << iNodeData[0] << " does not exist for shear curve tag " << iTagData[0] << endln << endln;
    return 0;
  }	
  Node *theNodeJ = 0;
  theNodeJ = theDomain->getNode(iNodeData[1]);
  if (theNodeJ == 0) {
    opserr << "WARNING RotationShearCurve -- Node with tag " << iNodeData[1] << " does not exist for shear curve tag " << iTagData[0] << endln << endln;
    return 0;
  }	
  if (iNodeData[2] < 3 || iNodeData[2] > 6) {
    opserr << "WARNING RotationShearCurve -- rotAxis is invalid\n";
    opserr << "rotAxis = 3 -- Rotation about z-axis - 2D\n";
    opserr << "rotAxis = 4 -- Rotation about x-axis - 3D\n";
    opserr << "rotAxis = 5 -- Rotation about y-axis - 3D\n";
    opserr << "rotAxis = 6 -- Rotation about z-axis - 3D\n" << endln;
    return 0;
  }
  if (argc == 9) {
    numData = 3;
    if (OPS_GetDoubleInput(&numData, dKdegData) != 0) {
      opserr << "WARNING RotationShearCurve -- invalid Vn? Vr? Kdeg?\n" << endln;
      return 0;
    }
    if (dKdegData[0] != -1 && !(dKdegData[0] > 0)) {
      opserr << "WARNING RotationShearCurve --  Vn input is invalid\n";
      opserr << "Vn = -1 -- Shear critical limit is not used\n";
      opserr << "Vn > 0 -- Shear critical limit is the input value\n" << endln;
      return 0;
    }
    if (dKdegData[1] < -1) {
      opserr << "WARNING RotationShearCurve -- Vr input is invalid\n";
      opserr << "Vr = -1 -- Residual shear strength = 0.2*(maximum shear at failure)\n";
      opserr << "-1 < Vr < 0 -- Residual shear strength = Vr*(maximum shear at failure)\n";
      opserr << "Vr >= 0 -- Residual shear strength is the input value\n" << endln;
      return 0;
    }
    if (dKdegData[2] >= 0) {
      opserr << "WARNING RotationShearCurve -- Kdeg input is invalid\n";
      opserr << "The degrading slope must be less than zero\n" << endln;
      return 0;
    }
    numData = 1;
    if (OPS_GetDoubleInput(&numData, dRotLimData) != 0) {
      opserr << "WARNING RotationShearCurve -- invalid rotLim?\n" << endln;
      return 0;
    }
    if (dRotLimData[0] <= 0) {
      opserr << "WARNING RotationShearCurve -- rotLim input must be greater than zero\n" << endln;
      return 0;
    }
    
    LimitCurve *theCurve = 0;
    theCurve = new RotationShearCurve(iTagData[0], iTagData[1],
				      iNodeData[0], iNodeData[1], iNodeData[2], dKdegData[0], dKdegData[1], dKdegData[2], dRotLimData[0], 0,
				      0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
				      0.0, 0.0, 0.0, theDomain, theElement, theNodeI, theNodeJ);
    if (theCurve == 0) {
      opserr << "WARNING RotationShearCurve -- could not create limitCurve with constructor " << iTagData[0] << endln << endln;
      return 0;
    }
    return theCurve;
  } 
  else {
    numData = 3;
    if (OPS_GetDoubleInput(&numData, dKdegData) != 0) {
      opserr << "WARNING RotationShearCurve -- invalid Vn? Vr? Kdeg?\n" << endln;
      return 0;
    }
    if (dKdegData[0] != -1 && !(dKdegData[0] >= 0)) {
      opserr << "WARNING RotationShearCurve --  Vn input is invalid\n";
      opserr << "Vn = -1 -- Shear critical limit is not used\n";
      opserr << "Vn = 0 -- Shear critical limit is calculated using ASCE 41 Eq. 6-4\n";
      opserr << "Vn > 0 -- Shear critical limit is the input value\n" << endln;
      return 0;
    }
    if (dKdegData[1] < -1) {
      opserr << "WARNING RotationShearCurve -- Vr input is invalid\n";
      opserr << "Vr = -1 -- Residual shear strength from regression\n";
      opserr << "-1 < Vr < 0 -- Residual shear strength = Vr*(maximum shear at failure)\n";
      opserr << "Vr >= 0 -- Residual shear strength is the input value\n" << endln;
      return 0;
    }
    if (dKdegData[2] > 0) {
      opserr << "WARNING RotationShearCurve -- Kdeg input is invalid\n";
      opserr << "Kdeg = 0 -- Degrading slope calculated by regressions\n";
      opserr << "Kdeg < 0 -- Degrading slope is the input value\n" << endln;
      return 0;
    }
    numData = 1;
    if (OPS_GetIntInput(&numData, iTypeData) != 0) {
      opserr << "WARNING RotationShearCurve -- invalid defType?\n" << endln;
      return 0;
    }
    if (iTypeData[0] > 5 || iTypeData[0] <= 0) {
      opserr << "WARNING RotationShearCurve -- invalid defType input?\n" << endln;
      opserr << "1 -- Flexure-Shear capacity based on theta_f rotation capacity\n";
      opserr << "2 -- Flexure-Shear capacity based on theta_total rotation capacity\n";
      opserr << "3 -- Flexure-Shear capacity based on theta_flexural rotation capacity\n";
      opserr << "4 -- Flexure-Shear capacity based on theta_total-plastic rotation capacity\n";
      opserr << "5 -- Flexure-Shear capacity based on theta_flexural-plastic rotation capacity\n" << endln;
      return 0;
    }
    numData = 14;
    if (OPS_GetDoubleInput(&numData, dPropData) != 0) {
      opserr << "WARNING RotationShearCurve -- invalid b? d? h? L? st? As? Acc? ld? db? rhot? f'c? fy? fyt? delta?\n" << endln;
      return 0;
    }
    LimitCurve *theCurve = 0;
    theCurve = new RotationShearCurve(iTagData[0], iTagData[1],
				      iNodeData[0], iNodeData[1], iNodeData[2], 
				      dKdegData[0], dKdegData[1], dKdegData[2], 0.0, iTypeData[0],
				      fabs(dPropData[0]), fabs(dPropData[1]), fabs(dPropData[2]), fabs(dPropData[3]), 
				      fabs(dPropData[4]), fabs(dPropData[5]), fabs(dPropData[6]), fabs(dPropData[7]), fabs(dPropData[8]), 
				      fabs(dPropData[9]), fabs(dPropData[10]), fabs(dPropData[11]), fabs(dPropData[12]), 
				      dPropData[13], theDomain, theElement, theNodeI, theNodeJ);
    if (theCurve == 0) {
      opserr << "WARNING RotationShearCurve -- could not create limitCurve with constructor " << iTagData[0] << endln << endln;
      return 0;
    }
    return theCurve;
  }
}
Ejemplo n.º 9
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;
}
Ejemplo n.º 10
0
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;
        }
    }
}
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;
}
Ejemplo n.º 12
0
int
ImposedMotionSP::applyConstraint(double time)
{
  // on first 
  if (theGroundMotion == 0 || theNode == 0 || theNodeResponse == 0) {
    Domain *theDomain = this->getDomain();

    theNode = theDomain->getNode(nodeTag);
    if (theNode == 0) {
      opserr << "ImposedMotionSP::applyConstraint() - node " << nodeTag << " does not exist\n";
      return -1;
    }

    int numNodeDOF = theNode->getNumberDOF();

    if (dofNumber < 0 || numNodeDOF <= dofNumber) {
      opserr << "ImposedMotionSP::applyConstraint() - dof number " << dofNumber++ << " at node " << nodeTag << " not valid\n";
      return -2;
    }

    theNodeResponse = new Vector(numNodeDOF);
    if (theNodeResponse == 0) {
      opserr << "ImposedMotionSP::applyConstraint() - out of memory\n";
      return -2;
    }
    
    LoadPattern *theLoadPattern = theDomain->getLoadPattern(patternTag);
    if (theLoadPattern == 0)
      return -3;

    theGroundMotion = theLoadPattern->getMotion(groundMotionTag);
    if (theGroundMotion == 0)
      return -4;
  }

  if (theNodeResponse == 0) 
    return -1;


  
  // now get the response from the ground motion
  theGroundMotionResponse = theGroundMotion->getDispVelAccel(time);
  
  //
  // now set the responses at the node
  //
  
  /* ***********************************************************
   * disp response the responsibility of constraint handler
   
   *theNodeResponse = theNode->getTrialDisp();
   (*theNodeResponse)(dofNumber) = theGroundMotionResponse(0);
   theNode->setTrialDisp(*theNodeResponse);
  *************************************************************/
  
  *theNodeResponse = theNode->getTrialVel();
  (*theNodeResponse)(dofNumber) = theGroundMotionResponse(1);
  theNode->setTrialVel(*theNodeResponse);    
  
  *theNodeResponse = theNode->getTrialAccel();
  (*theNodeResponse)(dofNumber) = theGroundMotionResponse(2);
  theNode->setTrialAccel(*theNodeResponse);        
  
  return 0;
}
Ejemplo n.º 13
0
RigidRod::RigidRod(Domain &theDomain, int nR, int nC) {

    
    // get a pointer to the retained node and constrained nodes - ensure these exist
    Node *nodeR = theDomain.getNode(nR);
    if (nodeR == 0) {
      opserr << "RigidRod::RigidRod - retained Node" <<  nR <<  "not in domain\n";
      return;
    }
    Node *nodeC = theDomain.getNode(nC);
    if (nodeR == 0) {
      opserr << "RigidRod::RigidRod - constrained Node" <<  nC <<  "not in domain\n";
      return;
    }

    // get the coordinates of the two nodes - check dimensions are the same
    const Vector &crdR = nodeR->getCrds();
    const Vector &crdC = nodeC->getCrds();
    int dimR = crdR.Size();
    int dimC = crdC.Size();
    if (dimR != dimC) {
      opserr << "RigidRod::RigidRod - 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 << "RigidRod::RigidRod - 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 << "RigidRod::RigidRod - numDOF at nodes " << nR << " and " << nC <<
	"must be >= dimension of problem\n";

      return;
    }

    
    // create the ID to identify the constrained dof 
    ID id(dimR);

    // construct the tranformation matrix Ccr, where  Uc = Ccr Ur & set the diag
    Matrix mat(dimR,dimR);
    mat.Zero();

    // set the values
    for (int i=0; i<dimR; i++) {
      mat(i,i) = 1.0;
      id(i) = i;
    }

    // create the MP_Constraint
    MP_Constraint *newC = new MP_Constraint(nR, nC, mat, id, id);
					    
    if (newC == 0) {
      opserr << "RigidRod::RigidRod - for nodes " << nR << " and " << nC << " out of memory\n";
      exit(-1);
    } else {
      // add the constraint to the domain
      if (theDomain.addMP_Constraint(newC) == false) {
	opserr << "RigidRod::RigidRod - for nodes " << nC << " and " << nR << " could not add to domain\n",
	delete newC;
      }
    }
}
Ejemplo n.º 14
0
//  TransformationFE(Element *, Integrator *theIntegrator);
//	construictor that take the corresponding model element.
TransformationFE::TransformationFE(int tag, Element *ele)
:FE_Element(tag, ele), theDOFs(0), numSPs(0), theSPs(0), modID(0), 
  modTangent(0), modResidual(0), numGroups(0), numTransformedDOF(0)
{
  // set number of original dof at ele
    numOriginalDOF = ele->getNumDOF();

    // create the array of pointers to DOF_Groups
    const ID &nodes = ele->getExternalNodes();
    Domain *theDomain = ele->getDomain();
    int numNodes = nodes.Size();
    theDOFs = new DOF_Group *[numNodes];
    if (theDOFs == 0) {
	opserr << "FATAL TransformationFE::TransformationFE() - out of memory craeting ";
	opserr << "array of size : " << numNodes << " for storage of DOF_Group\n";
	exit(-1);
    }

    numGroups = numNodes;

    // now fill the array of DOF_Group pointers
    for (int i=0; i<numNodes; i++) {
	Node *theNode = theDomain->getNode(nodes(i));
	if (theNode == 0) {
	    opserr << "FATAL TransformationFE::TransformationFE() - no Node with tag: ";
	    opserr << nodes(i) << " in the domain\n";;
	    exit(-1);
	}
	DOF_Group *theDofGroup = theNode->getDOF_GroupPtr();
	if (theDofGroup == 0) {
	    opserr << "FATAL TransformationFE::TransformationFE() - no DOF_Group : ";
	    opserr << " associated with node: " << nodes(i) << " in the domain\n";;
	    exit(-1);
	}	
	theDOFs[i] = theDofGroup;
    }

    // see if theTransformation array is big enough
    // if not delete the old and create a new one
    if (numNodes > sizeTransformations) {
	if (theTransformations != 0) 
	    delete [] theTransformations;
	
	theTransformations = new Matrix *[numNodes];
	if (theTransformations == 0) {
	    opserr << "FATAL TransformationFE::TransformationFE() - out of memory ";
	    opserr << "for array of pointers for Transformation matrices of size ";
	    opserr << numNodes;
	    exit(-1);
	}		    
	sizeTransformations = numNodes;
    }	

    // if this is the first element of this type create the arrays for 
    // modified tangent and residual matrices
    if (numTransFE == 0) {

	modMatrices = new Matrix *[MAX_NUM_DOF+1];
	modVectors  = new Vector *[MAX_NUM_DOF+1];
	dataBuffer = new double[MAX_NUM_DOF*MAX_NUM_DOF];
	localKbuffer = new double[MAX_NUM_DOF*MAX_NUM_DOF];
	dofData      = new int[MAX_NUM_DOF];
	sizeBuffer = MAX_NUM_DOF*MAX_NUM_DOF;
	
	if (modMatrices == 0 || modVectors == 0 || dataBuffer == 0 ||
	    localKbuffer == 0 || dofData == 0) {
	    opserr << "TransformationFE::TransformationFE(Element *) ";
	    opserr << " ran out of memory";	    
	}
	for (int i=0; i<MAX_NUM_DOF; i++) {
	    modMatrices[i] = 0;
	    modVectors[i] = 0;
	}
    }

    // increment the number of transformations
    numTransFE++;
}
Ejemplo n.º 15
0
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;
}
Ejemplo n.º 16
0
int 
MeshRegion::setNodes(const ID &theNods)
{
  // destroy the old lists
  if (theNodes != 0)
    delete theNodes;
  if (theElements != 0)
    delete theElements;

  //
  // create new element & node lists
  //

  // create empty lists
  Domain *theDomain = this->getDomain();
  if (theDomain == 0) {
    opserr << "MeshRegion::setNodes() - no domain yet set\n";
    return -1;
  }

  int numNodes = theNods.Size();
  theNodes = new ID(0, numNodes);
  theElements = new ID(0, numNodes);
  if (theNodes == 0 || theElements == 0) {
    opserr << "MeshRegion::setElements() - ran out of memory\n";
    return -1;
  }

  // add nodes to the node list if in the domain
  int loc = 0;
  for (int i=0; i<numNodes; i++) {
    int nodeTag = theNods(i);
    Node *theNode = theDomain->getNode(nodeTag);
    if (theNode != 0) {
      if (theNodes->getLocation(nodeTag) < 0)
	(*theNodes)[loc++] = nodeTag;      
    }
  }

  // now loop over the ele to create the ele list
  // NOTE - ele added to list if all it's nodes are in the region
  loc = 0;

  ElementIter &theEles = theDomain->getElements();
  Element *theEle;

  // loop over all ele
  while ((theEle = theEles()) != 0) {

    int eleTag = theEle->getTag();
    
    // check to see if all external nodes in node list
    bool in = true;
    const ID &theEleNodes = theEle->getExternalNodes();
    int numNodes = theEleNodes.Size();

    for (int i=0; i<numNodes; i++) {
      int nodeTag = theEleNodes(i);
      if (theNodes->getLocation(nodeTag) < 0) {
	in = false;
	i = numNodes;
      }
    }
    
    // if they are all in the node list add the ele to ele list
    if (in == true) 
      (*theElements)[loc++] = eleTag;
  }

  return 0;
}
Ejemplo n.º 17
0
// changed
RemoveRecorder::RemoveRecorder(int nodeID, 
			       ID &eleIDs, 
			       ID &secIDs, 
			       ID &slaveTags, 
			       Vector remCriteria, 
			       Domain &theDomainPtr, 
			       OPS_Stream &s,
			       bool echotimeflag, 
			       double deltat, 
			       const char *theFileName ,
			       Vector eleMass, 
			       double gAcc, 
			       int gDir, 
			       int gPat, 
			       int nTagbotn, 
			       int nTagmidn, 
			       int nTagtopn, 
			       int globgrav, 
			       const char *thefileNameinf)
  :Recorder(RECORDER_TAGS_RemoveRecorder),
   nodeTag(nodeID), 
   numEles(eleIDs.Size()), 
   eleTags(eleIDs.Size()), 
   secTags(secIDs.Size()), 
   numSecs(secIDs.Size()), 
   criteria(remCriteria),
   theDomain(&theDomainPtr), 
   slaveEleTags(slaveTags.Size()), 
   slaveFlag(false),
   echoTimeFlag(echotimeflag), 
   deltaT(deltat), 
   nextTimeStampToRecord(0.0), 
   gAcc(gAcc), 
   gDir(gDir), 
   gPat(gPat),
   nTagbotn(nTagbotn), 
   nTagmidn(nTagmidn), 
   nTagtopn(nTagtopn), 
   globgrav(globgrav),
   eleResponses(0)
{
  numRecs++;
#ifdef MMTDEBUGIO
  opserr<<"RemoveRecorder, constructor called"<<endln;
#endif
  
  numRules = criteria.Size()/2;

#ifdef MMTDEBUG
  for (int h=0 ; h<2 ; h++) {
    opserr<<"remCriteria["<<h<<"] = "<<criteria[h]<<endln;
  }
#endif

  eleResponses = new Response *[numEles];  
  for (int l=0 ; l<numEles ; l++) {
    eleTags(l) = eleIDs(l);
    eleResponses[l] = 0;
  }

  if (secIDs[0] != 0 || secIDs.Size() != 1) {
    for (int l=0 ; l<numSecs ; l++) {
      secTags(l) = secIDs(l);
#ifdef MMTDEBUG
      opserr<<"storing secID = "<<secIDs[l]<<endln;
#endif
    }
  } else
    secTags[0] = 0;
  
  if (slaveTags[0] != 0 || slaveTags.Size() != 1) {
    slaveFlag = true;
    for (int l=0 ; l<slaveTags.Size() ; l++) {
      slaveEleTags(l) = slaveTags(l);
#ifdef MMTDEBUG
      opserr<<"storing slaveEleID = "<<slaveTags[l]<<endln;
#endif
    }
  } else
    slaveEleTags[0] = 0;


  if (thefileNameinf != 0)  { 
    int fileNameLength2 = strlen(thefileNameinf) + 1;
    //   fileName = new char[fileNameLength + 8];
    fileNameinf = new char[fileNameLength2];
    strcpy(fileNameinf, thefileNameinf);
  }
  
  Element *theEle = 0;
  const char **argv = new const char *[1];
  if (fileNameinf == 0)
    argv[0] = "getRemCriteria1";
  else
    argv[0] = "getRemCriteria2";


  // Get the element	
  for (int j= 0; j<numEles; j++) {
    Element *theEle = theDomainPtr.getElement(eleTags[j]);
    if ( theEle == NULL ) {
      opserr << "WARNING RemoveRecorder::RemoveRecorder() - no element with tag: "
	     << eleTags[j] << " exists in Domain\n";
      eleResponses[j] = 0;
    } else {

      // set up the element responses
      eleResponses[j] = theEle->setResponse(argv, 1, s);
      if (eleResponses[j] == 0) {
	opserr << "WARNING :: getRemCriteria - not a response quantity of element\n";
      } else {
	if (fileNameinf != 0) {
	  Information &eleInfo = eleResponses[j]->getInformation();
	  eleInfo.setString(fileNameinf);
	}
      }  
    }
  }

  delete [] argv;


  if (slaveEleTags[0] != 0) {
    for (int k= 0; k<slaveTags.Size(); k++) {
      theEle = theDomainPtr.getElement(slaveTags[k]);
      if ( theEle == NULL ) {
	opserr << "WARNING RemoveRecorder::RemoveRecorder() - no element with tag: "
	       << slaveTags[k] << " exists in Domain\n";
	exit(-1);
      }
    }
  }
  
  // check if the recorder is for node removal
  if (nodeTag != 0) {
    Node *theNode = theDomainPtr.getNode(nodeTag);
    if ( theNode == NULL ) {
      opserr << "WARNING RemoveRecorder::RemoveRecorder() - no node with tag: "
	     << nodeTag << " exists in Domain\n";
      exit(-1);
    }
  }
  
  
  // extract masses
  eleMasses = eleMass;
  
  // if file is specified, copy name and open the file if it hasn't been opened
  if (theFileName != 0 && fileName == 0) {
    
    // create char array to store file name
    int fileNameLength = strlen(theFileName) + 1;
    //   fileName = new char[fileNameLength + 8];
    fileName = new char[fileNameLength];
    
    if (fileName == 0) {
      opserr << "RemoveRecorder::RemoveRecorder - out of memory creating string " <<
	fileNameLength << " long\n";
      exit(-1);
    }
    
    // compose and copy file name string
    strcpy(fileName, theFileName);
    //	char* dumName = new char(fileNameLength) + 1;
    //	strcpy(dumName, theFileName); 
    
    //	char *temp = "Collapse";
    //	fileName = strcat(temp, dumName);	
#ifdef MMTDEBUGIO
    //	opserr<<"theFileName "<<theFileName<<"len "<<strlen(theFileName)<<" fileNameLength "<<fileNameLength<<endln;
    //	opserr<<"filename "<<fileName<<"len "<<strlen(fileName)<<" temp "<<temp<<" len "<<strlen(temp)<<endln;
    
    //	opserr<<"filename "<<fileName*<<"len "<<strlen(fileName)<<" temp "<<temp*<<" len "<<strlen(temp)<<endln;
#endif
    
#ifdef MMTDEBUGIO
    opserr<<"filename "<<fileName<<" len "<<strlen(fileName)<<endln;
#endif
    //	delete [] temp;
    
    // open the file
    theFile.open(fileName, ios::out);
    if ((&theFile) == NULL) {
      opserr << "WARNING - RemoveRecorder::RemoveRecorder()";
      opserr << " - could not open file " << fileName << endln;
    }    
  }
  
#ifdef MMTDEBUG
  opserr<<"RemoveRecorder, constructor finished"<<endln;
#endif
}
Ejemplo n.º 18
0
int
TetMesh::remesh(double alpha)
{
    int ndm = OPS_GetNDM();
    if (ndm != 3) {
	opserr << "WARNING: TetMesh::remesh is only for 3D problem\n";
	return -1;
    }
    Domain* domain = OPS_GetDomain();
    if (domain == 0) {
        opserr << "WARNING: domain is not created\n";
        return -1;
    }

    // get all nodes
    std::map<int, std::vector<int> > ndinfo;
    TaggedObjectIter& meshes = OPS_getAllMesh();
    ID nodetags;
    Mesh* msh = 0;
    while((msh = dynamic_cast<Mesh*>(meshes())) != 0) {

        int id = msh->getID();
        int mtag = msh->getTag();

        if (id == 0) continue;

        // get bound nodes
        const ID& tags = msh->getNodeTags();
        for (int i=0; i<tags.Size(); ++i) {
            std::vector<int>& info = ndinfo[tags(i)];
            info.push_back(mtag);
            info.push_back(id);
            nodetags.insert(tags(i));
        }

        // get internal nodes
        const ID& newtags = msh->getNewNodeTags();
        for (int i=0; i<newtags.Size(); ++i) {
            std::vector<int>& info = ndinfo[newtags(i)];
            info.push_back(mtag);
            info.push_back(id);
            nodetags.insert(newtags(i));
        }
    }

    if (nodetags.Size() == 0) return 0;

    // calling mesh generator
    TetMeshGenerator gen;
    int nodecounter = nextNodeTag();
    for(int i=0; i<nodetags.Size(); ++i) {

        // get node
        Node* theNode = domain->getNode(nodetags(i));
        if(theNode == 0) {
            opserr<<"WARNING: node "<<nodetags(i)<<" is not defined\n";
            return -1;
        }
        const Vector& crds = theNode->getCrds();
        const Vector& disp = theNode->getTrialDisp();
        if(crds.Size() < ndm || disp.Size() < ndm) {
            opserr<<"WARNING: ndm < 3 or ndf < 3\n";
            return -1;
        }

	// create pc if not
	Pressure_Constraint* thePC = domain->getPressure_Constraint(nodetags(i));
	if(thePC != 0) {
	    thePC->setDomain(domain);
	} else {

	    // create pressure node
	    Node* pnode = 0;
	    pnode = new Node(nodecounter++, 1, crds(0), crds(1), crds(2));
	    if (pnode == 0) {
		opserr << "WARNING: run out of memory -- BgMesh::gridNodes\n";
		return -1;
	    }
	    if (domain->addNode(pnode) == false) {
		opserr << "WARNING: failed to add node to domain -- BgMesh::gridNodes\n";
		delete pnode;
		return -1;
	    }

	    thePC = new Pressure_Constraint(nodetags(i), pnode->getTag());
	    if(thePC == 0) {
		opserr<<"WARNING: no enough memory for Pressure_Constraint\n";
		return -1;
	    }
	    if (domain->addPressure_Constraint(thePC) == false) {
		opserr << "WARNING: failed to add PC to domain -- BgMesh::gridNodes\n";
		delete thePC;
		return -1;
	    }
	}

        // add point
        gen.addPoint(crds(0)+disp(0), crds(1)+disp(1), crds(2)+disp(2), 0);
    }

    // meshing
    gen.remesh(alpha);

    // get elenodes
    std::map<int,ID> meshelenodes;
    for(int i=0; i<gen.getNumTets(); i++) {

        // get points
        int p1,p2,p3,p4;
        gen.getTet(i,p1,p2,p3,p4);

        // get nodes
        int nds[4];
        nds[0] = nodetags(p1);
        nds[1] = nodetags(p2);
        nds[2] = nodetags(p3);
	nds[3] = nodetags(p4);

        // check if all nodes in same mesh
        std::vector<int>& info1 = ndinfo[nds[0]];
        int mtag = 0, id = 0;
        bool same = false;
        for (int k=0; k<(int)info1.size()/2; ++k) {
            // check if any mesh of node 1 is same for another three nodes
            mtag = info1[2*k];
            id = info1[2*k+1];

            int num = 0;
            for (int j=1; j<4; ++j) {
                std::vector<int>& infoj = ndinfo[nds[j]];
                for (int kj=0; kj<(int)infoj.size()/2; ++kj) {
                    int mtagj = infoj[2*kj];
                    if (mtag == mtagj) {
                        ++num;
                        break;
                    }
                }

            }
            if (num == 3) {
                same = true;
                break;
            }
        }

        // nodes in different mesh
        if (!same) {
            mtag = 0;
            id = 0;
            for (int j=0; j<4; ++j) {
                std::vector<int>& info = ndinfo[nds[j]];
                for (int k=0; k<(int)info.size()/2; ++k) {
                    if (info[2*k+1] < id) {
                        if (dynamic_cast<TetMesh*>(OPS_getMesh(info[2*k])) != 0) {
                            mtag = info[2*k];
                            id = info[2*k+1];
                        }
                    }
                }
            }
        }

        // if all connected to structure
        if (id >= 0) continue;

        // add elenodes to its mesh
        ID& elenodes = meshelenodes[mtag];
        for (int j=0; j<4; ++j) {
            elenodes[elenodes.Size()] = nds[j];
        }
    }

    // creat elements
    for (std::map<int,ID>::iterator it=meshelenodes.begin();
	 it!=meshelenodes.end(); ++it) {

        int mtag = it->first;
        ID& elenodes = it->second;

        msh = OPS_getMesh(mtag);
        if (msh != 0) {

            int id = msh->getID();

            // remove mesh for id<0
            if (id < 0) {
                if (msh->clearEles() < 0) {
                    opserr << "WARNING: failed to clear element in mesh"<<mtag<<"\n";
                    return -1;
                }

                if (msh->newElements(elenodes) < 0) {
                    opserr << "WARNING: failed to create new elements in mesh"<<mtag<<"\n";
                    return -1;
                }
            }
        }
    }

    return 0;
}
Ejemplo n.º 19
0
int
TetMesh::mesh()
{
    Domain* domain = OPS_GetDomain();
    if (domain == 0) {
        opserr << "WARNING: domain is not created\n";
        return -1;
    }

    // check
    double size = this->getMeshsize();
    if(size <= 0) {
        opserr<<"WARNING: mesh size <= 0\n";
        return -1;
    }
    if (mtags.Size() == 0) return 0;

    // get nodes and elements from boundary mesh
    ID ndtags;
    std::vector<TetMeshGenerator::Facet> facets;
    for (int i=0; i<mtags.Size(); ++i) {
	// get mesh
        Mesh* mesh = OPS_getMesh(mtags(i));
        if (mesh == 0) {
            opserr << "WARNING: mesh "<<mtags(i)<<" does not exist\n";
            return -1;
        }

	// get nodes
        const ID& tags = mesh->getNodeTags();
        for (int j=0; j<tags.Size(); ++j) {
            ndtags.insert(tags(j));
        }
        const ID& newtags = mesh->getNewNodeTags();
        for (int j=0; j<newtags.Size(); ++j) {
            ndtags.insert(newtags(j));
        }

	// get polygons
	int numelenodes = mesh->getNumEleNodes();
        const ID& elends = mesh->getEleNodes();
	TetMeshGenerator::Facet facet;
        for (int j=0; j<elends.Size()/numelenodes; ++j) {
	    TetMeshGenerator::Polygon polygon(numelenodes);
	    for (int k=0; k<numelenodes; ++k) {
		polygon[k] = elends(numelenodes*j+k);
	    }
            facet.push_back(polygon);
        }

	// add the mesh as a facet
	facets.push_back(facet);
    }
    if(ndtags.Size() < 4) {
        opserr<<"WARNING: input number of nodes < 4\n";
        return -1;
    }
    if(facets.size() < 4) {
        opserr<<"WARNING: input number of facets < 4\n";
        return -1;
    }
    this->setNodeTags(ndtags);

    // get correct index for factes
    for (unsigned int i=0; i<facets.size(); ++i) {
	for (unsigned int j=0; j<facets[i].size(); ++j) {
	    for (unsigned int k=0; k<facets[i][j].size(); ++k) {
		facets[i][j][k] = ndtags.getLocationOrdered(facets[i][j][k]);
		if (facets[i][j][k] < 0) {
		    opserr << "WARNING: failed to get a node in a facet -- Tetmesh::mesh\n";
		    return -1;
		}
	    }
	}
    }

    // calling mesh generator
    TetMeshGenerator gen;
    int nodecounter = nextNodeTag();
    for(int i=0; i<ndtags.Size(); i++) {
        // get node
        Node* theNode = domain->getNode(ndtags(i));
        if(theNode == 0) {
            opserr<<"WARNING: node "<<ndtags(i)<<" is not defined\n";
            return -1;
        }
        Vector crds = theNode->getCrds();
        const Vector& disp = theNode->getTrialDisp();
        if(crds.Size() != 3) {
            opserr<<"WARNING: ndm != 3\n";
            return -1;
        }
        if (disp.Size() >= crds.Size()) {
            for (int j=0; j<crds.Size(); ++j) {
                crds(j) += disp(j);
            }
        }

        // add point
        gen.addPoint(crds(0), crds(1), crds(2), 0);

        // add pc
        if (this->isFluid()) {
	    // create pressure constraint
	    Pressure_Constraint* thePC = domain->getPressure_Constraint(ndtags(i));
	    if(thePC != 0) {
		thePC->setDomain(domain);
	    } else {

		// create pressure node
		Node* pnode = 0;
		pnode = new Node(nodecounter++, 1, crds[0], crds[1], crds[2]);
		if (pnode == 0) {
		    opserr << "WARNING: run out of memory -- BgMesh::gridNodes\n";
		    return -1;
		}
		if (domain->addNode(pnode) == false) {
		    opserr << "WARNING: failed to add node to domain -- BgMesh::gridNodes\n";
		    delete pnode;
		    return -1;
		}

		thePC = new Pressure_Constraint(ndtags(i), pnode->getTag());
		if(thePC == 0) {
		    opserr<<"WARNING: no enough memory for Pressure_Constraint\n";
		    return -1;
		}
		if (domain->addPressure_Constraint(thePC) == false) {
		    opserr << "WARNING: failed to add PC to domain -- BgMesh::gridNodes\n";
		    delete thePC;
		    return -1;
		}
	    }
        }
    }

    for (unsigned int i=0; i<facets.size(); ++i) {
	gen.addFacet(facets[i],0);
    }

    // meshing
    gen.mesh(size*size*size/(6.0*1.414),false);

    // get points and create nodes
    int nump = gen.getNumPoints();
    if (nump == 0) {
        opserr << "WARNING: no nodes is meshed\n";
        return -1;
    }
    ID newndtags(nump-ndtags.Size());
    ID allndtags(nump);
    for (int i=0; i<ndtags.Size(); ++i) {
        allndtags(i) = ndtags(i);
    }

    for (int i=ndtags.Size(); i<nump; ++i) {
        // get point
        Vector crds(3);
        int mark = 0;
        gen.getPoint(i,crds(0),crds(1),crds(2),mark);
        Node* node = newNode(nodecounter++,crds);
        if (node == 0) {
            opserr << "WARING: failed to create node\n";
            return -1;
        }
        if (domain->addNode(node) == false) {
            opserr << "WARNING: failed to add node to domain\n";
            delete node;
            return -1;
        }
        allndtags(i) = node->getTag();
        newndtags(i-ndtags.Size()) = node->getTag();

        // add pc
        if (this->isFluid()) {
	    // create pressure constraint
	    Pressure_Constraint* thePC = domain->getPressure_Constraint(node->getTag());
	    if(thePC != 0) {
		thePC->setDomain(domain);
	    } else {

		// create pressure node
		Node* pnode = 0;
		pnode = new Node(nodecounter++, 1, crds(0), crds(1), crds(2));
		if (pnode == 0) {
		    opserr << "WARNING: run out of memory -- BgMesh::gridNodes\n";
		    return -1;
		}
		if (domain->addNode(pnode) == false) {
		    opserr << "WARNING: failed to add node to domain -- BgMesh::gridNodes\n";
		    delete pnode;
		    return -1;
		}

		thePC = new Pressure_Constraint(node->getTag(), pnode->getTag());
		if(thePC == 0) {
		    opserr<<"WARNING: no enough memory for Pressure_Constraint\n";
		    return -1;
		}
		if (domain->addPressure_Constraint(thePC) == false) {
		    opserr << "WARNING: failed to add PC to domain -- BgMesh::gridNodes\n";
		    delete thePC;
		    return -1;
		}
	    }
        }
    }
    this->setNewNodeTags(newndtags);

    // get tetrahedrons
    int numtet = gen.getNumTets();
    if (numtet == 0) return 0;
    ID elenodes(numtet*4);

    for(int i=0; i<numtet; i++) {
        int p1,p2,p3,p4;
        gen.getTet(i,p1,p2,p3,p4);
        elenodes(4*i) = allndtags(p1);
        elenodes(4*i+1) = allndtags(p2);
        elenodes(4*i+2) = allndtags(p3);
        elenodes(4*i+3) = allndtags(p4);
    }
    this->setEleNodes(elenodes);

    // create elemnts
    if (this->newElements(elenodes) < 0) {
        opserr << "WARNING: failed to create elements\n";
        return -1;
    }

    return 0;
}