void RefinamentoSingular(TPZAutoPointer<TPZGeoMesh> gmesh,int nref) { int64_t nnodes = gmesh->NNodes(); int64_t in; for (in=0; in<nnodes; in++) { TPZGeoNode *gno = &gmesh->NodeVec()[in]; if (abs(gno->Coord(0))< 1.e-6 && abs(gno->Coord(1)) < 1.e-6) { break; } } if (in == nnodes) { DebugStop(); } TPZGeoElSide gelside; int64_t nelem = gmesh->NElements(); for (int64_t el = 0; el<nelem; el++) { TPZGeoEl *gel = gmesh->ElementVec()[el]; int ncorner = gel->NCornerNodes(); for (int ic=0; ic<ncorner; ic++) { int64_t nodeindex = gel->NodeIndex(ic); if (nodeindex == in) { gelside = TPZGeoElSide(gel, ic); break; } } if (gelside.Element()) { break; } } if (!gelside.Element()) { DebugStop(); } for (int iref = 0; iref <nref; iref++) { TPZStack<TPZGeoElSide> gelstack; gelstack.Push(gelside); TPZGeoElSide neighbour = gelside.Neighbour(); while (neighbour != gelside) { gelstack.Push(neighbour); neighbour = neighbour.Neighbour(); } int64_t nstack = gelstack.size(); for (int64_t ist=0; ist < nstack; ist++) { if (!gelstack[ist].Element()->HasSubElement()) { TPZVec<TPZGeoEl *> subel; gelstack[ist].Element()->Divide(subel); } } } }
void AdjustBoundary(TPZGeoMesh *gmesh) { int64_t nel = gmesh->NElements(); for (int64_t el = 0; el<nel; el++) { TPZGeoEl *gel = gmesh->Element(el); if (gel->Dimension() == 3 || gel->HasSubElement()) { continue; } TPZGeoElSide gelside(gel,gel->NSides()-1); TPZGeoElSide neighbour = gelside.Neighbour(); bool should_refine = false; int nsub = -1; int numneigh = 0; while (gelside != neighbour) { nsub = neighbour.Element()->NSideSubElements(neighbour.Side()); if (neighbour.Element()->HasSubElement() && nsub > 1) { should_refine = true; } numneigh++; neighbour = neighbour.Neighbour(); } if (should_refine == true) { TPZAutoPointer<TPZRefPattern> match = TPZRefPatternTools::PerfectMatchRefPattern(gel); if (!match) { DebugStop(); } gel->SetRefPattern(match); TPZStack<TPZGeoEl *> subels; gel->Divide(subels); } } }
void TPZRefPrism::NewMidSideNode(TPZGeoEl *gel,int side,int &index) { MidSideNodeIndex(gel,side,index); if(side == 15 || side > 18) { return;//o nó geométrico não pode ser criado } if(index < 0) { TPZGeoElSide gelside = gel->Neighbour(side); if(gelside.Element()) { while(gelside.Element() != gel) { gelside.Element()->MidSideNodeIndex(gelside.Side(),index); if(index!=-1) return; gelside = gelside.Neighbour(); } } TPZVec<REAL> par(3,0.); TPZVec<REAL> coord(3,0.); if(side < TPZShapePrism::NCornerNodes) { index = gel->NodeIndex(side); return; } //aqui side = 6 a 20 side-=TPZShapePrism::NCornerNodes;//0,1,..,13 par[0] = MidCoord[side][0]; par[1] = MidCoord[side][1]; par[2] = MidCoord[side][2]; gel->X(par,coord); index = gel->Mesh()->NodeVec().AllocateNewElement(); gel->Mesh()->NodeVec()[index].Initialize(coord,*gel->Mesh()); } }
void TPZRefQuad::NewMidSideNode(TPZGeoEl *gel,int side,int &index) { MidSideNodeIndex(gel,side,index); if(index < 0) { TPZGeoElSide gelside = gel->Neighbour(side); if(gelside.Element()) { while(gelside.Element() != gel) { gelside.Element()->MidSideNodeIndex(gelside.Side(),index); if(index!=-1) return; gelside = gelside.Neighbour(); } } TPZVec<REAL> par(3,0.); TPZVec<REAL> coord(3,0.); if(side < TPZShapeQuad::NCornerNodes) { index = gel->NodeIndex(side); return; } //aqui side = 8 a 26 side-=TPZShapeQuad::NCornerNodes;//0,1,..,18 par[0] = MidCoord[side][0]; par[1] = MidCoord[side][1]; gel->X(par,coord); index = gel->Mesh()->NodeVec().AllocateNewElement(); gel->Mesh()->NodeVec()[index].Initialize(coord,*gel->Mesh()); } }
int64_t TPZGeoCloneMesh::CloneElement(TPZGeoEl *orgel){ int64_t i,j; // int nnod = orgel->NNodes(); // cout << "Original element nodes = " << nnod << endl; if(HasElement(orgel)) return Index(fMapElements[orgel]); // Create a cloned element TPZGeoEl *el = InitializeClone(orgel); int64_t elindex = Index(el); // cout << "\nClonned element\n"; // el->Print(cout); //fill the map fMapElements[orgel] = el; if(elindex >= fReferenceElement.NElements()) { fReferenceElement.Resize(elindex+1,0); } fReferenceElement[elindex] = orgel; //fill the neighbours for (i=0;i<orgel->NSides();i++){ el->SetSideDefined(i); TPZGeoElSide neig = orgel->Neighbour(i); if(!neig.Element()) continue; // insert all neighbours which have been cloned as neighbours // THIS IS OVERKILL it would be suficient to insert a single neighbour while(neig.Element() != orgel) { // verify if neig.Element has been cloned if (HasElement((neig.Element()))){ TPZGeoElSide sid(el,i); // sid.SetConnectivity(sid); //SetNeighbour(i,neig); TPZGeoElSide localneig(fMapElements[neig.Element()],neig.Side()); if(!sid.NeighbourExists(localneig)) { sid.SetConnectivity(localneig); } } neig = neig.Neighbour(); } } //loop over the sons if (orgel->HasSubElement()){ int subel = orgel->NSubElements(); for (j=0;j<subel;j++){ TPZGeoEl *gelson = orgel->SubElement(j); CloneElement(gelson); fMapElements[gelson]->SetFather(el); fMapElements[gelson]->SetFather(el->Index()); el->SetSubElement(j,fMapElements[gelson]); } } // el->Print(cout); return elindex; }
// IT IS BAD !!!! IMPROVE IT !!! void TPZGeoCloneMesh::AddBoundaryConditionElements(TPZGeoEl *eltoadd) { int nsides = eltoadd->NSides(); int is; for(is=0; is<nsides; is++) { TPZGeoElSide elside(eltoadd,is); TPZGeoElSide neighbour = elside.Neighbour(); #ifdef PZDEBUG if (!neighbour.Element()) DebugStop(); #endif while(neighbour != elside) { if(neighbour.Element()->Dimension() < eltoadd->Dimension() && neighbour.Side() == neighbour.Element()->NSides() - 1 // && neighbour.Element()->Reference() ) { TPZGeoEl *gel = neighbour.Element(); if (HasElement(gel)) { neighbour = neighbour.Neighbour(); continue; } TPZGeoEl *father = gel->Father(); while(father) { gel = father; father = gel->Father(); } CloneElement(gel); // verificar se neighbour.Element ja esta no map // TPZGeoEl *localpatch = fMapElements[neighbour.Element()]; TPZGeoEl *localpatch = fMapElements[gel]; // Jorge 2013/03/28 fPatchElements.insert(localpatch); } neighbour = neighbour.Neighbour(); #ifdef PZDEBUG if (!neighbour.Exists()) { DebugStop(); } #endif } } }
void InsertBoundaryElements(TPZGeoMesh *gmesh) { REAL xplane = 1435; REAL yplane = 1161; REAL zplane = -1530; REAL ztop = 122.8; REAL minx = 0; REAL minz = 0; REAL maxz = 0; int64_t nel = gmesh->NElements(); for (int64_t el=0; el<nel; el++) { TPZGeoEl *gel = gmesh->Element(el); if (gel->HasSubElement()) { continue; } int nsides = gel->NSides(); for (int is=0; is<nsides; is++) { int bccreated = 999; TPZGeoElSide gelside(gel,is); if (gel->SideDimension(is) == 1) { TPZManVector<REAL,3> xcenter(3); gelside.CenterX(xcenter); if (xcenter[2] > maxz) { maxz = xcenter[2]; } if (fabs(xcenter[0]) < 1 && fabs(xcenter[2]-ztop) < 1) { bccreated = bcloadtop; TPZGeoElSide neighbour = gelside.Neighbour(); while (neighbour != gelside) { if (neighbour.Element()->MaterialId() == bcloadtop) { bccreated = 999; } neighbour = neighbour.Neighbour(); } if (bccreated == bcloadtop) { std::cout << "Added boundary bcloadtop xcenter = " << xcenter << std::endl; } } } if (gel->SideDimension(is) == 2) { TPZManVector<REAL,3> xcenter(3); gelside.CenterX(xcenter); if (xcenter[0] < minx) { minx = xcenter[0]; } if (xcenter[2] < minz) { minz = xcenter[2]; } if (fabs(xcenter[2] - zplane) < 1.) { bccreated = bcbottom; } if (fabs(fabs(xcenter[0])-xplane) < 1) { bccreated = bcsidex; } if (fabs(fabs(xcenter[1])-yplane) < 1) { bccreated = bcsidey; } if (fabs(xcenter[2]-ztop) <1) { bccreated = bctopsurface; } } if(bccreated != 999) { if (gelside.Dimension() == 2 && gelside.Neighbour() != gelside) { DebugStop();; } gel->CreateBCGeoEl(is, bccreated); } } } std::cout << "minx = " << minx << " minz = " << minz << " maxz " << maxz << std::endl; }
/// Merge lines which are parallel void TPZFracSet::MergeParallelLines() { int64_t nel = fgmesh.NElements(); REAL maxcos = 0.; for (int64_t el = 0; el<nel; el++) { TPZGeoEl *gel = fgmesh.Element(el); if(!gel) continue; TPZManVector<REAL,3> dir1(3); Direction(gel, dir1); int nnodes = gel->NCornerNodes(); for(int is = 0; is<nnodes; is++) { TPZGeoElSide gelside(gel,is); TPZGeoElSide neighbour = gelside.Neighbour(); while (neighbour != gelside) { TPZManVector<REAL,3> dir2(3); Direction(neighbour.Element(), dir2); if (neighbour.Side() != is) { for (int i=0; i<3; i++) { dir2[i] *= -1.; } } REAL cosangle = 0.; for (int i=0; i<3; i++) { cosangle += dir1[i]*dir2[i]; } if (cosangle> maxcos) { maxcos = cosangle; } if (cosangle > 0.99) { std::cout << "Fractures " << gel->Index() << " and " << neighbour.Element()->Index() << " are parallel " << cosangle << "\n"; std::cout << "Index " << gel->NodeIndex(0) << " "; gel->Node(0).Print(); std::cout << "Index " << gel->NodeIndex(1) << " "; gel->Node(1).Print(); std::cout << "Index " << neighbour.Element()->NodeIndex(0) << " "; neighbour.Element()->Node(0).Print(); std::cout << "Index " << neighbour.Element()->NodeIndex(1) << " "; neighbour.Element()->Node(1).Print(); REAL l1 = Length(gel); REAL l2 = Length(neighbour.Element()); if (l1 < l2) { gel->RemoveConnectivities(); delete gel; fgmesh.ElementVec()[el] = 0; gel = 0; break; } else { neighbour.Element()->RemoveConnectivities(); int64_t neighindex = neighbour.Element()->Index(); delete neighbour.Element(); fgmesh.ElementVec()[neighindex] = 0; neighbour = gelside; } } neighbour = neighbour.Neighbour(); } if(!gel) break; } } std::cout << "max cosine angle " << maxcos << std::endl; }