NeoPZ
pzcheckgeom.cpp
Go to the documentation of this file.
1 
6 #include <fstream>
7 
8 #include "pzcheckgeom.h"
9 #include "pzquad.h"
10 #include "pztrnsform.h"
11 #include "pzstack.h"
12 #include "pzgeoelside.h"
13 
14 using namespace std;
15 
16 TPZCheckGeom::TPZCheckGeom(TPZGeoMesh *gmesh) : fMesh(gmesh) {
17 }
18 
20 
21  int check = 0;
22  check = check || CheckInternalTransforms(gel);
23  check = check || CheckRefinement(gel);
24  check = check || CheckNeighbourMap(gel);
25  return check;
26 }
27 
30 {
31  int check = 0;
32  int nsides = gel->NSides();
33  int geldim = gel->Dimension();
34  int is;
35  for(is=nsides-1; is>=0; is--) {
36  TPZStack<TPZGeoElSide> highdim;
37  int dim;
38  int sidedim = gel->SideDimension(is);
39  for(dim = sidedim+1; dim<= geldim; dim++) {
40  gel->AllHigherDimensionSides(is,dim,highdim);
41  }
42  int nhighdim = highdim.NElements();
43  int idim;
44  for(idim=0; idim<nhighdim; idim++) {
45  check = (CheckSideTransform(gel,is,highdim[idim].Side()) || check);
46  }
47  }
48  return check;
49 }
50 
53 {
54  int64_t nel = fMesh->NElements();
55  for(int64_t iel = 0; iel<nel; iel++) {
56  TPZGeoEl *gel = fMesh->ElementVec()[iel];
57  if(!gel) continue;
59  gel->Divide(subel);
60  }
61  return PerformCheck();
62 }
63 
64 /*** @brief Check if all node and elements ids are unique */
66 {
67  int64_t numnodes = fMesh->NNodes();
68  int64_t numels = fMesh->NElements();
69 
70  std::set<int64_t> nodeids;
71  std::set<int64_t> elsids;
72 
73  for (int64_t inode = 0; inode < numnodes; inode++) {
74  nodeids.insert(fMesh->NodeVec()[inode].Id());
75  }
76  if (nodeids.size() != numnodes) {
77  std::cout << "The nodes have duplicate ids - EXPECT TROUBLE!\n";
78  return 1;
79  }
80 
81 
82  for (int64_t iel = 0; iel < numels; iel++) {
83  elsids.insert(fMesh->ElementVec()[iel]->Id());
84  }
85  if (elsids.size() != numels) {
86  std::cout << "The elements have duplicate ids - EXPECT TROUBLE!\n";
87  return 1;
88  }
89 
90  return 0;
91 }
92 
94  int64_t nel = fMesh->NElements();
95  int check = 0;
96  for(int64_t iel = 0; iel<nel; iel++) {
97  TPZGeoEl *gel = fMesh->ElementVec()[iel];
98  if(!gel) continue;
99  check = (CheckElement(gel) || check);
100  }
101  check = (CheckIds() || check);
102  return check;
103 }
104 
105 
106 
108 
109  int check = 0;
110  if(!gel || !gel->HasSubElement()) return check;
111  int nsides = gel->NSides();
112  int is;
113  for(is=0; is<nsides; is++) {
115  gel->GetSubElements2(is,subel);
116  int nsub = subel.NElements();
117  int isub;
118  for(isub=0; isub<nsub; isub++) {
119  TPZGeoElSide fath = subel[isub].Father2();
120  int son = subel[isub].Element()->WhichSubel();
121  if(fath.Side() != is) {
122  PZError << "TPZCheckGeom::CheckRefinement non corresponding subelement/sides son "
123  << son << " sonside " << subel[isub].Side() << " fathside " << is <<
124  " fath2side " << fath.Side() << endl;
125  gel->Print();
126  check = 1;
127  }
128  }
129  }
130  int nsub = gel->NSubElements();
131  for(is=0; is<nsub; is++) {
132  TPZGeoEl *sub = gel->SubElement(is);
133  int nsubsides = sub->NSides();
134  int iss;
135  for(iss=0; iss<nsubsides; iss++) {
136  check = (CheckSubFatherTransform(sub,iss) || check);
137  }
138  }
139 
140  return check;
141 }
142 
143 int TPZCheckGeom::CheckSideTransform(TPZGeoEl *gel, int sidefrom, int sideto){
144 
145  int check = 0;
146  int nsides = gel->NSides();
147  TPZIntPoints *integ = gel->CreateSideIntegrationRule(sidefrom,2);
148  TPZTransform<> trans = gel->SideToSideTransform(sidefrom,sideto);
149  TPZTransform<> trans1 = gel->SideToSideTransform(sidefrom,nsides-1);
150  TPZTransform<> trans2 = gel->SideToSideTransform(sideto,nsides-1);
151  int sidefromdim = gel->SideDimension(sidefrom);
152  int sidetodim = gel->SideDimension(sideto);
153  int geldim = gel->Dimension();
154  TPZVec<REAL> intpoint(sidefromdim);
155  TPZVec<REAL> sidetopoint(sidetodim);
156  TPZVec<REAL> elpoint1(geldim),elpoint2(geldim);
157  TPZVec<REAL> x1(3),x2(3);
158  int nintpoints = integ->NPoints();
159  int ip;
160  REAL w;
161  for(ip=0; ip<nintpoints; ip++) {
162  integ->Point(ip,intpoint,w);
163  trans.Apply(intpoint,sidetopoint);
164  trans1.Apply(intpoint,elpoint1);
165  trans2.Apply(sidetopoint,elpoint2);
166  gel->X(elpoint1,x1);
167  gel->X(elpoint2,x2);
168  REAL dif = 0;
169  int nx = x1.NElements();
170  int ix;
171  for(ix=0; ix<nx; ix++) dif += (x1[ix]-x2[ix])*(x1[ix]-x2[ix]);
172  if(dif > 1.e-6) {
173  PZError << "TPZCheckGeom::CheckSideTransform sidefrom = "<< sidefrom
174  << " sideto = " << sideto << " dif = " << dif << endl;
175  gel->Print();
176  check = 1;
177  }
178  }
179  delete integ;
180  return check;
181 }
182 
184  int check = 0;
185  TPZGeoElSide father = subel->Father2(sidesub);
186  if(!father.Exists()) return check;
187  TPZIntPoints *integ = subel->CreateSideIntegrationRule(sidesub,2);
188  int subsidedim = subel->SideDimension(sidesub);
189  int subdim = subel->Dimension();
190  TPZTransform<> trans(subsidedim);
191  trans = subel->BuildTransform2(sidesub,father.Element(),trans);
192  int fathsidedim = father.Dimension();
193  int fathdim = father.Element()->Dimension();
194  int nsubsides = subel->NSides();
195  int nfathsides = father.Element()->NSides();
196  TPZTransform<> trans1 = subel->SideToSideTransform(sidesub,nsubsides-1);
197  TPZTransform<> trans2 = father.Element()->SideToSideTransform(father.Side(),nfathsides-1);
198  TPZVec<REAL> intpoint(subsidedim);
199  TPZVec<REAL> sidetopoint(fathsidedim);
200  TPZVec<REAL> elpoint1(subdim),elpoint2(fathdim);
201  TPZVec<REAL> x1(3),x2(3);
202  int nintpoints = integ->NPoints();
203  int ip;
204  REAL w;
205  for(ip=0; ip<nintpoints; ip++) {
206  integ->Point(ip,intpoint,w);
207  trans.Apply(intpoint,sidetopoint);
208  trans1.Apply(intpoint,elpoint1);
209  trans2.Apply(sidetopoint,elpoint2);
210  subel->X(elpoint1,x1);
211  father.Element()->X(elpoint2,x2);
212  int otherfatherside = father.Element()->WhichSide(elpoint2);
213  if(otherfatherside != father.Side()) {
214  int son = subel->WhichSubel();
215  PZError << "TPZCheckGeom::CheckSubFatherTransform son " << son << " sidesub = "<< sidesub
216  << " fathside = " << father.Side() << " otherfatherside = " << otherfatherside << endl;
217  check=1;
218  }
219  REAL dif = 0;
220  int64_t nx = x1.NElements();
221  int64_t ix;
222  for(ix=0; ix<nx; ix++) dif += (x1[ix]-x2[ix])*(x1[ix]-x2[ix]);
223  if(dif > 1.e-6) {
224  int son = subel->WhichSubel();
225  PZError << "TPZCheckGeom::CheckSubFatherTransform son " << son << " sidesub = "<< sidesub
226  << " fathside = " << father.Side() << " dif = " << dif << endl;
227  // subel->Print();
228  check = 1;
229  TPZTransform<> t = subel->ComputeParamTrans(father.Element(),father.Side(),sidesub);
230  t.PrintInputForm(cout);
231  cout << endl;
232  trans.PrintInputForm(cout);
233  cout << endl;
234  check = 1;
235  }
236 
237  }
238  if(check == 0) {
239  TPZTransform<> t = subel->ComputeParamTrans(father.Element(),father.Side(),sidesub);
240  check = t.CompareTransform(trans);
241  if(check == 1){
242  int son = subel->WhichSubel();
243  PZError << "TPZCheckGeom::CheckSubFatherTransform son " << son << " sidesub = "<< sidesub
244  << " fathside = " << father.Side() << endl;
245  t.PrintInputForm(cout);
246  cout << endl;
247  trans.PrintInputForm(cout);
248  cout << endl;
249  }
250  // compare t with trans
251  }
252 
253  delete integ;
254  return check;
255 
256 }
257 
258 #include "pzshapelinear.h"
259 #include "pzshapecube.h"
260 #include "pzshapepiram.h"
261 #include "pzshapeprism.h"
262 #include "pzshapequad.h"
263 #include "pzshapetetra.h"
264 #include "pzshapetriang.h"
265 
267  TPZCheckGeom local;
268  local.CreateMesh();
269  ofstream meshfile("mesh.txt");
270  local.fMesh->Print(meshfile);
271  local.DivideandCheck();
272  return 1;
273 }
274 
275 static REAL nodeco[12][3] = {
276  {0,0,0},
277  {1,0,0},
278  {2,0,0},
279  {0,1,0},
280  {1,1,0},
281  {2,1,0},
282  {0,0,1},
283  {1,0,1},
284  {2,0,1},
285  {0,1,1},
286  {1,1,1},
287  {2,1,1}
288 };
289 
290 static int nodind[7][8] = {
291  {0,1,4,3,6,7,10,9},
292  {1,4,10,7,2},
293  {8,7,10,2},
294  {2,5,4,8,11,10},
295  {0,1},
296  {0,1,7,6},
297  {1,2,7}
298 };
299 
300 static int numnos[7] = {8,5,4,6,2,4,3};
301 
303 
304  if(fMesh) DebugStop();
305  fMesh = new TPZGeoMesh();
306  int64_t noind[12];
307  int no;
308  for(no=0; no<12; no++) {
309  noind[no] = fMesh->NodeVec().AllocateNewElement();
310  TPZVec<REAL> coord(3);
311  coord[0] = nodeco[no][0];
312  coord[1] = nodeco[no][1];
313  coord[2] = nodeco[no][2];
314  fMesh->NodeVec()[noind[no]].Initialize(coord,*fMesh);
315  }
316  int matid = 1;
317  TPZVec<int64_t> nodeindex;
318  int nel;
319  for(nel=0; nel<7; nel++) {
320  int in;
321  nodeindex.Resize(numnos[nel]);
322  for(in=0; in<numnos[nel]; in++) {
323  nodeindex[in] = nodind[nel][in];
324  }
325  int64_t index;
326  switch(nel) {
327  case 0:
328  fMesh->CreateGeoElement(ECube, nodeindex, matid, index);
329  break;
330  case 1:
331  fMesh->CreateGeoElement(EPiramide, nodeindex,matid, index);
332  break;
333  case 2:
334  fMesh->CreateGeoElement(ETetraedro, nodeindex,matid, index);
335  break;
336  case 3:
337  fMesh->CreateGeoElement(EPrisma, nodeindex,matid, index);
338  break;
339  case 4:
340  fMesh->CreateGeoElement(EOned, nodeindex,matid, index);
341  break;
342  case 5:
343  fMesh->CreateGeoElement(EQuadrilateral, nodeindex,matid, index);
344  break;
345  case 6:
346  fMesh->CreateGeoElement(ETriangle, nodeindex,matid, index);
347  break;
348  default:
349  break;
350  }
351  }
353 }
354 
357 {
358  int check = 0;
359  int nsides = gel->NSides();
360  for (int is=0; is<nsides; is++) {
361  int sidedim = gel->SideDimension(is);
362  if (sidedim == 0) {
363  continue;
364  }
365  int order = 4;
366  TPZIntPoints *integ = gel->CreateSideIntegrationRule(is, order);
367  int npoints = integ->NPoints();
368  REAL w;
369  TPZManVector<REAL,3> X1(3),X2(3);
370  TPZGeoElSide gelside(gel,is);
371  TPZGeoElSide neighbour = gelside.Neighbour();
372  while (neighbour != gelside)
373  {
374  TPZTransform<> tr(sidedim);
375  gelside.SideTransform3(neighbour, tr);
376  TPZManVector<REAL,3> pt1(sidedim),pt2(sidedim);
377  for (int ip = 0; ip < npoints; ip++) {
378  integ->Point(ip, pt1, w);
379  tr.Apply(pt1, pt2);
380  gelside.X(pt1, X1);
381  neighbour.X(pt2, X2);
382  REAL norm = 0;
383  for (int i=0; i<3; i++) {
384  norm += (X1[i]-X2[i])*(X1[i]-X2[i]);
385  }
386  if (norm > 1.e-12) {
387  std::cout << "Incompatible geometry between neighbours pt1 = " << pt1 << " pt2 = " << pt2 << " X1 = " << X1 << " X2 = " << X2 << "\n";
388  gelside.Print(std::cout);
389  neighbour.Print(std::cout);
390  check = 1;
391  }
392  }
393  neighbour = neighbour.Neighbour();
394  }
395  }
396  return check;
397 }
398 
401 {
402  std::set<int64_t> elementid, nodeid;
403  int64_t nnode = fMesh->NNodes();
404  for (int64_t in=0; in<nnode; in++) {
405  int64_t id = fMesh->NodeVec()[in].Id();
406  if (id != -1) {
407  if (nodeid.find(id) == nodeid.end()) {
408  nodeid.insert(id);
409  }
410  else
411  {
412  std::cout << "Node id repetido id = " << id << std::endl;
413  DebugStop();
414  }
415  }
416  }
417  int64_t nelem = fMesh->NElements();
418  for (int64_t el=0; el<nelem; el++) {
419  TPZGeoEl *gel = fMesh->Element(el);
420  if (!gel) {
421  continue;
422  }
423  int64_t id = gel->Id();
424  if (elementid.find(id) != elementid.end()) {
425  std::cout << "Duplicate element id = " << id << std::endl;
426  DebugStop();
427  }
428  else
429  {
430  elementid.insert(id);
431  }
432  }
433 }
434 
436 {
437  for(int D = 0; D < nDiv; D++)
438  {
440  int nels = fMesh->NElements();
441  for(int elem = 0; elem < nels; elem++)
442  {
444  TPZGeoEl * gel = gelvec[elem];
445  if(!gel) continue;
446  if(!gel->HasSubElement()) gel->Divide(filhos);
447  }
448  }
449 }
Contains TPZShapeTetra class which implements the shape functions of a tetrahedral element...
int CheckElement(TPZGeoEl *gel)
Definition: pzcheckgeom.cpp:19
This class performs a series of consistency tests on geometric transformations between elements...
Definition: pzcheckgeom.h:16
virtual TPZGeoElSide Father2(int side) const
Returns the father/side of the father which contains the side of the sub element. ...
Definition: pzgeoel.cpp:376
void CreateMesh()
int AllocateNewElement()
Makes more room for new elements.
Definition: pzadmchunk.h:184
Contains the TPZInt1d, TPZIntTriang, TPZIntQuad, TPZIntCube3D, TPZIntTetra3D, TPZIntPyram3D and TPZIn...
virtual int NPoints() const =0
Returns number of points for the cubature rule related.
Contains declaration of TPZGeoElSide class which represents an element and its side, and TPZGeoElSideIndex class which represents an TPZGeoElSide index.
virtual TPZGeoEl * CreateGeoElement(MElementType type, TPZVec< int64_t > &cornerindexes, int matid, int64_t &index, int reftype=1)
Generic method for creating a geometric element. Putting this method centrally facilitates the modifi...
Definition: pzgmesh.cpp:1296
clarg::argInt nsub("-nsub", "number of substructs", 4)
void CheckUniqueId()
Verify is the ids of the elements and nodes are unique.
virtual TPZTransform< REAL > BuildTransform2(int side, TPZGeoEl *father, TPZTransform< REAL > &t)
Returns the transformation which maps the parameter side of the element/side into the parameter spac...
Definition: pzgeoel.cpp:386
Contains declaration of TPZCheckGeom class which performs a series of consistency tests on geometric ...
int64_t NElements() const
Number of elements of the mesh.
Definition: pzgmesh.h:129
int DivideandCheck()
divide all elements and call PerformCheck
Definition: pzcheckgeom.cpp:52
Utility class which represents an element with its side. The Geometric approximation classes Geometry...
Definition: pzgeoelside.h:83
Implements a chunk vector with free store administration. Utility.
Definition: TPZStream.h:39
TPZGeoElSide Neighbour() const
Definition: pzgeoel.h:754
static int main()
virtual int NSides() const =0
Returns the number of connectivities of the element.
virtual void Divide(TPZVec< TPZGeoEl *> &pv)
Divides the element and puts the resulting elements in the vector.
Definition: pzgeoel.h:742
virtual int SideDimension(int side) const =0
Return the dimension of side.
void SideTransform3(TPZGeoElSide neighbour, TPZTransform<> &t)
Accumulates the transformations from the current element/side to the neighbour/side.
int WhichSide(TPZVec< int64_t > &SideNodeIds)
Returns the side number which is connected to the SideNodes returns -1 if no side is found...
Definition: pzgeoel.cpp:165
Contains TPZShapeLinear class which implements the shape functions of a linear one-dimensional elemen...
void UniformRefine(int nDiv)
Uniform refine the geometric mesh.
int CheckSideTransform(TPZGeoEl *gel, int sidefrom, int sideto)
int CheckInternalTransforms(TPZGeoEl *)
check the internal side transformations
Definition: pzcheckgeom.cpp:29
Abstract class defining integration rules. Numerical Integration.
Definition: tpzintpoints.h:19
TPZTransform< REAL > ComputeParamTrans(TPZGeoEl *fat, int fatside, int sideson)
Definition: pzgeoel.cpp:845
Contains TPZShapeCube class which implements the shape functions of a hexaedral element.
virtual TPZGeoEl * SubElement(int is) const =0
Returns a pointer to the subelement is.
virtual TPZIntPoints * CreateSideIntegrationRule(int side, int order)=0
Creates an integration rule for the topology of the corresponding side and able to integrate a polyno...
int CheckNeighbourMap(TPZGeoEl *gel)
verify if the mapping between neighbouring elements is conforming
virtual void Resize(const int64_t newsize, const T &object)
Resizes the vector object reallocating the necessary storage, copying the existing objects to the new...
Definition: pzvec.h:373
virtual void Print(std::ostream &out=std::cout) const
Print the information of the grid to an ostream.
Definition: pzgmesh.cpp:130
int CompareTransform(TPZTransform< T > &t, REAL tol=1.e-6)
Compare the current transformation with t transformation considering a given tolerance.
Definition: pztrnsform.cpp:163
int WhichSubel() const
Returns the son number of the sub element gel.
Definition: pzgeoel.cpp:448
Defines the behaviour of all geometric elements. GeometryTPZGeoEl is the common denominator for all g...
Definition: pzgeoel.h:43
TPZGeoEl * Element(int64_t iel)
Definition: pzgmesh.h:139
#define DebugStop()
Returns a message to user put a breakpoint in.
Definition: pzerror.h:20
int64_t NNodes() const
Number of nodes of the mesh.
Definition: pzgmesh.h:126
void X(TPZVec< REAL > &loc, TPZVec< REAL > &result) const
X coordinate of a point loc of the side.
int PerformCheck()
verify compatibility between elements and their father and between elements and their neighbours ...
Definition: pzcheckgeom.cpp:93
virtual void GetSubElements2(int side, TPZStack< TPZGeoElSide > &subel) const
This method will return a partition of the side of the current element as the union of sub elements/...
Definition: pzgeoel.cpp:392
TPZAdmChunkVector< TPZGeoNode > & NodeVec()
Definition: pzgmesh.h:140
int CheckSubFatherTransform(TPZGeoEl *subel, int sidesub)
verify if the transformation between sons and father are conforming
static REAL nodeco[12][3]
TPZGeoMesh * fMesh
Definition: pzcheckgeom.h:18
void PrintInputForm(std::ostream &out)
Definition: pztrnsform.cpp:140
A simple stack.
virtual int HasSubElement() const =0
Return 1 if the element has subelements.
Contains TPZShapePrism class which implements the shape functions of a prism element.
int CheckRefinement(TPZGeoEl *gel)
check the maps between the element and its father
TPZGeoEl * Element() const
Definition: pzgeoelside.h:162
TPZCheckGeom(TPZGeoMesh *gmesh=NULL)
Definition: pzcheckgeom.cpp:16
void BuildConnectivity()
Build the connectivity of the grid.
Definition: pzgmesh.cpp:967
virtual int Dimension() const =0
Returns the dimension of the element.
virtual TPZTransform< REAL > SideToSideTransform(int sidefrom, int sideto)=0
Compute the transformation between the master element space of one side of an element to the master e...
virtual void AllHigherDimensionSides(int side, int targetdimension, TPZStack< TPZGeoElSide > &elsides)=0
int64_t Id() const
Returns the Id of the element.
Definition: pzgeoel.h:223
virtual void X(TPZVec< REAL > &qsi, TPZVec< REAL > &result) const =0
Return the coordinate in real space of the point coordinate in the master element space...
This class implements a geometric mesh for the pz environment. Geometry.
Definition: pzgmesh.h:48
static int numnos[7]
This class implements a stack object. Utility.
Definition: pzcheckmesh.h:14
int Dimension() const
the dimension associated with the element/side
void Print(std::ostream &out) const
print geometric characteristics of the element/side
Definition: pzeltype.h:61
int Side() const
Definition: pzgeoelside.h:169
int Exists() const
Definition: pzgeoelside.h:175
Contains TPZShapePiram class which implements the shape functions of a pyramid element.
Contains the TPZTransform<> class which implements an affine transformation between points in paramet...
int64_t NElements() const
Returns the number of elements of the vector.
Definition: pzvec.h:190
Implements an affine transformation between points in parameter space. Topology Utility.
Definition: pzmganalysis.h:14
Definition: pzeltype.h:55
virtual void Print(std::ostream &out=std::cout)
Print all relevant data of the element to cout.
Definition: pzgeoel.cpp:238
virtual int NSubElements() const =0
Returns the number of subelements of the element independent of the fact whether the element has alr...
static int nodind[7][8]
Contains TPZShapeQuad class which implements the shape functions of a quadrilateral element...
Contains TPZShapeTriang class which implements the shape functions of a triangular element...
void Apply(TPZVec< T > &vectorin, TPZVec< T > &vectorout)
Transforms the vector.
Definition: pztrnsform.cpp:121
virtual void Point(int i, TPZVec< REAL > &pos, REAL &w) const =0
Returns i-th point at master element and related weight.
#define PZError
Defines the output device to error messages and the DebugStop() function.
Definition: pzerror.h:15
TPZAdmChunkVector< TPZGeoEl * > & ElementVec()
Methods for handling pzlists.
Definition: pzgmesh.h:138