NeoPZ
TPZMHMixedMeshControl.cpp
Go to the documentation of this file.
1 //
2 // TPZMHMixedMeshControl.cpp
3 // PZ
4 //
5 // Created by Philippe Devloo on 09/10/16.
6 //
7 //
8 
10 #include "TPZVecL2.h"
11 #include "pzbndcond.h"
12 #include "TPZNullMaterial.h"
13 #include "TPZMatLaplacian.h"
14 #include "TPZLagrangeMultiplier.h"
15 
16 
17 #include <iostream>
18 #include <sstream>
19 #include <iterator>
20 #include <numeric>
21 
22 #include "pzsubcmesh.h"
23 
26 #include "TPZCompMeshTools.h"
27 #include "pzinterpolationspace.h"
28 #include "pzintel.h"
29 #include "TPZInterfaceEl.h"
31 
32 #include "TPZVTKGeoMesh.h"
33 #include "TPZNullMaterial.h"
34 
35 #ifdef LOG4CXX
36 static LoggerPtr logger(Logger::getLogger("pz.mhmixedmeshcontrol"));
37 #endif
38 
39 /*
40 TPZMHMixedMeshControl::TPZMHMixedMeshControl(TPZAutoPointer<TPZGeoMesh> gmesh, std::set<int64_t> &coarseindices) : TPZMHMeshControl(gmesh,coarseindices)
41 {
42  fFluxMesh = new TPZCompMesh(gmesh);
43  fFluxMesh->SetDimModel(gmesh->Dimension());
44  fCMesh = new TPZCompMesh(gmesh);
45  fCMesh->SetDimModel(gmesh->Dimension());
46 }
47 */
48 
50 {
51  fFluxMesh = new TPZCompMesh(gmesh);
52  fFluxMesh->SetDimModel(gmesh->Dimension());
53  fCMesh = new TPZMultiphysicsCompMesh(gmesh);
54  fCMesh->SetDimModel(gmesh->Dimension());
55 }
56 
58 {
63 }
64 
66 {
67  fFluxMesh = new TPZCompMesh(gmesh);
68  fFluxMesh->SetDimModel(gmesh->Dimension());
69  fCMesh = new TPZMultiphysicsCompMesh(gmesh);
70  fCMesh->SetDimModel(gmesh->Dimension());
71 }
72 
74 {
75  if(fCMesh)
76  {
77  fCMesh->CleanUp();
78  }
79  if(fFluxMesh)
80  {
81  int64_t nc = fFluxMesh->NConnects();
82  for (int64_t ic = 0; ic<nc; ic++) {
83  TPZConnect &c = fFluxMesh->ConnectVec()[ic];
84  if (c.HasDependency()) {
85  c.RemoveDepend();
86  }
87  }
88  fFluxMesh->CleanUp();
89  }
91  {
93  {
94  int64_t nc = fPressureFineMesh->NConnects();
95  for (int64_t ic = 0; ic<nc; ic++) {
97  if (c.HasDependency()) {
98  c.RemoveDepend();
99  }
100  }
101  }
103  }
104 }
105 
108 {
109  int matid = *fMaterialIds.begin();
110  TPZMaterial *mat = fCMesh->FindMaterial(matid);
111  if (!mat) {
112  DebugStop();
113  }
114  int nstate = mat->NStateVariables();
115  TPZFNMatrix<1,STATE> val1(nstate,nstate,0.), val2Flux(nstate,1,0.);
116  int typePressure = 0;
117 
118  if(fCMesh->MaterialVec().find(fSkeletonMatId) != fCMesh->MaterialVec().end())
119  {
120  std::cout << "Peripheral material inserted twice " << __PRETTY_FUNCTION__ << std::endl;
121  return;
122  }
123 
125  nullmat->SetDimension(mat->Dimension()-1);
126  nullmat->SetNStateVariables(nstate);
127  fCMesh->InsertMaterialObject(nullmat);
128 // TPZBndCond * bcFlux = mat->CreateBC(mat, fSkeletonMatId, typePressure, val1, val2Flux);
129  // bcN->SetForcingFunction(0,force);
130 // fCMesh->InsertMaterialObject(bcFlux);
131 
132 
133 
134 
135 }
136 
137 
138 
141 {
142  if (fpOrderInternal == 0 || fpOrderSkeleton == 0) {
143  DebugStop();
144  }
147 
149  if(fNState > 1){
152  }
153 #ifdef PZDEBUG
154  if (fFluxMesh->Dimension() != fGMesh->Dimension()) {
155  DebugStop();
156  }
157 #endif
158 
160  if(fNState > 1)
161  {
163  }
164 
166  std::cout << "Total number of equations " << fCMesh->Solution().Rows() << std::endl;
169 
171 #ifdef PZDEBUG2
172  {
173  std::ofstream out("Friendly.txt");
174  PrintFriendly(out);
175  }
177 #endif
178 
179  if (usersubstructure) {
180  HideTheElements();
181  }
182  fNumeq = fCMesh->NEquations();
183 
184 #ifdef PZDEBUG2
185  {
186  int64_t nel = fCMesh->NElements();
187  for(int64_t el = 0; el<nel; el++)
188  {
189  TPZCompEl *cel = fCMesh->Element(el);
190  TPZSubCompMesh *sub = dynamic_cast<TPZSubCompMesh *>(cel);
191  if(sub)
192  {
193  std::stringstream sout;
194  sout << "submesh_" << el << ".vtk";
195  std::ofstream file(sout.str());
196  TPZVTKGeoMesh::PrintCMeshVTK(sub, file,true);
197  }
198  }
199 
200  }
201 #endif
202 }
203 
204 
206 {
207  TPZCompMesh * cmeshHDiv = fFluxMesh.operator->();
208  cmeshHDiv->SetName("FluxMesh");
211 
212 #ifdef PZDEBUG
213  if(0)
214  {
215  std::ofstream out("FluxmeshBeforeSkeleton.txt");
216  fFluxMesh->Print(out);
217  }
218 #endif
219  CreateSkeleton();
220 
221  if (fHdivmaismais) {
222  int64_t nel = cmeshHDiv->ElementVec().NElements();
223  for (int64_t el = 0; el < nel; el++) {
224  TPZCompEl *cel = cmeshHDiv->ElementVec()[el];
225  TPZGeoEl *gel = cel->Reference();
226  if (gel->Dimension() == cmeshHDiv->Dimension()) {
227  int side = gel->NSides() - 1;
228  TPZInterpolatedElement *intel = dynamic_cast<TPZInterpolatedElement *> (cel);
229  intel->SetSideOrder(side, fpOrderInternal + fHdivmaismais);//seta ordem +hdivmais
231  }
232  }
233  cmeshHDiv->ExpandSolution();
234  }
235 
236  cmeshHDiv->ExpandSolution();
237 #ifdef PZDEBUG
238  if(0)
239  {
241  std::ofstream outmesh("MixedMeshControl_HDivMesh.txt");
242  Print(outmesh);
243  std::ofstream outvtk("MixedMesh.vtk");
244  TPZVTKGeoMesh::PrintGMeshVTK(fGMesh, outvtk,true);
245  }
246 #endif
247  return;
248 }
249 
252 {
253  TPZGeoMesh *gmesh = fGMesh.operator->();
254  int meshdim = gmesh->Dimension();
255  TPZCompMesh * cmeshHDiv = fFluxMesh.operator->();
256  gmesh->ResetReference();
257  cmeshHDiv->LoadReferences();
258  cmeshHDiv->SetDimModel(meshdim);
259  cmeshHDiv->ApproxSpace().SetAllCreateFunctionsHDiv(meshdim);
260  cmeshHDiv->SetDefaultOrder(fpOrderInternal);
261  if(fMaterialIds.size() == 0) DebugStop();
262  TPZMaterial *matl2;
263  for (auto item:fMaterialIds) {
264  TPZVecL2 *mat = new TPZVecL2(item);
265  matl2 = mat;
267  mat->SetDimension(meshdim);
268  cmeshHDiv->InsertMaterialObject(matl2);
269  }
270  for (auto item:fMaterialBCIds) {
271  TPZFNMatrix<1,STATE> val1(fNState,fNState,0.),val2(fNState,1,0.);
272  TPZBndCond *bc = matl2->CreateBC(matl2, item, 0, val1, val2);
273  cmeshHDiv->InsertMaterialObject(bc);
274  }
275  {
277  nullmat->SetDimension(meshdim-1);
278  nullmat->SetNStateVariables(fNState);
279  cmeshHDiv->InsertMaterialObject(nullmat);
280  if(fSecondSkeletonMatId != 0)
281  {
283  nullmat->SetDimension(meshdim-1);
284  nullmat->SetNStateVariables(fNState);
285  cmeshHDiv->InsertMaterialObject(nullmat);
286  }
287  }
288 
289 }
290 
291 
292 
294 {
295  TPZGeoMesh * gmesh = fGMesh.operator->();
296  gmesh->ResetReference();
297 
298  // the pressure mesh should be empty when calling this method
299  int64_t nskeletonconnects = fPressureFineMesh->NConnects();
300  if(nskeletonconnects != 0){
301  DebugStop();
302  }
303 
304  int porder = fpOrderInternal;
305  // create and organize the pressure mesh
306  // the pressure mesh is composed of discontinuous H1 elements
307  TPZCompMesh * cmeshPressure = fPressureFineMesh.operator->();
308  gmesh->ResetReference();
309  cmeshPressure->SetName("PressureMesh");
310  cmeshPressure->SetDimModel(gmesh->Dimension());
311  cmeshPressure->SetAllCreateFunctionsDiscontinuous(); //AQUI
312  cmeshPressure->ApproxSpace().CreateDisconnectedElements(true);
313  cmeshPressure->SetDefaultOrder(porder + fHdivmaismais);
314  int meshdim = cmeshPressure->Dimension();
315  // generate elements for all material ids of meshdim
316  std::set<int> matids;
317  for (auto it:fMaterialIds) {
318  TPZMaterial *mat = cmeshPressure->FindMaterial(it);
319  if (mat && mat->Dimension() == meshdim) {
320  matids.insert(it);
321  }
322  }
323  cmeshPressure->AutoBuild(matids);
325 
326  if(0)
327  {
328  std::ofstream out("PressureFineMesh.txt");
329  fPressureFineMesh->Print(out);
330  }
331 
332 
333 #ifdef PZDEBUG
334  // a very strange check!! Why does material id 1 need to be volumetric?
335  {
336  int64_t nel = fGMesh->NElements();
337  for (int64_t el = 0; el<nel; el++) {
338  TPZGeoEl *gel = fGMesh->Element(el);
339  if (gel && gel->MaterialId() == 1) {
340  if (gel->Dimension() != fGMesh->Dimension()) {
341  DebugStop();
342  }
343  }
344  }
345  }
346 #endif
347 
348  // the lagrange multiplier level is set to one
349  int64_t nc = cmeshPressure->NConnects();
350  for (int64_t ic=nskeletonconnects; ic<nc; ic++) {
351  cmeshPressure->ConnectVec()[ic].SetLagrangeMultiplier(1);
352  }
353  // associate the connects with the proper subdomain
354  gmesh->ResetReference();
355  int64_t nel = cmeshPressure->NElements();
356  for (int64_t el=0; el<nel; el++)
357  {
358  TPZCompEl *cel = cmeshPressure->Element(el);
359 #ifdef PZDEBUG
360  if (! cel) {
361  DebugStop();
362  }
363 #endif
364  // if a computational element was created outside the range of material ids
365  // something very strange happened...
366  TPZGeoEl *gel = cel->Reference();
367  if(fMaterialIds.find (gel->MaterialId()) == fMaterialIds.end())
368  {
369  DebugStop();
370  }
371  int domain = fGeoToMHMDomain[gel->Index()];
372 #ifdef PZDEBUG
373  if (domain == -1) {
374  DebugStop();
375  }
376 #endif
377 
378  SetSubdomain(cel, domain);
379  }
380 
381  if(0){
382  std::ofstream out("PressureFineMesh2.txt");
383  fPressureFineMesh->Print(out);
384  }
385 
386  return;
387 }
388 
389 
391 {
392  TPZGeoMesh * gmesh = fGMesh.operator->();
393  gmesh->ResetReference();
394  int porder = fpOrderInternal;
395  TPZCompMesh * cmeshRotation = fRotationMesh.operator->();
396  gmesh->ResetReference();
397  cmeshRotation->SetName("RotationMesh");
398  cmeshRotation->SetDimModel(gmesh->Dimension());
400  cmeshRotation->SetDefaultOrder(porder);
401 
402  int meshdim = cmeshRotation->Dimension();
403  std::set<int> matids;
404  for (auto it:fMaterialIds) {
405  TPZMaterial *mat = cmeshRotation->FindMaterial(it);
406  if (mat && mat->Dimension() == meshdim) {
407  matids.insert(it);
408  }
409  }
410  cmeshRotation->AutoBuild(matids);
412 
413  if(0)
414  {
415  std::ofstream out("RotationsMesh.txt");
416  fPressureFineMesh->Print(out);
417  }
418 
419 
420  int64_t nel = cmeshRotation->NElements();
421  for(int64_t i=0; i<nel; i++){
422  TPZCompEl *cel = cmeshRotation->ElementVec()[i];
423  TPZCompElDisc *celdisc = dynamic_cast<TPZCompElDisc *>(cel);
424  if(!celdisc) DebugStop();
425  if(celdisc && celdisc->Reference()->Dimension() != meshdim)
426  {
427  DebugStop();
428  }
429  celdisc->SetTotalOrderShape();
430  celdisc->SetFalseUseQsiEta();
431  }
432 
433  int64_t nc = cmeshRotation->NConnects();
434  for (int64_t ic=0; ic<nc; ic++) {
435  cmeshRotation->ConnectVec()[ic].SetLagrangeMultiplier(1);
436  }
437  gmesh->ResetReference();
438 
439  for (int64_t el=0; el<nel; el++)
440  {
441  TPZCompEl *cel = cmeshRotation->Element(el);
442 #ifdef PZDEBUG
443  if (! cel) {
444  DebugStop();
445  }
446 #endif
447  TPZGeoEl *gel = cel->Reference();
448  if(fMaterialIds.find (gel->MaterialId()) == fMaterialIds.end())
449  {
450  continue;
451  }
452 #ifdef PZDEBUG
453  if (fGeoToMHMDomain[gel->Index()] == -1) {
454  DebugStop();
455  }
456 #endif
457 
458  SetSubdomain(cel, fGeoToMHMDomain[gel->Index()]);
459  }
460 
461 
462  return;
463 }
464 
467 {
468  TPZCompMesh * cmeshPressure = fPressureFineMesh.operator->();
469 
470 
471  for (auto it = fMaterialIds.begin(); it != fMaterialIds.end(); it++)
472  {
473  int matid = *it;
474  if (cmeshPressure->MaterialVec().find(matid) == cmeshPressure->MaterialVec().end())
475  {
476  TPZNullMaterial *matl2 = new TPZNullMaterial((matid));
477  matl2->SetNStateVariables(fNState);
478  matl2->SetDimension(fGMesh->Dimension());
479  cmeshPressure->InsertMaterialObject(matl2);
480  }
481  else
482  {
483  DebugStop();
484  }
485  }
486  if(fPressureSkeletonMatId != 0)
487  {
489  DebugStop();
490  }
492  mathybrid->SetDimension(fGMesh->Dimension()-1);
493  mathybrid->SetNStateVariables(fNState);
495  }
496  else
497  {
498  DebugStop();
499  }
500 
501 }
502 
505 {
506  TPZCompMesh * cmeshRotation = fRotationMesh.operator->();
507 
508  for (auto it = fMaterialIds.begin(); it != fMaterialIds.end(); it++)
509  {
510  int matid = *it;
511  if (cmeshRotation->MaterialVec().find(matid) == cmeshRotation->MaterialVec().end())
512  {
513  TPZNullMaterial *matl2 = new TPZNullMaterial((matid));
514  if(fNState == 2)
515  {
516  matl2->SetNStateVariables(1);
517  } else if(fNState == 3)
518  {
519  matl2->SetNStateVariables(fNState);
520  }
521  matl2->SetDimension(fGMesh->Dimension());
522  cmeshRotation->InsertMaterialObject(matl2);
523  }
524  else
525  {
526  DebugStop();
527  }
528  }
529 
530 }
531 
532 
533 
535 {
537  cmeshes[0] = fFluxMesh.operator->();
538  cmeshes[1] = fPressureFineMesh.operator->();
539 
540  {
541  std::ofstream out("PressureMesh_MultiPhis.txt");
542  cmeshes[1] ->Print(out);
543 
544  std::ofstream out2("FluxMesh_MultiPhis.txt");
545  cmeshes[0] ->Print(out2);
546  }
547 
548 
549  if(fNState > 1) {
550  cmeshes.Resize(3);
551  cmeshes[2] = fRotationMesh.operator->();
552  }
553  TPZGeoMesh *gmesh = cmeshes[0]->Reference();
554  if(!gmesh)
555  {
556  std::cout<< "Geometric mesh doesn't exist" << std::endl;
557  DebugStop();
558  }
559  int dim = gmesh->Dimension();
560  gmesh->ResetReference();
561  // Multiphysics mesh
562  TPZCompMesh * MixedFluxPressureCmesh = fCMesh.operator->();
563  MixedFluxPressureCmesh->SetDimModel(dim);
564  MixedFluxPressureCmesh->SetAllCreateFunctionsMultiphysicElem();
565 
568 
569 #ifdef PZDEBUG
570  if(0)
571  {
572  std::ofstream out2("gmesh.txt");
573  gmesh->Print(out2);
574  std::ofstream out3("HDivMesh.txt");
575  fFluxMesh->Print(out3);
576  std::ofstream out4("PressureMesh.txt");
577  fPressureFineMesh->Print(out4);
578  }
579 #endif
580 
581  meshvector = cmeshes;
582 
583  // populate the connect to subdomain data structure for the multiphysics mesh
584  JoinSubdomains(meshvector, MixedFluxPressureCmesh);
585 
586  // Transferindo para a multifisica
587 // TPZBuildMultiphysicsMesh::AddElements(meshvector, MixedFluxPressureCmesh);
588 // TPZBuildMultiphysicsMesh::AddConnects(meshvector, MixedFluxPressureCmesh);
589  // copy the solution of the atomic meshes to the multiphysics mesh
590  TPZBuildMultiphysicsMesh::TransferFromMeshes(meshvector, MixedFluxPressureCmesh);
591 
592  std::pair<int,int> skelmatid(fSkeletonMatId,fSecondSkeletonMatId);
595 #ifdef PZDEBUG
596  if(0)
597  {
598  MixedFluxPressureCmesh->ComputeNodElCon();
599  std::ofstream file("cmeshmphys.vtk");
600  TPZVTKGeoMesh::PrintCMeshVTK(MixedFluxPressureCmesh, file,true);
601  std::ofstream out("cmeshmphys.txt");
602  MixedFluxPressureCmesh->Print(out);
603  }
604 #endif
605  MixedFluxPressureCmesh->CleanUpUnconnectedNodes();
606 
607 #ifdef PZDEBUG
608  if(0)
609  {
610  std::ofstream out("multiphysics.txt");
611  MixedFluxPressureCmesh->Print(out);
612  }
613 #endif
614 
615  return;
616 
617 }
618 
620 {
621  bool KeepOneLagrangian = true;
622  if (fHybridize) {
623  KeepOneLagrangian = false;
624  }
625  typedef std::set<int64_t> TCompIndexes;
626  std::map<int64_t, TCompIndexes> ElementGroups;
627  TPZGeoMesh *gmesh = fCMesh->Reference();
628  gmesh->ResetReference();
629  int dim = gmesh->Dimension();
631  int64_t nel = fCMesh->NElements();
632  for (int64_t el=0; el<nel; el++) {
633  TPZCompEl *cel = fCMesh->Element(el);
634  int64_t domain = WhichSubdomain(cel);
635  if (domain == -1) {
636  continue;
637  }
638  ElementGroups[domain].insert(el);
639  }
640  if (ElementGroups.size() <= 10)
641  {
642  std::cout << "Number of element groups " << ElementGroups.size() << std::endl;
643  std::map<int64_t,TCompIndexes>::iterator it;
644  for (it=ElementGroups.begin(); it != ElementGroups.end(); it++) {
645  std::cout << "Group " << it->first << " group size " << it->second.size() << std::endl;
646  std::cout << " elements ";
647  std::set<int64_t>::iterator its;
648  for (its = it->second.begin(); its != it->second.end(); its++) {
649  std::cout << *its << "|" << fCMesh->Element(*its)->Reference()->Index() << " ";
650  }
651  std::cout << std::endl;
652  }
653  }
654 
655  std::map<int64_t,int64_t> submeshindices;
656  TPZCompMeshTools::PutinSubmeshes(fCMesh.operator->(), ElementGroups, submeshindices, KeepOneLagrangian);
657  std::cout << "After putting in substructures\n";
658  fMHMtoSubCMesh = submeshindices;
661 
663 
664  std::cout << "Finished substructuring\n";
665 }
666 
668 void TPZMHMixedMeshControl::Print(std::ostream &out)
669 {
670 
672  if (fGMesh)
673  {
674  out << "******************* GEOMETRIC MESH *****************\n";
675  fGMesh->Print(out);
676  }
677 
679  // this mesh is the same as fCMesh if there are no lagrange multipliers assocated with the average pressure
680  if (fFluxMesh)
681  {
682  out << "******************* FLUX MESH *****************\n";
683  fFluxMesh->Print(out);
684  }
685 
687  // this mesh is the same as fCMesh if there are no lagrange multipliers assocated with the average pressure
688  if (fPressureFineMesh)
689  {
690  out << "******************* PRESSURE MESH *****************\n";
691  fPressureFineMesh->Print(out);
692  }
693 
694 
696  if (fCMesh)
697  {
698  out << "******************* COMPUTATIONAL MESH *****************\n";
699  fCMesh->Print(out);
700  }
701 
703  if (fCMeshLagrange)
704  {
705  out << "******************* LAGRANGE MULTIPLIER MESH *****************\n";
706  fCMeshLagrange->Print(out);
707  }
708 
711  {
712  out << "******************* CONSTANTE PRESSURE MESH *****************\n";
714  }
715 
717  out << "Skeleton Mat Id " << fSkeletonMatId << std::endl;
718 
720  out << "Lagrange mat id left - right " << fLagrangeMatIdLeft << " - " << fLagrangeMatIdRight << std::endl;
721 
723  out << "Internal polynomial order " << fpOrderInternal << std::endl;
724 
726  out << "Skeleton polynomial order " << fpOrderSkeleton << std::endl;
727 
729  {
730  out << "Geometric element indices of the coarse mesh ";
731  for (std::map<int64_t,int64_t>::iterator it= fMHMtoSubCMesh.begin(); it != fMHMtoSubCMesh.end(); it++) {
732  out << it->first << " " << it->second << " ";
733  }
734  out << std::endl;
735  }
737  out << "Skeleton element indices with associated left and right coarse element indices\n";
738  {
739  std::map<int64_t, std::pair<int64_t,int64_t> >::iterator it;
740  for (it = fInterfaces.begin(); it != fInterfaces.end(); it++) {
741  out << "skel index " << it->first << " Left Right indices " << it->second.first << " " << it->second.second << std::endl;
742  }
743  }
744 
746 
749  out << "Will generate a constant pressure mesh " << fLagrangeAveragePressure << std::endl;
751  out << "Subdomain indices of the connects by mesh\n";
752  for (auto it = fConnectToSubDomainIdentifier.begin(); it != fConnectToSubDomainIdentifier.end(); it++) {
753  TPZCompMesh *cmesh = it->first;
754  TPZManVector<int64_t> &cvec = it->second;
755  out << "Computational mesh pointer " << (void *) cmesh << std::endl;
756  for (int64_t i=0; i<cvec.size(); i++) {
757  if (i && !(i%20)) {
758  out << std::endl;
759  }
760  out << "(" << i << "->" << cvec[i] << ") ";
761  }
762  out << std::endl;
763  }
764 
765 }
766 
767 static void SetSubMatid(TPZGeoEl *gel, int matid)
768 {
769  int nsub = gel->NSubElements();
770  for (int isub=0; isub < nsub; isub++) {
771  TPZGeoEl *subel = gel->SubElement(isub);
772  subel->SetMaterialId(matid);
773  SetSubMatid(subel, matid);
774  }
775 }
776 static void SetAllMatid(TPZGeoEl *gel, int matid)
777 {
778  gel->SetMaterialId(matid);
779  TPZGeoEl *fat = gel->Father();
780  while (fat) {
781  fat->SetMaterialId(matid);
782  fat = fat->Father();
783  }
784  SetSubMatid(gel, matid);
785 }
786 
787 void TPZMHMixedMeshControl::HybridizeSkeleton(int skeletonmatid, int pressurematid)
788 {
789 
791  int64_t nskel = fInterfaces.size();
792  std::map<int64_t, std::pair<int64_t, int64_t> >::iterator it;
796 
798  // build the fluxorig datastructure : contains the original flux elements
799  // loop over the skeleton elements
800  for (it = fInterfaces.begin(); it != fInterfaces.end(); it++) {
801  TPZGeoEl *gel = fGMesh->Element(it->first);
802  // skip the boundary elements
803  if (it->first == it->second.second) {
804  continue;
805  }
806  if (gel->MaterialId() != skeletonmatid) {
807  continue;
808  }
809  int side = gel->NSides()-1;
810  TPZInterpolatedElement *orig = dynamic_cast<TPZInterpolatedElement *>(gel->Reference());
811  fluxorig.Push(orig);
812  }
814 
816  // first create a second flux element and a pressure element on top of the existing skeleton element
817  // loop over the skeleton elements
818  for (it = fInterfaces.begin(); it != fInterfaces.end(); it++) {
819  TPZGeoEl *gel = fGMesh->Element(it->first);
820  // skip the boundary elements
821  if (it->first == it->second.second) {
822  continue;
823  }
824  if (gel->MaterialId() != skeletonmatid) {
825  continue;
826  }
827  int side = gel->NSides()-1;
828  TPZGeoElSide gelside(gel,side);
829  TPZGeoElBC skeleton2(gelside,fSecondSkeletonMatId);
831  // create a flux boundary element
832  int64_t indexflux;
833  fFluxMesh->CreateCompEl(skeleton2.CreatedElement(), indexflux);
834  TPZInterpolatedElement *intel = dynamic_cast<TPZInterpolatedElement *>(fFluxMesh->Element(indexflux));
835  SetSubdomain(intel, -1);
836 #ifdef PZDEBUG
837  if (intel->NConnects() != 1) {
838  DebugStop();
839  }
840 #endif
841  // the side orientation of the boundary fluxes is +1 - we will need to fix the elements as well!
842  if (it->second.first < it->second.second) {
843  // totototo
844  intel->SetSideOrient(side, 1);
845  }
846  else
847  {
848  intel->SetSideOrient(side, 1);
849  }
850  skeleton2.CreatedElement()->ResetReference();
851 
852  // create a dim-1 dimensional pressure element
853  TPZGeoElBC pressuregel(gelside,pressurematid);
854  // this will be changed to the pressure mesh
855 // fFluxMesh->SetAllCreateFunctionsContinuous();
857  int64_t indexpressure;
858 // fFluxMesh->CreateCompEl(pressuregel.CreatedElement(), indexpressure);
859  fPressureFineMesh->CreateCompEl(pressuregel.CreatedElement(), indexpressure);
860  TPZInterpolatedElement *presel = dynamic_cast<TPZInterpolatedElement *>(fPressureFineMesh->Element(indexpressure));
861  SetSubdomain(presel, -1);
862  // set the lagrange multiplier to the highest level
863  int nc = presel->NConnects();
864  for (int ic=0; ic<nc; ic++) {
865  TPZConnect &c = presel->Connect(ic);
867  }
868  // This can only be done after all flux connects have been created!!!
869 // SetSubdomain(presel, -1);
870  pressuregel.CreatedElement()->ResetReference();
871  fluxsecond.Push(intel);
872  pressure.Push(presel);
873  }
875 
876  // switch the connect dependency around AND fix the side orientation
877  int64_t count = 0;
878  for (it = fInterfaces.begin(); it != fInterfaces.end(); it++) {
879  TPZGeoEl *gel = fGMesh->Element(it->first);
880  // skip the boundary elements
881  if (it->first == it->second.second) {
882  continue;
883  }
884  if (gel->MaterialId() != skeletonmatid) {
885  continue;
886  }
887  TPZCompEl *cel = gel->Reference();
888  if (!cel || cel != fluxorig[count]) {
889  DebugStop();
890  }
891  std::map<int64_t,std::list<TPZCompElSide> > connectedmap;
892  // connected elements will compute all the subelements of the skeleton element to left and right
893  ConnectedElements(it->first, it->second, connectedmap);
894  if (connectedmap.size() != 2) {
895  DebugStop();
896  }
897  // identify the domains left and right of the skeleton element
898  int64_t origdepindex = fluxorig[count]->ConnectIndex(0);
899  int64_t newdepindex = fluxsecond[count]->ConnectIndex(0);
900  std::list<TPZCompElSide> &updatelist = connectedmap[it->second.second];
901  for (std::list<TPZCompElSide>::iterator itlist = updatelist.begin(); itlist != updatelist.end(); itlist++)
902  {
903  TPZCompElSide smallCompElSide = *itlist;
904  TPZInterpolatedElement *smallel = dynamic_cast<TPZInterpolatedElement *>(smallCompElSide.Element());
905  if (smallel->NSideConnects(smallCompElSide.Side()) != 1) {
906  DebugStop();
907  }
908  TPZConnect &c = smallel->SideConnect(0, smallCompElSide.Side());
910  if(dep->fDepConnectIndex != origdepindex)
911  {
912  DebugStop();
913  }
914  dep->fDepConnectIndex = newdepindex;
915  // Set the side orientation to +1
916  smallel->SetSideOrient(smallCompElSide.Side(), 1);
917  }
918  SetSubdomain(fluxorig[count],it->second.first);
919  SetSubdomain(fluxsecond[count], it->second.second);
920  count++;
921  }
923  // switch the reference index of the original flux element and the pressure element
924  int64_t numflux = fluxorig.size();
925  for (int iflux=0; iflux<numflux; iflux++) {
926  int64_t fluxgelindex = fluxorig[iflux]->Reference()->Index();
927  int fluxmat = fluxorig[iflux]->Reference()->MaterialId();
928  int pressmat = pressure[iflux]->Reference()->MaterialId();
929  int64_t pressuregelindex = pressure[iflux]->Reference()->Index();
930  fluxorig[iflux]->SetReference(pressuregelindex);
931  pressure[iflux]->SetReference(fluxgelindex);
932  SetAllMatid(fluxorig[iflux]->Reference(), fluxmat);
933  SetAllMatid(pressure[iflux]->Reference(), pressmat);
934  }
935 
936  // The connects of the pressure mesh are not to be condensed
939 
940 }
941 
942 
943 // create the elements domain per domain with approximation spaces disconnected from each other
945 {
946  TPZGeoMesh *gmesh = fGMesh.operator->();
947  int meshdim = gmesh->Dimension();
948  TPZCompMesh * cmeshHDiv = fFluxMesh.operator->();
949  gmesh->ResetReference();
950  cmeshHDiv->LoadReferences();
951  cmeshHDiv->SetDimModel(meshdim);
952  cmeshHDiv->ApproxSpace().SetAllCreateFunctionsHDiv(meshdim);
953  cmeshHDiv->SetDefaultOrder(fpOrderInternal);
954 
955 
956  //Criar elementos computacionais malha MHM
957 
958  TPZGeoEl *gel = NULL;
959  TPZGeoEl *gsubel = NULL;
960  fConnectToSubDomainIdentifier[cmeshHDiv].Expand(10000);
961  int64_t nel = fGMesh->NElements();
962 
963  for (auto it = fMHMtoSubCMesh.begin(); it != fMHMtoSubCMesh.end(); it++)
964  {
965  // create a flux mesh one subdomain at a time
967  for (int64_t el = 0; el<nel; el++) {
968  TPZGeoEl *gel = fGMesh->Element(el);
969  if (!gel || gel->HasSubElement() || fGeoToMHMDomain[el] != it->first) {
970  continue;
971  }
972  int64_t index;
973  // create the flux element
974  cmeshHDiv->CreateCompEl(gel, index);
975  TPZCompEl *cel = cmeshHDiv->Element(index);
977  SetSubdomain(cel, it->first);
978  }
979 
980 
981  }
982 
985 }
986 
989 {
990  // comment this line or not to switch the type of skeleton elements
991  int meshdim = fFluxMesh->Dimension();
994  int order = fpOrderSkeleton;
995  if (order <= 0) {
996  order = 1;
997  }
998  // create the skeleton elements without applying the restraints of the elements of the subdomains
999  fFluxMesh->SetDefaultOrder(order);
1000  std::map<int64_t, std::pair<int64_t,int64_t> >::iterator it = fInterfaces.begin();
1001  while (it != fInterfaces.end()) {
1002  int64_t elindex = it->first;
1003  // skip the boundary elements
1004  // if (elindex == it->second.second) {
1005  // it++;
1006  // continue;
1007  // }
1008  TPZGeoEl *gel = fGMesh->ElementVec()[elindex];
1009  int64_t index;
1010  // create an element to model the flux between subdomains
1011  fFluxMesh->CreateCompEl(gel, index);
1012  TPZCompEl *cel = fFluxMesh->ElementVec()[index];
1013  int Side = gel->NSides()-1;
1014  TPZInterpolationSpace *intel = dynamic_cast<TPZInterpolationSpace *>(cel);
1015  SetSubdomain(cel, -1);
1016 
1017 
1018  if (elindex == it->second.second) {
1019  // this is a boundary element
1020  // set the side orientation of the boundary elements
1021  intel->SetSideOrient(Side, 1);
1022  SetSubdomain(cel, it->second.first);
1023  }
1024  else
1025  {
1026  if (it->second.first < it->second.second) {
1027  // set the flux orientation depending on the relative value of the element ids
1028  intel->SetSideOrient(Side, 1);
1029  }
1030  else
1031  {
1032  intel->SetSideOrient(Side, -1);
1033  }
1034  // this element will not be put in a subdomain
1035  SetSubdomain(cel, -1);
1036  }
1037  gel->ResetReference();
1038 
1039  it++;
1040  }
1041  // Apply restraints to the element/sides and the skeleton
1043 #ifdef PZDEBUG
1044  if(0)
1045  {
1046  std::ofstream out("FluxBeforeInterfaces.vtk");
1047  TPZVTKGeoMesh::PrintCMeshVTK(fFluxMesh.operator->(), out);
1048  }
1049 #endif
1050 #ifdef PZDEBUG
1051  // verify if any connect is restrained
1052  {
1053  int64_t nconnects = fFluxMesh->NConnects();
1054  for (int64_t ic = 0; ic<nconnects; ic++) {
1055  TPZConnect &c = fFluxMesh->ConnectVec()[ic];
1056  if (c.HasDependency()) {
1057  std::cout << "Connect index " << ic << " Has dependency\n";
1058  }
1059  }
1060  }
1061 #endif
1062  it = fInterfaces.begin();
1063  while (it != fInterfaces.end()) {
1064  // the index of the map of the interface data structure is the index of the geometric element
1065  int64_t elindex = it->first;
1066 
1067  // data structure containing the list of connected elements by subdomain
1068  std::map<int64_t,std::list<TPZCompElSide> > subels;
1069  // find the connected computational elements in function of the index of the geometric element
1070  ConnectedElements(elindex, it->second, subels);
1071 
1072 #ifdef LOG4CXX
1073  if(logger->isDebugEnabled())
1074  {
1075  std::stringstream sout;
1076  sout << "Interface elindex " << elindex << " left " << it->second.first << " right " << it->second.second << std::endl;
1077  sout << "Number of connected subdomains " << subels.size() << std::endl;
1078  for (std::map<int64_t,std::list<TPZCompElSide> >::iterator itlist = subels.begin(); itlist != subels.end(); itlist++)
1079  {
1080  sout << " SUBDOMAIN first " << itlist->first << "\n";
1081  std::list<TPZCompElSide> &lst = itlist->second;
1082  for (std::list<TPZCompElSide>::iterator its = lst.begin(); its != lst.end(); its++)
1083  {
1084  sout << " GeoElSide " << its->Reference() << std::endl;
1085  }
1086  }
1087  LOGPZ_DEBUG(logger,sout.str())
1088  }
1089 #endif
1090  TPZGeoEl *gel = fGMesh->ElementVec()[elindex];
1091  int side = gel->NSides()-1;
1092  TPZCompEl *cel = gel->Reference();
1093  // intel contains the flux skeleton element
1094  TPZInterpolatedElement *intel = dynamic_cast<TPZInterpolatedElement *>(cel);
1095 
1096  for (std::map<int64_t,std::list<TPZCompElSide> >::iterator itlist = subels.begin(); itlist != subels.end(); itlist++) {
1097  std::list<TPZCompElSide> &lst = itlist->second;
1098  for (std::list<TPZCompElSide>::iterator its = lst.begin(); its != lst.end(); its++) {
1099  TPZInterpolatedElement *intelsub = dynamic_cast<TPZInterpolatedElement *>(its->Element());
1100  if (!intelsub) {
1101  DebugStop();
1102  }
1103  intelsub->RestrainSide(its->Side(), intel, side);
1104  }
1105  }
1106  it++;
1107  }
1108  // this will renumber the connects that are now constrained
1110  fFluxMesh->SetDimModel(meshdim);
1111 }
1112 
1113 
1114 /*
1115 TPZGeoMesh *gmesh = fGMesh.operator->();
1116 int meshdim = gmesh->Dimension();
1117 TPZCompMesh * cmeshHDiv = fFluxMesh.operator->();
1118 gmesh->ResetReference();
1119 cmeshHDiv->LoadReferences();
1120 cmeshHDiv->SetDimModel(meshdim);
1121 cmeshHDiv->ApproxSpace().SetAllCreateFunctionsHDiv(meshdim);
1122 cmeshHDiv->SetDefaultOrder(fpOrderInternal);
1123 TPZVecL2 *matl2 = new TPZVecL2(1);
1124 cmeshHDiv->InsertMaterialObject(matl2);
1125 matl2 = new TPZVecL2(2);
1126 cmeshHDiv->InsertMaterialObject(matl2);
1127 TPZFNMatrix<1,STATE> val1(1,1,0.),val2(1,1,0.);
1128 TPZBndCond *bc = matl2->CreateBC(matl2, -1, 0, val1, val2);
1129 cmeshHDiv->InsertMaterialObject(bc);
1130 bc = matl2->CreateBC(matl2, -2, 0, val1, val2);
1131 cmeshHDiv->InsertMaterialObject(bc);
1132 bc = matl2->CreateBC(matl2, fSkeletonMatId, 0, val1, val2);
1133 cmeshHDiv->InsertMaterialObject(bc);
1134 
1135 int LagrangeMatIdLeft = 50;
1136 int LagrangeMatIdRight = 51;
1137 int nstate = 1;
1138 TPZLagrangeMultiplier *matleft = new TPZLagrangeMultiplier(LagrangeMatIdLeft,meshdim,nstate);
1139 TPZLagrangeMultiplier *matright = new TPZLagrangeMultiplier(LagrangeMatIdRight,meshdim,nstate);
1140 matleft->SetMultiplier(-1.);
1141 matright->SetMultiplier(-1.);
1142 cmeshHDiv->InsertMaterialObject(matleft);
1143 cmeshHDiv->InsertMaterialObject(matright);
1144 
1145 
1146 std::set<int> materialids;
1147 materialids.insert(1);
1148 materialids.insert(-1);
1149 materialids.insert(-2);
1150 cmeshHDiv->AutoBuild(materialids);
1151 
1152 cmeshHDiv->SetDefaultOrder(fpOrderSkeleton);
1153 materialids.clear();
1154 materialids.insert(fSkeletonMatId);
1155 cmeshHDiv->AutoBuild(materialids);
1156 
1157 
1158 // set the subdomain index of the connects for the flux elements
1159 std::map<int64_t,int64_t>::iterator it;
1160 for(it = fCoarseIndices.begin(); it != fCoarseIndices.end(); it++)
1161 {
1162  TPZGeoEl *gel = fGMesh->Element(it->first);
1163  TPZStack<TPZCompElSide> connected;
1164  TPZGeoElSide gelside(gel,gel->NSides()-1);
1165  gelside.EqualorHigherCompElementList2(connected, 0, 0);
1166  int nst = connected.size();
1167  for (int64_t ist = 0; ist<nst; ist++) {
1168  TPZCompEl *cel = connected[ist].Element();
1169  SetSubdomain(cel, it->first);
1170  }
1171 }
1172 */
1173 
1176 {
1177  std::pair<int,int> skelmatid(fSkeletonMatId,fSecondSkeletonMatId);
1179 }
1180 
1181 
1184 // neighbouring flux elements
1185 void TPZMHMixedMeshControl::CreateMultiPhysicsInterfaceElements(int dim, int pressmatid, std::pair<int,int> hdivmatid)
1186 {
1187  TPZCompMesh * cmeshPressure = fPressureFineMesh.operator->();
1188 
1189  // Computational multiplysics mesh
1190  TPZCompMesh * MixedFluxPressureCmesh = fCMesh.operator->();
1191  // load only dim dimensional elements
1192  MixedFluxPressureCmesh->Reference()->ResetReference();
1193  int64_t nel = MixedFluxPressureCmesh->NElements();
1194  for (int64_t el=0; el<nel; el++) {
1195  TPZCompEl *cel = MixedFluxPressureCmesh->Element(el);
1196  if (!cel || !cel->Reference()) {
1197  continue;
1198  }
1199  TPZGeoEl *gel = cel->Reference();
1200  if (gel->Dimension() != dim) {
1201  continue;
1202  }
1203  cel->LoadElementReference();
1204  }
1205 
1206  // for each pressure element neighbour of a skeleton element create two interface elements
1207  nel = cmeshPressure->NElements();
1208  for (int64_t el = 0; el<nel; el++) {
1209  TPZCompEl *cel = cmeshPressure->Element(el);
1210  if (!cel || !cel->Reference()) {
1211  continue;
1212  }
1213  TPZGeoEl *gel = cel->Reference();
1214  if (gel->Dimension() != dim || gel->MaterialId() != pressmatid) {
1215  continue;
1216  }
1217  if(!gel->Reference())
1218  {
1219  DebugStop();
1220  }
1221  TPZGeoElSide gelside(gel,gel->NSides()-1);
1222  // look for an fSkeletonWrapMatId element
1223  TPZGeoElSide neighbour = gelside.Neighbour();
1224  while (neighbour != gelside) {
1225  if (neighbour.Element()->MaterialId() == fSkeletonWrapMatId) {
1226  break;
1227  }
1228  neighbour = neighbour.Neighbour();
1229  }
1230  // we ignore elements without neighbouring fSkeletonWrapMatId?
1231  if (neighbour == gelside) {
1232  continue;
1233  }
1234  TPZStack<TPZCompElSide> celstack;
1235  // This method will put all equallevel elements on the stack, including the reference to the current element
1236  // Reference to the current element will be put last on the stack
1237  neighbour = gelside.Neighbour();
1238  while (neighbour != gelside) {
1239  if (neighbour.Element()->MaterialId() == hdivmatid.first || neighbour.Element()->MaterialId() == hdivmatid.second) {
1240  celstack.Push(neighbour.Reference());
1241  }
1242  neighbour = neighbour.Neighbour();
1243  }
1244  if (celstack.size() == 1) {
1245  int matid = celstack[0].Element()->Reference()->MaterialId();
1246  if (matid == fSecondSkeletonMatId) {
1247  continue;
1248  }
1249  }
1250  if (celstack.size() != 2) {
1251  std::cout << "Error found only material ids ";
1252  for (int i=0; i<celstack.size(); i++) {
1253  std::cout << celstack[i].Element()->Reference()->MaterialId() << " ";
1254  }
1255  std::cout << std::endl;
1256  DebugStop();
1257  }
1258  TPZCompElSide celside = gelside.Reference();
1259  // create an interface between the multiphysics element associated with the pressure element
1260  // and the neighbouring elements
1261  TPZGeoElBC gbcleft(gelside, fLagrangeMatIdLeft);
1262  TPZGeoElBC gbcright(gelside, fLagrangeMatIdRight);
1263  int64_t index1,index2;
1264 // celside.Element()->Print();
1265 // celstack[0].Element()->Print();
1266 // celstack[1].Element()->Print();
1267  new TPZMultiphysicsInterfaceElement(*MixedFluxPressureCmesh,gbcleft.CreatedElement(),index1,celstack[0],celside);
1268  new TPZMultiphysicsInterfaceElement(*MixedFluxPressureCmesh,gbcright.CreatedElement(),index2,celstack[1],celside);
1269 #ifdef LOG4CXX
1270  if(logger->isDebugEnabled())
1271  {
1272  std::stringstream sout;
1273  sout << "Created an interface skeleton element index " << index1 << " between mphys " << celstack[0].Element()->Index() << " and pressure mphyx " << celside.Element()->Index()
1274  << std::endl;
1275  sout << "Created an interface skeleton element index " << index2 << " between mphys " << celstack[1].Element()->Index() << " and pressure mphyx " << celside.Element()->Index();
1276  LOGPZ_DEBUG(logger, sout.str())
1277  }
1278 #endif
1279  }
1280 }
1281 
1284 {
1285  for (std::map<int64_t,int64_t>::iterator it=fMHMtoSubCMesh.begin(); it != fMHMtoSubCMesh.end(); it++) {
1286  TPZCompEl *cel = fCMesh->Element(it->second);
1287  TPZSubCompMesh *subcmesh = dynamic_cast<TPZSubCompMesh *>(cel);
1288  if (!subcmesh) {
1289  DebugStop();
1290  }
1292  subcmesh->ComputeNodElCon();
1293 
1294 #ifdef LOG4CXX2
1295  if(logger->isDebugEnabled())
1296  {
1297  std::stringstream sout;
1298  subcmesh->Print(sout);
1299  LOGPZ_DEBUG(logger, sout.str())
1300  }
1301 #endif
1302  // TODO: increment nelconnected of exterior connects
1303  bool keeplagrange = true;
1304  TPZCompMeshTools::CreatedCondensedElements(subcmesh, keeplagrange);
1305  subcmesh->CleanUpUnconnectedNodes();
1306  int numthreads = 0;
1307  int preconditioned = 0;
1308 #ifdef LOG4CXX2
1309  if(logger->isDebugEnabled())
1310  {
1311  std::stringstream sout;
1312  subcmesh->Print(sout);
1313  LOGPZ_DEBUG(logger, sout.str())
1314  }
1315 #endif
1316  TPZAutoPointer<TPZGuiInterface> guiInterface;
1317  subcmesh->SetAnalysisSkyline(numthreads, preconditioned, guiInterface);
1318  }
1319 
1320 }
1321 
1324 {
1326  int64_t nel = fPressureFineMesh->NElements();
1327  for (int64_t el=0; el<nel; el++) {
1328  TPZCompEl *cel = fPressureFineMesh->Element(el);
1329  if (cel) {
1330  delete cel;
1331  }
1332  }
1333 }
1334 
1337 {
1338  if (fCMesh->NElements() != 0) {
1339  DebugStop();
1340  }
1342  TPZMultiphysicsCompMesh *mphysics = dynamic_cast<TPZMultiphysicsCompMesh *>(fCMesh.operator->());
1343  int vecsize = 2;
1344  if(fNState > 1) vecsize = 3;
1345  TPZManVector<TPZCompMesh *> meshvec(vecsize);
1346  meshvec[0] = fFluxMesh.operator->();
1347  meshvec[1] = fPressureFineMesh.operator->();
1348  if(fNState > 1)
1349  {
1350  meshvec[2] = this->fRotationMesh.operator->();
1351  }
1352  TPZManVector<int64_t> shouldcreate(fGMesh->NElements(),0);
1353  std::set<int> matids;
1354  for (auto it : fCMesh->MaterialVec()) {
1355  matids.insert(it.first);
1356  }
1357  int64_t nel = fFluxMesh->NElements();
1358  for (int64_t el = 0; el<nel; el++) {
1359  TPZCompEl *cel = fFluxMesh->Element(el);
1360  TPZGeoEl *gel = cel->Reference();
1361  // this means that all geometric elements associated with flux elements will generate a computational element
1362  if (matids.find(gel->MaterialId()) == matids.end()) {
1363  DebugStop();
1364  }
1365  if (cel) {
1366  shouldcreate[cel->Reference()->Index()] = 1;
1367  }
1368  }
1369  nel = fPressureFineMesh->NElements();
1370  for (int64_t el=0; el<nel; el++) {
1371  TPZCompEl *cel = fPressureFineMesh->Element(el);
1372  TPZGeoEl *gel = cel->Reference();
1373  if (matids.find(gel->MaterialId()) == matids.end()) {
1374  DebugStop();
1375  }
1376  if (cel) {
1377  shouldcreate[cel->Reference()->Index()] = 1;
1378  }
1379  }
1380  // define the intersection of the finest references
1381  nel = fGMesh->NElements();
1382  for (int64_t el=0; el<nel; el++) {
1383  TPZGeoEl *gel = fGMesh->Element(el);
1384  if (shouldcreate[el])
1385  {
1386  TPZGeoEl *fat = gel->Father();
1387  while(fat)
1388  {
1389  if(shouldcreate[fat->Index()] == 1)
1390  {
1391  shouldcreate[fat->Index()] = 0;
1392  }
1393  fat = fat->Father();
1394  }
1395  }
1396  }
1397  TPZStack<int64_t> gelindexes;
1398  for (int64_t el=0; el<nel; el++) {
1399  if (shouldcreate[el])
1400  {
1401  gelindexes.Push(el);
1402  }
1403  }
1404 #ifdef LOG4CXX
1405  if(logger->isDebugEnabled())
1406  {
1407  std::stringstream sout;
1408  sout << "Geometric indices for which we will create multiphysics elements" << std::endl;
1409  sout << gelindexes;
1410 // std::cout << sout.str() << std::endl;
1411  LOGPZ_DEBUG(logger, sout.str())
1412  }
1413 #endif
1414  mphysics->BuildMultiphysicsSpace(meshvec,gelindexes);
1415 
1416 }
1417 
int64_t NElements() const
Number of computational elements allocated.
Definition: pzcmesh.h:169
bool fLagrangeAveragePressure
flag to determine whether a lagrange multiplier is included to force zero average pressures in the su...
TPZGeoMesh * Reference() const
Returns a pointer to the geometrical mesh associated.
Definition: pzcmesh.h:209
void SetAllCreateFunctionsDiscontinuous()
Create discontinuous approximation spaces.
static void CreatedCondensedElements(TPZCompMesh *cmesh, bool KeepOneLagrangian, bool keepmatrix=true)
created condensed elements for the elements that have internal nodes
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
virtual void BuildComputationalMesh(bool usersubstructure)
Create all data structures for the computational mesh.
void CreateHDivMHMMesh()
Create the mesh of the flux approximation space.
TPZAutoPointer< TPZCompMesh > fCMeshLagrange
computational mesh to represent the distributed flux in each subdomain
void SetAllCreateFunctionsContinuous()
Definition: pzcmesh.h:508
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
void SetName(const std::string &nm)
Set the mesh name.
Definition: pzcmesh.cpp:232
TPZAutoPointer< TPZCompMesh > fCMesh
computational MHM mesh being built by this class
static void GroupElements(TPZCompMesh *cmesh, std::set< int64_t > elbasis, std::set< int64_t > &grouped)
group the elements joining boundary elements and their neighbours
virtual void RestrainSide(int side, TPZInterpolatedElement *neighbour, int neighbourside)
Compute the shapefunction restraints which need to be applied to the shape functions on the side of t...
Definition: pzintel.cpp:849
int MaterialId() const
Returns the material index of the element.
Definition: pzgeoel.h:250
void BuildMultiPhysicsMesh()
build the multi physics mesh (not at the finest geometric mesh level
clarg::argBool bc("-bc", "binary checkpoints", false)
clarg::argInt nsub("-nsub", "number of substructs", 4)
int64_t NEquations()
This computes the number of equations associated with non-restrained nodes.
Definition: pzcmesh.cpp:721
clarg::argInt dimension("-d", "Matrices dimension M x M", 1000)
TPZGeoElSide Reference() const
Reference to the geometric element.
Definition: pzcompel.cpp:748
void SetFalseUseQsiEta()
int fSecondSkeletonMatId
material id associated with the skeleton elements
int fSkeletonMatId
material id associated with the skeleton elements
int64_t fGlobalSystemSize
number of equations when not condensing anything
virtual void HybridizeSkeleton(int skeletonmatid, int pressurematid)
virtual void InsertPeriferalPressureMaterialObjects()
Insert the necessary Pressure material objects to create the flux mesh.
virtual void Print(std::ostream &out=std::cout) const override
Prints the submesh information on the specified device/file out.
Definition: pzsubcmesh.cpp:498
void SetLagrangeMultiplier(unsigned char mult)
Set the connect as a pressure connect or not.
Definition: pzconnect.h:236
int64_t WhichSubdomain(TPZCompEl *cel)
returns to which subdomain a given element beint64_ts
std::set< int > fMaterialIds
materials used for modeling the differential equation
Contains declaration of TPZInterpolationSpace class which implements the interface for interpolated c...
static void SetAllMatid(TPZGeoEl *gel, int matid)
int64_t NElements() const
Number of elements of the mesh.
Definition: pzgmesh.h:129
bool fHybridize
flag to indicate whether we create a hybridized mesh
virtual int Dimension() const =0
Returns the integrable dimension of the material.
std::set< int > fMaterialBCIds
materials for boundary conditions
virtual int NStateVariables() const =0
Returns the number of state variables associated with the material.
Utility class which represents an element with its side. The Geometric approximation classes Geometry...
Definition: pzgeoelside.h:83
int fpOrderInternal
interpolation order of the internal elements
virtual void CreateMultiPhysicsInterfaceElements(int dim)
Create the interfaces between the pressure elements of dimension dim.
int64_t NElements() const
Access method to query the number of elements of the vector.
TPZGeoElSide Neighbour() const
Definition: pzgeoel.h:754
int fSkeletonWrapMatId
material index of the skeleton wrap
virtual int NSides() const =0
Returns the number of connectivities of the element.
std::map< TPZCompMesh *, TPZManVector< int64_t > > fConnectToSubDomainIdentifier
geometric index of the connects - subdomain where the connect will be internal
virtual void Resize(const int64_t newsize, const T &object)
Resizes the vector object.
Definition: pzmanvector.h:426
void CleanUp()
Delete all the dynamically allocated data structures.
Definition: pzcmesh.cpp:161
void LoadReferences()
Map this grid in the geometric grid.
Definition: pzcmesh.cpp:482
virtual void LoadElementReference()
Loads the geometric element reference.
Definition: pzcompel.cpp:601
void CreateDisconnectedElements(bool create)
Determine if the mesh will be created with disconnected elements After the mesh is created...
TPZConnect & SideConnect(int icon, int is)
Returns a pointer to the icon th connect object along side is.
Definition: pzintel.cpp:105
virtual void CreatePressureMHMMesh()
Create the pressure mesh which is dual to the flux mesh.
void SetDefaultOrder(int order)
Definition: pzcmesh.h:403
TPZManVector< int64_t > fGeoToMHMDomain
vector of coarse domain index associated with each geometric element
int fPressureSkeletonMatId
material id associated with the skeleton elements in a hybrid context
This abstract class defines the behaviour which each derived class needs to implement.
Definition: TPZMaterial.h:39
virtual TPZGeoEl * SubElement(int is) const =0
Returns a pointer to the subelement is.
Contains the TPZBndCond class which implements a boundary condition for TPZMaterial objects...
void SetAllCreateFunctionsHDiv(int meshdim)
Create an approximation space with HDiv elements.
TPZCompEl * CreateCompEl(TPZGeoEl *gel, int64_t &index)
Create a computational element based on the geometric element.
Definition: pzcmesh.h:462
int64_t size() const
Returns the number of elements of the vector.
Definition: pzvec.h:196
TPZCompEl * Element(int64_t iel)
Definition: pzcmesh.h:185
int fLagrangeMatIdLeft
material id associated with the lagrange multiplier elements
TPZCreateApproximationSpace & ApproxSpace()
Definition: pzcmesh.h:498
void SetNStateVariables(int nstate)
void Push(const T object)
Pushes a copy of the object on the stack.
Definition: pzstack.h:80
This abstract class defines the behaviour which each derived class needs to implement.
Definition: TPZVecL2.h:22
int64_t fDepConnectIndex
Definition: pzconnect.h:69
virtual void CreateRotationMesh()
Create the rotation mesh to elasticity problem.
virtual void CheckMeshConsistency()
verify the consistency of the datastructure
virtual void Print(std::ostream &out=std::cout) const
Print the information of the grid to an ostream.
Definition: pzgmesh.cpp:130
Structure to reference dependency.
Definition: pzconnect.h:67
static void TransferFromMeshes(TPZVec< TPZCompMesh *> &cmeshVec, TPZCompMesh *MFMesh)
Transfer information from a specific set of meshes for the current mesh multiphysics.
TPZAutoPointer< TPZCompMesh > fFluxMesh
computational mesh to contain the pressure elements
Defines the behaviour of all geometric elements. GeometryTPZGeoEl is the common denominator for all g...
Definition: pzgeoel.h:43
static void PrintCMeshVTK(TPZCompMesh *cmesh, std::ofstream &file, bool matColor=true)
Generate an output of all geometric elements that have a computational counterpart to VTK...
TPZGeoEl * Element(int64_t iel)
Definition: pzgmesh.h:139
int64_t Index() const
Returns the index of the element within the element vector of the mesh.
Definition: pzgeoel.h:730
void SetAllCreateFunctionsDiscontinuous()
Definition: pzcmesh.h:503
Implements a group of computational elements as a mesh and an element. Computational Mesh...
Definition: pzsubcmesh.h:36
#define DebugStop()
Returns a message to user put a breakpoint in.
Definition: pzerror.h:20
Contains declaration of TPZInterfaceElement class which computes the contribution over an interface b...
virtual void ExpandSolution()
Adapt the solution vector to new block dimensions.
Definition: pzcmesh.cpp:396
#define LOGPZ_DEBUG(A, B)
Define log for debug info.
Definition: pzlog.h:87
This class defines the boundary condition for TPZMaterial objects.
Definition: pzbndcond.h:29
void SetAllCreateFunctionsHDiv()
Definition: pzcmesh.h:523
int Dimension() const
Returns the dimension of the simulation.
Definition: pzcmesh.h:148
Contains the declaration of the TPZBuildmultiphysicsMesh class.
virtual void ComputeNodElCon()
Compute the number of elements connected to each connect object.
Definition: pzcmesh.cpp:668
Contains the declaration of multiphysic interface class.
static void PutinSubmeshes(TPZCompMesh *cmesh, std::set< int64_t > &elindices, int64_t &index, bool KeepOneLagrangian)
Put the element set into a subcompmesh and make the connects internal.
TPZMaterial * FindMaterial(int id)
Find the material with identity id.
Definition: pzcmesh.cpp:297
TPZCompEl * Reference() const
Return a pointer to the element referenced by the geometric element.
Definition: pzgeoel.h:750
virtual void AutoBuild(const std::set< int > *MaterialIDs)
Creates the computational elements, and the degree of freedom nodes.
Definition: pzcmesh.cpp:308
virtual void GroupandCondenseElements()
group and condense the elements
int64_t Rows() const
Returns number of rows.
Definition: pzmatrix.h:803
virtual void PrintFriendly(std::ostream &out)
print in a user friendly manner
int HasDependency() const
Returns whether exist dependecy information.
Definition: pzconnect.h:292
virtual void InsertPeriferalHdivMaterialObjects()
Insert the necessary H(div) material objects to create the flux mesh.
TPZAutoPointer< TPZCompMesh > fCMeshConstantPressure
computational mesh to represent the constant states
void CreateHDivPressureMHMMesh()
Create the multiphysics mesh.
TPZAutoPointer< TPZCompMesh > fPressureFineMesh
computational mesh to contain the pressure elements
std::map< int64_t, int64_t > fMHMtoSubCMesh
indices of the geometric elements which define the skeleton mesh and their corresponding subcmesh ind...
void HideTheElements()
put the elements in TPZSubCompMesh, group the elements and condense locally
void SetDimension(int dim)
int64_t NConnects() const
Number of connects allocated including free nodes.
Definition: pzcmesh.h:163
TPZAdmChunkVector< TPZConnect > & ConnectVec()
Return a reference to the connect pointers vector.
Definition: pzcmesh.h:198
int64_t Index() const
Returns element index of the mesh fELementVec list.
Definition: pzcompel.h:821
TPZAutoPointer< TPZGeoMesh > fGMesh
geometric mesh used to create the computational mesh
virtual int NConnects() const override=0
Returns the number of connect objects of the element.
static void PrintGMeshVTK(TPZGeoMesh *gmesh, std::ofstream &file, bool matColor=true)
Default constructor for graphical mesh with VTK format.
void SetDimension(int dim)
Definition: TPZVecL2.h:58
virtual TPZConnect & Connect(int i) const
Returns a pointer to the ith node.
Definition: pzcompel.cpp:298
void DeletePressureElements()
delete the pressure elements leaving the geometric mesh without pointing to the computational mesh ...
void SetDimModel(int dim)
Set de dimension of the domain of the problem.
Definition: pzcmesh.h:139
TPZGeoEl * CreatedElement()
Recovers pointer to the geometric element created.
Definition: pzgeoelbc.h:39
std::map< int,TPZMaterial *> & MaterialVec()
Returns a reference to the material pointers vector.
Definition: pzcmesh.h:203
virtual int HasSubElement() const =0
Return 1 if the element has subelements.
Implements the interfaces for TPZCompElDisc, TPZInterfaceElement and TPZInterpolatedElement. Computational element.
void ConnectedElements(int64_t skeleton, std::pair< int64_t, int64_t > &leftright, std::map< int64_t, std::list< TPZCompElSide > > &ellist)
identify connected elements to the skeleton elements
Structure to help the construction of geometric elements along side of a given geometric element...
Definition: pzgeoelbc.h:21
int fNState
number of state variables
class oriented towards the creation of multiscale hybrid meshes - YES
virtual TPZBndCond * CreateBC(TPZMaterial *reference, int id, int typ, TPZFMatrix< STATE > &val1, TPZFMatrix< STATE > &val2)
Creates an object TPZBndCond derived of TPZMaterial.
virtual void SetSideOrient(int side, int sideorient)
It set the normal orientation of the element by the side. Only side that has dimension equal to my di...
Contains declaration of TPZSubCompMesh class which implements a group of computational elements as a ...
void SetSubdomain(TPZCompEl *cel, int64_t subdomain)
associates the connects of an element with a subdomain
int InsertMaterialObject(TPZMaterial *mat)
Insert a material object in the datastructure.
Definition: pzcmesh.cpp:287
static void SetTotalOrderShape(TPZCompMesh *cmesh)
Set total order shape functions for all Discontinuous elements in cmesh.
virtual void InsertPeriferalMaterialObjects()
Insert Boundary condition objects that do not perform any actual computation.
virtual void CleanUpUnconnectedNodes()
Delete the nodes which have no elements connected to them.
Definition: pzcmesh.cpp:498
virtual void SetPreferredOrder(int order) override=0
Sets the preferred interpolation order along a side.
virtual int Dimension() const =0
Returns the dimension of the element.
TPZCompEl * Element() const
Gives a pointer to the reference computational element.
Definition: pzcompel.h:675
int Dimension()
Get Dimension.
Definition: pzgmesh.h:291
TPZAutoPointer< TPZCompMesh > fRotationMesh
computational mesh to contain the rotation elements
int64_t fGlobalSystemWithLocalCondensationSize
number of equations considering local condensation
TPZGeoEl * Reference() const
Return a pointer to the corresponding geometric element if such exists, return 0 otherwise.
Definition: pzcompel.cpp:1137
virtual int NSideConnects(int iside) const override=0
Returns the number of dof nodes along side iside.
This class implements a geometric mesh for the pz environment. Geometry.
Definition: pzgmesh.h:48
This class implements a stack object. Utility.
Definition: pzcheckmesh.h:14
void ResetReference()
Reset the element referenced by the geometric element to NULL.
Definition: pzgeoel.h:431
Computes the contribution over an interface between two discontinuous elements. Computational Element...
virtual void ComputeNodElCon() override
Computes the number of elements connected to each connect object.
Definition: pzsubcmesh.cpp:298
TPZDepend * FirstDepend()
Definition: pzconnect.h:296
Implements computational mesh. Computational Mesh.
Definition: pzcmesh.h:47
TPZAdmChunkVector< TPZCompEl * > & ElementVec()
Returns a reference to the element pointers vector.
Definition: pzcmesh.h:183
virtual void CreateInternalFluxElements()
void Print(std::ostream &out)
print the data structure
Contains declaration of TPZInterpolatedElement class which implements computational element of the in...
void SetMaterialId(int id)
Sets the material index of the element.
Definition: pzgeoel.h:395
int Side() const
Returns the side index.
Definition: pzcompel.h:688
void BuildMultiphysicsSpace(TPZVec< int > &active_approx_spaces, TPZVec< TPZCompMesh * > &mesh_vector)
Set active approximation spaces.
virtual void CreateSkeleton()
will create the elements on the skeleton
void RemoveDepend(int64_t myindex, int64_t dependindex)
Remove dependency between connects if exist.
Definition: pzconnect.cpp:178
Contains the TPZMatLaplacian class.
int fpOrderSkeleton
interpolation order of the skeleton elements
void SetAnalysisSkyline(int numThreads, int preconditioned, TPZAutoPointer< TPZGuiInterface > guiInterface)
Condense the internal equations using a skyline symetric matrix the preconditioned argument indicates...
clarg::argInt porder("-porder", "polinomial order", 1)
This class implements a discontinuous element (for use with discontinuous Galerkin). Computational Element.
Definition: TPZCompElDisc.h:35
virtual void InsertPeriferalRotationMaterialObjects()
Insert the necessary Rotation material objects to create the flux mesh.
int64_t fNumeq
number of equations of the global system
void JoinSubdomains(TPZVec< TPZCompMesh *> &meshvec, TPZCompMesh *multiphysicsmesh)
Subdomains are identified by computational mesh, this method will join.
std::map< int64_t, std::pair< int64_t, int64_t > > fInterfaces
indices of the skeleton elements and their left/right partition indexes
void ResetReference()
Resets all load references in elements and nodes.
Definition: pzgmesh.cpp:197
void SetNStateVariables(int nstate)
Definition: TPZVecL2.h:68
Defines the interface of a computational element. Computational Element.
Definition: pzcompel.h:59
void SetAllCreateFunctionsMultiphysicElem()
Definition: pzcmesh.h:542
Contains the TPZVTKGeoMesh class which implements the graphical mesh to VTK environment to geometric ...
virtual int NSubElements() const =0
Returns the number of subelements of the element independent of the fact whether the element has alr...
TPZGeoEl * Father() const
Computes the normal vectors needed for forming HDiv vector valued shape functions.
Definition: pzgeoel.cpp:2574
static void SetSubMatid(TPZGeoEl *gel, int matid)
T * end() const
Returns a pointer to the last+1 element.
Definition: pzvec.h:455
TPZFMatrix< STATE > & Solution()
Access the solution vector.
Definition: pzcmesh.h:219
virtual void SetSideOrder(int side, int order)=0
Sets the interpolation order of side to order.
Implements computational element based on an interpolation space. Computational Element.
Definition: pzintel.h:27
Non abstract class which implements full matrices with preallocated storage with (N+1) entries...
Definition: pzfmatrix.h:716
virtual void Print(std::ostream &out=std::cout) const
Prints mesh data.
Definition: pzcmesh.cpp:236
TPZAdmChunkVector< TPZGeoEl * > & ElementVec()
Methods for handling pzlists.
Definition: pzgmesh.h:138