NeoPZ
pzcheckrestraint.cpp
Go to the documentation of this file.
1 
6 #include "pzcheckrestraint.h"
7 #include "pzintel.h"
8 #include "pzcmesh.h"
9 #include "pztrnsform.h"
10 #include "pzgeoelside.h"
11 #include "pzquad.h"
12 #include "pzgeoel.h"
13 #include "pzcheckgeom.h"
14 #include "TPZMaterial.h"
15 
16 using namespace std;
17 
19  // Stores the small computational element with commom side
20  fSmall = smalll;
21  // Gets one element in lower level than small
22  fLarge = smalll.LowerLevelElementList(1);
23  // Checking whether element in lower level is neighbour than large element with commom side
24  if (!large.Reference().NeighbourExists(fLarge.Reference())) {
25  cout << "TPZCheckRestraint created for a wrong large element\n";
26  }
27  // Stores large element with commom side
28  fLarge = large;
29 
30  // The small element as interpolate element
31  TPZInterpolatedElement *smallel = dynamic_cast<TPZInterpolatedElement *> (smalll.Element());
32  // Gets the number of shape functions for small element over the commom side
33  int smallsize = smallel->NSideShapeF(fSmall.Side());
34  // Gets the number of connects over the commom side for small element
35  int nsmallconnect = smallel->NSideConnects(fSmall.Side());
36  int smallside = fSmall.Side();
37 
38  // The large element as interpolate element
39  TPZInterpolatedElement *largel = dynamic_cast<TPZInterpolatedElement *> (fLarge.Element());
40  if(!largel) {
41  cout << "TPZCheckRestraint created for an element/side without restraint\n";
42  largel = smallel;
43  fLarge = fSmall;
44  }
45  // Gets the number of shape functions for large element over the commom side
46  int largesize = largel->NSideShapeF(fLarge.Side());
47  // Gets the number of connects over the commom side for large element
48  int nlargeconnect = largel->NSideConnects(fLarge.Side());
49  int largeside = fLarge.Side();
50 
51  // Redimensioning of restraint matrix
52  fRestraint.Redim(smallsize,largesize);
53  fMesh = smallel->Mesh();
54  int nmat = fMesh->MaterialVec().size();
55  int nstate = 1;
56  if(nmat) {
57  std::map<int, TPZMaterial * >::iterator mit = fMesh->MaterialVec().begin();
58  nstate = mit->second->NStateVariables();
59  }
60 
61  fSmallSize.Resize(nsmallconnect);
62  fSmallPos.Resize(nsmallconnect);
63  fSmallConnect.Resize(nsmallconnect);
64  fLargeSize.Resize(nlargeconnect);
65  fLargePos.Resize(nlargeconnect);
66  fLargeConnect.Resize(nlargeconnect);
67  int ic;
68  int nc = nsmallconnect;
69  if(nc) fSmallPos[0] = 0;
70  for(ic=0; ic<nc; ic++) {
71  int connectindex = smallel->SideConnectLocId(ic,smallside);
72  TPZConnect &connect = smallel->Connect(connectindex);
73  fSmallSize[ic] = smallel->NConnectShapeF(connectindex,connect.Order());
74  if(smallel->Connect(connectindex).CheckDependency(fSmallSize[ic], fMesh, nstate) == -1) {
75  cout << "TPZCheckRestraint incompatible small element connect dimensions\n";
76  }
77  if(ic) fSmallPos[ic] = fSmallPos[ic-1] + fSmallSize[ic-1];
78  fSmallConnect[ic] = smallel->SideConnectIndex(ic,smallside);
79  }
80  nc = nlargeconnect;
81  if(nc) fLargePos[0] = 0;
82  for(ic=0; ic<nc; ic++) {
83  int connectindex = largel->SideConnectLocId(ic,largeside);
84  TPZConnect &c = largel->Connect(connectindex);
85  fLargeSize[ic] = largel->NConnectShapeF(connectindex,c.Order());
86  if(largel->Connect(connectindex).CheckDependency(fLargeSize[ic], fMesh, nstate) == -1 ){
87  cout << "TPZCheckRestraint incompatible large element connect dimensions\n";
88  }
89  if(ic) fLargePos[ic] = fLargePos[ic-1] + fLargeSize[ic-1];
90  fLargeConnect[ic] = largel->SideConnectIndex(ic,largeside);
91  }
92  nc = nsmallconnect;
93  for(ic=0; ic<nc; ic++) {
94  AddConnect(fSmallConnect[ic]);
95  }
96 }
97 
98 int TPZCheckRestraint::SmallConnect(int connectid) {
99  int nc = fSmallConnect.NElements();
100  int ic;
101  for(ic=0; ic<nc; ic++) if(fSmallConnect[ic] == connectid) return ic;
102  return -1;
103 }
104 
106  int nc = fLargeConnect.NElements();
107  int ic;
108  for(ic=0; ic<nc; ic++) if(fLargeConnect[ic] == connectid) return ic;
109  return -1;
110 }
111 
112 void TPZCheckRestraint::AddConnect(int connectindex) {
113  int smalll = SmallConnect(connectindex);
114  TPZConnect &smallc = fMesh->ConnectVec()[connectindex];
115  int large = LargeConnect(connectindex);
116 
117  if(large != -1) {
118  if(smalll == -1) {
119  cout << "TPZCheckRestraint::AddConnect data structure error 0\n";
120  return;
121  }
122  int firstl = fSmallPos[smalll];
123  // int lastl = firstl+fSmallSize[small];
124  int firstc = fLargePos[large];
125  int lastc = firstc+fLargeSize[large];
126  int ic,il;
127  for(ic=firstc,il=firstl; ic<lastc; ic++,il++) {
128  fRestraint(il,ic) = 1.;
129  }
130  } else {
131  TPZConnect::TPZDepend *depend = smallc.FirstDepend();
132  if(!depend) {
133  cout << "TPZCheckRestraint::AddConnect data structure error 1\n";
134  }
135  while(depend) {
136  AddDependency(connectindex,depend->fDepConnectIndex,depend->fDepMatrix);
137  depend = depend->fNext;
138  }
139  }
140 }
141 
142 void TPZCheckRestraint::AddDependency(int smallconnectindex, int largeconnectindex, TPZFMatrix<REAL> &dependmatrix) {
143 
144  int smalll = SmallConnect(smallconnectindex);
145  // TPZConnect &smallc = fMesh->ConnectVec()[smallconnectindex];
146  int large = LargeConnect(largeconnectindex);
147  if(large != -1) {
148  int firstl = fSmallPos[smalll];
149  int lastl = firstl+fSmallSize[smalll];
150  int firstc = fLargePos[large];
151  int lastc = firstc+fLargeSize[large];
152  int ic,il;
153  if (firstc != lastc && firstl != lastl && (firstc < 0 || lastc > fRestraint.Cols() || firstl < 0 || lastl > fRestraint.Rows())){
154  cout << "TPZCheckRestraint::AddDependency : indexing error\n";
155  int a;
156  cin >> a;
157  return;
158  }
159  if ((lastc - firstc) != dependmatrix.Cols() || (lastl-firstl) != dependmatrix.Rows()){
160  cout << "TPZCheckRestraint::AddDependency : incompatible dimensions\n";
161  int a;
162  cin >> a;
163  return;
164  }
165  for(il=firstl; il<lastl; il++) {
166  int line = il - firstl;
167  for (ic=firstc; ic<lastc; ic ++){
168  int column = ic - firstc;
169  if (ic < 0 || ic >= fRestraint.Cols() || il < 0 || il >= fRestraint.Rows()){
170  cout << "TPZCheckRestraint::AddDependency : Should never pass here, was already checked 1\n";
171  int a;
172  cin >> a;
173  return;
174  }
175  if (line >= dependmatrix.Rows() || column >= dependmatrix.Cols()){
176  cout << "TPZCheckRestraint::AddDependency : Should never pass here, was already checked 2\n";
177  int a;
178  cin >> a;
179  return;
180  }
181  fRestraint(il,ic) += (REAL)dependmatrix(line,column);
182  }
183  }
184  } else {
185  TPZConnect &largec = fMesh->ConnectVec()[largeconnectindex];
186  TPZConnect::TPZDepend *depend = largec.FirstDepend();
187  if(!depend) {
188  // recado de erro
189  cout << "TPZCheckRestraint::Error:\tLarge connect without dependency\n";
190  cout.flush();
191  return;
192  }
193  while(depend) {
194  // comparar dimensao das matrizes
195  int deprows,depcols;
196  deprows = depend->fDepMatrix.Rows();
197  depcols = dependmatrix.Cols();
198 
199  if (deprows != depcols){
200  cout << "TPZCheckRestraint::Error:\tLarge connect without dependency\n";
201  cout.flush();
202  //return;
203  }
204 
205  TPZFMatrix<REAL> depmat = dependmatrix * depend->fDepMatrix;
206  AddDependency(smallconnectindex,depend->fDepConnectIndex,depmat);
207  depend = depend->fNext;
208  }
209  }
210 }
211 
213 
214  return fRestraint;
215 
216 }
217 
219 
220  TPZInterpolatedElement *smallel = dynamic_cast<TPZInterpolatedElement *> (fSmall.Element());
221  TPZInterpolatedElement *largel = dynamic_cast<TPZInterpolatedElement *> (fLarge.Element());
222  TPZIntPoints *intrule = smallel->Reference()->CreateSideIntegrationRule(fSmall.Side(),2);
223  int dims = smallel->Reference()->SideDimension(fSmall.Side());
224  int diml = largel->Reference()->SideDimension(fLarge.Side());
225  TPZVec<int> ord(dims,5);
226  intrule->SetOrder(ord);
227  TPZGeoElSide smallside = fSmall.Reference();
228  TPZGeoElSide largeside = fLarge.Reference();
229  TPZTransform<> t(smallside.Dimension());
230  smallside.SideTransform3(largeside,t);
231 
232  TPZTransform<> T = smallel->Reference()->ComputeParamTrans(largel->Reference(),fLarge.Side(), fSmall.Side());//transforma��o direta, sem acumulo
233  if(T.CompareTransform(t))//caso erro � maior que tol=1.e-6 retorna 1
234  PZError << "TPZCheckRestraint::CheckRestraint transformation error!\n";
235 
236  int numint = intrule->NPoints();
237  int numshapes = fRestraint.Rows();
238  int numshapel = fRestraint.Cols();
239  TPZFMatrix<REAL> phis(numshapes,1),dphis(dims,numshapes),phil(numshapel,1),dphil(diml,numshapel);
240  TPZFMatrix<REAL> philcheck(numshapel,1);
241  TPZVec<REAL> points(3),pointl(3),point(3);
242  int in,check = 0;
243  REAL weight,error;
244  for(int it=0; it<numint; it++) {
245  intrule->Point(it,points,weight);
246  smallel->SideShapeFunction(fSmall.Side(),points,phis,dphis);
247  t.Apply(points,pointl);
248  largel->SideShapeFunction(fLarge.Side(),pointl,phil,dphil);
249  fRestraint.Multiply(phis,philcheck,1);
250  error = 0.;
251  for(in=0; in<numshapel; in++) {
252  error += (philcheck(in,0)-phil(in,0))*(philcheck(in,0)-phil(in,0));
253  }
254  error = sqrt(error/numshapel);
255  if(error > 1.e-6) {
256  check = 1;
257  cout << "TPZCheckRestraint failed error = " << error << endl;
258  }
259  }
260  delete intrule;
261  return check;
262 }
263 
264 void TPZCheckRestraint::Print(ostream &out){
265 
266  fSmall.Element()->Print(out);
267  out <<"Small side: " <<fSmall.Side() << endl;
268  fLarge.Element()->Print(out);
269  out << "Large side: " <<fLarge.Side() << endl;
270  fRestraint.Print("Restraint Matrix",out);
271 
272  out << "hierarqui of elements ";
273  fSmall.Reference().Element()->Print(out);
274  TPZGeoElSide smallgeo = fSmall.Reference();
275  TPZGeoElSide largegeo = fLarge.Reference();
276  while(smallgeo.Exists() && !smallgeo.NeighbourExists(largegeo))
277  {
278  out << "Small element side = " << smallgeo.Side() << endl;
279  out << "Small geometric element printout \n";
280  smallgeo.Element()->Print();
281  smallgeo = smallgeo.Element()->Father2(smallgeo.Side());
282  }
283  if(!smallgeo.Exists())
284  {
285  out << "TPZCheckRestraint::Print inconsistent datastructure\n";
286  } else {
287  out << "Small element side = " << smallgeo.Side() << endl;
288  out << "Small geometric element printout \n";
289  smallgeo.Element()->Print();
290  }
291  out << "Large element side = " << largegeo.Side() << endl;
292  out << "Large geometric element printout \n";
293  largegeo.Element()->Print();
294 
295  int nsmal = fSmallConnect.NElements();
296  int nlarge = fLargeConnect.NElements();
297  int is, il;
298 
299  out << "fSmallConnect" << endl;
300  for (is=0;is<nsmal;is++){
301  out << "fSmallConnect [ " << is << "] = \t " << fSmallConnect[is] << endl;
302  }
303 
304 
305  out << "fLargeConnect" << endl;
306  for (il=0;il<nlarge;il++){
307  out << "fLargeConnect [ " << il << "] = \t " << fLargeConnect[il] << endl;
308  }
309  out << endl;
310 
311 }
312 
314 
315  TPZCheckGeom chkgeo;
316  chkgeo.CheckSubFatherTransform(fSmall.Element()->Reference(),fSmall.Side());
317  chkgeo.CheckRefinement(fSmall.Element()->Reference()->Father());
318 
319 
320  TPZStack<int> smalldim;
321  fSmall.Reference().Element()->LowerDimensionSides(fSmall.Side(),smalldim);
322  int cap = smalldim.NElements();
323  int s;
324  for(s=0; s<cap; s++) {
325  TPZCompElSide smalll(fSmall.Element(),smalldim[s]);
326  TPZCompElSide largedim = smalll.LowerLevelElementList(1);
327  if(!largedim.Exists()) continue;
328  TPZCheckRestraint diag(smalll,largedim);
329  if(diag.CheckRestraint()) {
330  (cout) << "CheckRestraint failed for :" << endl;
331  } else {
332  (cout) << "CheckRestraint is consistent for : " << endl;
333  }
334  diag.Print(cout);
335  int cind = largedim.Element()->ConnectIndex(largedim.Side());
336  TPZCompElSide largelargedim = largedim.LowerLevelElementList(1);
337  while(largelargedim.Exists() && LargeConnect(cind) == -1) {
338  TPZCheckRestraint diag2(largedim,largelargedim);
339  if(diag2.CheckRestraint()) {
340  (cout) << "CheckRestraint failed for :" << endl;
341  } else {
342  (cout) << "CheckRestraint is consistent for : " << endl;
343  }
344  diag2.Print(cout);
345  largedim = largelargedim;
346  largelargedim = largelargedim.LowerLevelElementList(1);
347  if(largelargedim.Exists()) {
348  cind = largelargedim.Element()->ConnectIndex(largedim.Side());
349  } else {
350  (cout) << "TPZCheckRestraint::Diagnose inconsistent data structure 2\n";
351  }
352  }
353  }
354 }
355 
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
Contains the TPZInt1d, TPZIntTriang, TPZIntQuad, TPZIntCube3D, TPZIntTetra3D, TPZIntPyram3D and TPZIn...
Will verify the consistency of the restraints of shape functions along a side. Computational Element...
virtual int NPoints() const =0
Returns number of points for the cubature rule related.
TPZCompElSide LowerLevelElementList(int onlyinterpolated)
Returns all connected elements which have level lower to the current element.
Definition: pzcompel.cpp:824
Implements computational element and a side. Computational Element.
Definition: pzcompel.h:632
Represents a set of shape functions associated with a computational element/side. Computational Eleme...
Definition: pzconnect.h:30
Contains declaration of TPZGeoElSide class which represents an element and its side, and TPZGeoElSideIndex class which represents an TPZGeoElSide index.
Contains declaration of TPZCheckRestraint class which verify the consistency of the restraints of sha...
void Print(std::ostream &out)
Prints the information into the computational elements and side and geometric information also...
virtual int NConnectShapeF(int icon, int order) const =0
Returns the number of shapefunctions associated with a connect.
TPZCheckRestraint(TPZCompElSide smalll, TPZCompElSide large)
Constructor with small and large element with commom side.
TPZGeoElSide Reference() const
Reference to the geometric element.
Definition: pzcompel.cpp:748
Contains declaration of TPZCheckGeom class which performs a series of consistency tests on geometric ...
void Diagnose()
Get the small element and check restraints with all elements with lower dimension on side correspondi...
Utility class which represents an element with its side. The Geometric approximation classes Geometry...
Definition: pzgeoelside.h:83
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 CheckDependency(int nshape, TPZCompMesh *mesh, int nstate)
Definition: pzconnect.cpp:326
virtual void SideShapeFunction(int side, TPZVec< REAL > &point, TPZFMatrix< REAL > &phi, TPZFMatrix< REAL > &dphi) override=0
Compute the values of the shape function along the side.
Abstract class defining integration rules. Numerical Integration.
Definition: tpzintpoints.h:19
void error(char *string)
Definition: testShape.cc:7
TPZTransform< REAL > ComputeParamTrans(TPZGeoEl *fat, int fatside, int sideson)
Definition: pzgeoel.cpp:845
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...
unsigned char Order() const
Access function to return the order associated with the connect.
Definition: pzconnect.h:217
void AddDependency(int smallconnectid, int largeconnectid, TPZFMatrix< REAL > &depend)
int64_t fDepConnectIndex
Definition: pzconnect.h:69
Structure to reference dependency.
Definition: pzconnect.h:67
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
virtual void SetOrder(TPZVec< int > &ord, int type=0)=0
Sets the order of the cubature rule.
int CheckRestraint()
Gets the shape functions over the sides of the small and large elements and check the matrix restrain...
virtual int SideConnectLocId(int icon, int is) const override=0
Returns the local node number of icon along is.
TPZCompMesh * Mesh() const
Return a pointer to the grid of the element.
Definition: pzcompel.cpp:288
int64_t Rows() const
Returns number of rows.
Definition: pzmatrix.h:803
int CheckSubFatherTransform(TPZGeoEl *subel, int sidesub)
verify if the transformation between sons and father are conforming
expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ sqrt
Definition: tfadfunc.h:120
int Exists() const
Verifies if the object is non null (initialized)
Definition: pzcompel.h:697
TPZDepend * fNext
Definition: pzconnect.h:71
Contains declaration of TPZCompMesh class which is a repository for computational elements...
virtual TPZConnect & Connect(int i) const
Returns a pointer to the ith node.
Definition: pzcompel.cpp:298
int LargeConnect(int connectid)
std::map< int,TPZMaterial *> & MaterialVec()
Returns a reference to the material pointers vector.
Definition: pzcmesh.h:203
virtual int64_t ConnectIndex(int i) const =0
Returns the index of the ith connectivity of the element.
int CheckRefinement(TPZGeoEl *gel)
check the maps between the element and its father
TPZGeoEl * Element() const
Definition: pzgeoelside.h:162
TPZFNMatrix< 50, REAL > fDepMatrix
Definition: pzconnect.h:70
int NSideShapeF(int side) const
Returns the number of shape functions on a side.
Definition: pzintel.cpp:73
TPZCompEl * Element() const
Gives a pointer to the reference computational element.
Definition: pzcompel.h:675
TPZGeoEl * Reference() const
Return a pointer to the corresponding geometric element if such exists, return 0 otherwise.
Definition: pzcompel.cpp:1137
TPZCompElSide Reference() const
Returns a pointer to the elementside referenced by the geometric elementside.
virtual int NSideConnects(int iside) const override=0
Returns the number of dof nodes along side iside.
int Dimension() const
the dimension associated with the element/side
int64_t SideConnectIndex(int icon, int is) const
Returns the index of the c th connect object along side is.
Definition: pzintel.cpp:101
TPZDepend * FirstDepend()
Definition: pzconnect.h:296
int Side() const
Definition: pzgeoelside.h:169
Contains declaration of TPZInterpolatedElement class which implements computational element of the in...
int Exists() const
Definition: pzgeoelside.h:175
int64_t Cols() const
Returns number of cols.
Definition: pzmatrix.h:809
Contains the TPZTransform<> class which implements an affine transformation between points in paramet...
int NeighbourExists(const TPZGeoElSide &neighbour) const
Returns 1 if neighbour is a neighbour of the element along side.
int64_t NElements() const
Returns the number of elements of the vector.
Definition: pzvec.h:190
void AddConnect(int connectindex)
Implements an affine transformation between points in parameter space. Topology Utility.
Definition: pzmganalysis.h:14
virtual void Print(std::ostream &out=std::cout)
Print all relevant data of the element to cout.
Definition: pzgeoel.cpp:238
TPZFMatrix< REAL > & RestraintMatrix()
Returns the restraint matrix.
Implements computational element based on an interpolation space. Computational Element.
Definition: pzintel.h:27
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
int SmallConnect(int connectid)