Rocstar  1.0
Rocstar multiphysics simulation application
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Node.cpp
Go to the documentation of this file.
1 /* Generated by Together */
2 
3 #include "Node.hpp"
4 #include "Face.hpp"
5 #include "Element.hpp"
6 #include "FaceList.hpp"
7 #include "ElementList.hpp"
8 #include "Mesh.hpp"
9 
10 #include <assert.h>
11 #include <string.h>
12 
13 Node::Node() :
14 d_ID(-1),
15 d_flag(e_unset_flag),
16 d_nextNode (this),
17 d_faceArraySize(0),
18 d_numFaces(0),
19 d_elementArraySize(0),
20 d_numElements(0)
21 {}
22 
24 d_position( pos ),
25 d_ID(-1),
26 d_flag(e_unset_flag),
27 d_nextNode (this),
28 d_faceArraySize(0),
29 d_numFaces(0),
30 d_elementArraySize(0),
31 d_numElements(0)
32 {}
33 
34 Node::Node(MVec pos, int flag) :
35 d_position( pos ),
36 d_ID(-1),
37 d_flag(flag),
38 d_nextNode (this),
39 d_faceArraySize(0),
40 d_numFaces(0),
41 d_elementArraySize(0),
42 d_numElements(0)
43 {}
44 
46 
47  if( d_faceArraySize > 0 ){
48  delete [] d_faces;
49  }
50  if( d_elementArraySize > 0 ){
51  delete [] d_elements;
52  }
53 }
54 
56 
57  if( d_faceArraySize == d_numFaces ){
58  d_faceArraySize = (int)( d_faceArraySize * 1.25 + 3);
59  Face **new_arr = new Face*[d_faceArraySize];
60  if( d_numFaces > 0 ){
61  memcpy(new_arr, d_faces, d_numFaces * sizeof(Face*) );
62  delete [] d_faces;
63  }
64  d_faces = new_arr;
65  }
67  d_numFaces++;
68 }
69 
71 
72  int i;
73  int dif = 0;
74  for( i = 0; i < d_numFaces; i++ ){
75  if( (dif == 0) && (d_faces[i] == face) ){
76  dif++;
77  continue;
78  }
79  if( dif > 0 ){
80  d_faces[i - dif] = d_faces[i];
81  }
82  }
83  d_numFaces -= dif;
84 }
85 
87 
89  d_elementArraySize = (int)( d_elementArraySize * 1.25 + 3);
90  Element **new_arr = new Element*[d_elementArraySize];
91  if( d_numElements > 0 ){
92  memcpy(new_arr, d_elements, d_numElements * sizeof(Element*) );
93  delete [] d_elements;
94  }
95  d_elements = new_arr;
96  }
97  d_elements[d_numElements] = elem;
98  d_numElements++;
99 }
100 
101 
102 void Node::removeElement(Element * element){
103 
104  int i;
105  int dif = 0;
106  for( i = 0; i < d_numElements; i++ ){
107  if( (dif == 0) && (d_elements[i] == element) ){
108  dif++;
109  continue;
110  }
111  if( dif > 0 ){
112  d_elements[i - dif] = d_elements[i];
113  }
114  }
115  d_numElements -= dif;
116 }
117 
118 Face* Node::sharedFace(Node* n2, Node* n3, Node* n4 ){
119 
120  int i;
121  for( i = 0; i < d_numFaces; i++ ){
122  Node** fnodes = d_faces[i]->getNodes();
123  int numn = d_faces[i]->getNumNodes();
124  int count=0;
125  int k;
126  for( k = 0; k < numn; k++ ){
127  if( fnodes[k] == n2 || fnodes[k] == n3 || fnodes[k] == n4){
128  count++;
129  }
130  }
131  if( ( n4 == 0 && count == 2) || count == 3 ){
132  return d_faces[i];
133  }
134  }
135  return 0;
136 }
137 
138 
139 void Node::addNextLink( Node* link ){
140 
141  Node* prev = this;
142 
143  while( prev->d_nextNode != this ){
144  prev = prev->d_nextNode;
145  }
146  // now prev->next is this one
147  prev->d_nextNode = link;
148  prev = link;
149  while( prev->d_nextNode != link ){
150  prev = prev->d_nextNode;
151  }
152  // now prev->next is link
153  prev->d_nextNode = this;
154 
155  prev = this;
156  while( prev->d_nextNode != this ){
157  prev = prev->d_nextNode;
158  }
159 }
160 
161 
162 boolean Node::separate( Mesh* mesh, FaceList* list, int new_material ){
163 
164  //Use the facelist to get a list of involved elements, and see if they can
165  //be separated or not. This method should be called getSeparableElements. It
166  //returns an element list with the involved elements if separable, empty if not
167  //separable.
168  ElementList* sep_elements = getSeparateElements( list );
169 
170  if( !sep_elements ){ //not a separable node.
171  return FALSE;
172  }
173 
174  //Its separable - make a new node at the same position, and add it to the mesh.
175  //Note that it should have the same nodeflag as the initial node.
176  Node *new_node = new Node(d_position, d_flag);
177  mesh->addNode( new_node );
178 
179  //now we have to go back to the mesh class... kind of wierd design.
180  mesh->replaceNode(this, new_node, sep_elements, new_material );
181 
182  delete sep_elements;
183 
184  // now can call separate again for this & for new_node
185  // recursion to separate further
186 
187  new_node->separate( mesh, list, new_material );
188  separate( mesh, list, new_material);
189  return TRUE;
190 }
191 
193 
194  // Collect ONLY regular faces - not in cohesive,
195  // not boundary, not in the "list" ("list" is a facelist of
196  // the faces involving the node that is trying to be separated).
197 
198  //"list" is used as a separator list of faces. We need to build a list of
199  //faces that CAN be traversed. That list will be node_faces.
200 
201  FaceList node_faces;
202  int i;
203  for( i = 0; i < d_numFaces; i++ ){
204  //step through all the faces in the d_faces array for this node.
205  Face *face = d_faces[i];
206  //see if each face is on the "list" of separable faces sent in.
207  if( list->move_to( face )){
208  continue; //if it is, then go to the next face.
209  }
210 
211  //if this face is an exterior face, or if either element that it
212  //is associated with is cohesive, then don't add it to the facelist.
213  if( !face->getElement2() || face->getElement1()->isCohesive() ||
214  face->getElement2()->isCohesive() ){
215  continue;
216  }
217  node_faces.insert_first( face );
218  }
219 
220  //count the number of non-cohesive ("real") elements attached to this node.
221  int count_real=0;
222  for( i = 0; i < d_numElements; i++ ){
223  if( !d_elements[i]->isCohesive() ){
224  count_real++;
225  }
226  }
227 
228  // Try to find ONE non-cohesive element. Note the "break" in the "if"
229  // below if one is found!
230  ElementList *shared_elements = new ElementList;
231  for( i = 0; i < d_numElements; i++ ){
232  if( !d_elements[i]->isCohesive() ){
233  shared_elements->insert_first(d_elements[i]);
234  break;
235  }
236  }
237 
238  //We should always find at least one non-cohesive element (says Alla).
239  if( shared_elements->size() != 1 ){
240  // thoretically this should not happen (pure cohesive node)
241  delete shared_elements;
242  return 0; //get out of town if node is pure cohesive - can't separate.
243  }
244 
245  // Since we found one non-cohesive element, now try to add more
246  boolean changed = TRUE;
247  while( changed ) {
248  changed = FALSE;
249  //number of faces with non-cohesive or non-exterior elements on both sides.
250  int size = node_faces.size();
251  int i;
252  //loop over all the candidate faces for this node.
253  for( i = 0; i < size; i++ ) {
254  //retrieve the list of faces for this node.
255  Face* face = node_faces.get();
256  boolean found=FALSE;
257  // check if face belongs to any shared element
258  shared_elements->reset();
259  int nums = shared_elements->size();
260  int j;
261  //for each element in the shared_elements list...
262  for( j = 0; j < nums; j++ ) {
263  Element* sh_el = shared_elements->get();
264  Element* oelem(0);
265  //check and see if the current face involves one of the elements on the list.
266  //If so, get the other element that is on the other side of the face (put
267  //in oelem).
268  if( face->getElement1() == sh_el ){
269  oelem = face->getElement2();
270  }
271  else if( face->getElement2() == sh_el ){
272  oelem = face->getElement1();
273  }
274  //if find the second element ...
275  if( oelem ){
276  found = TRUE;
277  //if it's not already on the shared elements list, then put it on the list.
278  if( !shared_elements->move_to( oelem ) ){
279  shared_elements->insert_first( oelem );
280  }
281  break; //exit j loop (element loop)
282  }
283 
284  //get ready to check the next element.
285  shared_elements->next();
286 
287  } //for (j=0...
288 
289  if( found ){
290  //remove the current face from the facelist
291  node_faces.remove();
292  //get ready to look at the new facelist (sans the current face)
293  changed = TRUE;
294  //exit the i loop and go back to the while (start over with new list of faces)
295  break;
296  }
297 
298  //one of the faces must be part of elements that are already on the list, so go on!
299  node_faces.next();
300 
301  } //for (i=0 ...
302  } //while(changed)
303 
304  // count_real is the number of non-cohesive elements attached to this node.
305  // have separation surface
306  //if the actual number of elements is greater than the number you found, then there must
307  //be a separation plane. If it is the same, then you went all the way around and found no
308  //boundary.
309  if( count_real > shared_elements->size() ){
310  return shared_elements;
311  }
312  delete shared_elements;
313  return 0;
314 }
#define FALSE
Definition: vinci.h:133
boolean separate(Mesh *mesh, FaceList *list, int new_material)
Definition: Node.cpp:162
int d_flag
Definition: Node.hpp:102
Node * d_nextNode
Definition: Node.hpp:104
This class encapsulate a node over a window manifold.
Definition: Manifold_2.h:370
Face * sharedFace(Node *n2, Node *n3, Node *n4=0)
Definition: Node.cpp:118
Definition: face.h:90
Element * get()
Definition: ElementList.hpp:87
j indices k indices k
Definition: Indexing.h:6
void addFace(Face *face)
Definition: Node.cpp:55
Element ** d_elements
Definition: Node.hpp:110
Node()
Default constructor.
Definition: Manifold_2.h:373
Definition: MVec.hpp:8
Element * getElement2()
Get the pointer to the second element that this face is associated with.
Definition: Face.hpp:197
void addNode(Node *node)
The following add/remove/get methods are utility methods to add, remove, or return instances of nodes...
Definition: Mesh.cpp:60
Class Mesh is the main class that holds all information to describe the current state of the mesh...
Definition: Mesh.hpp:19
void addNextLink(Node *link)
Definition: Node.cpp:139
int d_numFaces
Definition: Node.hpp:108
int d_numElements
Definition: Node.hpp:112
void reset()
Definition: ElementList.hpp:76
MVec d_position
Definition: Node.hpp:99
int size()
Definition: FaceList.hpp:95
~Node()
Definition: Node.cpp:45
int d_elementArraySize
Definition: Node.hpp:111
void next()
Definition: FaceList.hpp:80
blockLoc i
Definition: read.cpp:79
void replaceNode(Node *node, Node *new_node, ElementList *sep_elements, int new_material)
Definition: Mesh.cpp:245
#define TRUE
Definition: vinci.h:134
Face * remove()
Definition: FaceList.cpp:76
Face ** d_faces
Definition: Node.hpp:106
Node ** getNodes()
Returns the array of nodes.
Definition: Face.hpp:185
void insert_first(Element *val)
Definition: ElementList.hpp:69
boolean isCohesive() const
Definition: Element.hpp:112
static T_VertexSet * face
Definition: vinci_lass.c:79
j indices j
Definition: Indexing.h:6
boolean move_to(Face *val)
Definition: FaceList.cpp:102
Face * get()
Definition: FaceList.hpp:87
boolean move_to(Element *val)
ElementList * getSeparateElements(FaceList *list)
Definition: Node.cpp:192
int d_faceArraySize
Definition: Node.hpp:107
void removeFace(Face *face)
Definition: Node.cpp:70
The Face class is an abstract base class that supplies implemented general methods, as well as a vew virtual interface methods to child classes.
Definition: Face.hpp:19
void addElement(Element *elem)
Definition: Node.cpp:86
Element * getElement1()
Get the pointer to the first element that this face is associated with.
Definition: Face.hpp:191
void removeElement(Element *elem)
Definition: Node.cpp:102
virtual int getNumNodes() const =0
Retrieves the number of nodes that make up the face.
void insert_first(Face *val)
Definition: FaceList.hpp:69