Rocstar  1.0
Rocstar multiphysics simulation application
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Mesh.cpp
Go to the documentation of this file.
1 /* Generated by Together */
2 
3 #include <string.h> /* added by Zaczek,M 6/7/2001 ... for memcpy() */
4 #include "Mesh.hpp"
5 #include "Element.hpp"
6 #include "Face.hpp"
7 #include "Node.hpp"
8 #include "IntList.hpp"
9 #include "NodeList.hpp"
10 #include "ElementList.hpp"
11 #include "FaceList.hpp"
12 #include "FaceListList.hpp"
13 
15  d_nodes(0),
16  d_numNodes(0),
17  d_nodeArraySize(0),
18  d_faces(0),
19  d_numFaces(0),
20  d_faceArraySize(0),
21  d_elements(0),
22  d_numElements(0),
23  d_elementArraySize(0)
24 {
25 
26  Element::setMesh( this );
27  Face::setMesh( this );
28  minEdge = 1E+25;
29 
30 }
31 
33 
34  if( d_elements ){
35  int i;
36  for( i = 0; i < d_numElements; i++ ){
37  delete d_elements[i];
38  }
39  delete [] d_elements;
40  }
41 
42  if( d_faces ){
43  int i;
44  for( i = 0; i < d_numFaces; i++ ){
45  delete d_faces[i];
46  }
47  delete [] d_faces;
48  }
49 
50  if( d_nodes ){
51  int i;
52  for( i = 0; i < d_numNodes; i++ ){
53  delete d_nodes[i];
54  }
55  delete [] d_nodes;
56  }
57 }
58 
59 
61 
62  if( d_nodeArraySize == d_numNodes ){
63  d_nodeArraySize = (int)( d_nodeArraySize * 1.25 + 3);
64  Node **new_arr = new Node*[d_nodeArraySize];
65  if( d_numNodes > 0 ){
66  memcpy(new_arr, d_nodes, d_numNodes * sizeof(Node*) );
67  delete [] d_nodes;
68  }
69  d_nodes = new_arr;
70  }
71  d_nodes[d_numNodes] = node;
72  node->setID(d_numNodes + 1);
73  d_numNodes++;
74 
75 }
76 
78 
79  int i;
80  int dif = 0;
81  for( i = 0; i < d_numNodes; i++ ){
82  if( d_nodes[i] == node ){
83  dif++;
84  continue;
85  }
86  if( dif > 0 ){
87  d_nodes[i - dif] = d_nodes[i];
88  d_nodes[i - dif]->setID( i - dif + 1 );
89  }
90  }
91  d_numNodes -= dif;
92 
93 }
94 
95 
97 
98  if( d_faceArraySize == d_numFaces ){
99  d_faceArraySize = (int)( d_faceArraySize * 1.25 + 3);
100  Face **new_arr = new Face*[d_faceArraySize];
101  if( d_numFaces > 0 ){
102  memcpy(new_arr, d_faces, d_numFaces * sizeof(Face*) );
103  delete [] d_faces;
104  }
105  d_faces = new_arr;
106  }
108  face->setID(d_numFaces + 1);
109  d_numFaces++;
110 }
111 
113 
114  int i;
115  int dif = 0;
116  for( i = 0; i < d_numFaces; i++ ){
117  if( d_faces[i] == face ){
118  dif++;
119  continue;
120  }
121  if( dif > 0 ){
122  d_faces[i - dif] = d_faces[i];
123  d_faces[i - dif]->setID( i - dif + 1 );
124  }
125  }
126  d_numFaces -= dif;
127 
128 
129 }
130 
131 void Mesh::addElement(Element* element){
132 
134  d_elementArraySize = (int)( d_elementArraySize * 1.25 + 3);
135  Element **new_arr = new Element*[d_elementArraySize];
136  if( d_numElements > 0 ){
137  memcpy(new_arr, d_elements, d_numElements * sizeof(Element*) );
138  delete [] d_elements;
139  }
140  d_elements = new_arr;
141  }
142  d_elements[d_numElements] = element;
143  element->setID(d_numElements + 1);
144  d_numElements++;
145 
146 }
147 
148 void Mesh::removeElement(Element * element){
149 
150  int i;
151  int dif = 0;
152  for( i = 0; i < d_numElements; i++ ){
153  if( d_elements[i] == element ){
154  dif++;
155  continue;
156  }
157  if( dif > 0 ){
158  d_elements[i - dif] = d_elements[i];
159  d_elements[i - dif]->setID( i - dif + 1 );
160  }
161  }
162  d_numElements -= dif;
163 
164 }
165 
166 
167 boolean Mesh::addCohesive( int material1, int material2, int new_material ){
168 
169  // go over all faces & for each one which has two elems
170  // with the mat1 & mat2 - generate a cohesive (if neither of
171  // the two elems is cohesive) - have a list of those (to split
172  // at nodes later)
173 
174  FaceList faces;
175 
176  // collect the faces
177  int i;
178  for( i = 0; i < d_numFaces; i++ ){
179  Element *e1 = d_faces[i]->getElement1();
180  Element *e2 = d_faces[i]->getElement2();
181  if( e1 && e2 && !e1->isCohesive()
182  && !e2->isCohesive()
183  && ( ( e1->getMaterialType() == material1
184  && e2->getMaterialType() == material2 )
185  || ( e1->getMaterialType() == material2
186  && e2->getMaterialType() == material1 ) ) ){
187  // fits
188  faces.insert_first( d_faces[i] );
189  }
190  }
191 
192  // Collect nodes & their faces
193 
194  NodeList sep_nodes;
195  FaceListList node_faces;
196  int size = faces.size();
197  faces.reset();
198  for( i = 0; i < size; i++ ){
199  Face* face = faces.get();
200  faces.next();
201  int num = face->getNumNodes();
202  Node** fnodes = face->getNodes();
203  int j;
204  for( j = 0; j < num; j++ ){
205  if( sep_nodes.move_to( fnodes[j] ) ){
206  int ind = sep_nodes.index();
207  node_faces.index( ind );
208  node_faces.get()->insert_first( face );
209  }
210  else {
211  sep_nodes.insert_first( fnodes[j] );
212  FaceList* newlist = new FaceList;
213  newlist->insert_first( face );
214  node_faces.insert_first( newlist );
215  }
216  }
217  }
218 
219  // now go over the nodes & check if separable...
220 
221  // check at each node
222  // if have two element groups separated by cohesives (or our faces)
223  // if yes separate the two.
224 
225  int sep_count = 0;
226  int node_size = sep_nodes.size();
227  sep_nodes.reset();
228  node_faces.reset();
229  for( i = 0; i < node_size; i++ ) {
230  int j = i;
231  Node* node = sep_nodes.get();
232  FaceList* flist = node_faces.get();
233  sep_nodes.next();
234  node_faces.next();
235  boolean separated = node->separate( this, flist, new_material );
236  if( separated ) sep_count++;
237  delete flist;
238  }
239  cerr << " separated " << sep_count << " nodes, out of " << node_size
240  << " involved" << endl;
241 
242  return ( sep_count >0 ? TRUE : FALSE );
243 }
244 
245 void Mesh::replaceNode( Node* node, Node* new_node,
246  ElementList *sep_elements, int new_material ){
247 
248  // add any cohesives which have one side inside the sep_elements
249 
250  int size = sep_elements->size();
251  //out_faces will ultimately contain the list of faces that form the outside
252  //of the sep_elements group of elements.
253  FaceList out_faces;
254  int i;
255  //for each element in the sep_elements list...
256  for( i = 0; i < size; i++ ) {
257  sep_elements->index(i);
258  Element* elem = sep_elements->get();
259  int numf = elem->getNumFaces();
260  Face** faces = elem->getFaces();
261  int j;
262  //for each face in each element...
263  for( j = 0; j < numf; j++ ){
264  Face* face = faces[j];
265 
266  //see of this face contains the node we're working on...
267  if( !face->containsNode( node ) ){
268  continue; //try next face
269  }
270 
271  //if yes, get the element on the other side of this face...
272  Element* oelem= (face->getElement1() == elem
273  ? face->getElement2()
274  : face->getElement1() );
275 
276  //if its an outside face (no second element), then go to the next face...
277  if( !oelem ){
278  continue;
279  }
280 
281  //if the second element is already on our element list, go to next face...
282  if( sep_elements->move_to( oelem ) ){
283  continue;
284  }
285 
286  //otherwise, if it's a cohesive element on the other side of the face...
287  if( oelem->isCohesive() ) {
288  //get the second face of the cohesive element (first is in "face")
289  Face** cofaces = oelem->getFaces();
290  Face* oface = ( cofaces[0] == face ? cofaces[1] : cofaces[0] );
291  //now get the element that is on the other side of the cohesive element
292  Element* other = (oface->getElement1() == oelem
293  ? oface->getElement2()
294  : oface->getElement1() );
295  //if that other element is already on our list of elements, then append
296  //the first one to the list (it wasn't on our list - we checked above).
297  if( sep_elements->move_to( other ) ) {
298  sep_elements->append( oelem );
299  }
300  else {
301  //otherwise add the face we're working with to the out_faces list.
302  //(if the opposite element does not belong in our element list, then it is
303  //an outside "separator" face)
304  out_faces.insert_first( face );
305  }
306  } // if( oelem->isCohesive() )
307  else { //if the other element is not cohesive, and is not in the sep_elements list,
308  //then it is a boundary.
309  out_faces.insert_first( face );
310  }
311 
312  } //for( j = 0 ...
313  } // for( i = 0 ...
314 
315  int num_out_faces = out_faces.size();
316 
317  //Task: if the face does not belong to a cohesive element, then we have to make one.
318  //Otherwise, we need to replace the node in the current face. Somewhere here there
319  //is a bug right now (8/13/01)
320 
321  //for each face in the out_faces array, get the elements on either side.
322  for( i = 0; i < num_out_faces; i++ ){
323  Face *face = out_faces.get();
324  out_faces.next();
325  Element* e1 = face->getElement1();
326  Element* e2 = face->getElement2();
327  if( !e2 ) { // the sep replacement will handle
328  continue;
329  }
330  //if neither of them are cohesive, add a cohesive element between them.
331  if( !e1->isCohesive() && !e2->isCohesive() ){
332  //elem is used to ensure correct direction of the normals.
333  Element* elem = ( sep_elements->move_to( e1 ) ? e1 : e2 );
334  Element* new_elem = face->buildCohesive( elem, node, new_node );
335  new_elem->setMaterialType( new_material );
336  addElement( new_elem );
337  }
338  else if( e1->isCohesive() ){ // e2 is in sep
339  e1->replaceFaceNode( node, new_node, face );
340  }
341  else {
342  e2->replaceFaceNode( node, new_node, face );
343  }
344  }
345 
346  // go and replace in all the elements
347  // including inside the faces
348  //replace nodes in the elements in the sep_element list. Bug may be here as well.
349  sep_elements->reset();
350  size = sep_elements->size();
351  for( i = 0; i < size; i++ ){
352 
353  sep_elements->get()->replaceNode( node, new_node );
354  sep_elements->next();
355  }
356 }
357 
358 
359 ostream & operator<<(ostream & stream, Mesh & mesh){
360 
361  int j;
362  int numcohesive = 0;
363  for (j=0; j<mesh.d_numElements; j++) {
364  if ((*mesh.d_elements[j]).isCohesive()) numcohesive += 1;
365  }
366 
367  stream << (mesh.d_numElements - numcohesive) << '\t' << mesh.d_numNodes
368  << '\t' << numcohesive << '\t' << mesh.getMinEdge() <<endl;
369 
370  stream.setf(ios::uppercase);
371  stream.setf(ios::scientific,ios::floatfield);
372  stream.precision(9);
373  int numbc_nodes = 0;
374  int i;
375  for( i = 0; i < mesh.d_numNodes;i++ ){
376  stream << (*mesh.d_nodes[i]);
377  if( mesh.d_nodes[i]->getFlag() != Node::e_unset_flag ){
378  numbc_nodes++;
379  }
380  }
381  stream << numbc_nodes << endl;
382  for( i = 0; i < mesh.d_numNodes;i++ ){
383  if( mesh.d_nodes[i]->getFlag() != Node::e_unset_flag ){
384  stream << mesh.d_nodes[i]->getID() << '\t' << mesh.d_nodes[i]->getFlag()<< endl;
385  }
386  }
387  for( i = 0; i < mesh.d_numElements; i++ ){
388  stream << (*mesh.d_elements[i]);
389  }
390 
391  return stream;
392 }
393 
394 
395 //Returns the length of the shortest edge in an element.
396 double Mesh::calcEdgeLength(int elementID){
397 
398  return(d_elements[elementID]->getMinEdgeLength());
399 
400 }
401 
402 istream & operator>>(istream & stream, Mesh & mesh){
403 
404  int numn;
405  int nume;
406  stream >> nume >> numn;
407 
408  mesh.d_nodeArraySize = numn;
409  mesh.d_nodes = new Node*[numn];
410  // read nodes
411  int i;
412  for( i = 0; i < numn;i++ ){
413  mesh.d_nodes[i] = new Node();
414  stream >> (*mesh.d_nodes[i]);
415  }
416  mesh.d_numNodes = numn;
417 
418  mesh.d_elementArraySize = nume;
419  mesh.d_elements = new Element*[nume];
420 
421  // assume ~ twice as elements
422 
423  mesh.d_faceArraySize = nume * 2;
424  mesh.d_faces = new Face*[mesh.d_faceArraySize];
425 
426 
427  for( i = 0; i < nume;i++ ){
428  int id, type;
429  double currentEdge;
430  stream >> id >> type;
431  mesh.d_elements[i] = Element::create( id, (Element::Type)type );
432  stream >> (*mesh.d_elements[i]);
433  currentEdge = (mesh.calcEdgeLength(i));
434  if (currentEdge < mesh.getMinEdge()) mesh.setMinEdge(currentEdge);
435  }
436  mesh.d_numElements = nume;
437  // read groups
438 
439  int numbcn;
440  stream >> numbcn;
441  // read nodes with flag
442  for( i = 0; i < numbcn; i++ ){
443  int num;
444  int flag;
445  stream >> num >> flag;
446  mesh.d_nodes[num-1]->setFlag( flag );
447  }
448 
449  //read faces with flag (three nodes and the flag)
450  int numFaceFlags, numFaceNodes, elementtype, theflag, totalFaces;
451 
452  stream >> numFaceFlags; //number of faces in input file with flags
453  totalFaces = mesh.getNumFaces(); //total number of existing faces in mesh
454 
455  for (i=0 ; i < numFaceFlags ; i++) {
456  stream >> elementtype; //type of element the face is associated with
457  //make a temporary working face to hold the node info
458  Face* theFace = Face::create((Face::eType)elementtype);
459  stream >> *theFace;
460  stream >> theflag;
461  numFaceNodes = theFace->getNumNodes(); //number of nodes in this face
462 
463  //take "theFace" and compare it's nodes against the nodes in every face in the
464  //Mesh list of faces until we find a match. When we find a match, set it's flag,
465  //and then go on to the next face in the list. This is very inefficient, but
466  //without knowing what element the supplied face is in, I don't know how else to
467  //go about it.
468  int j;
469  for (j=0; j < totalFaces; j++) {
470  Face* trialFace = mesh.getFace(j+1); //getFace assumes ID's starting with 1
471  Node** theNodes = theFace->getNodes();
472  Node** trialNodes = trialFace->getNodes();
473  boolean nodeFound;
474  int numFound;
475  numFound=0;
476 
477  //for each node in the face to be found...
478  int k;
479  for (k=0; k<numFaceNodes; k++) {
480  nodeFound=FALSE;
481  int numExistingFaceNodes;
482  numExistingFaceNodes = trialFace->getNumNodes();
483  if (numFaceNodes != numExistingFaceNodes) break; //faces aren't compatible
484 
485  //...see if it's in the current face in the mesh that we're looking at.
486  int m;
487  for (m=0; m<numExistingFaceNodes; m++) {
488  if(theNodes[k]==trialNodes[m]) {
489  nodeFound=TRUE;
490  numFound++;
491  break;
492  }
493  }
494  if(!nodeFound) break; //if we didn't find the node, try the next face
495  //if we found all the nodes in any face, then set the flag and read the next face in.
496  if(numFound==numFaceNodes) {
497  trialFace->setFlag(theflag);
498  break;
499  }
500  }
501  }
502  delete theFace;
503  }
504  return stream;
505 }
506 
507 void Mesh::write_boundary(ostream & stream){
508 
509  int count = 0;
510  int i;
511  for( i = 0; i < d_numFaces; i++ ){
512  if( d_faces[i]->isExterior() ){
513  count++;
514  }
515  }
516  stream << count << endl;
517 
518  for( i = 0; i < d_numFaces; i++ ){
519  if( d_faces[i]->isExterior() ){
520  Element* e1 = d_faces[i]->getElement1();
521  stream << e1->getID() << '\t';
522  int numf = e1->getNumFaces();
523  Face** efaces = e1->getFaces();
524  int j;
525  for( j = 0; j < numf; j++ ){
526  if( d_faces[i] == efaces[j] ){
527  stream << j + 1 << '\t' << d_faces[i]->getFlag() << endl;
528  break;
529  }
530  }
531  }
532  }
533 }
534 
#define FALSE
Definition: vinci.h:133
boolean separate(Mesh *mesh, FaceList *list, int new_material)
Definition: Node.cpp:162
void insert_first(FaceList *val)
void addFace(Face *face)
Definition: Mesh.cpp:96
int d_numFaces
Definition: Mesh.hpp:122
virtual void replaceFaceNode(Node *node, Node *new_node, Face *face)
Definition: Element.cpp:168
int size()
Definition: NodeList.hpp:95
static Element * create(int id, Type type)
Definition: Element.cpp:35
void setFlag(int theFlag)
Sets the flag for the face.
Definition: Face.hpp:179
int getMaterialType() const
Definition: Element.hpp:118
Face ** d_faces
1..*
Definition: Mesh.hpp:121
void next()
Definition: NodeList.hpp:80
This class encapsulate a node over a window manifold.
Definition: Manifold_2.h:370
Definition: face.h:90
Element * get()
Definition: ElementList.hpp:87
int index() const
~Mesh()
Definition: Mesh.cpp:32
Node * get()
Definition: NodeList.hpp:87
j indices k indices k
Definition: Indexing.h:6
void removeNode(Node *node)
Definition: Mesh.cpp:77
static Face * create(eType type)
Definition: Face.cpp:34
void replaceNode(Node *node, Node *new_node)
Definition: Element.cpp:138
int d_faceArraySize
Definition: Mesh.hpp:123
void setMaterialType(int mtype)
Definition: Element.hpp:121
Element * getElement2()
Get the pointer to the second element that this face is associated with.
Definition: Face.hpp:197
int getFlag() const
Gets the flag for the face.
Definition: Face.hpp:182
boolean addCohesive(int material1, int material2, int new_material=-1)
The addCohesive method is the driver for the entire process of adding cohesive elements to the mesh...
Definition: Mesh.cpp:167
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
int getID()
Definition: Node.hpp:119
int d_numElements
Definition: Mesh.hpp:130
int d_nodeArraySize
The current size of the nodes array (must be as big or bigger than numNodes).
Definition: Mesh.hpp:116
Definition: adj.h:150
FaceList * get()
virtual int getNumFaces() const =0
void reset()
Definition: ElementList.hpp:76
Node ** d_nodes
An ordered array of all nodes in the mesh.
Definition: Mesh.hpp:105
int size()
Definition: FaceList.hpp:95
int getFlag() const
Definition: Node.hpp:150
boolean containsNode(Node *node) const
Definition: Face.cpp:108
double calcEdgeLength(int elementID)
Definition: Mesh.cpp:396
void addElement(Element *element)
Definition: Mesh.cpp:131
Face ** getFaces()
Definition: Element.hpp:106
void removeElement(Element *element)
Definition: Mesh.cpp:148
void reset()
Definition: NodeList.hpp:76
virtual Element * buildCohesive(Element *side_elem, Node *node, Node *new_node)=0
void next()
Definition: FaceList.hpp:80
Element ** d_elements
Array of all the Elements in the mesh.
Definition: Mesh.hpp:129
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
double minEdge
Definition: Mesh.hpp:133
void reset()
Definition: FaceList.hpp:76
int getNumFaces()
Definition: Mesh.hpp:149
void setMinEdge(double me)
Definition: Mesh.hpp:158
int d_numNodes
The number of Nodes in the nodes array.
Definition: Mesh.hpp:110
void setID(int theID)
Definition: Element.hpp:100
Node ** getNodes()
Returns the array of nodes.
Definition: Face.hpp:185
int getID() const
Definition: Element.hpp:97
void removeFace(Face *face)
Definition: Mesh.cpp:112
static void setMesh(Mesh *emesh)
Definition: Element.hpp:124
int index() const
boolean isCohesive() const
Definition: Element.hpp:112
static T_VertexSet * face
Definition: vinci_lass.c:79
Mesh()
Definition: Mesh.cpp:14
j indices j
Definition: Indexing.h:6
static void setMesh(Mesh *emesh)
Definition: Face.hpp:215
unsigned long id(const Leda_like_handle &x)
Definition: Handle.h:107
int index() const
Definition: NodeList.cpp:110
Face * getFace(int ID)
Definition: Mesh.hpp:140
Face * get()
Definition: FaceList.hpp:87
boolean move_to(Element *val)
void setID(int theID)
Sets the serial ID for the face.
Definition: Face.hpp:173
void setFlag(int flag)
Definition: Node.hpp:153
int d_elementArraySize
Definition: Mesh.hpp:131
void setID(int theID)
Definition: Node.hpp:116
std::istream & operator>>(std::istream &is, CGAL::Aff_transformation_2< R > &t)
std::ostream & operator<<(std::ostream &os, const COM_exception &ex)
Print out a given exception.
boolean move_to(Node *val)
Definition: NodeList.cpp:102
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
Element * getElement1()
Get the pointer to the first element that this face is associated with.
Definition: Face.hpp:191
eType
Definition: Face.hpp:24
void write_boundary(ostream &stream)
Definition: Mesh.cpp:507
double getMinEdge()
Definition: Mesh.hpp:155
virtual int getNumNodes() const =0
Retrieves the number of nodes that make up the face.
void append(Element *val)
Definition: ElementList.cpp:58
void insert_first(Node *val)
Definition: NodeList.hpp:69
void insert_first(Face *val)
Definition: FaceList.hpp:69