Ice Sheet System Model  4.18
Code documentation
Functions
CreateFaces.cpp File Reference

: create faces from 2d mesh More...

#include "../../classes/classes.h"
#include "../../shared/shared.h"
#include "./ModelProcessorx.h"

Go to the source code of this file.

Functions

void CreateFaces (IoModel *iomodel)
 
void CreateFaces3d (IoModel *iomodel)
 

Detailed Description

: create faces from 2d mesh

Definition in file CreateFaces.cpp.

Function Documentation

◆ CreateFaces()

void CreateFaces ( IoModel iomodel)

Definition at line 9 of file CreateFaces.cpp.

9  {/*{{{*/
10 
11  /*If faces are already present, exit*/
12  if(iomodel->faces) return;
13 
14  /*Some checks*/
15  if(iomodel->numberofvertices<3) _error_("not enough elements in mesh");
16  _assert_(iomodel->elements);
17 
18  /*Check Iomodel properties*/
20  /*Keep going*/
21  }
22  else if(iomodel->domaintype==Domain3DEnum){
23  CreateFaces3d(iomodel);
24  return;
25  }
26  else{
27  _error_("mesh dimension not supported yet");
28  }
29 
30  /*Intermediaries*/
31  bool exist;
32  int i,j,v1,v2,v3;
33  int maxnbf,nbf;
34 
35  /*Maximum number of faces*/
36  maxnbf = 3*iomodel->numberofelements;
37 
38  /*Initialize intermediaries*/
39  int* facestemp = xNew<int>(maxnbf*4); /*format: [vertex1 vertex2 element1 element2] */
40  bool* exchange = xNewZeroInit<bool>(maxnbf); /*Faces are ordered, we need to keep track of vertex swapping*/
41  for(i=0;i<maxnbf;i++) facestemp[i*4+3]=-1; /*Initialize last column of faces as -1 (boundary edge) */
42 
43  /*Initialize chain*/
44  int* head_minv = xNew<int>(iomodel->numberofvertices);
45  int* next_face = xNew<int>(maxnbf);
46  for(i=0;i<iomodel->numberofvertices;i++) head_minv[i]=-1;
47 
48  /*Initialize number of faces*/
49  nbf = 0;
50 
51  for(i=0;i<iomodel->numberofelements;i++){
52  for(j=0;j<3;j++){
53 
54  /*Get the two indices of the edge number j of the ith triangle*/
55  v1 = iomodel->elements[i*3+j];
56  if(j==2)
57  v2 = iomodel->elements[i*3+0];
58  else
59  v2 = iomodel->elements[i*3+j+1];
60 
61  /*v1 and v2 must be sorted*/
62  if(v2<v1){
63  v3=v2; v2=v1; v1=v3;
64  }
65 
66  /*This edge a priori has not been processed yet*/
67  exist = false;
68 
69  /*Go through all processed faces connected to v1 and check whether we have seen this edge yet*/
70  _assert_(v1>=0 && v1<iomodel->numberofvertices);
71  for(int e=head_minv[v1]; e!=-1; e=next_face[e]){
72  if(facestemp[e*4+1]==v2){
73  exist = true;
74  facestemp[e*4+3]=i+1;
75  break;
76  }
77  }
78 
79  /*If this edge is new, add it to the lists*/
80  if(!exist){
81  _assert_(nbf<maxnbf);
82 
83  /*Update faces*/
84  facestemp[nbf*4+0] = v1;
85  facestemp[nbf*4+1] = v2;
86  facestemp[nbf*4+2] = i+1;
87  if(v1!=iomodel->elements[i*3+j]) exchange[nbf]=true;
88 
89  /*Update chain*/
90  next_face[nbf] = head_minv[v1];
91  head_minv[v1] = nbf;
92 
93  /*Increase number of faces*/
94  nbf++;
95  }
96  }
97  }
98 
99  /*Clean up*/
100  xDelete<int>(head_minv);
101  xDelete<int>(next_face);
102 
103  /*Create final faces*/
104  int* faces = xNew<int>(nbf*4); /*vertex1 vertex2 element1 element2*/
105  for(int i=0;i<nbf;i++){
106  if(exchange[i]){
107  faces[i*4+0]=facestemp[i*4+1];
108  faces[i*4+1]=facestemp[i*4+0];
109  }
110  else{
111  faces[i*4+0]=facestemp[i*4+0];
112  faces[i*4+1]=facestemp[i*4+1];
113  }
114  faces[i*4+2]=facestemp[i*4+2];
115  faces[i*4+3]=facestemp[i*4+3];
116  }
117  xDelete<int>(facestemp);
118  xDelete<bool>(exchange);
119 
120  /*Assign output pointers*/
121  iomodel->faces = faces;
122  iomodel->numberoffaces = nbf;
123 }/*}}}*/

◆ CreateFaces3d()

void CreateFaces3d ( IoModel iomodel)

Definition at line 124 of file CreateFaces.cpp.

124  {/*{{{*/
125 
126  /*Intermediaries*/
127  int i,j,k,v0,cols,facemaxnbv;
128  int elementnbf,elementnbv,facenbv;
129  int *elementfaces = NULL;
130  int *elementfaces_markers = NULL;
131 
132  /*Mesh specific face indexing per element*/
133  switch(iomodel->meshelementtype){
134  case PentaEnum:
135  elementnbv = 6; /*Number of vertices per element*/
136  elementnbf = 5; /*Number of faces per element*/
137  facemaxnbv = 4; /*Maximum number of vertices per face*/
138  cols = facemaxnbv + 1;
139  elementfaces = xNew<int>(elementnbf*cols);
140  elementfaces_markers = xNew<int>(elementnbf);
141  /*2 triangles*/
142  elementfaces_markers[0] = 1;
143  elementfaces_markers[1] = 1;
144  elementfaces[cols*0+0] = 3; elementfaces[cols*0+1] = 0; elementfaces[cols*0+2] = 1; elementfaces[cols*0+3] = 2;
145  elementfaces[cols*1+0] = 3; elementfaces[cols*1+1] = 3; elementfaces[cols*1+2] = 4; elementfaces[cols*1+3] = 5;
146  /*3 quads*/
147  elementfaces_markers[2] = 2;
148  elementfaces_markers[3] = 2;
149  elementfaces_markers[4] = 2;
150  elementfaces[cols*2+0] = 4; elementfaces[cols*2+1] = 1; elementfaces[cols*2+2] = 2; elementfaces[cols*2+3] = 5; elementfaces[cols*2+4] = 4;
151  elementfaces[cols*3+0] = 4; elementfaces[cols*3+1] = 2; elementfaces[cols*3+2] = 0; elementfaces[cols*3+3] = 3; elementfaces[cols*3+4] = 5;
152  elementfaces[cols*4+0] = 4; elementfaces[cols*4+1] = 0; elementfaces[cols*4+2] = 1; elementfaces[cols*4+3] = 4; elementfaces[cols*4+4] = 3;
153  break;
154  case TetraEnum:
155  elementnbv = 4; /*Number of vertices per element*/
156  elementnbf = 4; /*Number of faces per element*/
157  facemaxnbv = 3; /*Maximum number of vertices per face*/
158  cols = facemaxnbv + 1;
159  elementfaces = xNew<int>(elementnbf*cols);
160  elementfaces_markers = xNew<int>(elementnbf);
161  /*4 triangles*/
162  elementfaces_markers[0] = 1;
163  elementfaces_markers[1] = 1;
164  elementfaces_markers[2] = 1;
165  elementfaces_markers[3] = 1;
166  elementfaces[cols*0+0] = 3; elementfaces[cols*0+1] = 0; elementfaces[cols*0+2] = 1; elementfaces[cols*0+3] = 2;
167  elementfaces[cols*1+0] = 3; elementfaces[cols*1+1] = 0; elementfaces[cols*1+2] = 3; elementfaces[cols*1+3] = 1;
168  elementfaces[cols*2+0] = 3; elementfaces[cols*2+1] = 1; elementfaces[cols*2+2] = 3; elementfaces[cols*2+3] = 2;
169  elementfaces[cols*3+0] = 3; elementfaces[cols*3+1] = 0; elementfaces[cols*3+2] = 2; elementfaces[cols*3+3] = 3;
170  break;
171  default:
172  _error_("mesh "<< EnumToStringx(iomodel->meshelementtype) <<" not supported");
173  }
174 
175  /*Allocate connectivity*/
176  int *element_face_connectivity = xNew<int>(iomodel->numberofelements*elementnbf); /*format: [face1 face2 ...] */
177  int *element_vface_connectivity = NULL;
178  if(iomodel->meshelementtype==PentaEnum){
179  element_vface_connectivity = xNew<int>(iomodel->numberofelements*3); /*format: [face1 face2 face3] */
180  }
181 
182  /*Maximum number of faces for initial allocation*/
183  int maxnbf = elementnbf*iomodel->numberofelements;
184  int facescols = 4+facemaxnbv; _assert_(facescols>6);
185 
186  /*Initialize intermediaries*/
187  int* facestemp = xNew<int>(maxnbf*facescols); /*format: [element1 element2 marker nbv vertex1 vertex2 vertex3 ...] */
188  int* vfacestemp = xNew<int>(maxnbf*4);
189  for(i=0;i<maxnbf;i++) facestemp[i*facescols+1]=-1; /*Initialize second column of faces as -1 (boundary face) */
190 
191  /*Initialize chain*/
192  int* head_minv = xNew<int>(iomodel->numberofvertices);
193  int* next_face = xNew<int>(maxnbf);
194  for(i=0;i<iomodel->numberofvertices;i++) head_minv[i]=-1;
195 
196  /*Initialize number of faces and list of vertex indices*/
197  int nbf = 0;
198  int* v = xNew<int>(facemaxnbv);
199  for(i=0;i<iomodel->numberofelements;i++){
200  for(j=0;j<elementnbf;j++){
201 
202  /*Get indices of current face*/
203  facenbv = elementfaces[cols*j+0];
204  for(k=0;k<facenbv;k++){
205  v[k] = iomodel->elements[i*elementnbv + elementfaces[cols*j+k+1]] - 1;
206  }
207 
208  /*Sort list of vertices*/
209  HeapSort(v,elementfaces[cols*j+0]);
210  v0 = v[0]; _assert_(v0>=0 && v0<iomodel->numberofvertices);
211 
212  /*This face a priori has not been processed yet*/
213  bool exist = false;
214 
215  /*Go through all processed faces connected to v0 and check whether we have seen this face yet*/
216  for(int f=head_minv[v0]; f!=-1; f=next_face[f]){
217  if(facestemp[f*facescols+5]==v[1]+1 && facestemp[f*facescols+6]==v[2]+1){
218  exist = true;
219  facestemp[f*facescols+1]=i+1;
220  element_face_connectivity[i*elementnbf+j]=f;
221  break;
222  }
223  }
224 
225  /*If this face is new, add it to the lists*/
226  if(!exist){
227  _assert_(nbf<maxnbf);
228 
229  /*Update faces*/
230  facestemp[nbf*facescols+0] = i+1;
231  facestemp[nbf*facescols+2] = elementfaces_markers[j];
232  facestemp[nbf*facescols+3] = facenbv;
233  for(k=0;k<facenbv;k++) facestemp[nbf*facescols+4+k] = v[k]+1;
234 
235  /*Update Connectivity*/
236  element_face_connectivity[i*elementnbf+j]=nbf;
237 
238  /*Update chain*/
239  next_face[nbf] = head_minv[v0];
240  head_minv[v0] = nbf;
241 
242  /*Increase number of faces*/
243  nbf++;
244  }
245  }
246  }
247 
248  /*Vertical faces*/
249  int nbvf = 0;
250  if(iomodel->meshelementtype==PentaEnum){
251  for(i=0;i<iomodel->numberofvertices;i++) head_minv[i]=-1;
252  for(i=0;i<iomodel->numberofelements;i++){
253  for(j=2;j<5;j++){
254  for(k=0;k<4;k++) v[k] = iomodel->elements[i*elementnbv + elementfaces[cols*j+k+1]] - 1;
255  HeapSort(v,4);
256  v0 = v[0]; _assert_(v0>=0 && v0<iomodel->numberofvertices);
257  bool exist = false;
258  for(int f=head_minv[v0]; f!=-1; f=next_face[f]){
259  if(vfacestemp[f*4+1]==v[1]+1 && vfacestemp[f*4+2]==v[2]+1){
260  exist = true;
261  element_vface_connectivity[i*3+(j-2)]=f;
262  break;
263  }
264  }
265  if(!exist){ _assert_(nbvf<maxnbf);
266  for(k=0;k<4;k++) vfacestemp[nbvf*4+k] = v[k]+1;
267  element_vface_connectivity[i*3+(j-2)]=nbvf;
268  next_face[nbvf] = head_minv[v0];
269  head_minv[v0] = nbvf;
270  nbvf++;
271  }
272  }
273  }
274  }
275 
276  /*Clean up*/
277  xDelete<int>(head_minv);
278  xDelete<int>(next_face);
279  xDelete<int>(v);
280  xDelete<int>(elementfaces);
281  xDelete<int>(elementfaces_markers);
282 
283  /*Create final faces (now that we have the correct size)*/
284  int* faces = xNew<int>(nbf*facescols);
285  xMemCpy<int>(faces,facestemp,nbf*facescols);
286  xDelete<int>(facestemp);
287  int* vfaces = xNew<int>(nbvf*4);
288  xMemCpy<int>(vfaces,vfacestemp,nbvf*4);
289  xDelete<int>(vfacestemp);
290 
291  /*Assign output pointers*/
292  iomodel->faces = faces;
293  iomodel->verticalfaces = vfaces;
294  iomodel->numberoffaces = nbf;
295  iomodel->numberofverticalfaces = nbvf;
296  iomodel->facescols = facescols;
297  iomodel->elementtofaceconnectivity = element_face_connectivity;
298  iomodel->elementtoverticalfaceconnectivity = element_vface_connectivity;
299 }/*}}}*/
_assert_
#define _assert_(ignore)
Definition: exceptions.h:37
IoModel::verticalfaces
int * verticalfaces
Definition: IoModel.h:89
TetraEnum
@ TetraEnum
Definition: EnumDefinitions.h:1300
IoModel::elementtofaceconnectivity
int * elementtofaceconnectivity
Definition: IoModel.h:86
IoModel::numberoffaces
int numberoffaces
Definition: IoModel.h:97
IoModel::numberofvertices
int numberofvertices
Definition: IoModel.h:99
Domain2DhorizontalEnum
@ Domain2DhorizontalEnum
Definition: EnumDefinitions.h:534
IoModel::numberofelements
int numberofelements
Definition: IoModel.h:96
IoModel::facescols
int facescols
Definition: IoModel.h:90
EnumToStringx
const char * EnumToStringx(int enum_in)
Definition: EnumToStringx.cpp:15
CreateFaces3d
void CreateFaces3d(IoModel *iomodel)
Definition: CreateFaces.cpp:124
Domain3DEnum
@ Domain3DEnum
Definition: EnumDefinitions.h:536
_error_
#define _error_(StreamArgs)
Definition: exceptions.h:49
IoModel::faces
int * faces
Definition: IoModel.h:88
IoModel::numberofverticalfaces
int numberofverticalfaces
Definition: IoModel.h:98
PentaEnum
@ PentaEnum
Definition: EnumDefinitions.h:1231
IoModel::elements
int * elements
Definition: IoModel.h:79
IoModel::meshelementtype
int meshelementtype
Definition: IoModel.h:91
IoModel::elementtoverticalfaceconnectivity
int * elementtoverticalfaceconnectivity
Definition: IoModel.h:87
IoModel::domaintype
int domaintype
Definition: IoModel.h:78
Domain2DverticalEnum
@ Domain2DverticalEnum
Definition: EnumDefinitions.h:535
HeapSort
void HeapSort(T *c, long n)
Definition: HeapSort.h:5