void
UniformExcitation::setDomain(Domain *theDomain) 
{
  this->LoadPattern::setDomain(theDomain);

  // now we go through and set all the node velocities to be vel0 
  // for those nodes not fixed in the dirn!
  if (vel0 != 0.0) {

    SP_ConstraintIter &theSPs = theDomain->getSPs();
    SP_Constraint *theSP;
    ID constrainedNodes(0);
    int count = 0;
    while ((theSP=theSPs()) != 0) {
      if (theSP->getDOF_Number() == theDof) {
	constrainedNodes[count] = theSP->getNodeTag();
	count++;
      }
    }


    NodeIter &theNodes = theDomain->getNodes();
    Node *theNode;
    Vector newVel(1);
    int currentSize = 1;
    while ((theNode = theNodes()) != 0) {
      int tag = theNode->getTag();
      if (constrainedNodes.getLocation(tag) < 0) {
	int numDOF = theNode->getNumberDOF();
	if (numDOF != currentSize) 
	  newVel.resize(numDOF);
	
	newVel = theNode->getVel();
	newVel(theDof) = vel0;
	theNode->setTrialVel(newVel);
	theNode->commitState();
      }
    }
  }
}
Exemple #2
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;
  }
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
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
DomainPartitioner::partition(int numParts, bool usingMain, int mainPartitionTag, int specialElementTag)
{

  usingMainDomain = usingMain;
  mainPartition = mainPartitionTag;

  // first we ensure the partitioned domain has numpart subdomains
  // with tags 1 through numparts
  for (int i=1; i<=numParts; i++) {
    if (i != mainPartition) {
      Subdomain *subdomainPtr = myDomain->getSubdomainPtr(i);
      if (subdomainPtr == 0) {
	opserr << "DomainPartitioner::partition - No Subdomain: ";
	opserr << i << " exists\n";
	return -1;
      }
    }
  }

  // we get the ele graph from the domain and partition it
  //    Graph &theEleGraph = myDomain->getElementGraph();
  //    theElementGraph = new Graph(myDomain->getElementGraph());

  theElementGraph = &(myDomain->getElementGraph());

  int theError = thePartitioner.partition(*theElementGraph, numParts);

  if (theError < 0) {
    opserr << "DomainPartitioner::partition";
    opserr << " - the graph partioner failed to partition the ";
    opserr << "element graph\n";
    return -10+theError;
  }

  /* print graph */
  //  opserr << "DomainPartitioner::partition - eleGraph: \n";
  //  theElementGraph->Print(opserr, 4);
  
  VertexIter &theVertices1 = theElementGraph->getVertices();
  Vertex *vertexPtr = 0;
  bool moreThanOne = false;
  
  vertexPtr = theVertices1();
  int vertexOnePartition  = 0;
  if (vertexPtr != 0)
    vertexOnePartition  = vertexPtr->getColor();  
  while ((moreThanOne == false) && ((vertexPtr = theVertices1()) != 0)) {
    int partition = vertexPtr->getColor();
    if (partition != vertexOnePartition ) {
      moreThanOne = true;
    }
  }

  if (moreThanOne == false) {
    opserr <<"DomainPartitioner::partition - too few elements for model to be partitioned\n";
    return -1;
  }

  int specialElementColor = 1;
  if (specialElementTag != 0) {
    bool found = false;
    VertexIter &theVerticesSpecial = theElementGraph->getVertices();
    while ((found == false) && ((vertexPtr = theVerticesSpecial()) != 0)) {
      int eleTag = vertexPtr->getRef();
      if (eleTag == specialElementTag) {
	found = true;
	int vertexColor = vertexPtr->getColor();
	if (vertexColor != 1)
	  //	  specialElementColor = vertexColor;
	  vertexPtr->setColor(1);
      }
    }
  }
  
      
  // we create empty graphs for the numParts subdomains,
  // in the graphs we place the vertices for the elements on the boundaries
  
  // we do not invoke the destructor on the individual graphs as 
  // this would invoke the destructor on the individual vertices

  if (theBoundaryElements != 0)
    delete [] theBoundaryElements;
  
  theBoundaryElements = new Graph * [numParts];
  if (theBoundaryElements == 0) {
    opserr << "DomainPartitioner::partition(int numParts)";
    opserr << " - ran out of memory\n";
    numPartitions = 0;  
    return -1;
  }

  for (int l=0; l<numParts; l++) {
    theBoundaryElements[l] = new Graph(2048); // graphs can grow larger; just an estimate
    
    if (theBoundaryElements[l] == 0) {
      opserr << "DomainPartitioner::partition(int numParts)";
      opserr << " - ran out of memory\n";
      numPartitions = 0;
      return -1;
    }
  }
  
  numPartitions = numParts;

  //  opserr << "DomainPartitioner::partition() - nodes \n";  
  
  // we now create a MapOfTaggedObjectStorage to store the NodeLocations
  // and create a new NodeLocation for each node; adding it to the map object

  theNodeLocations = new MapOfTaggedObjects();
  if (theNodeLocations == 0) {
    opserr << "DomainPartitioner::partition(int numParts)";
    opserr << " - ran out of memory creating MapOfTaggedObjectStorage for node locations\n";
    numPartitions = 0;
    return -1;
  }

  NodeIter &theNodes = myDomain->getNodes();
  Node *nodePtr;
  while ((nodePtr = theNodes()) != 0) {
    NodeLocations *theNodeLocation = new NodeLocations(nodePtr->getTag());
    if (theNodeLocation == 0) {
      opserr << "DomainPartitioner::partition(int numParts)";
      opserr << " - ran out of memory creating NodeLocation for node: " << nodePtr->getTag() << endln;
      numPartitions = 0;
      return -1;
    }
    if (theNodeLocations->addComponent(theNodeLocation) == false) {
      opserr << "DomainPartitioner::partition(int numParts)";
      opserr << " - failed to add NodeLocation to Map for Node: " << nodePtr->getTag() << endln;
      numPartitions = 0;
      return -1;
    }
  }

  //
  // we now iterate through the vertices of the element graph
  // to see if the vertex is a boundary vertex or not - if it is
  // we add to the appropriate graph created above. We also set the
  // value the color variable of each of the external nodes connected 
  // to the element to a value which will indicate that that node will
  // have to be added to the subdomain.
  //
  
  VertexIter &theVertexIter = theElementGraph->getVertices();
  while ((vertexPtr = theVertexIter()) != 0) {
    int eleTag = vertexPtr->getRef();
    int vertexColor = vertexPtr->getColor();
    
    const ID &adjacency = vertexPtr->getAdjacency();
    int size = adjacency.Size();
    for (int i=0; i<size; i++) {
      Vertex *otherVertex = theElementGraph->getVertexPtr(adjacency(i));
      if (otherVertex->getColor() != vertexColor) {
	theBoundaryElements[vertexColor-1]->addVertex(vertexPtr,false);
	i = size;
      }
    }
    
    Element *elePtr = myDomain->getElement(eleTag);
    const ID &nodes = elePtr->getExternalNodes();
    size = nodes.Size();
    for (int j=0; j<size; j++) {
      int nodeTag = nodes(j);
      TaggedObject *theTaggedObject = theNodeLocations->getComponentPtr(nodeTag);
      if (theTaggedObject == 0) {
	opserr << "DomainPartitioner::partition(int numParts)";
	opserr << " - failed to find NodeLocation in Map for Node: " << nodePtr->getTag() << " -- A BUG!!\n";
	numPartitions = 0;
	return -1;	
      }
      NodeLocations *theNodeLocation = (NodeLocations *)theTaggedObject;
      theNodeLocation->addPartition(vertexColor);
    }
  }

  // now go through the MP_Constraints and ensure the retained node is in every 
  // partition the constrained node is in
  MP_ConstraintIter &theMPs = myDomain->getMPs();
  MP_Constraint *mpPtr;
  while ((mpPtr = theMPs()) != 0) {
    int retained = mpPtr->getNodeRetained();
    int constrained = mpPtr->getNodeConstrained();
    
    TaggedObject *theRetainedObject = theNodeLocations->getComponentPtr(retained);      
    TaggedObject *theConstrainedObject = theNodeLocations->getComponentPtr(constrained);
    
    if (theRetainedObject == 0 || theConstrainedObject == 0) {
      opserr << "DomainPartitioner::partition(int numParts)";
      if (theRetainedObject == 0)
	opserr << " - failed to find NodeLocation in Map for Node: " << retained << " -- A BUG!!\n";
      if (theConstrainedObject == 0)
	opserr << " - failed to find NodeLocation in Map for Node: " << constrained << " -- A BUG!!\n";
      numPartitions = 0;
      return -1;	
    }
    
    NodeLocations *theRetainedLocation = (NodeLocations *)theRetainedObject;
    NodeLocations *theConstrainedLocation = (NodeLocations *)theConstrainedObject;
    ID &theConstrainedNodesPartitions = theConstrainedLocation->nodePartitions;
    int numPartitions = theConstrainedNodesPartitions.Size();
    for (int i=0; i<numPartitions; i++) {
      theRetainedLocation->addPartition(theConstrainedNodesPartitions(i));
    }
  }

  // we now add the nodes, 
  TaggedObjectIter &theNodeLocationIter = theNodeLocations->getComponents();
  TaggedObject *theNodeObject;

  while ((theNodeObject = theNodeLocationIter()) != 0) {
    NodeLocations *theNodeLocation = (NodeLocations *)theNodeObject;

    int nodeTag = theNodeLocation->getTag();
    ID &nodePartitions = theNodeLocation->nodePartitions;
    int numPartitions = theNodeLocation->numPartitions;

    for (int i=0; i<numPartitions; i++) {
      int partition = nodePartitions(i);	  
      if (partition != mainPartition) {      
	Subdomain *theSubdomain = myDomain->getSubdomainPtr(partition); 
	if (numPartitions == 1) {
	  Node *nodePtr = myDomain->removeNode(nodeTag);
	  theSubdomain->addNode(nodePtr);
	} else {
	  Node *nodePtr = myDomain->getNode(nodeTag);
	  theSubdomain->addExternalNode(nodePtr);	  
	}
      }
    }
  }

  // we now move the elements 
  VertexIter &theVertices = theElementGraph->getVertices();
  while ((vertexPtr = theVertices()) != 0) {
    // move the element
    int partition = vertexPtr->getColor();
    if (partition != mainPartition) {          
      int eleTag = vertexPtr->getRef();

      //      opserr << "removing ele: " << eleTag << endln;
      
      Element *elePtr = myDomain->removeElement(eleTag);  
      //      opserr << *elePtr;

      if (elePtr != 0) {
	//	opserr << "adding ele - start\n";
	Subdomain *theSubdomain = myDomain->getSubdomainPtr(partition);  
	theSubdomain->addElement(elePtr);

	//	opserr << "adding ele - done\n";
      } else {
	opserr << "DomainPartitioner::partioner - element GONE! - eleTag " << eleTag << endln;
      }
    } 
  }

  // now we go through the load patterns and move NodalLoad
  // 1) make sure each subdomain has a copy of the partitioneddomains load patterns.
  // 2) move nodal loads
  // 3) move SP_Constraints
  
  LoadPatternIter &theLoadPatterns = myDomain->getLoadPatterns();
  LoadPattern *theLoadPattern;
  while ((theLoadPattern = theLoadPatterns()) != 0) {
    int loadPatternTag = theLoadPattern->getTag();

    
    // check that each subdomain has a loadPattern with a similar tag and class tag
    for (int i=1; i<=numParts; i++) {
      if (i != mainPartition) {
	Subdomain *theSubdomain = myDomain->getSubdomainPtr(i);
	LoadPattern *loadPatternCopy = theSubdomain->getLoadPattern(loadPatternTag);
	if (loadPatternCopy == 0) {
	  LoadPattern *newLoadPattern = theLoadPattern->getCopy();
	  if (newLoadPattern == 0) {
	    opserr << "DomaiPartitioner::partition - out of memory creating LoadPatterns\n";
 	    return -1;
	  }
	  theSubdomain->addLoadPattern(newLoadPattern);
	}
      }
    }

    // now remove any nodal loads that correspond to internal nodes in a subdomain
    // and add them to the appropriate loadpattern in the subdomain
    
    NodalLoadIter &theNodalLoads = theLoadPattern->getNodalLoads();
    NodalLoad *theNodalLoad;
    while ((theNodalLoad = theNodalLoads()) != 0) {
      int nodeTag = theNodalLoad->getNodeTag();

      TaggedObject *theTaggedObject = theNodeLocations->getComponentPtr(nodeTag);
      if (theTaggedObject == 0) {
	opserr << "DomainPartitioner::partition(int numParts)";
	opserr << " - failed to find NodeLocation in Map for Node: " << nodeTag << " -- A BUG!!\n";
	numPartitions = 0;
	return -1;	
      }
    
      NodeLocations *theNodeLocation = (NodeLocations *)theTaggedObject;
      ID &nodePartitions = theNodeLocation->nodePartitions;
      int numPartitions = theNodeLocation->numPartitions;
      for (int i=0; i<numPartitions; i++) {
	int partition = nodePartitions(i);	  
	if (partition != mainPartition) {      
	  if (numPartitions == 1) {
	    Subdomain *theSubdomain = myDomain->getSubdomainPtr(partition);
	    theLoadPattern->removeNodalLoad(theNodalLoad->getTag());
	    if ((theSubdomain->addNodalLoad(theNodalLoad, loadPatternTag)) != true)
	      opserr << "DomainPartitioner::partition() - failed to add Nodal Load\n";
	  }
	}
      }      
    }

  
    SP_ConstraintIter &theSPs = theLoadPattern->getSPs();
    SP_Constraint *spPtr;
    while ((spPtr = theSPs()) != 0) {
      int nodeTag = spPtr->getNodeTag();
      
      TaggedObject *theTaggedObject = theNodeLocations->getComponentPtr(nodeTag);
      if (theTaggedObject == 0) {
	opserr << "DomainPartitioner::partition(int numParts)";
	opserr << " - failed to find NodeLocation in Map for Node: " << nodeTag << " -- A BUG!!\n";
	numPartitions = 0;
	return -1;	
      }
      
      NodeLocations *theNodeLocation = (NodeLocations *)theTaggedObject;
      ID &nodePartitions = theNodeLocation->nodePartitions;
      int numPartitions = theNodeLocation->numPartitions;
      for (int i=0; i<numPartitions; i++) {
	int partition = nodePartitions(i);	  
	if (partition != mainPartition) {      
	  Subdomain *theSubdomain = myDomain->getSubdomainPtr(partition); 
	  if (numPartitions == 1) 
	    theLoadPattern->removeSP_Constraint(spPtr->getTag());
	  int res = theSubdomain->addSP_Constraint(spPtr, loadPatternTag);
	  if (res < 0)
	    opserr << "DomainPartitioner::partition() - failed to add SP Constraint\n";
	}
      }    
    }  

    ElementalLoadIter &theLoads = theLoadPattern->getElementalLoads();
    ElementalLoad *theLoad;
    while ((theLoad = theLoads()) != 0) {
      int loadEleTag = theLoad->getElementTag();

      SubdomainIter &theSubdomains = myDomain->getSubdomains();
      Subdomain *theSub;
      bool added = false;
      while (((theSub = theSubdomains()) != 0) && (added == false)) {
	bool res = theSub->hasElement(loadEleTag);
	if (res == true) {
	  theLoadPattern->removeElementalLoad(theLoad->getTag());
	  theSub->addElementalLoad(theLoad, loadPatternTag);
	  if (res < 0)
	    opserr << "DomainPartitioner::partition() - failed to add ElementalLoad\n";
	  added = true;
	}
      }   
    }
  }

  // add the single point constraints, 
  
  SP_ConstraintIter &theDomainSP = myDomain->getSPs();
  SP_Constraint *spPtr;
  while ((spPtr = theDomainSP()) != 0) {
    int nodeTag = spPtr->getNodeTag();

    TaggedObject *theTaggedObject = theNodeLocations->getComponentPtr(nodeTag);
    if (theTaggedObject == 0) {
      opserr << "DomainPartitioner::partition(int numParts)";
      opserr << " - failed to find NodeLocation in Map for Node: " << nodeTag << " -- A BUG!!\n";
      numPartitions = 0;
      return -1;	
    }
    
    NodeLocations *theNodeLocation = (NodeLocations *)theTaggedObject;
    ID &nodePartitions = theNodeLocation->nodePartitions;
    int numPartitions = theNodeLocation->numPartitions;
    for (int i=0; i<numPartitions; i++) {
      int partition = nodePartitions(i);	  

      if (partition != mainPartition) {      
	Subdomain *theSubdomain = myDomain->getSubdomainPtr(partition); 
	if (numPartitions == 1) {
	  myDomain->removeSP_Constraint(spPtr->getTag());
	}
	int res = theSubdomain->addSP_Constraint(spPtr);
	if (res < 0)
	  opserr << "DomainPartitioner::partition() - failed to add SP Constraint\n";
      }
    }    
  }  

  // move MP_Constraints - add an MP_Constraint to every partition a constrained node is in
  MP_ConstraintIter &moreMPs = myDomain->getMPs();
  while ((mpPtr = moreMPs()) != 0) {
    int constrained = mpPtr->getNodeConstrained();
    TaggedObject *theConstrainedObject = theNodeLocations->getComponentPtr(constrained);
    NodeLocations *theConstrainedLocation = (NodeLocations *)theConstrainedObject;
    ID &theConstrainedNodesPartitions = theConstrainedLocation->nodePartitions;
    int numPartitions = theConstrainedLocation->numPartitions;
    for (int i=0; i<numPartitions; i++) {
      int partition = theConstrainedNodesPartitions(i);
      if (partition != mainPartition) {
	Subdomain *theSubdomain = myDomain->getSubdomainPtr(partition);
	if (numPartitions == 1) 
	  myDomain->removeMP_Constraint(mpPtr->getTag());
	int res = theSubdomain->addMP_Constraint(mpPtr);
	if (res < 0)
	  opserr << "DomainPartitioner::partition() - failed to add MP Constraint\n";
      }
    }
  }

  // now we go through all the subdomains and tell them to update
  // their analysis for the new layouts
  
  SubdomainIter &theSubDomains = myDomain->getSubdomains();
  Subdomain *theSubDomain;
  while ((theSubDomain = theSubDomains()) != 0) 
    theSubDomain->domainChange();
  
  // we invoke change on the PartitionedDomain
  myDomain->domainChange();

  myDomain->clearElementGraph();
    
  // we are done
  partitionFlag = true;

  return 0;
}
Exemple #6
0
GSA_Recorder::GSA_Recorder(Domain &theDom, 
			   const char *fileName, 
			   const char *title1,
			   const char *title2,
			   const char *title3,
			   const char *jobno,
			   const char *initials,
			   const char *spec,
			   const char *currency,
			   const char *length,
			   const char *force,
			   const char *temp,
			   double dT)
: Recorder(RECORDER_TAGS_GSA_Recorder),
  theDomain(&theDom), ndm(3), ndf(6), counter(0), deltaT(dT), nextTimeStampToRecord(0.0)
{
  // open file 
  if (theFile.setFile(fileName, OVERWRITE) < 0) {
    opserr << "WARNING - GSA_Recorder::GSA_Recorder()";
    opserr << " - could not open file " << fileName << endln;
    exit(-1);
  } 

  // spit out header data
  if (title1 != 0)
    theFile << "TITLE\t" << title1;
  else
    theFile << "TITLE\t" << "No Title";


  if (title2 != 0)
    theFile << "\t" << title2;
  else
    theFile << "\t" << "BLANK";


  if (title3 != 0)
    theFile << "\t" << title3;
  else
    theFile << "\t" << "BLANK";  


  if (jobno != 0)
    theFile << "\t" << jobno;
  else
    theFile << "\t" << "0000";


  if (initials != 0)
    theFile<< "\t" << initials << endln;
  else
    theFile << "\t" << "ANOTHER\n";  


  if (spec != 0)
    theFile << "SPEC\t" << spec << endln;


  if (currency != 0)
    theFile << "CURRENCY\t" << currency << endln;


  if (length != 0)
    theFile << "UNIT_DATA\tLENGTH\t" << length << endln; 


  if (force != 0)
    theFile << "UNIT_DATA\tFORCE\t" << force << endln;


  if (temp != 0)
    theFile << "UNIT_DATA\tTEMP\t" << temp << endln;


  // spit out nodal data
  NodeIter &theNodes = theDomain->getNodes();
  Node *theNode;
  while ((theNode=theNodes()) != 0) {
    int nodeTag = theNode->getTag();
    theFile << "NODE\t" << nodeTag;
    const Vector &crds = theNode->getCrds();
    if (crds.Size() != ndm) {
      opserr << "WARNING - GSA_Recorder::GSA_Recorder() - node: " <<  nodeTag ;
      opserr << " has invalid number of coordinates, expecting: " << ndm << " got: " << crds.Size() << endln;
      exit(-1);
    }
    const Vector &disp = theNode->getTrialDisp();
    if (disp.Size() != ndf) {
      opserr << "WARNING - GSA_Recorder::GSA_Recorder() - node: " <<  nodeTag ;
      opserr << " has invalid number of dof, expecting: " << ndf << " got: " << disp.Size() << endln;
      exit(-1);
    }
    for (int i=0; i<ndm; i++)
      theFile << "\t" << crds(i);
    theFile << endln;
  }
  
  
  // open file and spit out the initial data
  SP_ConstraintIter &theSPs = theDomain->getSPs();
  SP_Constraint *theSP;
  ID theConstrainedNodes(0,6);
  ID theSpMatrix(0, 6*ndf);
  int numNodesWithSP = 0;
  while ((theSP=theSPs()) != 0) {
    int nodeTag =  theSP->getNodeTag();
    int location = theConstrainedNodes.getLocation(nodeTag);
    if (location < 0) {
      theConstrainedNodes[numNodesWithSP] = nodeTag;
      for (int i=0; i<ndf; i++)
	theSpMatrix[numNodesWithSP*ndf+i] = 0;	  
      location = numNodesWithSP++;
    }
    int id = theSP->getDOF_Number();
    theSpMatrix[location*ndf + id] = 1;
  }
  
  for (int j=0; j<numNodesWithSP; j++) {
    theFile << "SPC\t" <<  theConstrainedNodes[j] << "\t0";
    for (int i=0; i<ndf; i++)
      theFile << "\t" << theSpMatrix[j*ndf+i];
    theFile << endln;
  }
  
  ElementIter &theElements = theDomain->getElements();
  Element *theElement;
  while ((theElement=theElements()) != 0) {
    theElement->Print(theFile, -1);
  }

}
Exemple #7
0
int
LoadPattern::recvSelf(int cTag, Channel &theChannel, FEM_ObjectBroker &theBroker)
{

  // get my current database tag
  // NOTE - dbTag equals 0 if not sending to a database OR has not yet been sent
  int myDbTag = this->getDbTag();

  // into an ID we place all info needed to determine state of LoadPattern
  int numNod, numEle, numSPs;
  ID lpData(11);

  if (theChannel.recvID(myDbTag, cTag, lpData) < 0) {
    opserr << "LoadPattern::recvSelf - channel failed to recv the initial ID\n";
    return -1;
  }

  isConstant = lpData(7);

  this->setTag(lpData(10));

  if (isConstant == 0) { // we must recv the load factor in a Vector
    Vector data(2);
    if (theChannel.recvVector(myDbTag, cTag, data) < 0) {
      opserr << "LoadPattern::recvSelf - channel failed to recv the Vector\n";
      return -2;
    }
    loadFactor = data(0);
    scaleFactor = data(1);
  }
  
  // read data about the time series
  if (lpData(8) != -1) {
    if (theSeries == 0) {
      theSeries = theBroker.getNewTimeSeries(lpData(8));
    } else if (theSeries->getClassTag() != lpData(8)) {
      delete theSeries;    
      theSeries = theBroker.getNewTimeSeries(lpData(8));
    }
    if (theSeries == 0) {
      opserr << "LoadPattern::recvSelf - failed to create TimeSeries\n";
      return -3;
    }
  
    theSeries->setDbTag(lpData(9));

    if (theSeries->recvSelf(cTag, theChannel, theBroker) < 0) {
      opserr << "LoadPattern::recvSelf - the TimeSeries failed to recv\n";
      return -3;
    }
  }

  /*
  if (theChannel.isDatastore() == 1) {
    static ID theLastSendTag(1);
    if (theChannel.recvID(myDbTag,0,theLastSendTag) == 0)
      lastGeoSendTag = theLastSendTag(0);
  }
  */

  if (lastChannel != theChannel.getTag() || currentGeoTag != lpData(0) || theChannel.isDatastore() == 0) {

    // clear out the all the components in the current load pattern
    this->clearAll();
    lastChannel = theChannel.getTag();
    currentGeoTag = lpData(0);

    numNod = lpData(1);
    numEle = lpData(2);
    numSPs = lpData(3);
    dbNod = lpData(4);
    dbEle = lpData(5);
    dbSPs = lpData(6);    

    // 
    // now we rebuild the nodal loads
    //
    
    // first get the information from the domainData about the nodes
    if (numNod != 0) {
      ID nodeData(2*numNod);

      // now receive the ID about the nodes, class tag and dbTags
      if (theChannel.recvID(dbNod, currentGeoTag, nodeData) < 0) {
	opserr << "LoadPAttern::recvSelf - channel failed to recv the NodalLoad ID\n";
	return -2;
      }

      // now for each NodalLoad we 1) get a new node of the correct type from the ObjectBroker
      // 2) ensure the node exists and set it's dbTag, 3) we invoke recvSelf on this new 
      // blank node and 4) add this node to the domain

      int loc = 0;

      for (int i=0; i<numNod; i++) {
	int classTag = nodeData(loc);
	int dbTag = nodeData(loc+1);
	
	NodalLoad *theNode = theBroker.getNewNodalLoad(classTag);

	if (theNode == 0) {
	  opserr << "LoadPattern::recv - cannot create NodalLoad with classTag " << classTag << endln;
	  return -2;
	}			
	
	theNode->setDbTag(dbTag);
	
	if (theNode->recvSelf(cTag, theChannel, theBroker) < 0) {
	  opserr << "LoadPattern::recvSelf - NodalLoad with dbTag " << dbTag << " failed in recvSelf\n";
	  return -2;
	}			

	if (this->addNodalLoad(theNode) == false) {
	  opserr << "LoadPattern::recvSelf - failed adding NodalLoad tagged " << theNode->getTag() << " into LP!\n";
	  return -3;
	}			
	  
	loc+=2;
      }   
    }

    // 
    // now we rebuild the ElementalLoads .. same as NodalLoads above .. see comments above
    //
    
    if (numEle != 0) {
      ID eleData(2*numEle);
      
      if (theChannel.recvID(dbEle, currentGeoTag, eleData) < 0) {
	opserr << "LoadPattern::recvSelf - channel failed to recv the EleLoad ID\n";
	return -2;
      }

      int loc = 0;
      for (int i=0; i<numEle; i++) {
	int classTag = eleData(loc);
	int dbTag = eleData(loc+1);
      
	ElementalLoad *theEle = theBroker.getNewElementalLoad(classTag);
	if (theEle == 0) {
	  opserr << "LoadPattern::recv - cannot create ElementalLoad with classTag " << classTag << endln;
	  return -2;
	}			

	theEle->setDbTag(dbTag);
	
	if (theEle->recvSelf(cTag, theChannel, theBroker) < 0) {
	  opserr << "LoadPattern::recvSelf - Ele with dbTag " << dbTag << " failed in recvSelf\n";
	  return -2;
	}			
	
	if (this->addElementalLoad(theEle) == false) {
	  opserr << "LoadPattern::recvSelf - could not add Ele with tag " << theEle->getTag() << " into LP!\n";
	  return -3;
	}			
	
	loc+=2;
      }
    }

    // 
    // now we rebuild the SP_Constraints .. same as nodes above .. see above if can't understand!!
    //
    
    if (numSPs != 0) {
      ID spData(2*numSPs);

      if (theChannel.recvID(dbSPs, currentGeoTag, spData) < 0) {
	opserr << "LoadPattern::recvSelf - channel failed to recv the SP_Constraints ID\n";
	return -2;
      }

      int loc = 0;
      for (int i=0; i<numSPs; i++) {
	int classTag = spData(loc);
	int dbTag = spData(loc+1);
      
	SP_Constraint *theSP = theBroker.getNewSP(classTag);
	if (theSP == 0) {
	  opserr << "LoadPattern::recv - cannot create SP_Constraint with classTag " << classTag << endln;
	  return -2;
	}			
	theSP->setDbTag(dbTag);
      
	if (theSP->recvSelf(cTag, theChannel, theBroker) < 0) {
	  opserr << "LoadPattern::recvSelf - SP_Constraint with dbTag " << dbTag << " failed in recvSelf\n";
	  return -2;
	}			
	
	if (this->addSP_Constraint(theSP) == false) {
	  opserr << "LoadPattern::recvSelf - could not add SP_Constraint with tag " << theSP->getTag()
		 << " into LP!\n";
				  
	  return -3;
	}			
	
	loc+=2;
      }
    }

    // now set the load pattern db count
    currentGeoTag = lpData(0);
    lastGeoSendTag  = currentGeoTag;

  } else {
    if (theSeries != 0)
      if (theSeries->recvSelf(cTag, theChannel, theBroker) < 0) {
	opserr << "LoadPattern::recvSelf - the TimeSeries failed to recv\n";
	return -3;
      }

    
    NodalLoad *theNode;
    NodalLoadIter &theNodes = this->getNodalLoads();
    while ((theNode = theNodes()) != 0) {
      if (theNode->recvSelf(cTag, theChannel, theBroker) < 0) {
	opserr << "LoadPattern::recvSelf - node with tag " << theNode->getTag() << " failed in recvSelf\n";
	return -7;
      }
    }

    ElementalLoad *theEle;
    ElementalLoadIter &theElements = this->getElementalLoads();
    while ((theEle = theElements()) != 0) {
      if (theEle->recvSelf(cTag, theChannel, theBroker) < 0) {
	opserr << "LoadPattern::recvSelf - element with tag " << theEle->getTag() << " failed in recvSelf\n";
	return -8;
      }
    }

    SP_Constraint *theSP;
    SP_ConstraintIter &theSPs = this->getSPs();
    while ((theSP = theSPs()) != 0) {
      if (theSP->recvSelf(cTag, theChannel, theBroker) < 0) {
	opserr << "LoadPattern::recvSelf - SP_Constraint tagged " << theSP->getTag() << "  failed recvSelf\n";
	return -9;
      }
    }    
  }

  // if we get here we are successfull
  return 0;
}
Exemple #8
0
int
LoadPattern::sendSelf(int cTag, Channel &theChannel)
{
  // get my current database tag
  // NOTE - dbTag equals 0 if not sending to a database OR has not yet been sent
  int myDbTag = this->getDbTag();

  // into an ID we place all info needed to determine state of LoadPattern
  int numNodLd, numEleLd, numSPs;
  ID lpData(11);

  numNodLd = theNodalLoads->getNumComponents();
  numEleLd = theElementalLoads->getNumComponents();
  numSPs = theSPs->getNumComponents();

  lpData(10) = this->getTag();
  lpData(0) = currentGeoTag;
  lpData(1) = numNodLd;
  lpData(2) = numEleLd;
  lpData(3) = numSPs;

  if (dbNod == 0) {
    dbNod = theChannel.getDbTag();
    dbEle = theChannel.getDbTag();
    dbSPs = theChannel.getDbTag();
  } 

  lpData(4) = dbNod;
  lpData(5) = dbEle;
  lpData(6) = dbSPs;

  lpData(7) = isConstant;

  if (theSeries != 0) {
    int dbtag = theSeries->getDbTag();
    int classtag = theSeries->getClassTag();
    if (dbtag == 0) {
      dbtag = theChannel.getDbTag();
      theSeries->setDbTag(dbtag);
    }
    lpData(8) = classtag;
    lpData(9) = dbtag;
  } else
    lpData(8) = -1;


  // see if we can save sending the vector containing just the load factor
  // will happen in parallel if sending the loadPattern .. not in database

  if (theChannel.sendID(myDbTag, cTag, lpData) < 0) {
    opserr << "LoadPattern::sendSelf - channel failed to send the initial ID\n";
    return -1;
  }    
  
  if (isConstant == 0) {
    Vector data(2);
    data(0) = loadFactor;
    data(1) = scaleFactor;
    if (theChannel.sendVector(myDbTag, cTag, data) < 0) {
      opserr << "LoadPattern::sendSelf - channel failed to send the Vector\n";
      return -2;
    }

  }

  if (theSeries != 0)
    if (theSeries->sendSelf(cTag, theChannel) < 0) {
      opserr << "LoadPattern::sendSelf - the TimeSeries failed to send\n";
      return -3;
    }

  // now check if data defining the objects in the LoadPAttern needs to be sent 
  // NOTE THIS APPROACH MAY NEED TO CHANGE FOR VERY LARGE PROBLEMS IF CHANNEL CANNOT
  // HANDLE VERY LARGE ID OBJECTS.

  /*
  if (theChannel.isDatastore() == 1) {
    static ID theLastSendTag(1);
    if (theChannel.recvID(myDbTag,0,theLastSendTag) == 0)
      lastGeoSendTag = theLastSendTag(0);
    else
      lastGeoSendTag = -1;
  }
  */

  if (lastChannel != theChannel.getTag() || lastGeoSendTag != currentGeoTag || theChannel.isDatastore() == 0) {

    lastChannel = theChannel.getTag();

    //
    // into an ID we are gonna place the class and db tags for each node so can rebuild
    // this ID we then send to the channel
    //

    // create the ID and get the node iter
    if (numNodLd != 0) {
      ID nodeData(numNodLd*2);
      NodalLoad *theNode;
      NodalLoadIter &theNodes = this->getNodalLoads();
      int loc =0;

      // loop over nodes in domain adding their classTag and dbTag to the ID
      while ((theNode = theNodes()) != 0) {
	nodeData(loc) = theNode->getClassTag();
	int dbTag = theNode->getDbTag();
	
	// if dbTag still 0 get one from Channel; 
	// if this tag != 0 set the dbTag in node
	if (dbTag == 0 && myDbTag != 0) {// go get a new tag and setDbTag in ele if this not 0 
	  dbTag = theChannel.getDbTag();
	  if (dbTag != 0)
	    theNode->setDbTag(dbTag);
	}
	
	nodeData(loc+1) = dbTag;
	loc+=2;
      }    

      // now send the ID
      if (theChannel.sendID(dbNod, currentGeoTag, nodeData) < 0) {
	opserr << "LoadPattern::sendSelf - channel failed to send the NodalLoads ID\n";
	return -4;
      }
    }

    // we do the same for elemental loads as we did for nodal loads above .. see comments above!

    if (numEleLd != 0) {
      ID elementData(numEleLd*2);
      ElementalLoad *theEle;
      ElementalLoadIter &theElements = this->getElementalLoads();
      int loc = 0;
    
      while ((theEle = theElements()) != 0) {
	elementData(loc) = theEle->getClassTag();
	int dbTag = theEle->getDbTag();

	if (dbTag == 0 && myDbTag != 0) {// go get a new tag and setDbTag in ele if this not 0 
	  dbTag = theChannel.getDbTag();
	  if (dbTag != 0)
	    theEle->setDbTag(dbTag);
	}
      
	elementData(loc+1) = dbTag;
	loc+=2;
      }

      // now send the ID
      if (theChannel.sendID(dbEle, currentGeoTag, elementData) < 0) {
	opserr << "Domain::send - channel failed to send the element ID\n";
	return -5;
      }
    }

    // we do the same for SP_Constraints as for NodalLoads above .. see comments above!
    
    if (numSPs != 0) {
      ID spData(numSPs*2);
      SP_Constraint *theSP;
      SP_ConstraintIter &theSPs = this->getSPs();
      int loc = 0;
    
      while ((theSP = theSPs()) != 0) {
	spData(loc) = theSP->getClassTag();
	int dbTag = theSP->getDbTag();

	if (dbTag == 0 && myDbTag != 0) {// go get a new tag and setDbTag in ele if this not 0 
	  dbTag = theChannel.getDbTag();
	  if (dbTag != 0)
	    theSP->setDbTag(dbTag);
	}
	
	spData(loc+1) = dbTag;
	loc+=2;
      }    

      if (theChannel.sendID(dbSPs, currentGeoTag, spData) < 0) {
	opserr << "LoadPAttern::sendSelf - channel failed sending SP_Constraint ID\n";
	return -6;
      }
    }

    // set the lst send db tag so we don't have to do all that again
    lastGeoSendTag = currentGeoTag;
    if (theChannel.isDatastore() == 1) {
      static ID theLastSendTag(1);
      theLastSendTag(0) = lastGeoSendTag;
      theChannel.sendID(myDbTag,0, theLastSendTag);
    }
  }

  // now we invoke sendSelf on all the NodalLoads, ElementalLoads and SP_Constraints
  // which have been added to the LoadCase
  NodalLoad *theNode;
  NodalLoadIter &theNodes = this->getNodalLoads();
  while ((theNode = theNodes()) != 0) {
    if (theNode->sendSelf(cTag, theChannel) < 0) {
      opserr << "LoadPattern::sendSelf - node with tag " << theNode->getTag() << " failed in sendSelf\n";
      return -7;
    }
  }

  ElementalLoad *theEle;
  ElementalLoadIter &theElements = this->getElementalLoads();
  while ((theEle = theElements()) != 0) {
    if (theEle->sendSelf(cTag, theChannel) < 0) {
      opserr << "LoadPattern::sendSelf - element with tag " << theEle->getTag() << " failed in sendSelf\n";
      return -8;
    }
  }

  SP_Constraint *theSP;
  SP_ConstraintIter &theSPs = this->getSPs();
  while ((theSP = theSPs()) != 0) {
    if (theSP->sendSelf(cTag, theChannel) < 0) {
      
      opserr << "LoadPattern::sendSelf - SP_Constraint: " << *theSP << " failed sendSelf\n";
      return -9;
    }
  }    

  // if we get here we are successfull
  return 0;
}