NeoPZ
pzrefquad.cpp
Go to the documentation of this file.
1 
6 #include "pzrefquad.h"
7 #include "pzgeoquad.h"
8 #include "pzshapequad.h"
9 #include "TPZGeoElement.h"
10 #include "pzgeoel.h"
11 #include "pzgmesh.h"
12 
13 using namespace pzshape;
14 using namespace std;
15 
16 namespace pzrefine {
17 
18  static int nsubeldata[9] = {1,1,1,1,3,3,3,3,9};
19 
20  static int subeldata[9][9][2] =
21  {
22  {{0,0}},/*side=0 {isub0{0,1},isub1{0,1},isub2{0,1},...}*/
23  {{1,1}},/*side=1*/
24  {{2,2}},/*side=2*/
25  {{3,3}},/*side=3*/
26  {{0,1},{0,4},{1,4}},/*side=4*/ // {{0,4},{0,1},{1,4}},/*side=4*/
27  {{1,2},{1,5},{2,5}},/*side=5*/
28  {{2,3},{2,6},{3,6}},/*side=6*/
29  {{3,0},{3,7},{0,7}},/*side=7*/ //{0,2},{0,8},{1,8},{2,8},{3,8},{0,5},{0,6},{2,4},{2,7}}/*side=8*/
30  {{0,2},{0,5},{0,6},{2,4},{2,7},{0,8},{1,8},{2,8},{3,8}}/*side=8*/
31  };
32 
33  static int MidSideNodes[5][2] = {
34  {0,1},//side 4
35  {1,2},//side 5
36  {2,3},//side 6
37  {3,0},//side 7
38  {0,2} //side 8
39  };
40 
41 
42  static REAL MidCoord[5][2] = {
43  {0.,-1.},//side 4
44  {1.,0.}, //side 5
45  {0.,1.}, //side 6
46  {-1.,0.},//side 7
47  {0.,0.} //side 8
48  };
49 
56  const int NumInNeigh = 5;
57  static int InNeigh[4][NumInNeigh][3] = {
58  {{1,1,0},{2,1,3},{3,3,0},{5,1,7},{6,3,4}},
59  {{0,0,1},{2,2,1},{3,2,0},{6,2,4},{7,0,5}},
60  {{0,3,1},{1,1,2},{3,3,2},{4,1,6},{7,3,5}},
61  {{0,0,3},{1,0,2},{2,2,3},{4,0,6},{5,2,7}}
62  };
63 
67  static int CornerSons[4][4] = {
68  {0,4,8,7},
69  {4,1,5,8},
70  {8,5,2,6},
71  {7,8,6,3}
72  };
73 
74  static REAL buildt[4][9][3][2] = {
75  /*S0*/
76  {/*0*/{{0.,0.},{0.,0.},{-1.,-1.}},//por colunas
77  /*1*/{{0.,0.},{0.,0.},{0.,0.}},
78  /*2*/{{0.,0.},{0.,0.},{0.,0.}},
79  /*3*/{{0.,0.},{0.,0.},{0.,0.}},
80  /*4*/{{.5,0.},{0.,0.},{-.5,0.}},
81  /*5*/{{0.,.5},{0.,0.},{0.,-.5}},
82  /*6*/{{-.5,0.},{0.,0.},{-.5,0.}},
83  /*7*/{{.5,0.},{0.,0.},{.5,0.}},
84  /*8*/{{.5,0.},{0.,.5},{-.5,-.5}}},
85  /*S1*/
86  {/*0*/{{0.,0.},{0.,0.},{0.,0.}},
87  /*1*/{{0.,0.},{0.,0.},{1.,-1.}},
88  /*2*/{{0.,0.},{0.,0.},{0.,0.}},
89  /*3*/{{0.,0.},{0.,0.},{0.,0.}},
90  /*4*/{{.5,0.},{0.,0.},{.5,0.}},
91  /*5*/{{.5,0.},{0.,0.},{-.5,0.}},
92  /*6*/{{-.5,0.},{0.,0.},{.5,0.}},
93  /*7*/{{0.,-.5},{0.,0.},{0.,-.5}},
94  /*8*/{{.5,0},{0.,.5},{.5,-.5}}},
95  /*S2*/
96  {/*0*/{{0.,0.},{0.,0.},{0.,0.}},
97  /*1*/{{0.,0.},{0.,0.},{0.,0.}},
98  /*2*/{{0.,0.},{0.,0.},{1.,1.}},
99  /*3*/{{0.,0.},{0.,0.},{0.,0.}},
100  /*4*/{{.5,0.},{0.,0.},{.5,0.}},
101  /*5*/{{.5,0.},{0.,0.},{.5,0.}},
102  /*6*/{{.5,0.},{0.,0.},{-.5,0.}},
103  /*7*/{{0.,-.5},{0.,0.},{0.,.5}},
104  /*8*/{{.5,0.},{0.,.5},{.5,.5}}},
105  /*S3*/
106  {/*0*/{{0.,0.},{0.,0.},{0.,0.}},
107  /*1*/{{0.,0.},{0.,0.},{0.,0.}},
108  /*2*/{{0.,0.},{0.,0.},{0.,0.}},
109  /*3*/{{0.,0.},{0.,0.},{-1.,1.}},
110  /*4*/{{.5,0.},{0.,0.},{-.5,0.}},
111  /*5*/{{0.,.5},{0.,0.},{0.,.5}},
112  /*6*/{{.5,0.},{0.,0.},{.5,0.}},
113  /*7*/{{.5,0.},{0.,0.},{-.5,0.}},
114  /*8*/{{.5,0.},{0.,.5},{-.5,.5}}}
115  };
116 
117  static int fatherside[TPZRefQuad::NSubEl][TPZShapeQuad::NSides] = {
118  /*0*/ {0,4,8,7,4,8,8,7,8},
119  /*1*/ {4,1,5,8,4,5,8,8,8},
120  /*2*/ {8,5,2,6,8,5,6,8,8},
121  /*3*/ {7,8,6,3,8,8,6,7,8}
122  };
123 
124 
125  //Into Divides is necesary to consider the connectivity with the all neighboards
126  void TPZRefQuad::Divide(TPZGeoEl *geo,TPZVec<TPZGeoEl *> &SubElVec) {
127  int i;
128  if(geo->HasSubElement()) {
129  SubElVec.Resize(NSubEl);
130  for(i=0;i<NSubEl;i++) SubElVec[i] = geo->SubElement(i);
131  return;//If exist fSubEl return this sons
132  }
133  int j,sub,matid=geo->MaterialId();
134  int64_t index;
135  int np[TPZShapeQuad::NSides];//guarda conectividades dos 4 subelementos
136 
137  for(j=0;j<TPZShapeQuad::NCornerNodes;j++) np[j] = geo->NodeIndex(j);
138  for(sub=TPZShapeQuad::NCornerNodes;sub<TPZShapeQuad::NSides;sub++) {
139  NewMidSideNode(geo,sub,index);
140  np[sub] = index;
141  }
142  // creating new subelements
143  for(i=0;i<TPZShapeQuad::NCornerNodes;i++) {
144  TPZManVector<int64_t> cornerindexes(TPZShapeQuad::NCornerNodes);
145  for(int j=0;j<TPZShapeQuad::NCornerNodes;j++) cornerindexes[j] = np[CornerSons[i][j]];
146  int64_t index;
147  TPZGeoEl *subel = geo->Mesh()->CreateGeoElement(EQuadrilateral,cornerindexes,matid,index,0);
148  geo->SetSubElement(i , subel);
149  }
150 
151  SubElVec.Resize(NSubEl);
152  for(sub=0;sub<NSubEl;sub++) {
153  SubElVec[sub] = geo->SubElement(sub);
154  SubElVec[sub]->SetFather(geo);
155  SubElVec[sub]->SetFatherIndex(geo->Index());
156  }
157  for(i=0;i<NSubEl;i++) {//conectividades entre os filhos : viz interna
158  for(j=0;j<NumInNeigh;j++) { //lado do subel numero do filho viz. lado do viz.
159  geo->SubElement(i)->SetNeighbour(InNeigh[i][j][0],TPZGeoElSide(geo->SubElement(InNeigh[i][j][1]),InNeigh[i][j][2]));
160  }
161  }
162 
164  }
165 
166  void TPZRefQuad::NewMidSideNode(TPZGeoEl *gel,int side,int64_t &index) {
167 
168  MidSideNodeIndex(gel,side,index);
169  if(index < 0) {
170  TPZGeoElSide gelside = gel->Neighbour(side);
171  if(gelside.Element()) {
172  while(gelside.Element() != gel) {
173  gelside.Element()->MidSideNodeIndex(gelside.Side(),index);
174  if(index!=-1) return;
175  gelside = gelside.Neighbour();
176  }
177  }
178  TPZVec<REAL> par(3,0.);
179  TPZVec<REAL> coord(3,0.);
180  if(side < TPZShapeQuad::NCornerNodes) {
181  index = gel->NodeIndex(side);
182  return;
183  }
184  //aqui side = 8 a 26
185  side-=TPZShapeQuad::NCornerNodes;//0,1,..,18
186  par[0] = MidCoord[side][0];
187  par[1] = MidCoord[side][1];
188  gel->X(par,coord);
189  index = gel->Mesh()->NodeVec().AllocateNewElement();
190  gel->Mesh()->NodeVec()[index].Initialize(coord,*gel->Mesh());
191  }
192  }
193 
194  void TPZRefQuad::MidSideNodeIndex(const TPZGeoEl *gel,int side,int64_t &index) {
195  index = -1;
196  if(side<0 || side>TPZShapeQuad::NSides-1) {
197  PZError << "TPZRefQuad::MidSideNodeIndex. Bad parameter side = " << side << endl;
198  return;
199  }
200  //sides 0 a 3
201  if(side<TPZShapeQuad::NCornerNodes) {//o nó medio do lado 0 é o 0 etc.
202  index = (gel)->NodeIndex(side);
203  return;
204  }
205  //o no medio da face eh o centro e o no medio do centro e o centro
206  //como no de algum filho se este existir
207  //caso tenha filhos eh o canto de algum filho, se nao tiver filhos retorna -1
208  if(gel->HasSubElement()) {
210  index=(gel->SubElement(MidSideNodes[side][0]))->NodeIndex(MidSideNodes[side][1]);
211  }
212  }
213 
214  void TPZRefQuad::GetSubElements(const TPZGeoEl *father,int side, TPZStack<TPZGeoElSide> &subel){
215 
216 // subel.Resize(0);
217  if(side<0 || side>TPZShapeQuad::NSides || !father->HasSubElement()){
218  PZError << "TPZRefQuad::GetSubelements called with error arguments\n";
219  return;
220  }
221  int nsub = NSideSubElements(side);
222  for(int i=0;i<nsub;i++)
223  subel.Push(TPZGeoElSide(father->SubElement(subeldata[side][i][0]),subeldata[side][i][1]));
224  }
225 
226  int TPZRefQuad::NSideSubElements(int side) {
227  if(side<0 || side>TPZShapeQuad::NSides-1){
228  PZError << "TPZRefQuad::NSideSubelements called with error arguments\n";
229  return -1;
230  }
231  return nsubeldata[side];
232  }
233 
234  TPZTransform<> TPZRefQuad::GetTransform(int side,int whichsubel){
235 
236  if(side<0 || side>(TPZShapeQuad::NSides-1)){
237  PZError << "TPZRefQuad::GetTransform side out of range or father null\n";
238  return TPZTransform<>(0,0);
239  }
240  int smalldim = TPZShapeQuad::SideDimension(side);
241  int fatherside = FatherSide(side,whichsubel);
242  int largedim = TPZShapeQuad::SideDimension(fatherside);
243  TPZTransform<> trans(largedim,smalldim);
244  int i,j;
245  for(i=0; i<largedim; i++) {
246  for(j=0; j<smalldim; j++) {
247  trans.Mult()(i,j) = buildt[whichsubel][side][j][i];
248  }
249  trans.Sum() (i,0) = buildt[whichsubel][side][2][i];
250  }
251  return trans;
252  }
253 
254  int TPZRefQuad::FatherSide(int side,int whichsubel){
255 
256  if(side<0 || side>TPZShapeQuad::NSides-1){
257  PZError << "TPZRefQuad::Father2 called error" << endl;
258  return -1;
259  }
260  return fatherside[whichsubel][side];
261  }
262 
263  int TPZRefQuad::ClassId() const{
264  return Hash("TPZRefQuad");
265  }
266 
267 };
static int InNeigh[4][NumInNeigh][3]
Definition: pzrefquad.cpp:57
static int subeldata[9][9][2]
Definition: pzrefquad.cpp:20
int AllocateNewElement()
Makes more room for new elements.
Definition: pzadmchunk.h:184
static int fatherside[TPZRefQuad::NSubEl][TPZShapeQuad::NSides]
Definition: pzrefquad.cpp:117
int MaterialId() const
Returns the material index of the element.
Definition: pzgeoel.h:250
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
virtual void SetNeighbour(int side, const TPZGeoElSide &neighbour)=0
Fill in the data structure for the neighbouring information.
clarg::argInt nsub("-nsub", "number of substructs", 4)
static int nsubeldata[9]
Definition: pzrefquad.cpp:18
groups all classes dedicated to the computation of shape functions
Definition: pzshapeextend.h:16
const TPZFMatrix< T > & Mult() const
Definition: pztrnsform.h:64
Contains the TPZRefQuad class which implements the uniform refinement of a geometric quadrilateral el...
Utility class which represents an element with its side. The Geometric approximation classes Geometry...
Definition: pzgeoelside.h:83
This class implements a simple vector storage scheme for a templated class T. Utility.
Definition: pzgeopoint.h:19
TPZGeoElSide Neighbour() const
Definition: pzgeoel.h:754
TPZGeoMesh * Mesh() const
Returns the mesh to which the element belongs.
Definition: pzgeoel.h:220
virtual int64_t NodeIndex(int i) const =0
Returns the index of the ith node the index is the location of the node in the nodevector of the mesh...
static REAL buildt[4][9][3][2]
Definition: pzrefquad.cpp:74
virtual TPZGeoEl * SubElement(int is) const =0
Returns a pointer to the subelement is.
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
Contains declaration of TPZMesh class which defines a geometrical mesh and contains a corresponding l...
void Push(const T object)
Pushes a copy of the object on the stack.
Definition: pzstack.h:80
Defines the behaviour of all geometric elements. GeometryTPZGeoEl is the common denominator for all g...
Definition: pzgeoel.h:43
int64_t Index() const
Returns the index of the element within the element vector of the mesh.
Definition: pzgeoel.h:730
static int CornerSons[4][4]
Definition: pzrefquad.cpp:67
TPZAdmChunkVector< TPZGeoNode > & NodeVec()
Definition: pzgmesh.h:140
const TPZFMatrix< T > & Sum() const
Definition: pztrnsform.h:66
Groups all classes which model the h refinement These classes are used as template arguments of...
Definition: pzrefpoint.cpp:15
virtual TPZGeoElSide Neighbour(int side)=0
Returns a pointer to the neighbour and the neighbourside along side of the current element...
int32_t Hash(std::string str)
Definition: TPZHash.cpp:10
virtual void SetSubElement(int i, TPZGeoEl *gel)=0
Sets the subelement of index i.
virtual int HasSubElement() const =0
Return 1 if the element has subelements.
TPZGeoEl * Element() const
Definition: pzgeoelside.h:162
static REAL MidCoord[5][2]
Definition: pzrefquad.cpp:42
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 stack object. Utility.
Definition: pzcheckmesh.h:14
int Side() const
Definition: pzgeoelside.h:169
static int SideDimension(int side)
returns the dimension of the side
Implements an affine transformation between points in parameter space. Topology Utility.
Definition: pzmganalysis.h:14
Contains declaration of TPZGeoElement class which implements a generic geometric element with a unifo...
const int NumInNeigh
Definition: pzrefprism.cpp:97
virtual void SetSubElementConnectivities()
Initializes the external connectivities of the subelements.
Definition: pzgeoel.cpp:563
Contains TPZShapeQuad class which implements the shape functions of a quadrilateral element...
#define PZError
Defines the output device to error messages and the DebugStop() function.
Definition: pzerror.h:15
virtual void MidSideNodeIndex(int side, int64_t &index) const =0
Returns the midside node index along a side of the element.
static int MidSideNodes[5][2]
Definition: pzrefquad.cpp:33