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; }
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; }