NeoPZ
pzreftriangle.cpp
Go to the documentation of this file.
1 
6 #include "pzreftriangle.h"
7 #include "pzgeotriangle.h"
8 #include "pzshapetriang.h"
9 #include "TPZGeoElement.h"
10 #include "pzgeoelside.h"
11 #include "pzgeoel.h"
12 #include "pzgmesh.h"
13 
14 using namespace pzshape;
15 using namespace std;
16 
17 namespace pzrefine {
18 
19  static int nsubeldata[7] = {1,1,1,3,3,3,7};
20 
21  static int subeldata[7][7][2] = {
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  // {{0,3},{0,1},{1,3}},/*side=3*/
26  {{0,1},{0,3},{1,3}},/*side=3*/
27  // {{1,4},{1,2},{2,4}},/*side=4*/
28  {{1,2},{1,4},{2,4}},/*side=4*/
29  // {{2,5},{2,0},{0,5}},/*side=5*/
30  {{2,0},{2,5},{0,5}},/*side=5*/
31  //{{0,6},{1,6},{2,6},{3,6},{2,3},{0,4},{1,5}}/*side=6*/
32  {{2,3},{0,4},{1,5},{0,6},{1,6},{2,6},{3,6}}/*side=6*/
33  };
34 
35  static int MidSideNodes[3][2] = {
36  {0,1},
37  {1,2},
38  {2,0}
39  };
40 
41  static REAL MidCoord[3][2] = {
42  {0.5,0.}, //side 3
43  {0.5,0.5}, //side 4
44  {0.,0.5} //side 5
45  };
46 
52  const int NumInNeigh = 6;
53  static int InNeigh[4][NumInNeigh][3] = {
54  {{1,1,0},{2,3,1},{4,3,4},{-1},{-1},{-1}},
55  {{0,3,2},{2,2,1},{5,3,5},{-1},{-1},{-1}},
56  {{0,0,2},{1,3,0},{3,3,3},{-1},{-1},{-1}},
57  {{0,1,2},{1,2,0},{2,0,1},{3,2,3},{4,0,4},{5,1,5}}
58  };
59 
63  static int CornerSons[4][3] = {
64  {0,3,5},
65  {3,1,4},
66  {5,4,2},
67  {4,5,3}
68  };
69 
70  static REAL buildt[4][7][3][2] = {//por colunas
71  /*S0*/ {
72  /*0*/{{0.,0.},{0.,0.},{0.,0.}},
73  /*1*/{{0.,0.},{0.,0.},{0.,0.}},
74  /*2*/{{0.,0.},{0.,0.},{0.,0.}},
75  /*3*/{{.5,0.},{0.,0.},{-.5,0.}},
76  /*4*/{{-.25,.25},{0.,0.},{.25,.25}},
77  /*5*/{{.5,0.},{0.,0.},{.5,0.}},
78  /*6*/{{.5,0.},{0.,.5},{0.,0.}}},
79  /*S1*/ {
80  /*0*/{{0.,0.},{0.,0.},{0.,0.}},
81  /*1*/{{0.,0.},{0.,0.},{0.,1.}},
82  /*2*/{{0.,0.},{0.,0.},{0.,0.}},
83  /*3*/{{.5,0.},{0.,0.},{.5,0.}},
84  /*4*/{{.5,0.},{0.,0.},{-.5,0.}},
85  /*5*/{{0.,-.25},{0.,0.},{.5,.25}},
86  /*6*/{{.5,0.},{0.,.5},{.5,0.}}},
87  /*S2*/ {
88  /*0*/{{0.,0.},{0.,0.},{0.,0.}},
89  /*1*/{{0.,0.},{0.,0.},{0.,0.}},
90  /*2*/{{0.,0.},{0.,0.},{0.,1.}},
91  /*3*/{{.25,0.},{0.,0.},{.25,.5}},
92  /*4*/{{.5,0.},{0.,0.},{.5,0.}},
93  /*5*/{{.5,0.},{0.,0.},{-.5,0.}},
94  /*6*/{{.5,0.},{0.,.5},{0.,.5}}},
95  /*S3*/ {
96  /*0*/{{0.,0.},{0.,0.},{0.,0.}},
97  /*1*/{{0.,0.},{0.,0.},{0.,0.}},
98  /*2*/{{0.,0.},{0.,0.},{0.,0.}},
99  /*3*/{{-.25,0.},{0.,0.},{.25,.5}},
100  /*4*/{{.25,-.25},{0.,0.},{.25,.25}},
101  /*5*/{{0.,.25},{0.,0.},{.5,.25}},
102  /*6*/{{-.5,0.},{0.,-.5},{.5,.5}}}
103  };
104 
105  static int fatherside[TPZRefTriangle::NSubEl][TPZShapeTriang::NSides] = {
106  /*0*/ {0,3,5,3,6,5,6},
107  /*1*/ {3,1,4,3,4,6,6},
108  /*2*/ {5,4,2,6,4,5,6},
109  /*3*/ {4,5,3,6,6,6,6}
110  };
111 
112  //Into Divides is necesary to consider the connectivity with the all neighboards
113  void TPZRefTriangle::Divide(TPZGeoEl *geo,TPZVec<TPZGeoEl *> &SubElVec) {
114  int i;
115  if(geo->HasSubElement()) {
116  SubElVec.Resize(NSubEl);
117  for(i=0;i<NSubEl;i++) SubElVec[i] = geo->SubElement(i);
118  return;//If exist fSubEl return this sons
119  }
120  int j,sub,matid=geo->MaterialId();
121  int64_t index;
122  int np[TPZShapeTriang::NSides];//guarda conectividades dos 4 subelementos
123 
124  for(j=0;j<TPZShapeTriang::NCornerNodes;j++) np[j] = geo->NodeIndex(j);
125  for(sub=TPZShapeTriang::NCornerNodes;sub<TPZShapeTriang::NSides-1;sub++) {
126  NewMidSideNode(geo,sub,index);
127  np[sub] = index;
128  }
129  // creating new subelements
130  for(i=0;i<NSubEl;i++) {
131  TPZManVector<int64_t> cornerindexes(TPZShapeTriang::NCornerNodes);
132  for(int j=0;j<TPZShapeTriang::NCornerNodes;j++) cornerindexes[j] = np[CornerSons[i][j]];
133  int64_t index;
134  TPZGeoEl *subel = geo->CreateGeoElement(ETriangle,cornerindexes,matid,index);
135  geo->SetSubElement(i ,subel);
136  }
137 
138  SubElVec.Resize(NSubEl);
139  for(sub=0;sub<NSubEl;sub++) {
140  SubElVec[sub] = geo->SubElement(sub);
141  SubElVec[sub]->SetFather(geo);
142  SubElVec[sub]->SetFatherIndex(geo->Index());
143  }
144  for(i=0;i<NSubEl;i++) {//conectividades entre os filhos : viz interna
145  for(j=0;j<NumInNeigh;j++) { //lado do subel numero do filho viz. lado do viz.
146  if(InNeigh[i][j][0]<0) continue;
147  geo->SubElement(i)->SetNeighbour(InNeigh[i][j][0],TPZGeoElSide(geo->SubElement(InNeigh[i][j][1]),InNeigh[i][j][2]));
148  }
149  }
151  }
152 
153  void TPZRefTriangle::NewMidSideNode(TPZGeoEl *gel,int side,int64_t &index) {
154 
155  MidSideNodeIndex(gel,side,index);
156  if(index < 0) {
157  TPZGeoElSide gelside = gel->Neighbour(side);
158  if(gelside.Element()) {
159  while(gelside.Element() != gel) {
160  gelside.Element()->MidSideNodeIndex(gelside.Side(),index);
161  if(index!=-1) return;
162  gelside = gelside.Neighbour();
163  }
164  }
165  TPZVec<REAL> par(3,0.);
166  TPZVec<REAL> coord(3,0.);
167  if(side < TPZShapeTriang::NCornerNodes) {
168  index = gel->NodeIndex(side);
169  return;
170  }
171  //aqui side = 8 a 26
172  side-=TPZShapeTriang::NCornerNodes;//0,1,..,18
173  par[0] = MidCoord[side][0];
174  par[1] = MidCoord[side][1];
175  gel->X(par,coord);
176  index = gel->Mesh()->NodeVec().AllocateNewElement();
177  gel->Mesh()->NodeVec()[index].Initialize(coord,*gel->Mesh());
178  }
179  }
180 
181  void TPZRefTriangle::MidSideNodeIndex(const TPZGeoEl *gel,int side,int64_t &index) {
182  index = -1;
183  if(side<0 || side>TPZShapeTriang::NSides-1) {
184  PZError << "TPZRefTriangle::MidSideNodeIndex. Bad parameter side = " << side << endl;
185  return;
186  }
187  //sides 0 a 3
188  if(side<TPZShapeTriang::NCornerNodes) {//o n� medio do lado 0 � o 0 etc.
189  index = (gel)->NodeIndex(side);
190  return;
191  }
192  //o n� medio da face � o centro e o n� medio do centro � o centro
193  //como n� de algum filho se este existir
194  //caso tenha filhos � o canto de algum filho, se n�o tiver filhos retorna -1
195  if(gel->HasSubElement()) {
197  index=(gel->SubElement(MidSideNodes[side][0]))->NodeIndex(MidSideNodes[side][1]);
198  }
199  }
200 
201  void TPZRefTriangle::GetSubElements(const TPZGeoEl *father,int side, TPZStack<TPZGeoElSide> &subel){
202 // subel.Resize(0);
203  if(side<0 || side>TPZShapeTriang::NSides || !father->HasSubElement()){
204  PZError << "TPZRefTriangle::GetSubelements2 called with error arguments\n";
205  return;
206  }
207  int nsub = NSideSubElements(side);//nsubeldata[side];
208  for(int i=0;i<nsub;i++)
209  subel.Push(TPZGeoElSide(father->SubElement(subeldata[side][i][0]),subeldata[side][i][1]));
210  }
211 
212  int TPZRefTriangle::NSideSubElements(int side) {
213  if(side<0 || side>TPZShapeTriang::NSides-1){
214  PZError << "TPZRefTriangle::NSideSubelements2 called with error arguments\n";
215  return -1;
216  }
217  return nsubeldata[side];
218  }
219 
220  TPZTransform<> TPZRefTriangle::GetTransform(int side,int whichsubel){
221  if(side<0 || side>(TPZShapeTriang::NSides-1)){
222  PZError << "TPZRefTriangle::GetTransform side out of range or father null\n";
223  return TPZTransform<>(0,0);
224  }
225  int smalldim = TPZShapeTriang::SideDimension(side);
226  int fatherside = FatherSide(side,whichsubel);
227  int largedim = TPZShapeTriang::SideDimension(fatherside);
228  TPZTransform<> trans(largedim,smalldim);
229  int i,j;
230  for(i=0; i<largedim; i++) {
231  for(j=0; j<smalldim; j++) {
232  trans.Mult()(i,j) = buildt[whichsubel][side][j][i];
233  }
234  trans.Sum() (i,0) = buildt[whichsubel][side][2][i];
235  }
236  return trans;
237  }
238 
239  int TPZRefTriangle::FatherSide(int side,int whichsubel){
240  if(side<0 || side>TPZShapeTriang::NSides-1){
241  PZError << "TPZRefTriangle::Father2 called error" << endl;
242  return -1;
243  }
244  return fatherside[whichsubel][side];
245  }
246 
247  int TPZRefTriangle::ClassId() const{
248  return Hash("TPZRefTriangle");
249  }
250 };
static int InNeigh[4][NumInNeigh][3]
int AllocateNewElement()
Makes more room for new elements.
Definition: pzadmchunk.h:184
Contains declaration of TPZGeoElSide class which represents an element and its side, and TPZGeoElSideIndex class which represents an TPZGeoElSide index.
int MaterialId() const
Returns the material index of the element.
Definition: pzgeoel.h:250
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 CornerSons[4][3]
groups all classes dedicated to the computation of shape functions
Definition: pzshapeextend.h:16
const TPZFMatrix< T > & Mult() const
Definition: pztrnsform.h:64
static REAL buildt[4][7][3][2]
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 int fatherside[TPZRefTriangle::NSubEl][TPZShapeTriang::NSides]
virtual TPZGeoEl * SubElement(int is) const =0
Returns a pointer to the subelement is.
static REAL MidCoord[3][2]
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 SideDimension(int side)
Returns the dimension of the side.
TPZAdmChunkVector< TPZGeoNode > & NodeVec()
Definition: pzgmesh.h:140
static int subeldata[7][7][2]
const TPZFMatrix< T > & Sum() const
Definition: pztrnsform.h:66
virtual TPZGeoEl * CreateGeoElement(MElementType type, TPZVec< int64_t > &nodeindexes, int matid, int64_t &index)=0
Creates a geometric element according to the type of the father element.
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
Contains the TPZRefTriangle class which implements the uniform refinement of a geometric triangular e...
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
static int nsubeldata[7]
static int MidSideNodes[3][2]
int Side() const
Definition: pzgeoelside.h:169
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 TPZShapeTriang class which implements the shape functions of a triangular 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.