Ejemplo n.º 1
0
int
ConstraintHandler::doneNumberingDOF(void)
{
  // iterate through the FE_Element getting them to set their IDs
  FE_EleIter &theEle = theAnalysisModelPtr->getFEs();
  FE_Element *elePtr;
  while ((elePtr = theEle()) != 0)
    elePtr->setID();
  return 0;
}
int 
TransformationConstraintHandler::doneNumberingDOF(void)
{
    // iterate through the DOF_Groups telling them that their ID has now been set
    AnalysisModel *theModel1=this->getAnalysisModelPtr();
    DOF_GrpIter &theDOFS = theModel1->getDOFs();
    DOF_Group *dofPtr;
    while ((dofPtr = theDOFS()) != 0) {
       dofPtr->doneID();
    }


    // iterate through the FE_Element getting them to set their IDs
    AnalysisModel *theModel=this->getAnalysisModelPtr();
    FE_EleIter &theEle = theModel->getFEs();
    FE_Element *elePtr;
    while ((elePtr = theEle()) != 0) {
      elePtr->setID();
    }

    return 0;
}
Ejemplo n.º 3
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.º 4
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.º 5
0
int XC::ParallelNumberer::numberDOF(int lastDOF)
  {
    int result = 0;

    // get a pointer to the model & check its not null
    AnalysisModel *theModel = this->getAnalysisModelPtr();
    Domain *theDomain = 0;
    if(theModel) theDomain = theModel->getDomainPtr();
  
    if(theModel == 0 || theDomain == 0)
      {
        std::cerr << "WARNING XC::ParallelNumberer::numberDOF(int) -";
        std::cerr << " - no AnalysisModel.\n";
        return -1;
      }
  
    if(lastDOF != -1)
      {
        std::cerr << "WARNING XC::ParallelNumberer::numberDOF(int lastDOF):";
        std::cerr << " does not use the lastDOF as requested\n";
      }

    Graph &theGraph= theModel->getDOFGroupGraph();

    // if subdomain, collect graph, send it off, get 
    // ID back containing dof tags & start id numbers.
    if(processID != 0)
      {
        CommParameters cp(0,*theChannels[0]);
        const int numVertex = theGraph.getNumVertex();

        /*
        static XC::ID test(2); test(0) = processID; test(1) = 25;
        theChannel->recvID(0, 0, test);
        */

        cp.sendMovable(theGraph,DistributedObj::getDbTagData(),CommMetaData(1));

        // recv iD
        ID theID(2*numVertex);
        cp.receiveID(theID,DistributedObj::getDbTagData(),CommMetaData(2));

        // set vertex numbering based on ID received
        for(int i=0; i<numVertex; i ++)
          {
            const int vertexTag= theID(i);
            int startID= theID(i+numVertex);
            //Vertex *vertexPtr = theGraph.getVertexPtr(vertexTag);
            const int dofTag= vertexTag;
            DOF_Group *dofPtr= theModel->getDOF_GroupPtr(dofTag);
            if(!dofPtr)
              {
                std::cerr << "WARNING ParallelNumberer::numberDOF - ";
                std::cerr << "DOF_Group " << dofTag << "not in XC::AnalysisModel!\n";
                result= -4;
              }
            else
              {
                const ID &theDOFID= dofPtr->getID();
                //std::cerr << "P: " << processID << " dofTag: " << dofTag << " " << "start: " << startID << " " << theDOFID;
                const int idSize= theDOFID.Size();
                for(int j=0; j<idSize; j++)
                  if(theDOFID(j) == -2 || theDOFID(j) == -3) dofPtr->setID(j, startID++);
              }
            //const ID &theDOFID= dofPtr->getID();
          }
        cp.sendID(theID,DistributedObj::getDbTagData(),CommMetaData(2));
      } 
    else
      {
        // if XC::main domain, collect graphs from all subdomains,
        // merge into 1, number this one, send to subdomains the
        // id containing dof tags & start id's.

        // for P0 domain determine original vertex and ref tags
        const int numVertex= theGraph.getNumVertex(); 
        const int numVertexP0= numVertex;

        ID vertexTags(numVertex);
        ID vertexRefs(numVertex);
        Vertex *vertexPtr;
        int loc= 0;
        VertexIter &theVertices= theGraph.getVertices();
        while((vertexPtr= theVertices()) != 0)
          {
            vertexTags[loc]= vertexPtr->getTag();
            vertexRefs[loc]= vertexPtr->getRef();
            loc++;
          }
    
        const int numChannels= theChannels.size();
	std::vector<ID> theSubdomainIDs(numChannels);
        FEM_ObjectBroker theBroker;

        // for each subdomain we receive graph, create an XC::ID (to store
        // subdomain graph to merged graph vertex mapping and the final
        // subdoain graph vertex to startDOF mapping) and finally merge the
        // subdomain graph

        for(int j=0; j<numChannels; j++)
          {
            CommParameters cp(0,*theChannels[j]);
            Graph theSubGraph;

            /*
            static XC::ID test(2); test(0)= processID; test(1)= 25;
            theChannel->sendID(0, 0, test);
            */
            cp.receiveMovable(theSubGraph,DistributedObj::getDbTagData(),CommMetaData(3));
            theSubdomainIDs[j]= ID(theSubGraph.getNumVertex()*2);
            this->mergeSubGraph(theGraph, theSubGraph, vertexTags, vertexRefs, theSubdomainIDs[j]);
          }
    
        // we use graph numberer if one was provided in constructor,
        // otherwise we number based on subdomains (all in subdomain 1 numbered first, 
        // then  those in 2 not in 1 and so on till done.
        //    GraphNumberer *theNumberer= this->getGraphNumbererPtr();

        ID theOrderedRefs(theGraph.getNumVertex());

        if(theNumberer)
          {
            // use the supplied graph numberer to number the merged graph
            theOrderedRefs= theNumberer->number(theGraph, lastDOF);     
          }
        else
          {
            // assign numbers based on the subdomains

            int loc= 0;
            for(int l=0; l<numChannels; l++)
              {
                const ID &theSubdomain= theSubdomainIDs[l];
                int numVertexSubdomain= theSubdomain.Size()/2;

                for(int i=0; i<numVertexSubdomain; i++)
                  {
                    const int vertexTagMerged= theSubdomain(i+numVertexSubdomain);
                    //  int refTag= vertexRefs[vertexTags.getLocation(vertexTagMerged)];
                    if(theOrderedRefs.getLocation(vertexTagMerged) == -1)
                      theOrderedRefs[loc++]= vertexTagMerged;
                  }
              }

            // now order those not yet ordered in p0
            for(int j=0; j<numVertexP0; j++)
              {
                int refTagP0= vertexTags[j];
                if(theOrderedRefs.getLocation(refTagP0) == -1)
                  theOrderedRefs[loc++]= refTagP0;
              }        
          }
    int count= 0;
    for(int i=0; i<theOrderedRefs.Size(); i++)
      {
        int vertexTag= theOrderedRefs(i);
        //      int vertexTag= vertexTags[vertexRefs.getLocation(tag)];
        Vertex *vertexPtr= theGraph.getVertexPtr(vertexTag);
        int numDOF= vertexPtr->getColor();
        vertexPtr->setTmp(count);
        count += numDOF;
      }

    // number own dof's
    for(int i=0; i<numVertexP0; i++  ) {
      int vertexTag= vertexTags(i);
      Vertex *vertexPtr= theGraph.getVertexPtr(vertexTag);

      int startID= vertexPtr->getTmp();
      int dofTag= vertexTag;
      DOF_Group *dofPtr;        
      dofPtr= theModel->getDOF_GroupPtr(dofTag);
      if(dofPtr == 0) {
        std::cerr << "WARNING XC::ParallelNumberer::numberDOF - ";
        std::cerr << "DOF_Group (P0) " << dofTag << "not in XC::AnalysisModel!\n";
        result= -4;
      } else {
        const ID &theDOFID= dofPtr->getID();
        int idSize= theDOFID.Size();
        for(int j=0; j<idSize; j++)
          if(theDOFID(j) == -2 || theDOFID(j) == -3) dofPtr->setID(j, startID++);
      }
    }

    // now given the ordered refs we determine the mapping for each subdomain
    // and send the id with the information back to the subdomain, which it uses to order
    // it's own graph
    for(int k=0; k<numChannels; k++)
     {
        CommParameters cp(0,*theChannels[k]);
        ID &theSubdomain= theSubdomainIDs[k];
        int numVertexSubdomain= theSubdomain.Size()/2;

        for(int i=0; i<numVertexSubdomain; i++)
          {
            int vertexTagMerged= theSubdomain[numVertexSubdomain+i];
            Vertex *vertexPtr= theGraph.getVertexPtr(vertexTagMerged);
            int startDOF= vertexPtr->getTmp();
            theSubdomain[i+numVertexSubdomain]= startDOF;
          }
        cp.sendID(theSubdomain,DistributedObj::getDbTagData(),CommMetaData(4));
        cp.receiveID(theSubdomain,DistributedObj::getDbTagData(),CommMetaData(4));
      }      
  }

  // iterate through the XC::FE_Element getting them to set their IDs
  FE_EleIter &theEle= theModel->getFEs();
  FE_Element *elePtr;
  while ((elePtr= theEle()) != 0)
    elePtr->setID();
  
  return result;
}
int
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.º 7
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;
}