Ejemplo n.º 1
0
const Vector &
LoadPattern::getExternalForceSensitivity(int gradNumber)
{

    // THIS METHOD IS CURRENTLY ONLY USED FOR THE STATIC CASE
    // IT SHOULD BE DELETED AND REPLACED BY THE DYNAMIC CASE

    // Initial declarations
    Vector tempRandomLoads(1);
    int sizeRandomLoads;

    // Start with a fresh return vector
    if (randomLoads == 0) {
        randomLoads = new Vector(1);
    }
    else {
        delete randomLoads;
        randomLoads = new Vector(1);
    }

    // Prepare the vector identifying which loads are random.
    NodalLoad *theNodalLoad = 0;
    NodalLoadIter &theNodalIter = this->getNodalLoads();
    int i;

    // Loop through the nodal loads to pick up possible contributions
    int nodeNumber;
    int dofNumber;
    while ((theNodalLoad = theNodalIter()) != 0)  {
        const Vector &gradientVector = theNodalLoad->getExternalForceSensitivity(gradNumber);
        if (gradientVector(0) != 0.0 ) {

            // Found a random load! Get nodeNumber and dofNumber
            nodeNumber = theNodalLoad->getNodeTag();
            dofNumber = (int)gradientVector(0);

            // Update the randomLoads vector
            sizeRandomLoads = randomLoads->Size();
            if (sizeRandomLoads == 1) {
                delete randomLoads;
                randomLoads = new Vector(2);
                (*randomLoads)(0) = (double)nodeNumber;
                (*randomLoads)(1) = (double)dofNumber;
            }
            else {
                tempRandomLoads = (*randomLoads);
                delete randomLoads;
                randomLoads = new Vector(sizeRandomLoads+2);
                for (i=0; i<sizeRandomLoads; i++) {
                    (*randomLoads)(i) = tempRandomLoads(i);
                }
                (*randomLoads)(sizeRandomLoads) = nodeNumber;
                (*randomLoads)(sizeRandomLoads+1) = dofNumber;
            }
        }
    }

    return (*randomLoads);
}
Ejemplo n.º 2
0
mObject patternsToJSON(void) {
    LoadPatternIter &thePatterns = theDomain.getLoadPatterns();
    LoadPattern *thePattern;
    TimeSeries *theSeries;
    NodalLoadIter *nli;
    NodalLoad *nload;
    const Vector *load_vec; 
    // TODO:
    // ElementalLoadIter *eli;
    // SP_ConstraintIter *spci;

    mObject patterns, pattern, nloads;
    mArray arr;
    mValue tmp, tmp2, tmp3;
    char tag_str[15];
    int i, size;

    patterns.clear();
    while ((thePattern = thePatterns()) != 0) {
        pattern.clear();
        // TODO:
        tmp = thePattern->getClassType();
        pattern["type"] = tmp;
        theSeries = thePattern->getTimeSeries();
        tmp2 = theSeries->getTag();
        sprintf(tag_str, "%d", tmp2.get_int());
        pattern["tsTag"] = tag_str;

        nli = &(thePattern->getNodalLoads());
        nloads.clear();
        while((nload = (*nli)()) != 0) {
            tmp2 = nload->getNodeTag();
            sprintf(tag_str, "%d", tmp2.get_int());
            load_vec = nload->getLoadValue();
            size = load_vec->Size();
            arr.clear();
            for (i = 0; i < size; i++) {
                tmp3 = (*load_vec)(i);
                arr.push_back(tmp3);
            }
            nloads[tag_str] = arr;
        }
        pattern["nodalLoads"] = nloads;

        tmp2 = thePattern->getTag();
        sprintf(tag_str, "%d", tmp2.get_int());
        patterns[tag_str] = pattern;
    }
	
    return patterns; 
}
Ejemplo n.º 3
0
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;
}
Ejemplo n.º 4
0
int
LoadPattern::setParameter(const char **argv, int argc, Parameter &param)
{
    if (theSeries == 0) {
        opserr << "set/update/activate parameter is illegaly called in LoadPattern " << endln;
	return 0;
    }

    if (argc < 1)
      return -1;

    // Nodal load
    if (strstr(argv[0],"loadAtNode") != 0) {

      if (argc < 3)
	return -1;

        RVisRandomProcessDiscretizer = false;

        int nodeNumber = atoi(argv[1]);
        NodalLoad *thePossibleNodalLoad;
        NodalLoad *theNodalLoad = 0;
        NodalLoadIter &theNodalIter = this->getNodalLoads();

        while ((thePossibleNodalLoad = theNodalIter()) != 0) {
            if ( nodeNumber == thePossibleNodalLoad->getNodeTag() ) {
                theNodalLoad = thePossibleNodalLoad;
            }
        }

	if (theNodalLoad != 0)
	  return theNodalLoad->setParameter(&argv[2], argc-2, param);
	else
	  return -1;
    }

    else if (strstr(argv[0],"elementPointLoad") != 0 || strstr(argv[0],"elementLoad") != 0) {

      if (argc < 3)
	return -1;

      RVisRandomProcessDiscretizer = false;

      int eleNumber = atoi(argv[1]);
      ElementalLoad *theEleLoad = 0;
      ElementalLoadIter &theEleLoadIter = this->getElementalLoads();
      while ((theEleLoad = theEleLoadIter()) != 0) {
	int eleTag = theEleLoad->getElementTag();
	if (eleNumber == eleTag) {
	  return theEleLoad->setParameter(&argv[2], argc-2, param);
	}
      }

      return -1;
    }

    else if (strstr(argv[0],"randomProcessDiscretizer") != 0) {

      if (argc < 2)
	return -1;

        RVisRandomProcessDiscretizer = true;
        return theSeries->setParameter(&argv[1], argc-1, param);
    }

    // Unknown parameter
    else
      return -1;
}
Ejemplo n.º 5
0
int
RemoveRecorder::elimNode(int theNodeTag, double timeStamp)
{  
  // remove from domain but do not delete yet!
  Node *theNode = theDomain->removeNode(theNodeTag);
  
  // go through all load patterns and remove associated loads and constraints
  LoadPatternIter &theLoadPatterns = theDomain->getLoadPatterns();
  LoadPattern *thePattern;
  
  while ((thePattern = theLoadPatterns()) != 0) {
    
    // start with nodal laods
    NodalLoadIter theLoads = thePattern->getNodalLoads();
    NodalLoad *theLoad;
    
    //		ID theLoadTags(0,12); 
    //		int cnt=0;
    while ((theLoad = theLoads()) != 0) {
      
      int NodeTag = theLoad->getNodeTag();
      if (NodeTag == theNodeTag) {
	//				theLoadTags[cnt] = theLoad->getTag();
	//				cnt++;
#ifdef MMTDEBUG
	opserr<<"identified load pattern "<<theLoad->getTag()<<" acting on node "<<theNode<<endln;
#endif
	NodalLoad *theNodalLoad = thePattern->removeNodalLoad(theLoad->getTag());
	if (theNodalLoad != 0) {
#ifdef MMTDEBUG
	  opserr<<"deleting nodal load pattern "<<theLoad->getTag()<<endln;
#endif
	  delete theNodalLoad;
	}	
      }
    }
    
    //		for (int i=0; i<cnt; i++) {
    //			NodalLoad *theNodalLoad = thePattern->removeNodalLoad(theLoadTags[i]);
    //			if (theNodalLoad != 0) {
    //				delete theNodalLoad;
    //																			#ifdef MMTDEBUG
    //				opserr<<"deleting nodal load pattern "<<theLoadTags(i)<<endln;
    //																			#endif
    //			}	
    //		}
    
    // follow with sp constraints
    SP_ConstraintIter &theSPs = thePattern->getSPs();
    SP_Constraint *theSP;
    
    while ((theSP = theSPs()) != 0) {
      
      int spNode = theSP->getNodeTag();
      if (spNode == theNodeTag) {
//				theSPTags[cnt] = theSP->getTag();
//				cnt++;
#ifdef MMTDEBUG
	opserr<<"identified SP_Constraint "<<theSP->getTag()<<" acting on node "<<spNode<<endln;
#endif
	SP_Constraint *theSPConstraint = thePattern->removeSP_Constraint(theSP->getTag());
	if (theSPConstraint != 0) {
#ifdef MMTDEBUG
	  opserr<<"deleting SP_Constraint "<<theSP->getTag()<<endln;
#endif
	  delete theSPConstraint;
	}	
      }
    }
  }
  
  
  // we also have to remove any sp constraints from the domain that do not belong to load patterns (support fixity)
  SP_ConstraintIter &theSPs = theDomain->getSPs();
  SP_Constraint *theSP;
  
  //	  ID theSPTags(0,12); 
  //	  int cnt=0;
  while ((theSP = theSPs()) != 0) {
    
    int spNode = theSP->getNodeTag();
    if (spNode == theNodeTag) {
      //				theSPTags[cnt] = theSP->getTag();
      //				cnt++;
#ifdef MMTDEBUG
      opserr<<"identified SP_Constraint "<<theSP->getTag()<<" acting on node "<<spNode<<endln;
#endif
      SP_Constraint *theSPConstraint = theDomain->removeSP_Constraint(theSP->getTag());
      if (theSPConstraint != 0) {
#ifdef MMTDEBUG
	opserr<<"deleting SP_Constraint "<<theSP->getTag()<<endln;
#endif
	delete theSPConstraint;
      }	
    }
  }
  
  //		for (int i=0; i<cnt; i++) {
  //		  SP_Constraint *theSPconstraint = theDomain->removeSP_Constraint(theSPTags[i]);
  //		  if (theSPconstraint != 0) {
  //		    delete theSPconstraint;
  //		  }	
  //		}
  
  if (theNode != 0) {
    // delete theNode;
    /////////////////// M.Talaat : Again, avoid recorder trouble
    theNode->revertToStart();
  }
  
  RemoveRecorder::remNodeList[numRemNodes] = theNode->getTag();
  //  RemoveRecorder::remNodes[numRemNodes] = theNode;
  //  RemoveRecorder::numRemNodes ++;

  Node **newRemNodes = new Node *[numRemNodes+1];
  for (int ii=0; ii<numRemNodes; ii++)
    newRemNodes[ii] = remNodes[ii];
  newRemNodes[numRemNodes] = theNode;
  if (remNodes != 0)
    delete [] remNodes;
  remNodes = newRemNodes;
  
  numRemNodes++;

	       
  
  // now give us some notice of what happened
  if (fileName != 0)
    theFile<<timeStamp<<" Node "<<theNode->getTag()<<"\n";
  if (echoTimeFlag == true)
    opserr<<"Node "<<theNode->getTag()<<" removed, Time/Load Factor = " <<timeStamp<<endln;
  
  return 0;
}