NeoPZ
TPZRefPattern.cpp
Go to the documentation of this file.
1 // /**
2 // * @file
3 // * @brief Contains the implementation of the TPZRefPattern methods.
4 // */
5 // /* Generated by Together */
6 
7 #include "TPZRefPattern.h"
8 #include "TPZRefPatternTools.h"
10 #include "TPZVTKGeoMesh.h"
11 // #include "pztrnsform.h"
12 // #include "pzreal.h"
13 // #include "pzgmesh.h"
14 // #include "pzquad.h"
15 // #include "pzvec.h"
16 // #include "pzeltype.h"
17 // #include "tpzpermutation.h"
18 // #include "pzgeoel.h"
19 // #include "pzlog.h"
20 
21 // #include <set>
22 
23 // #include <fstream>
24 // #include <sstream>
25 
26 //iniatilizing static variables
28 const int TPZRefPattern::fNonInitializedId = -50;
30 const std::string TPZRefPattern::fNonInitializedName = "noname";
32 std::map<MElementType, std::list<TPZRefPattern::TPZRefPatternPermute> > TPZRefPattern::fPermutations;
33 
34  #ifdef LOG4CXX
35  static LoggerPtr logger(Logger::getLogger("pz.mesh.TPZRefPattern"));
36  #endif
37 
38 
39 TPZRefPattern::TPZRefPattern() : fId(fNonInitializedId), fName(fNonInitializedName),
40 fSideRefPattern(0), fPermutedRefPatterns(0), fNSubEl(0){
41 
42 }
43 
47  fName = cp.fName;
48  fId = cp.fId;
52  fNSubEl = cp.fNSubEl;
53 }
54 
57 {
58  fNSubEl = copy.fNSubEl;
59  this->PermuteMesh(permute);
60 
62 
66 }
67 
69  fRefPatternMesh = gmesh;
71 }
72 
74 {
76 }
77 
78 TPZRefPattern::TPZRefPattern(const std::string &file ) : fSideRefPattern(0), fId(fNonInitializedId), fName("noname")
79 {
80  std::ifstream input(file.c_str());
82 
83  /*
84  BuildName();
85  ofstream output(file.c_str());
86  ExportPattern(output);
87  */
88 }
89 
91 {
93  {
94  return 0;
95  }
96  TPZGeoEl *father = fRefPatternMesh.ElementVec()[0];
97  TPZGeoEl *compfather = compare->fRefPatternMesh.ElementVec()[0];
98  if(father->Type() != compfather->Type())
99  {
100  return 0;
101  }
102 
103  int nnodes = fRefPatternMesh.NNodes();
104  int dim = father->Dimension();
105  std::map<int,int> nodemap;
106  //check coords
107  REAL Tol;
108  ZeroTolerance(Tol);
109  int in;
110  for(in = 0; in < nnodes; in++){
111  TPZManVector<REAL,3> coord(3,0.), coordcompare(3,0.);
112  TPZManVector<REAL,3> elparam(dim,0.), compareparam(dim,0.);
113 
114  for(int i = 0; i < 3; i++){
115  coord[i] = fRefPatternMesh.NodeVec()[in].Coord(i);
116  }
117 
118  TPZManVector<REAL> diff(nnodes,0.);
119  int jn;
120  for(jn = 0; jn < nnodes; jn++){
121  int j;
122  for(j = 0; j < 3; j++){
123  coordcompare[j] = compare->fRefPatternMesh.NodeVec()[jn].Coord(j);
124  }
125 
126  for(j=0 ; j<dim; j++){
127  diff[jn] += (coord[j]-coordcompare[j])*(coord[j]-coordcompare[j]);
128  }
129 
130  diff[jn] = sqrt(diff[jn]);
131  if(diff[jn] < ZeroTolerance()){
132  nodemap[in] = jn;
133  break;
134  }
135  }
136 
137  if(jn == nnodes)
138  {
139  return 0;
140  }
141  }
142 
143  int nelem = fRefPatternMesh.NElements();
144  std::map<int,int> elementmap;
145 
146  int iel;
147  for(iel = 0; iel < nelem; iel++)
148  {
149  std::set<int> nodeset;
150  TPZGeoEl *igel = fRefPatternMesh.ElementVec()[iel];
151  int nnode = igel->NNodes();
152 
153  int in;
154  for(in = 0; in < nnode; in++)
155  {
156  nodeset.insert(nodemap[igel->NodeIndex(in)]);
157  }
158 
159  int jel;
160  for(jel = 0; jel < nelem; jel++)
161  {
162  if(elementmap.find(jel) != elementmap.end())
163  {
164  continue;
165  }
166  std::set<int> compnodeset;
167  TPZGeoEl *jgel = compare->fRefPatternMesh.ElementVec()[jel];
168  int jnnode = jgel->NNodes();
169 
170  int jn;
171  if(jnnode != nnode)
172  {
173  continue;
174  }
175 
176  for(jn = 0; jn < jnnode; jn++)
177  {
178  compnodeset.insert(jgel->NodeIndex(jn));
179  }
180 
181  if(nodeset == compnodeset)
182  {
183  elementmap[jel] = iel;
184  break;
185  }
186  }
187 
188  if(jel == nelem)
189  {
190  return 0;
191  }
192  }
193 
194  return 1;
195 }
196 
197 
198  void TPZRefPattern::Print(std::ostream &out) const
199  {
200  out << "TPZRefPattern::PrintMore\n\n";
201  int iSide,iSubEl;
202  out << "Refinement Pattern named " << fName << std::endl;
203 
204  out<<"SUB-ELEMENT INFO"<<std::endl;
205  int nSubs = fSubElSideInfo.size();
206  for(iSubEl=0;iSubEl<nSubs;iSubEl++){
207  out<<"sub-el: "<<iSubEl<<std::endl;
208  int nSides = fSubElSideInfo[iSubEl].size();
209  for(iSide=0;iSide<nSides;iSide++){
210  out<<"\tside: "<<iSide<<std::endl;
211  out<<"\tfather side: "<<fSubElSideInfo[iSubEl][iSide].first<<std::endl;
212  auto transform = fSubElSideInfo[iSubEl][iSide].second;
213  out << "\tsub/side = " << iSubEl + 1 << "/" << iSide << " FatherSide = " << fSubElSideInfo[iSubEl][iSide].first << std::endl;
214  out << "\tTransform = " << std::endl;
215  transform.Mult().Print("Transformation T: ", out);
216  transform.Sum().Print("Translation b: ", out);
217  }
218  }
219 
220  out<<"FATHER SIDES INFO"<<std::endl;
221  int nSidesFather = fRefPatternMesh.ElementVec()[0]->NSides();
222  for(iSide=0;iSide<nSidesFather;iSide++){
223  out<<"side :"<<iSide<<std::endl;
224  SPZFatherSideInfo &fatherInfo = fFatherSideInfo[iSide];
225 
226  out<<"\tInternal nodes:"<<std::endl;
227  int nNodes = fatherInfo.fSideNodes.size();
228  for(int iNode = 0; iNode < nNodes; iNode++){
229  out<<"\t\tnode "<<iNode<<" index: "<<fatherInfo.fSideNodes[iNode]<<std::endl;
230  }
231 
232  out<<"\tSubGeoElSides:"<<std::endl;
233  int nSideSons = fatherInfo.fSideSons.size();
234  for(int iGeoElSide = 0; iGeoElSide < nSideSons; iGeoElSide++){
235  out<<"\t\telement: "<<FindSubEl(fatherInfo.fSideSons[iGeoElSide].Element()) + 1;
236  out<<" side: "<< fatherInfo.fSideSons[iGeoElSide].Side()<<std::endl;
237  }
238  }
239  }
240 
241 void TPZRefPattern::PrintMore(std::ostream &out) const{
242  Print(out);
244 }
245 
246 void TPZRefPattern::ShortPrint(std::ostream &out) const
247 {
248  TPZGeoEl *fatherEl = fRefPatternMesh.ElementVec()[0];
249  int nsides = fatherEl->NSides();
250  TPZVec<int> indices;
251  //TPZVec<int> selected(nsides,0);
252  out << fatherEl->TypeName();
253  out << " Id " << fId << " Sides " ;
254  for (int p=0 ; p<nsides; p++){
255  if (fatherEl->SideDimension(p)==1 && NSideNodes(p))
256  {
257  out << p << " ";
258  }
259  }
260 
261  for(int n = 0; n < fRefPatternMesh.NodeVec().NElements(); n++)
262  {
263  out << " | ";
264  for(int c = 0; c < 3; c++)
265  {
266  out << fRefPatternMesh.NodeVec()[n].Coord(c) << " ";
267  }
268  out << " | ";
269  }
270 }
271 
272 void TPZRefPattern::PrintVTK(std::ofstream &file, bool matColor) const
273 {
274  // TPZGeoMesh * gmesh = &(RefPatternMesh());
275  // TPZRefPatternTools::PrintGMeshVTK(gmesh, file, matColor);
276 
277  TPZGeoMesh const & rGmesh = fRefPatternMesh;
278  TPZGeoMesh * gmesh = new TPZGeoMesh;
279 
280  int64_t nNodes = rGmesh.NNodes();
281  int64_t nElements = rGmesh.NElements();
282 
283  TPZVec < TPZVec <REAL> > NodeCoord(nNodes);
284  for(int64_t i = 0; i < nNodes; i++) NodeCoord[i].Resize(3,0.);
285 
286  //setting nodes coords
287  for(int64_t n = 0; n < nNodes; n++)
288  {
289  NodeCoord[n][0] = rGmesh.NodeVec()[n].Coord(0);
290  NodeCoord[n][1] = rGmesh.NodeVec()[n].Coord(1);
291  NodeCoord[n][2] = rGmesh.NodeVec()[n].Coord(2);
292  }
293 
294  //initializing gmesh->NodeVec()
295  gmesh->NodeVec().Resize(nNodes);
296  TPZVec <TPZGeoNode> Node(nNodes);
297  for(int64_t n = 0; n < nNodes; n++)
298  {
299  Node[n].SetNodeId(n);
300  Node[n].SetCoord(NodeCoord[n]);
301  gmesh->NodeVec()[n] = Node[n];
302  }
303  for(int64_t el = 1; el < nElements; el++)
304  {
305  TPZGeoEl * Elem = rGmesh.ElementVec()[el];
306  TPZVec<int64_t> cornerindexes(Elem->NNodes());
307  int64_t id = Elem->Id();
308  for(int n = 0; n < Elem->NNodes(); n++)
309  {
310  cornerindexes[n] = Elem->NodeIndex(n);
311  }
312  gmesh->CreateGeoElement(Elem->Type(), cornerindexes, Elem->MaterialId(), id);
313  }
314  gmesh->BuildConnectivity();
315 
316  TPZVTKGeoMesh::PrintGMeshVTK(gmesh, file, matColor);
317 }
318 
319 void TPZRefPattern::ExportPattern(std::ostream &out) const{
320  out << fRefPatternMesh.NNodes() << ' ' << fRefPatternMesh.NElements() << std::endl << std::endl;
321  out << fId << ' ' << fName << std::endl << std::endl ;
322 
323  for (int i = 0; i < fRefPatternMesh.NNodes() ; i++)
324  {
325  for (int k=0; k<3; k++)
326  {
327  out << fRefPatternMesh.NodeVec()[i].Coord(k) << ' ';
328  }
329  out << std::endl;
330  }
331 
332  out << std::endl ;
333 
334  for (int i = 0; i < fRefPatternMesh.NElements(); i++)
335  {
336  out << fRefPatternMesh.ElementVec()[i]->Type() << " " << fRefPatternMesh.ElementVec()[i]->NCornerNodes() << " " ;
337  for (int k = 0; k < fRefPatternMesh.ElementVec()[i]->NCornerNodes(); k++)
338  {
339  out << fRefPatternMesh.ElementVec()[i]->NodeIndex(k) << " " ;
340  }
341  out << std::endl;
342  }
343  out << std::endl;
344 }
345 
346 void TPZRefPattern::WritePattern(std::ofstream &out) const{
347 
348  ExportPattern(out);
349 
350  int nperm = fPermutedRefPatterns.size();
351  out << nperm << ' ';
352  for(int el = 0; el < nperm; el++)
353  {
354  out << fPermutedRefPatterns[el] << ' ';
355  }
356  out << std::endl;
357 
358  TPZGeoEl *father = fRefPatternMesh.ElementVec()[0];
359  int nsides = father->NSides();
360  int is;
361  for(is=0; is<nsides; is++)
362  {
363  out << fSideRefPattern[is] << ' ';
364  }
365  out << std::endl;
366 }
367 
369  return Hash("TPZRefPattern");
370 }
371 
372 void TPZRefPattern::Read(TPZStream &buf, void *context){
373  int nSubElSides = -1;
374  buf.Read(&nSubElSides);
375  fSubElSideInfo.Resize(nSubElSides);
376  for(int iSubElSide = 0; iSubElSide < nSubElSides; iSubElSide++){
377  int nSides = -1;
378  buf.Read(&nSides);
379  fSubElSideInfo[iSubElSide].Resize(nSides);
380  for(int iSide = 0; iSide < nSides; iSide++){
381  int first = -1;
382  buf.Read(&first);
383  TPZTransform<REAL> second;
384  second.Read(buf,context);
385  fSubElSideInfo[iSubElSide][iSide] = std::make_pair(first,second);
386  }
387  }
388  buf.Read(fFatherSideInfo);
389  buf.Read(&fName);
390  buf.Read(&fId);
391  buf.Read(fSideRefPattern);
393  fRefPatternMesh.Read(buf,context);
394  buf.Read(&fNSubEl);
395 }
396 
397 void TPZRefPattern::Write(TPZStream &buf, int withclassid) const{
398  const int nSubElSides = fSubElSideInfo.size();
399  buf.Write(&nSubElSides);
400  for(int iSubElSide = 0; iSubElSide < nSubElSides; iSubElSide++){
401  const int nSides = fSubElSideInfo[iSubElSide].size();
402  buf.Write(&nSides);
403  for(int iSide = 0; iSide < nSides; iSide++){
404  buf.Write(&fSubElSideInfo[iSubElSide][iSide].first);
405  fSubElSideInfo[iSubElSide][iSide].second.Write(buf,withclassid);
406  }
407  }
408  buf.Write(fFatherSideInfo);
409  buf.Write(&fName);
410  buf.Write(&fId);
411  buf.Write(fSideRefPattern);
413  fRefPatternMesh.Write(buf,withclassid);
414  buf.Write(&fNSubEl);
415 
416 }
417 
418 
420 {
421  #ifdef PZDEBUG
422  if(fNSubEl != fSubElSideInfo.size()){
423  PZError << "The refinement pattern is not in a consistent state."<<std::endl;
424  PZError << "It has two different values of number of sub-elements, namely: "<<std::endl;
425  PZError << fNSubEl<<" and "<<fSubElSideInfo.size()<<std::endl;
426  PZError << "Aborting..."<<std::endl;
427  DebugStop();
428  }
429  #endif
430  return fNSubEl;
431 }
432 
433 int TPZRefPattern::FatherSide(int side, int sub) const
434 {
435  #ifdef PZDEBUG
436  if(sub < 0 || sub >= NSubElements()){
437  PZError << "TPZRefPattern::FatherSide: wrong parameter 'sub'."<<std::endl;
438  PZError << "The current ref pattern has "<<NSubElements()<<" and the parameter 'sub' was "<<sub<<std::endl;
439  DebugStop();
440 
441  }
442  if(side < 0 || side >= fRefPatternMesh.ElementVec()[sub+1]->NSides()){
443  PZError << "TPZRefPattern::FatherSide: wrong parameter 'side'."<<std::endl;
444  PZError << "The current sub element has "<<fRefPatternMesh.ElementVec()[sub+1]->NSides()<<" sides ";
445  PZError << "and the parameter 'side' was "<<side<<std::endl;
446  DebugStop();
447  }
448  #endif
449  return fSubElSideInfo[sub][side].first;
450 }
451 int TPZRefPattern::NSideSubGeoElSides(int fatherSide) const{
452  #ifdef PZDEBUG
453  if(!CheckSideConsistency(fatherSide)) {
454  DebugStop();
455  }
456  #endif
457 
458  return fFatherSideInfo[fatherSide].fSideSons.size();
459 }
460 
461 void TPZRefPattern::SideSubGeoElSide(int fatherSide, int subElPos, TPZGeoElSide & subGeoEl) const{
462  #ifdef PZDEBUG
463  if(!CheckSideAndSubElConsistency(fatherSide,subElPos)) {
464  DebugStop();
465  }
466  #endif
467  subGeoEl = fFatherSideInfo[fatherSide].fSideSons[subElPos];
468 }
469 
470  TPZTransform<> TPZRefPattern::Transform(int subElSide, int sub)
471  {
472  #ifdef PZDEBUG
473  if(sub<0 || sub >= NSubElements()) {
474  DebugStop();
475  }
476  TPZGeoEl *subEl = Element(sub+1);
477  if(subElSide<0 || subElSide >= subEl->NSides()){
478  DebugStop();
479  }
480  #endif
481  return fSubElSideInfo[sub][subElSide].second;
482  }
483 
484 void TPZRefPattern::SideNodes(int fatherSide, TPZVec<int> &vecNodes){
485 #ifdef PZDEBUG
486  if(!CheckSideConsistency(fatherSide)) {
487  DebugStop();
488  }
489 #endif
490  vecNodes = fFatherSideInfo[fatherSide].fSideNodes;
491 }
492 
493 int TPZRefPattern::NSideNodes(int fatherSide) const{
494  #ifdef PZDEBUG
495  if(!CheckSideConsistency(fatherSide)) {
496  DebugStop();
497  }
498  #endif
499  return fFatherSideInfo[fatherSide].fSideNodes.size();
500 }
501 
503  return fRefPatternMesh.NNodes();
504 }
505 
507  const int side = fatherSide.Side();
508 
509  for (auto &geoElSide : fFatherSideInfo[side].fSideSons ) {
510  if(geoElSide.Element() == son) return true;
511  }
512  return false;
513 }
514 
516  int nel = NSubElements()+1;/*sub-elements and father el*/
517  if(iel < 0 || iel >= nel){
518  PZError << "TPZRefPattern::Element the element with the following id does not exist: " << iel << std::endl;
519  DebugStop();
520  }
521  return ( fRefPatternMesh.ElementVec()[iel] );
522 }
523 
525  #ifdef PZDEBUG
526  if(!CheckSideConsistency(side)) {
527  DebugStop();
528  }
529  #endif
530  nodeIndexes.Resize(NSideNodes(side));
531  int count = 0;
532  for(auto &subElSide : fFatherSideInfo[side].fSideSons){
533  if(subElSide.Dimension() == 0){
534  nodeIndexes[count] = TPZGeoElSideIndex(subElSide);
535  nodeIndexes[count].SetElementIndex(nodeIndexes[count].ElementIndex());
536  count++;
537  }
538  }
539 }
540 
542  #ifdef PZDEBUG
543  if(!CheckSideConsistency(side)) {
544  DebugStop();
545  }
546  #endif
547  const int nSubElSides = fFatherSideInfo[side].fSideSons.size();
548  sideIndexes.Resize(nSubElSides);
549  for(int iSub = 0; iSub < nSubElSides; iSub++){
550  sideIndexes[iSub] = TPZGeoElSideIndex(fFatherSideInfo[side].fSideSons[iSub]);
551  sideIndexes[iSub].SetElementIndex(sideIndexes[iSub].ElementIndex());
552  }
553 }
554 
556 {
557  #ifdef PZDEBUG
558  if(!CheckSideConsistency(side)) {
559  DebugStop();
560  }
561  #endif
562  gelvec = fFatherSideInfo[side].fSideSons;
563  return gelvec.size();//numero de elementos da particao do lado
564 }
565 
567 {
568  const int id = this->fSideRefPattern[side];
569 
570  return gRefDBase.FindRefPattern(id);
571 }
572 
574 {
575  int nNodes = gel->NCornerNodes();
576  int totalNodes = fRefPatternMesh.NNodes();
577  newnodeindexes.Resize(totalNodes);
578 
579  if (gel->HasSubElement()){
580  std::cout << "CreateNewNodes called for an element which is already divided. \n";
581  std::cout.flush();
582  return;
583  }
584 
585  int nSides = gel->NSides();
586  for (int side = nNodes;side<nSides;side++){
587  CreateMidSideNodes(gel,side,newnodeindexes);
588  }
589 }
590 
591 void TPZRefPattern::CreateMidSideNodes(TPZGeoEl * gel, int side, TPZVec<int64_t> &newnodeindexes)
592 {
593  TPZGeoMesh *gmesh = gel->Mesh();
594  //SideNodes returns a vector with the indexes of the internal nodes of the side side
595  TPZManVector<int> sideNodes;
596  SideNodes(side,sideNodes);
597  TPZGeoElSide gelside(gel,side);
598  TPZGeoElSide neighbour(gelside.Neighbour());
599  TPZManVector<int64_t> sideindices(0);
600  //checks if a neighbour element has created a midsidenode already
601  while(neighbour.Element() && neighbour != gelside){
602  if(neighbour.HasSubElement() && neighbour.Element()->NSideSubElements(neighbour.Side()) > 1)
603  {
604  neighbour.Element()->MidSideNodeIndices(neighbour.Side(),sideindices);
605  break;
606  }
607  neighbour = neighbour.Neighbour();
608  }
609  for (int j=0;j<sideNodes.NElements();j++){
610  int index = sideNodes[j];
611  //new node coordinates
612  TPZManVector<REAL,3> refnodecoord_X(3,0.);
613  TPZManVector<REAL,3> neighbourcoord_X(3,0.);
614 
615  for (int k=0;k<3;k++){
616  double coord = fRefPatternMesh.NodeVec()[index].Coord(k);
617  refnodecoord_X[k] = coord;
618  }
619 
620  TPZManVector<REAL,3> newnodecoord_xi(Element(0)->Dimension(),0.);
621 
622  //getting node coordinates in refpattern mesh: just a matter of adjusting dimension
623  for(int iX = 0; iX < Element(0)->Dimension(); iX++) newnodecoord_xi[iX] = refnodecoord_X[iX];
624 
625  //coordinates of the node to be created (if it hasnt been created yet)
626  TPZManVector<REAL,3> newnodecoord_X(3);
627  gel->X(newnodecoord_xi,newnodecoord_X);
628 
629  newnodeindexes[index] = -1;
630  REAL smallestDiff = -1.;
631  int smallestDiffIndex = -1;
632  //check if the node has already been created using information previsouly obtained from neighbour
633  for(int i=0; i< sideindices.NElements(); i++)
634  {
635  for(int k=0; k<3; k++) neighbourcoord_X[k] = gmesh->NodeVec()[sideindices[i]].Coord(k);
636  REAL dif = 0.;
637  for (int k=0;k<3;k++)
638  {
639  dif += (newnodecoord_X[k] - neighbourcoord_X[k]) * (newnodecoord_X[k] - neighbourcoord_X[k]);
640  }
641  if(smallestDiffIndex < 0. || smallestDiff > dif)
642  {
643  smallestDiff = dif;
644  smallestDiffIndex = i;
645  }
646  }
647  if (smallestDiff < 1e-2 && sideindices.NElements() != 0)
648  {
649  newnodeindexes[index] = sideindices[smallestDiffIndex];
650  }
651  if (smallestDiff >= 1.e-2 && sideindices.NElements() != 0)
652  {
653 #ifdef LOG4CXX
654  {
655  std::stringstream sout;
656  sout << "Incompatible refinement patterns detected\n";
657  sout << "Closest node at distance " << smallestDiff << std::endl;
658  gel->Print(sout);
659  LOGPZ_ERROR(logger,sout.str())
660  }
661 #endif
662  std::cout << "Refpattern is trying to create midnode but there is another node which is not in the right position!\n";
663  std::cout << "Either the refinement patterns are incompatible or there is an issue with the mapping.\n";
664  std::cout << "newnodecoord_X(" << newnodecoord_X[0] << "," << newnodecoord_X[1] << "," << newnodecoord_X[2] << ")" << std::endl;
665  std::cout << "neighbourcoord_X(" << neighbourcoord_X[0] << "," << neighbourcoord_X[1] << "," << neighbourcoord_X[2] << ")" << std::endl;
666  DebugStop();
667  }
668  if (newnodeindexes[index] == -1)
669  {
670  //If no one has created the node yet, it should be created
671  int64_t newindex = gmesh->NodeVec().AllocateNewElement();
672  gmesh->NodeVec()[newindex].Initialize(newnodecoord_X,*gmesh);
673  newnodeindexes[index] = newindex;
674  }
675  }
676 }
677 
678 
681  {
682  return;
683  }
684 
685  TPZGeoEl *fatherEl = fRefPatternMesh.ElementVec()[0];
686 
687  int nsides = fatherEl->NSides();
688  fSideRefPattern.Resize(nsides,-1);
689  fSideRefPattern.Fill(-1.);
690 
691  int thisId = this->Id();
692  fSideRefPattern[nsides-1] = thisId;
693 
694  int is;
695  for(is=0; is<nsides-1; is++)
696  {
697  if(fatherEl->SideDimension(is) == 0) continue;
698  if(NSideSubGeoElSides(is) == 1) continue;
699 
701 
702  BuildSideMesh(is, sideref->fRefPatternMesh);
703 
705 
706  sideref->fNSubEl = sideref->fRefPatternMesh.NElements()-1;
707  sideref->ComputeTransforms();
708  sideref->ComputePartition();
711 
712  if(!found.operator ->())
713  {
714  if(this->NameInitialized())
715  {
716  sideref->BuildName();
717  }
718  sideref->GenerateSideRefPatterns();
719  gRefDBase.InsertRefPattern(sideref);
720  fSideRefPattern[is] = sideref->Id();
721  sideref->InsertPermuted();
722  }
723  else
724  {
725  fSideRefPattern[is] = found->Id();
726  }
727  }
728 }
729 
731 {
733  {
734  return;
735  }
736 
738  TPZGeoEl * gel = fRefPatternMesh.ElementVec()[0];
740  MElementType geltype = gel->Type();
741 
742  std::list<TPZRefPatternPermute> &permlist = fPermutations[geltype];
743  std::list<TPZRefPatternPermute>::iterator it;
744  fPermutedRefPatterns.resize(permlist.size());
745 
746  int64_t counter;
747  for(it=permlist.begin(), counter=0; it != permlist.end(); it++,counter++)
748  {
749  TPZAutoPointer<TPZRefPattern> refp(new TPZRefPattern(*this,(*it).fPermute));
751 
752 #ifdef LOG4CXX
753  if (logger->isDebugEnabled())
754  {
755  std::stringstream sout;
756  sout << "Permutation " << it->fPermute;
757  sout << "Created refpattenr refp ";
758  refp->Print(sout);
759  sout << "found refpattern ";
760  if(found) found->Print(sout);
761  else sout << "Pattern not found";
762  LOGPZ_DEBUG(logger,sout.str())
763  }
764 #endif
765 
766  if(found)
767  {
768  fPermutedRefPatterns[counter] = found->Id();
769  }
770  else
771  {
772  if(this->NameInitialized())
773  {
774  refp->BuildName();
775  }
777  }
778  }
779 }
780 
782  TPZAutoPointer<TPZRefPattern> sideref = this->SideRefPattern(side);
783  if(!sideref) return nullptr;
784  return sideref->FindRefPattern(trans);
785 }
786 
787 /****************************PROTECTED METHODS*************************************************************************/
788 
790 {
791  REAL tol = 1.e-6;
792  if(!fRefPatternMesh.ElementVec().NElements() || ! fRefPatternMesh.ElementVec()[0]) return 0;
793  MElementType type = fRefPatternMesh.ElementVec()[0]->Type();
794 
795  std::list<TPZRefPatternPermute> &permlist = fPermutations[type];
796  std::list<TPZRefPatternPermute>::iterator it;
797  for(it = permlist.begin(); it != permlist.end(); it++)
798  {
799  TPZRefPatternPermute &tmp = (*it);
800  if(!tmp.fTransform.CompareTransform(trans, tol))
801  {
802  TPZAutoPointer<TPZRefPattern> refpPerm = new TPZRefPattern(*this, tmp.fPermute);
804 
805  return found;
806  }
807  }
808  return 0;
809 }
810 
812  TPZGeoEl * fatherEl = fRefPatternMesh.ElementVec()[0];
813 
814 
815  const int dim = fatherEl->Dimension();
816  const int nNodes = fRefPatternMesh.NodeVec().NElements();
817  TPZManVector< TPZManVector<REAL,3> ,20> nodecoords_inQSI(nNodes,TPZManVector<REAL,3>(dim,0));
818  TPZManVector<REAL,3> nodecoords_inX(3,0);
819  TPZManVector<REAL,3> temp(3,0.);
820  REAL Tol;
821  ZeroTolerance(Tol);
822  for(int n = 0; n < nNodes; n++)
823  {
824  fRefPatternMesh.NodeVec()[n].GetCoordinates(nodecoords_inX);
825  fatherEl->ComputeXInverse(nodecoords_inX, nodecoords_inQSI[n],Tol);
826  }
827 
828  TPZVec<REAL> coordQSIprojected(dim,0.);
829  for(int n = 0; n < nNodes; n++)
830  {
831  //Let us guarantee that ComputeXInverse did not result in a point outside the reference element
832  fatherEl->ProjectInParametricDomain(nodecoords_inQSI[n], coordQSIprojected);
833 
834  int c;
835  for(c = 0; c < dim; c++)
836  {
837  double qsi = coordQSIprojected[c];
838  fRefPatternMesh.NodeVec()[n].SetCoord(c,qsi);
839  }
840  for(; c < 3; c++)
841  {
842  fRefPatternMesh.NodeVec()[n].SetCoord(c,0.);
843  }
844  }
845 }
846 
848  if (!fatherEl)
849  {
850  PZError << "Error at " << __PRETTY_FUNCTION__ << " at line " << __LINE__ << " Father Element is NULL\n";
851  return;
852  }
853  MElementType fatherEltype = fatherEl->Type();
854 
855  if(fPermutations.count(fatherEltype))
856  {
857  return;
858  }
859  TPZGeoMesh *fatherElMesh = fatherEl->Mesh();
860  TPZGeoMesh gmesh;
861  gmesh.NodeVec().Resize(fatherEl->NNodes());
862 
863  int iNode, nNodes = fatherEl->NNodes();
864  for(iNode = 0; iNode < nNodes; iNode++)
865  {
866  gmesh.NodeVec()[iNode].Initialize(fatherElMesh->NodeVec()[fatherEl->NodeIndex(iNode)], gmesh);
867  }
868  TPZManVector<int64_t,8> nodes(nNodes), nodesPerm(nNodes);
869  for(iNode = 0; iNode < nNodes; iNode++)
870  {
871  nodes[iNode]=iNode;
872  }
873  int matid = fatherEl->MaterialId();
874  TPZPermutation permute(nNodes);
875  TPZTransform<> trans(fatherEl->Dimension());
876  TPZRefPatternPermute refpermute;
877 
878  refpermute.fPermute = permute;
879  refpermute.fTransform = trans;
880  fPermutations[fatherEl->Type()].push_back(refpermute);
881  permute++;
882  TPZGeoEl *fatherElPermuted;
883  TPZVec<int> permutedSides;
884  while(!permute.IsFirst())
885  {
886  permute.Permute(nodes,nodesPerm);
887  int64_t index;
888  fatherElPermuted = gmesh.CreateGeoElement(fatherEl->Type(),nodesPerm,matid,index,0);
889 // fatherEl->GetPermutation()
890  bool valid = false;
891  int nPermutes = fatherEl->NPermutations();
892  for(int iPermute = 1; iPermute < nPermutes; iPermute++){//its ok to skip the first (trivial) permutation
893  fatherEl->GetPermutation(iPermute,permutedSides);
894  for(iNode = 0; iNode < nNodes; iNode++) {
895  if ( permutedSides[iNode] != nodesPerm[iNode]) break;
896  }
897  if(iNode == nNodes){
898  valid = true;//found the correspondent permutation
899  break;
900  }
901  }
902  if(valid)
903  {
904  TPZRefPatternPermute candidate;
905  candidate.fPermute = permute;
906  candidate.fTransform = ComputeParamTransform(fatherEl,fatherElPermuted,fatherEl->NSides()-1,fatherEl->NSides()-1);
907  fPermutations[fatherEl->Type()].push_back(candidate);
908  }
909  permute++;
910  }
911 }
912 
914  TPZGeoEl *fatherEl = fRefPatternMesh.Element(0);
915  if(!fatherEl)
916  {
917  PZError << "TPZRefPattern::ComputePartition Father not exists?!\n";
918  DebugStop();
919  }
920 
921  const int nSubEls = fRefPatternMesh.NElements() - 1;
922  fSubElSideInfo.Resize(nSubEls);
923 
924  REAL Tol;
925  ZeroTolerance(Tol);
926  const int dim = fatherEl->Dimension();
927  TPZManVector<REAL,3> massCenter(3,0.), xPoint(3,0.), fatherParam(dim,0.);
928  for(int iSubEl=0; iSubEl < nSubEls; iSubEl++)
929  {
930  TPZGeoEl *son = Element(iSubEl+1);
931  massCenter.Resize(son->Dimension());
932  int nSides = son->NSides();
933  fSubElSideInfo[iSubEl].Resize(nSides);
934  for(int iSide = 0; iSide < nSides; iSide++)
935  {
936  TPZGeoElSide elside (son, iSide);
937 
938  son->CenterPoint(iSide,massCenter);
939  son->X(massCenter,xPoint);//already in father's coordinates. but the dimension must be set up
940  for(int iX = 0; iX < dim; iX++) fatherParam[iX] = xPoint[iX];
941  const int fatherSide = fatherEl->WhichSide(fatherParam);
942  fSubElSideInfo[iSubEl][iSide].first = fatherSide;
943 // fSubElSideInfo[iSubEl][iSide].second = son->ComputeParamTrans(fatherEl,fatherSide,iSide);
944  fSubElSideInfo[iSubEl][iSide].second = ComputeParamTransform(son,fatherEl,iSide,fatherSide);
945  }
946  }
947 }
948 
950  //this method will fill the fFatherSideInfo data structure
951  TPZGeoEl *fatherEl = Element(0);
952  int nSides = fatherEl->NSides();
953 
954  fFatherSideInfo.Resize(nSides);
955  for(int iSide = 0; iSide < nSides; iSide++){
956 
957  TPZStack<TPZGeoElSide> sideSonsStack;
958  TPZStack<int> cornerNodeStack;
959  TPZStack<int> internalNodesStack;
960  const int nSideNodes = fatherEl->NSideNodes(iSide);
961  for(int iNode = 0; iNode < nSideNodes; iNode++){
962  const int nodeIndex = fatherEl->SideNodeIndex(iSide,iNode);
963  cornerNodeStack.push_back(nodeIndex);
964  }
965  for(auto iSubEl = 0; iSubEl < NSubElements(); iSubEl++){
966  TPZGeoEl *subEl = Element(iSubEl+1);
967  for(auto iSubElSide = 0; iSubElSide < subEl->NSides(); iSubElSide ++){
968  int fatherSide = FatherSide(iSubElSide,iSubEl);
969  if(fatherSide == iSide){
970  TPZGeoElSide geoElSideCandidate(subEl,iSubElSide);
971  bool isInList = false;
972  for(int iGelSide = 0; iGelSide < sideSonsStack.size(); iGelSide++){
973  if(isInList) break;
974  TPZGeoElSide neighbour = geoElSideCandidate.Neighbour();
975  while(neighbour.Element() && neighbour.Element()->Id() != geoElSideCandidate.Element()->Id()){
976  if(neighbour == sideSonsStack[iGelSide]){
977  isInList = true;
978  break;
979  }
980  neighbour = neighbour.Neighbour();
981  }
982  }
983  if(!isInList) {
984  sideSonsStack.push_back(geoElSideCandidate);
985  if(subEl->SideDimension(iSubElSide) == 0){
986  const int nodeIndex = subEl->NodeIndex(iSubElSide);
987  bool isNodeInList = false;
988  const int nCornerNodes = cornerNodeStack.size();
989  const int nInternalNodes = internalNodesStack.size();
990  for(int iNode = 0; iNode < nInternalNodes; iNode++){
991  if(internalNodesStack[iNode] == nodeIndex) isNodeInList = true;
992  }
993  //the following garantees that for a 0D side its node is put correctly in internalNodesStack
994  for(int iNode = 0; iNode < nCornerNodes && fatherEl->SideDimension(iSide) > 0; iNode++){
995  if(cornerNodeStack[iNode] == nodeIndex) isNodeInList = true;
996  }
997  if(!isNodeInList){
998  internalNodesStack.push_back(nodeIndex);
999  }
1000  }
1001  }
1002  }
1003  }
1004  }
1005  fFatherSideInfo[iSide].fSideNodes.Resize(internalNodesStack.size());
1006  for(auto iNode = 0; iNode < internalNodesStack.size(); iNode++){
1007  fFatherSideInfo[iSide].fSideNodes[iNode] = internalNodesStack[iNode];
1008  }
1009  fFatherSideInfo[iSide].fSideSons.Resize(sideSonsStack.size());
1010  for(auto iSubEl = 0; iSubEl < sideSonsStack.size(); iSubEl++){
1011  fFatherSideInfo[iSide].fSideSons[iSubEl] = sideSonsStack[iSubEl];
1012  }
1013  }
1014 }
1015 
1017  const int nSubEls = NSubElements();
1018  for(int i = 0; i < nSubEls; i++){
1019  if(fRefPatternMesh.ElementVec()[i+1] == geoEl){
1020  return i;
1021  }
1022  }
1023  PZError<<"TPZRefPattern::FindSubEl: ERROR"<<std::endl;
1024  PZError<<"This method should not be called with an element ";
1025  PZError<<"that is not a sub-element of this Refinement Pattern."<<std::endl;
1026  PZError<<"Aborting..."<<std::endl;
1027  DebugStop();
1028  return -1;
1029 }
1030 
1031 bool TPZRefPattern::CheckSideConsistency(const int fatherSide) const{
1032  int nSides = fRefPatternMesh.ElementVec()[0]->NSides();
1033  if(fatherSide < 0 || fatherSide >= nSides)
1034  {
1035  PZError << "TPZRefPattern::NSideSubElements: wrong argument\n";
1036  PZError << "father side = " << fatherSide << std::endl;
1037  return false;
1038  }
1039  return true;
1040 }
1041 
1042 bool TPZRefPattern::CheckSideAndSubElConsistency(const int fatherSide, const int subEl) const{
1043  const int nSides = fRefPatternMesh.ElementVec()[0]->NSides();
1044  const int nSubGeoElSides = NSideSubGeoElSides(fatherSide);
1045  if(fatherSide < 0 || fatherSide >= nSides || subEl < 0 || subEl >= nSubGeoElSides)
1046  {
1047  PZError << "TPZRefPattern::CheckSideAndSubElConsistency: wrong argument\n";
1048  PZError << "father side = " << fatherSide << std::endl;
1049  PZError << "subEl = " << subEl << std::endl;
1050  return false;
1051  }
1052  return true;
1053 }
1054 
1055 void TPZRefPattern::BuildSideMesh(int side, TPZGeoMesh &SideRefPatternMesh)
1056 {
1058  {
1059  return;
1060  }
1061  TPZGeoEl *gel = fRefPatternMesh.ElementVec()[0];
1062  TPZStack<int> allsides;
1063  std::map<int,int> allsidenodes;
1064  int count =0;
1065  gel->LowerDimensionSides(side, allsides);
1066  allsides.Push(side);
1067  int s;
1068  for(s=0; s<allsides.NElements(); s++)
1069  {
1070  TPZStack<int> sidenodes;
1071  SideNodes(allsides[s],sidenodes);
1072  int t;
1073  for(t=0; t<sidenodes.NElements(); t++)
1074  {
1075  if(!allsidenodes.count(sidenodes[t])) allsidenodes[sidenodes[t]] = count++;
1076  }
1077  }
1078  SideRefPatternMesh.NodeVec().Resize(allsidenodes.size());
1079  std::map<int,int>::iterator it;
1080  for(it = allsidenodes.begin(); it!= allsidenodes.end(); it++)
1081  {
1082  int nodeorig = (*it).first;
1083  int nodedest = (*it).second;
1084 
1085  SideRefPatternMesh.NodeVec()[nodedest].Initialize(fRefPatternMesh.NodeVec()[nodeorig], SideRefPatternMesh);
1086  SideRefPatternMesh.NodeVec()[nodedest].SetNodeId(nodedest);
1087  }
1088  TPZStack<int64_t> nodeindices;
1089  nodeindices.Resize(gel->NSideNodes(side));
1090  int64_t in;
1091  for(in=0; in<nodeindices.NElements(); in++)
1092  {
1093  nodeindices[in] = allsidenodes[gel->SideNodeIndex(side,in)];
1094  }
1095  int matid = gel->MaterialId();
1096  int64_t index;
1097  TPZGeoEl *father = SideRefPatternMesh.CreateGeoElement(gel->Type(side),nodeindices,matid,index,1);
1098  int sidedim = father->Dimension();
1099  TPZStack<TPZGeoElSide> gelvec;
1100  SidePartition(gelvec, side);
1101  int nsub = gelvec.NElements();
1102  int subel;
1103  for(subel=0; subel<nsub; subel++)
1104  {
1105  if(gelvec[subel].Dimension() != sidedim)
1106  {
1107  continue;
1108  }
1109  nodeindices.Resize(gelvec[subel].NSideNodes());
1110  for(in=0; in<nodeindices.NElements(); in++)
1111  {
1112  nodeindices[in] = allsidenodes[gelvec[subel].SideNodeIndex(in)];
1113  }
1114  MElementType type = gelvec[subel].Element()->Type(gelvec[subel].Side());
1115  TPZGeoEl *subel = SideRefPatternMesh.CreateGeoElement(type,nodeindices,matid,index);
1116  subel->SetFather(father);
1117  }
1118  SideRefPatternMesh.BuildConnectivity();
1119 }
1120 
1121 
1123 {
1125 }
1126 
1128 {
1129  int in;
1130  TPZGeoEl *father = this->fRefPatternMesh.ElementVec()[0];
1131  int nn = father->NNodes();
1132  TPZVec<int> nodes(nn), nodeperm(nn);
1133  for(in=0; in<nn; in++){
1134  nodes[in] = father->NodeIndex(in);
1135  }
1136  permute.Permute(nodes,nodeperm);
1137  for(in=0; in<nn; in++){
1138  father->SetNodeIndex(in, nodeperm[in]);
1139  }
1142 }
1143 
1145  int nNodes, nElems;
1146  pattern >> nNodes >> nElems;
1147  pattern >> fId >> fName;
1148 
1149  TPZManVector<REAL,3> coord(3);
1150  fRefPatternMesh.NodeVec().Resize(nNodes);
1151 
1152  //criacao dos nohs
1153  for(int iNode = 0; iNode < nNodes; iNode++)
1154  {
1155  pattern >> coord[0];
1156  pattern >> coord[1];
1157  pattern >> coord[2];
1158  fRefPatternMesh.NodeVec()[iNode].Initialize(iNode,coord,fRefPatternMesh);
1159  }
1160  TPZGeoEl *father = 0;
1161  //criacao dos elementos geometricos que definem a particao
1162  int ntype, nummat, naorners, incid, el;
1163  for(el=0; el<nElems; el++)//os sub-elementos podem nao ter de uma mesma geometria
1164  {
1165  pattern >> ntype >> nummat;
1166  MElementType etype = (MElementType) ntype;
1167  naorners = MElementType_NNodes(etype);
1168  TPZVec<int64_t> nodes(naorners);
1169  for(incid = 0; incid < naorners; incid++)
1170  {
1171  pattern >> nodes[incid];
1172  }
1173  int64_t index;
1174  TPZGeoEl *subel = fRefPatternMesh.CreateGeoElement(etype, nodes, nummat, index, 0);
1175  if(el == 0)
1176  {
1177  father = subel;
1179  }
1180  if(el > 0)
1181  {
1182  subel->SetFather(father);
1183  subel->SetFatherIndex(father->Index());
1184  }
1185  }
1187 }
1188 
1190  //ensure that the all the sub-elements are aware of their father
1191  //the first element is supposed to be the father element
1192  TPZGeoEl* fatherEl = fRefPatternMesh.Element(0);
1193  MElementType type = fatherEl->Type();
1195 
1196  for(int iSubEl = 0; iSubEl < fNSubEl; iSubEl++){
1197  TPZGeoEl* subEl = fRefPatternMesh.Element(iSubEl + 1);
1198  subEl->SetFather(fatherEl);
1199  subEl->SetFatherIndex(0);
1200  }
1201 
1203  fRefPatternMesh.BuildConnectivity();//sub-element connectivities
1204  GeneratePermutations(fatherEl);
1205 
1206  ComputeTransforms();//compute the transformation between sons and father-el
1207  ComputePartition();//compute the partition of the father element in (side,sub-element)
1208 
1210 }
1211 
1212 TPZTransform<> TPZRefPattern::ComputeParamTransform(TPZGeoEl *geoElSon, TPZGeoEl *geoElFather, int sideSon, int sideFather){
1213  int dimFather = geoElFather->Dimension();
1214  int dimSideFather = geoElFather->SideDimension(sideFather);
1215  int dimSon = geoElSon->Dimension();
1216  int dimSideSon = geoElSon->SideDimension(sideSon);
1217  if(dimSideFather < dimSideSon){
1218  PZError << "\nTPZRefPattern::ComputeParamTransform called with sides error\n";
1219  DebugStop();
1220  }
1221 
1223  if(!geoElFather->SideDimension(sideFather)) return TPZTransform<>(0,0);
1224 
1225  REAL weight;
1226  TPZFNMatrix<9> jac(dimSon,dimSon),axes(3,3,0.);
1227  TPZFNMatrix<9> jacinv(dimSon,dimSon);
1228  TPZManVector<REAL,3> x(3,0.);
1229  TPZManVector<REAL,3> intpoint(dimSideSon,0.);
1230  int tam = (dimSideSon+1);
1231  TPZFNMatrix<16> hess(tam,tam,0.),grad0(tam,1,0.);
1232  TPZIntPoints *intrule = geoElSon->CreateSideIntegrationRule(sideSon,2);
1233  TPZManVector<int,3> order(dimSideSon,2);
1234  intrule->SetOrder(order);
1235  //integrating over the side of the son that is contained on the father's side
1236  int ij,ik,indp;
1237  REAL D2Edaikdaij,D2Edcidaij,D2Edci2;
1238  D2Edcidaij = 0.;
1239  D2Edci2 = 0.;
1240  for(ij=0;ij<dimSideSon;ij++){
1241  for(ik=ij;ik<dimSideSon;ik++){
1242  D2Edaikdaij = 0.;
1243  D2Edcidaij = 0.;
1244  for(indp = 0; indp < intrule->NPoints(); ++indp){
1245  intrule->Point(indp,intpoint,weight);
1246  D2Edaikdaij += intpoint[ik]*intpoint[ij]*weight;
1247  if(ik==ij) D2Edcidaij += intpoint[ij]*weight;
1248  if(ij==0 && ik==0) D2Edci2 += weight;
1249  }
1250  hess(ij,ik) = 2.*D2Edaikdaij;
1251  hess(ik,ij) = hess(ij,ik);
1252  if(ik==ij) {
1253  hess(ij,dimSideSon) = 2.*D2Edcidaij;
1254  hess(dimSideSon,ij) = hess(ij,dimSideSon);
1255  }
1256  if(ij==0 && ik==0) hess(dimSideSon,dimSideSon) = 2.*D2Edci2;
1257  }
1258  }// end of integral
1259  //defining transform from the son's side to the son's element
1260  TPZTransform<> transformSideToSon(dimSon);//identidade
1261  if(dimSideSon<dimSon) transformSideToSon = geoElSon->SideToSideTransform(sideSon,geoElSon->NSides()-1);
1262  TPZTransform<> fatelside = geoElFather->SideToSideTransform(geoElFather->NSides()-1,sideFather);
1263  TPZManVector<REAL,3> sidepoint(dimSon);
1264  int j;
1265  TPZFNMatrix<9> Amat(dimSideFather,dimSideSon,0.),Bmat(dimSideFather,1,0.);
1266  REAL Tol;
1267  ZeroTolerance(Tol);
1268  TPZVec<REAL> xiFather(dimFather,0.);
1269  TPZVec<REAL> xiFatherSide(dimSideFather,0.);
1270  for(int ifat=0;ifat<dimSideFather;ifat++){
1271  REAL DEdci = 0.;
1272  for(j=0;j<(dimSideSon+1);j++){
1273  REAL DEdaij = 0.;
1274  for(indp = 0; indp < intrule->NPoints(); ++indp){
1275  intrule->Point(indp,intpoint,weight);
1276  transformSideToSon.Apply(intpoint,sidepoint);//lado do filho para o seu interior: mestre
1277  geoElSon->X(sidepoint,x);//this is already on father's domain, but in 3 dimensions
1278  for(int iX = 0; iX < dimFather; iX++) xiFather[iX] = x[iX];
1279  fatelside.Apply(xiFather,xiFatherSide);
1280  if(j<dimSideSon) DEdaij += xiFatherSide[ifat]*intpoint[j]*weight;
1281  if(j==0) DEdci += xiFatherSide[ifat]*weight;
1282  }
1283  if(j<dimSideSon) grad0(j,0) = 2.*DEdaij;
1284  if(j==0) grad0(dimSideSon,0) = 2.*DEdci;
1285  if(!dimSideSon) grad0(0,0) = DEdci;
1286  }
1287 
1288  if(dimSideSon) hess.SolveDirect(grad0,ELU);
1289  for(int k=0;k<dimSideSon;k++) Amat(ifat,k) = grad0(k,0);
1290  Bmat(ifat,0) = grad0(dimSideSon,0);
1291  }
1292 
1293  delete intrule;
1294  TPZTransform<> t(dimSideFather,dimSideSon);
1295  t.SetMatrix(Amat,Bmat);
1296  return t;
1297 }
1298 
1300  return Hash("TPZRefPattern::TPZRefPatternPermute");
1301 }
1302 
1304  fPermute.Read(buf, context);
1305  fTransform.Read(buf, context);
1306 }
1307 
1308 void TPZRefPattern::TPZRefPatternPermute::Write(TPZStream& buf, int withclassid) const { //ok
1309  fPermute.Write(buf, withclassid);
1310  fTransform.Write(buf, withclassid);
1311 }
1312 
1313 void TPZRefPattern::SPZFatherSideInfo::Read(TPZStream& buf, void* context) { //ok
1314  buf.Read(fSideNodes);
1315  buf.Read(fSideSons);
1316 }
1317 
1318 void TPZRefPattern::SPZFatherSideInfo::Write(TPZStream& buf, int withclassid) const { //ok
1319  buf.Write(fSideNodes);
1320  buf.Write(fSideSons);
1321 }
virtual int64_t SideNodeIndex(int side, int nodenum) const =0
Returns the index of the nodenum node of side.
void PermuteMesh(const TPZPermutation &permute)
Copy the mesh structure applying the permutation on the nodenumbers of the first element.
void Print(std::ostream &out=std::cout)
Prints the structural information of the vector object to the output stream. This method will not p...
Definition: pzvec.h:482
TPZVec< TPZVec< std::pair< int, TPZTransform< REAL > > > > fSubElSideInfo
Data structure with sub element info.
Definition: TPZRefPattern.h:90
bool CheckSideConsistency(const int fatherSide) const
void Permute(const TPZVec< int > &in, TPZVec< int > &out) const
Applies the current permutation on the vector in and produces the vector out.
TPZVec< TPZGeoElSide > fSideSons
a vector of TPZGeoElSide relative to its sons
Definition: TPZRefPattern.h:99
int AllocateNewElement()
Makes more room for new elements.
Definition: pzadmchunk.h:184
virtual int NPoints() const =0
Returns number of points for the cubature rule related.
virtual void LowerDimensionSides(int side, TPZStack< int > &smallsides) const =0
TPZVec< int > fSideRefPattern
Refinement for elements associated with a certain side of the current element. Usually, this is used for boundary/interface elements.
void ExportPattern(std::ostream &out) const
void ReadAndCreateRefinementPattern(std::istream &file)
int MaterialId() const
Returns the material index of the element.
Definition: pzgeoel.h:250
static const int fNonInitializedId
Id for identifying a non initialized pattern.
Definition: TPZRefPattern.h:80
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
bool IsFatherNeighbour(TPZGeoElSide fatherSide, TPZGeoEl *son) const
Verifies the neighbouring relationship between a son and a father&#39;s side.
virtual void resize(const int64_t newsize)
Definition: pzvec.h:213
TPZTransform fTransform
Transformation to the nodes.
int ClassId() const override
Define the class id associated with the class.
clarg::argInt nsub("-nsub", "number of substructs", 4)
TPZTransform ComputeParamTransform(TPZGeoEl *geoElFrom, TPZGeoEl *geoElTo, int sideFrom, int sideTo)
static std::string BuildRefPatternModelName(TPZRefPattern &refp)
Returns the the name of refpattern model.
void InsertRefPattern(TPZAutoPointer< TPZRefPattern > &refpat)
Insert the refinement pattern in the list of availabe refinement patterns assigns an Id to refPattern...
TPZGeoEl * Element(int iel)
It returns the element number iel from the stack of elements of the geometric mesh.
void Write(TPZStream &buf, int withclassid) const override
Writes this object to the TPZStream buffer. Include the classid if withclassid = true.
Definition: pzgmesh.cpp:1505
virtual int NCornerNodes() const =0
Returns the number of corner nodes of the element.
void Write(TPZStream &buf, int withclassid) const override
Writes this object to the TPZStream buffer. Include the classid if withclassid = true.
int64_t NElements() const
Number of elements of the mesh.
Definition: pzgmesh.h:129
void InsertPermuted()
Generate all permuted partitions and insert them in the mesh.
int operator==(const TPZAutoPointer< TPZRefPattern > compare) const
Utility class which represents an element with its side. The Geometric approximation classes Geometry...
Definition: pzgeoelside.h:83
TPZAutoPointer< TPZRefPattern > FindRefPattern(TPZTransform<> &trans)
clarg::argString input("-if", "input file", "cube1.txt")
int64_t NElements() const
Access method to query the number of elements of the vector.
TPZGeoElSide Neighbour() const
Definition: pzgeoel.h:754
AutoPointerMutexArrayInit tmp
TPZGeoMesh * Mesh() const
Returns the mesh to which the element belongs.
Definition: pzgeoel.h:220
virtual int NSides() const =0
Returns the number of connectivities of the element.
TPZTransform Transform(int subElSide, int sub)
It returns the TPZTransform associated with a certain sub-element&#39;s side to the father&#39;s coordinates...
void SetRefPatternMeshToMasterDomain()
Sets the RefPatternMesh in (x,y,z)_coordinates to (qsi,eta,zeta)_coordinates, always respecting the R...
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...
void InternalNodesIndexes(int side, TPZVec< TPZGeoElSideIndex > &nodeIndexes)
TPZGeoMesh fRefPatternMesh
Geometric mesh which defines the topology of the current refinement pattern.
virtual int SideDimension(int side) const =0
Return the dimension of side.
void CreateMidSideNodes(TPZGeoEl *gel, int side, TPZVec< int64_t > &newnodeindexes)
This method is used to create / identify the midside nodes for element elindex in its division proces...
void SetDimension(int dim)
Set Dimension.
Definition: pzgmesh.h:285
virtual void Resize(const int64_t newsize, const T &object)
Resizes the vector object.
Definition: pzmanvector.h:426
Data structure for storage of refinement information for a father&#39;s side.
Definition: TPZRefPattern.h:95
virtual void GetPermutation(const int &i, TPZVec< int > &permutation) const =0
TPZAutoPointer< TPZRefPattern > FindRefPattern(TPZAutoPointer< TPZRefPattern > &refpat)
Check whether the refinement pattern already exists.
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
void Read(TPZStream &buf, void *context) override
read objects from the stream
Definition: pzgmesh.cpp:1487
int SidePartition(TPZVec< TPZGeoElSide > &gelvec, int side)
It returns a stack from sub-elements and its sides. This stack partitions side of the element father...
TPZRefPatternDataBase gRefDBase
External variable to data base of patterns.
TPZAutoPointer< TPZRefPattern > SideRefPattern(int side)
Abstract class defining integration rules. Numerical Integration.
Definition: tpzintpoints.h:19
void CreateNewNodes(TPZGeoEl *gel, TPZVec< int64_t > &newnodeindexes)
This method is used to create / identify the nodes of the refined elements.
virtual void CenterPoint(int side, TPZVec< REAL > &masscent) const =0
It returns the coordinates from the center of the side of the element in the element coordinate space...
virtual std::string TypeName() const
Returns the type of the element as a string.
Definition: pzgeoel.h:262
Utility class which represents an element index with its side. Geometry.
Definition: pzgeoelside.h:33
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...
bool NameInitialized()
int64_t size() const
Returns the number of elements of the vector.
Definition: pzvec.h:196
void PrintVTK(std::ofstream &file, bool matColor=false) const
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
void Resize(const int newsize)
Increase the size of the chunk vector.
Definition: pzadmchunk.h:280
bool CheckSideAndSubElConsistency(const int fatherSide, const int subEl) const
static const double tol
Definition: pzgeoprism.cpp:23
void Push(const T object)
Pushes a copy of the object on the stack.
Definition: pzstack.h:80
virtual void SetNodeIndex(int i, int64_t nodeindex)=0
Initializes the node i of the element.
void Read(TPZStream &buf, void *context) override
read objects from the stream
void InternalSidesIndexes(int side, TPZVec< TPZGeoElSideIndex > &sideIndexes)
Fill a vector with TPZGeoElSideIndex_s with respect to internal subelements of a given side...
virtual void Write(const bool val)
Definition: TPZStream.cpp:8
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
Defines the behaviour of all geometric elements. GeometryTPZGeoEl is the common denominator for all g...
Definition: pzgeoel.h:43
int Id() const
Return the id of the refinement pattern.
int FatherSide(int side, int sub) const
Returns the father side associated with a given side of a certain sub element.
TPZGeoEl * Element(int64_t iel)
Definition: pzgmesh.h:139
virtual void SetFatherIndex(int64_t fatherindex)
Sets the father element index This method is not called SetFather in order to avoid implicit conversi...
Definition: pzgeoel.h:490
int64_t Index() const
Returns the index of the element within the element vector of the mesh.
Definition: pzgeoel.h:730
int FindSubEl(TPZGeoEl *) const
#define DebugStop()
Returns a message to user put a breakpoint in.
Definition: pzerror.h:20
void BuildSideMesh(int side, TPZGeoMesh &SideRefPatternMesh)
Build a geometric mesh associated with the side of the refinement pattern.
int64_t NNodes() const
Number of nodes of the mesh.
Definition: pzgmesh.h:126
virtual void SetOrder(TPZVec< int > &ord, int type=0)=0
Sets the order of the cubature rule.
int fNSubEl
Number of subelements. Must be available before the mesh is generated.
#define LOGPZ_DEBUG(A, B)
Define log for debug info.
Definition: pzlog.h:87
int MElementType_NNodes(MElementType elType)
constant which defines the type of HDiv approximation space
Definition: pzeltype.h:80
Definition: pzmatrix.h:52
void Read(TPZStream &buf, void *context) override
read objects from the stream
Definition: pztrnsform.h:90
virtual MElementType Type() const =0
Returns the element type acording to pzeltype.h.
TPZAdmChunkVector< TPZGeoNode > & NodeVec()
Definition: pzgmesh.h:140
std::string fName
Auxiliar structure to permute nodes.
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
void SideNodes(int fatherSide, TPZVec< int > &vecNodes)
It returns a TPZVec containing the nodes contained in a given father&#39;s side.
virtual void PrintTopologicalInfo(std::ostream &out=std::cout) const
Definition: pzgmesh.cpp:169
void Read(TPZStream &buf, void *context)
void SideSubGeoElSide(int fatherSide, int subElPos, TPZGeoElSide &subGeoEl) const
Gives information about the ith subelement contained in a given father&#39;s side.
#define LOGPZ_ERROR(A, B)
Define log for errors (cout)
Definition: pzlog.h:93
static std::map< MElementType, std::list< TPZRefPatternPermute > > fPermutations
Map of all valid permutations.
static void PrintGMeshVTK(TPZGeoMesh *gmesh, std::ofstream &file, bool matColor=true)
Default constructor for graphical mesh with VTK format.
Contains the TPZRefPattern class which defines the topology of the current refinement pattern to a me...
int NSideNodes(int fatherSide) const
Returns the number of internal nodes of side.
virtual int NSideNodes(int side) const =0
Returns the number of nodes for a particular side.
int32_t Hash(std::string str)
Definition: TPZHash.cpp:10
virtual int HasSubElement() const =0
Return 1 if the element has subelements.
virtual int NNodes() const =0
Returns the number of nodes of the element.
TPZGeoEl * Element() const
Definition: pzgeoelside.h:162
TPZVec< SPZFatherSideInfo > fFatherSideInfo
Data structure for storage of refinement information for each father&#39;s side fFatherSideInfo[i] will ...
int NSideSubGeoElSides(int fatherSide) const
Returns the number of TPZGeoElSides associated with a father&#39;s side.
void BuildConnectivity()
Build the connectivity of the grid.
Definition: pzgmesh.cpp:967
int fId
id of the refinement pattern
Contains the TPZRefPatternDataBase class which defines data base of patterns.
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...
Defines the topology of the current refinement pattern to a mesh. Refine.
Definition: TPZRefPattern.h:77
int64_t Id() const
Returns the Id of the element.
Definition: pzgeoel.h:223
TPZVec< int > fSideNodes
a vector of nodes contained in the i-th side
Definition: TPZRefPattern.h:97
bool ComputeXInverse(TPZVec< REAL > &XD, TPZVec< REAL > &ksi, REAL Tol)
Computes the XInverse and returns true if ksi belongs to master element domain.
Definition: pzgeoel.cpp:686
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...
int NSubElements() const
This class implements a geometric mesh for the pz environment. Geometry.
Definition: pzgmesh.h:48
MElementType
Define the element types.
Definition: pzeltype.h:52
virtual int ProjectInParametricDomain(TPZVec< REAL > &qsi, TPZVec< REAL > &qsiInDomain)=0
Ortogonal projection from given qsi to a qsiInDomain (all in the element parametric domain) ...
This class implements a stack object. Utility.
Definition: pzcheckmesh.h:14
void Print(std::ostream &out=std::cout) const
Prints the useful information of a Refinement Pattern in a ostream file.
int Side() const
Definition: pzgeoelside.h:169
void PrintMore(std::ostream &out=std::cout) const
void ResetConnectivities()
Reset all connectivities.
Definition: pzgmesh.cpp:1576
void SetFather(TPZGeoEl *father)
Sets the father element.
Definition: pzgeoel.h:481
static const std::string fNonInitializedName
Name for identifying a non initialized pattern.
Definition: TPZRefPattern.h:82
void Fill(const T &copy, const int64_t from=0, const int64_t numelem=-1)
Will fill the elements of the vector with a copy object.
Definition: pzvec.h:460
void ComputeTransforms()
Calculates the transforms between the parametric coordinates of the sides of the son to the father&#39;s ...
void Write(TPZStream &buf, int withclassid) const
TPZVec< int > fPermutedRefPatterns
Vector containing refinement patterns for each permutation of the master element. ...
void GeneratePermutations(TPZGeoEl *gel)
Automatically generate all permuted numberings for the father element of RefPatternMesh.
Defines the interface for saving and reading data. Persistency.
Definition: TPZStream.h:50
int64_t NElements() const
Returns the number of elements of the vector.
Definition: pzvec.h:190
void WritePattern(std::ofstream &out) const
Implements an affine transformation between points in parameter space. Topology Utility.
Definition: pzmganalysis.h:14
void SetMatrix(TPZFMatrix< T > &mult, TPZFMatrix< T > &sum)
Sets the transformation matrices.
Definition: pztrnsform.cpp:96
virtual int NPermutations() const =0
virtual void Print(std::ostream &out=std::cout)
Print all relevant data of the element to cout.
Definition: pzgeoel.cpp:238
void GenerateSideRefPatterns()
Generate the refinement patterns associated with the sides of the father element. ...
REAL ZeroTolerance()
Returns the tolerance to Zero value. Actually: .
Definition: pzreal.h:633
Contains the TPZVTKGeoMesh class which implements the graphical mesh to VTK environment to geometric ...
void push_back(const T object)
Definition: pzstack.h:48
void Read(TPZStream &buf, void *context) override
read objects from the stream
void Write(TPZStream &buf, int withclassid) const override
Writes this object to the TPZStream buffer. Include the classid if withclassid = true.
void ShortPrint(std::ostream &out=std::cout) const
void Apply(TPZVec< T > &vectorin, TPZVec< T > &vectorout)
Transforms the vector.
Definition: pztrnsform.cpp:121
Contains the TPZRefPatternTools class which defines tools of pattern.
This class generates all permutations of n values. Utility.
virtual int SolveDirect(TPZFMatrix< TVar > &F, const DecomposeType dt, std::list< int64_t > &singular)
Solves the linear system using Direct methods.
Definition: pzmatrix.cpp:710
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
void ComputePartition()
It computers the partition of the sides of the father element using the sides of the children...
void CreateRefinementPattern()
virtual void Read(bool &val)
Definition: TPZStream.cpp:91
TPZPermutation fPermute
permutation of the nodes
TPZAdmChunkVector< TPZGeoEl * > & ElementVec()
Methods for handling pzlists.
Definition: pzgmesh.h:138
int ClassId() const override
Define the class id associated with the class.
int NNodes() const
Returns the number of nodes of the mesh.