65SloanGraph :: ~SloanGraph()
69void SloanGraph :: initialize()
71 int nnodes =
domain->giveNumberOfDofManagers();
73 this->
nodes.reserve(nnodes);
74 this->
dmans.reserve(nnodes);
75 std :: map< DofManager*, int > dman2map;
79 for (
auto &dman :
domain->giveDofManagers() ) {
80 nodes.emplace_back(
this, ++count);
81 dmans.push_back(dman.get());
82 dman2map.insert({dman.get(), count});
85 for (
auto &elem :
domain->giveElements() ) {
86 this->
nodes.reserve(
nodes.size() + elem->giveNumberOfInternalDofManagers() );
87 this->
dmans.reserve(
dmans.size() + elem->giveNumberOfInternalDofManagers() );
88 for (
int j = 1; j <= elem->giveNumberOfInternalDofManagers(); ++j ) {
89 nodes.emplace_back(
this, ++count);
90 dmans.push_back( elem->giveInternalDofManager(j) );
91 dman2map.insert({elem->giveInternalDofManager(j), count});
95 for (
auto &bc :
domain->giveBcs() ) {
96 this->
nodes.reserve(
nodes.size() + bc->giveNumberOfInternalDofManagers() );
97 this->
dmans.reserve(
dmans.size() + bc->giveNumberOfInternalDofManagers() );
98 for (
int j = 1; j <= bc->giveNumberOfInternalDofManagers(); ++j ) {
99 nodes.emplace_back(
this, ++count);
100 dmans.push_back( bc->giveInternalDofManager(j) );
101 dman2map.insert({bc->giveInternalDofManager(j), count});
107 for (
auto &elem :
domain->giveElements() ) {
108 int ielemnodes = elem->giveNumberOfDofManagers();
109 int ielemintdmans = elem->giveNumberOfInternalDofManagers();
110 int ndofmans = ielemnodes + ielemintdmans;
111 connections.
resize(ndofmans);
112 for (
int j = 1; j <= ielemnodes; j++ ) {
113 connections.
at(j) = dman2map[ elem->giveDofManager(j) ];
115 for (
int j = 1; j <= ielemintdmans; j++ ) {
116 connections.
at(ielemnodes + j) = dman2map[ elem->giveInternalDofManager(j) ];
118 for (
int j = 1; j <= ndofmans; j++ ) {
119 for (
int k = j + 1; k <= ndofmans; k++ ) {
121 this->
giveNode( connections.
at(j) ).addNeighbor( connections.
at(k) );
122 this->
giveNode( connections.
at(k) ).addNeighbor( connections.
at(j) );
129 for (
auto &dman :
dmans ) {
133 if ( dman->hasAnySlaveDofs() ) {
134 std :: set< int >masters;
137 for (
Dof *dof: *dman ) {
138 if ( !dof->isPrimaryDof() ) {
141 dof->giveMasterDofManArray(dofMasters);
142 for (
int m : dofMasters ) {
148 for (
int connection: masters ) {
149 this->
giveNode(count).addNeighbor(connection);
150 this->
giveNode(connection).addNeighbor(count);
158SloanGraph :: giveNode(
int num)
164SloanGraph :: giveNodeWithMinDegree()
166 int nnodes = (int)
nodes.size();
168 int min = nnodes + 1;
170 for (
int i = 1; i <= nnodes; i++ ) {
171 int deg = this->
giveNode(i).giveDegree();
172 if ( deg < min && deg > 0 && ( this->
giveNode(i).giveNewNumber() == 0 ) ) {
182SloanGraph :: findPeripheralNodes()
187 std :: unique_ptr< SloanLevelStructure > Spine;
195 OOFEM_WARNING(
"Unsupported value of SpineQuality, using (Good)");
200 Spine = std::make_unique<SloanLevelStructure>(
this, InitialRoot);
203 int CurrentDiameter = Spine->giveDepth();
204 int TrialDepth, TrialWidth;
205 std :: list< int >candidates;
206 int newStartNode = 1;
208 while ( newStartNode ) {
212 int MinimumWidth =
domain->giveNumberOfDofManagers();
214 for (
int Root: candidates ) {
215 std :: unique_ptr< SloanLevelStructure > TrialSpine(
new SloanLevelStructure(
this, Root) );
217 if ( TrialSpine->formYourself(MinimumWidth) == 0 ) {
221 TrialDepth = TrialSpine->giveDepth();
222 TrialWidth = TrialSpine->giveWidth();
223 if ( TrialWidth < MinimumWidth && TrialDepth > CurrentDiameter ) {
224 Spine = std :: move( TrialSpine );
226 CurrentDiameter = Spine->giveDepth();
231 if ( TrialWidth < MinimumWidth ) {
232 MinimumWidth = TrialWidth;
254 for (
int node: LastLevel ) {
255 if ( lastDegree != this->
giveNode( node ).giveDegree() ) {
256 lastDegree = this->
giveNode( node ).giveDegree();
257 candidates.push_back( node );
264SloanGraph :: computeTrueDiameter()
271SloanGraph :: findBestRoot()
276 int nnodes = (int)
nodes.size();
277 clock_t time_1, time_0 = :: clock();
278 for (
int i = 1; i <= nnodes; i++ ) {
281 if ( Depth > Diameter ) {
289 OOFEM_LOG_INFO(
"%d roots (%5.1f per cent) checked: largest pseudo-diameter = %d\n", i,
float ( 100 * i ) / nnodes, Diameter);
301SloanGraph :: giveOptimalProfileDensity()
303 int nnodes = (int)
nodes.size();
307 d /= ( nnodes * ( nnodes + 1 ) );
314SloanGraph :: initStatusAndPriority()
319 int nnodes =
domain->giveNumberOfDofManagers();
321 for (
auto &node:
nodes ) {
322 int Distance = node->giveDistance();
323 int Degree = node->giveDegree();
325 node->setPriority(Priority);
326 node->setStatus(SloanGraphNode :: Inactive);
333 int Distance, Degree, Priority;
338 for (
int i = 1; i <= NumLevels; i++ ) {
339 for (
int nodeNum: BackSpine.
giveLevel(i) ) {
341 this->
giveNode(nodeNum).setDistance(Distance);
342 Degree = this->
giveNode(nodeNum).giveDegree();
344 this->
giveNode(nodeNum).setPriority(Priority);
345 this->
giveNode(nodeNum).setStatus(SloanGraphNode :: Inactive);
354SloanGraph :: evaluateNodeDistances()
366 for (
int i = 1; i <= NumLevels; i++ ) {
367 for (
int nodeNum: BackSpine.
giveLevel(i) ) {
368 this->
giveNode(nodeNum).setDistance(i - 1);
376SloanGraph :: assignOldNumbers()
378 for (
auto &node:
nodes ) {
379 node.assignOldNumber();
385SloanGraph :: numberIsolatedNodes(
int &NextNumber,
int &labeledNodes)
387 for (
auto &node:
nodes ) {
388 if ( node.giveDegree() == 0 ) {
389 node.setNewNumber(++NextNumber);
397SloanGraph :: assignNewNumbers()
399 int Start, inext, NextNumber = 0;
400 int labeledNodes = 0;
402 for (
auto &node:
nodes ) {
403 node.setNewNumber(0);
415 this->
queue.push_back(Start);
416 this->
giveNode(Start).setStatus(SloanGraphNode :: Preactive);
421 while ( !this->
queue.empty() ) {
426 if ( nextNode.
giveStatus() == SloanGraphNode :: Preactive ) {
431 nextNode.
setStatus(SloanGraphNode :: Postactive);
445 this->
queue.push_back(Start);
446 this->
giveNode(Start).setStatus(SloanGraphNode :: Preactive);
449 if ( labeledNodes !=
domain->giveNumberOfDofManagers() ) {
450 OOFEM_ERROR(
"Internal error:\n%s",
"Isolated nodes or separated sub-domains exist");
458SloanGraph :: insertNeigborsOf(
int next)
463 if ( this->
giveNode(nodeNum).giveStatus() == SloanGraphNode :: Inactive ) {
464 this->
giveNode(nodeNum).setStatus(SloanGraphNode :: Preactive);
465 this->
queue.push_front(nodeNum);
471SloanGraph :: modifyPriorityAround(
int next)
473 SloanGraphNode :: SloanGraphNode_StatusType status;
478 if ( neighborNode.
giveStatus() == SloanGraphNode :: Preactive ) {
480 neighborNode.
setStatus(SloanGraphNode :: Active);
484 if ( status == SloanGraphNode :: Active || status == SloanGraphNode :: Preactive ) {
486 }
else if ( status == SloanGraphNode :: Inactive ) {
488 this->
queue.push_front(nnodeNum);
489 neighborOfNeighbor.
setStatus(SloanGraphNode :: Preactive);
497SloanGraph :: findTopPriorityInQueue()
499 int candidate = 0, priority, pmax = -
WeightDegree * (
domain->giveNumberOfDofManagers() + 1 );
500 std :: list< int > :: iterator toDel;
502 for (
auto pos =
queue.begin(); pos !=
queue.end(); ++pos ) {
503 priority = this->
giveNode(* pos).givePriority();
504 if ( pmax < priority ) {
512 this->
queue.erase(toDel);
520SloanGraph :: computeProfileSize()
531 for (
auto &node:
nodes ) {
532 ProfSize += node.computeProfileHeight();
543SloanGraph :: askNewOptimalNumbering(
TimeStep *tStep)
546 dmans[ dmanNum - 1 ]->askNewEquationNumbers(tStep);
552SloanGraph :: writeRenumberingTable(FILE *file)
554 int nnodes = (int)
nodes.size();
556 for (
int i = 1; i <= nnodes; i++ ) {
557 int inew = this->
giveNode(i).giveNewNumber();
558 fprintf(file,
"%8i %8i\n", i, inew);
563SloanGraph :: writeOptimalRenumberingTable(FILE *OutputFile)
570 for (
int i = 1; i <= nnodes; i++ ) {
579SloanGraph :: printParameters()
581 printf(
"\nCurrent parameter values:\n");
588SloanGraph :: setParameters(
int wdeg,
int wdis)
600SloanGraph :: tryParameters(
int wdeg,
int wdis)
613 int nnodes = (int)
nodes.size();
618 for (
int i = 1; i <= nnodes; i++ ) {
626SloanGraph :: giveFullProfileSize()
628 int n = (int)
nodes.size();
629 return n * ( n + 1 );
std ::list< int > & giveNeighborList()
Returns the neighbor list of receiver.
SloanGraphNode_StatusType giveStatus()
Returns receiver status.
void increasePriorityBy(int p)
Increases the priority of receiver by given value.
void setNewNumber(int n)
Sets the new number of receiver.
void setStatus(SloanGraphNode_StatusType s)
Sets the status of receiver to given value.
int WeightDistance
Integer distance weight.
int numberOfNodes
number of graph nodes (=numberOfNodes+numberOfElementInternalNodes)
void extractCandidates(std ::list< int > &candidates, SloanLevelStructure &Spine)
SpineQualityType SpineQuality
int giveNodeWithMinDegree()
Returns graph node number with minimal degree.
int WeightDegree
Integer degree weight.
std::vector< DofManager * > dmans
List of dof managers corresponding to nodes.
void evaluateNodeDistances()
Evaluates the nodal distances from backSpine. The backSpine is generated if not available.
std::vector< SloanGraphNode > nodes
List of graph nodes.
void initStatusAndPriority()
Initializes statuses and priority of nodes of receiver.
std ::list< int > queue
Priority queue of active or preactive nodes.
Domain * domain
Domain asoociated to graph.
int OptimalWeightDegree
Optimal degree weight.
void modifyPriorityAround(int)
Modifies the priority around node with max priority.
IntArray OptimalRenumberingTable
void setParameters(int wdeg, int wdis)
Sets weight degee and weight dist to given values.
void insertNeigborsOf(int)
Inserts inactive neighbours of given node as preactive ones.
void assignNewNumbers()
Implementation of node labeling algorithm.
void findPeripheralNodes()
Finds the peripheral nodes (rooted in optimal start node) according to receiver quality and current w...
int OptimalWeightDistance
Optimal distance weight.
void setWeightDegree(int w)
Sets weight degree to given value.
int MinimalProfileSize
Minimal profile size obtained.
void setWeightDistance(int w)
Sets weight distance to given value.
int nodeDistancesFlag
Flag indicating that node distances from endNode were already computed.
int endNode
End peripheral node.
SloanGraphNode & giveNode(int num)
Return graph node.
int startNode
Start peripheral node.
void assignOldNumbers()
Assigns old node numbers as new ones. Used to compute the profile of existing old numbering.
int findTopPriorityInQueue()
Finds node with highest priority in queue, removes its entry and returns its number.
void numberIsolatedNodes(int &NextNumber, int &labeledNodes)
Numbers isolated nodes (those with degree equal to 0).
int giveDepth()
Returns the depth of receiver.
IntArray & giveLevel(int num)
Returns the i-th level of receiver.
#define OOFEM_WARNING(...)
#define OOFEM_LOG_INFO(...)
FloatArrayF< N > min(const FloatArrayF< N > &a, const FloatArrayF< N > &b)
void sort(IntArray &arry, operation op)