void TPZGeoCloneMesh::Write(TPZStream &buf, int withclassid) const { TPZGeoMesh::Write(buf,withclassid); try { if(!fGeoReference) { std::cout << "Cloned geo mesh without geometric mesh from which this mesh is cloned." << std::endl; DebugStop(); } TPZPersistenceManager::WritePointer(fGeoReference, &buf); buf.Write(fMapNodes); // Maps elements with original elements std::map<int64_t,int64_t> MappingElements; TPZGeoEl *gel; int64_t indexorig, indexcloned; std::map<TPZGeoEl* , TPZGeoEl* >::const_iterator it; for(it=fMapElements.begin();it!=fMapElements.end();it++) { gel = it->first; indexorig = gel->Index(); gel = it->second; indexcloned = gel->Index(); MappingElements.insert(std::make_pair(indexorig,indexcloned)); } buf.Write(MappingElements); // Writing index of the elements in fReferenceElement TPZStack<int64_t> RefElements; int64_t sz = fReferenceElement.size(); for(int64_t ii=0;ii<sz;ii++) { RefElements.push_back(fReferenceElement[ii]->Index()); } buf.Write(RefElements); // Have to save a compact structure of the vector?? // Writing index of the elements in fPatchElement std::set<int> PatchElements; std::set<TPZGeoEl* >::iterator itpatch = fPatchElements.begin(); while(itpatch != fPatchElements.end()) { PatchElements.insert((*itpatch)->Index()); itpatch++; } buf.Write(PatchElements); int64_t rootindex = fGeoRoot->Index(); buf.Write(&rootindex,1); } catch(const exception& e) { cout << "Exception catched! " << e.what() << std::endl; cout.flush(); DebugStop(); } }//method
/// Delete very short fractures void TPZFracSet::DeleteVeryShortFractures(REAL length) { int64_t nel = fgmesh.NElements(); double lmin = 2000.; for (int64_t el=0; el<nel; el++) { TPZGeoEl *gel = fgmesh.Element(el); if (!gel) { continue; } int64_t inode0 = gel->NodeIndex(0); int64_t inode1 = gel->NodeIndex(1); if (gel->Neighbour(0).Element() == gel || gel->Neighbour(1).Element() == gel) { REAL l = Length(gel); if (l<lmin) { lmin = l; } if(l < length) { std::cout << "Deleting Fracture " << gel->Index() << " length " << l << std::endl; std::cout << "Index " << gel->NodeIndex(0) << " "; gel->Node(0).Print(); std::cout << "Index " << gel->NodeIndex(1) << " "; gel->Node(1).Print(); gel->RemoveConnectivities(); delete gel; fgmesh.ElementVec()[el] = 0; gel = 0; } } } std::cout << "shortest fracture length " << lmin << std::endl; }
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; }
void GetElIndexCoarseMesh(TPZAutoPointer<TPZGeoMesh> gmesh, std::set<int64_t> &coarseindex) { int nel = gmesh->NElements(); int iel; int hassubel=0; int dim = gmesh->Dimension(); int eldim; for(iel = 0; iel<nel; iel++) { TPZGeoEl * gel = gmesh->ElementVec()[iel]; if(!gel) DebugStop(); hassubel = gel->HasSubElement(); eldim = gel->Dimension(); if(!hassubel && eldim ==dim) { coarseindex.insert(gel->Index()); } } }
/// 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; }
/// Transfer to the geometric mesh void TPZFracSet::ToGeoMesh() { fgmesh.CleanUp(); fgmesh.NodeVec() = fNodeVec; int64_t nfrac = fFractureVec.NElements(); for (int64_t ifr = 0; ifr < nfrac; ifr++) { TPZManVector<int64_t,2> nodes(2); nodes = fFractureVec[ifr].fNodes; int64_t index; fgmesh.CreateGeoElement(EOned, nodes, fFractureVec[ifr].fMatId, index); } fgmesh.BuildConnectivity(); int64_t nel = fgmesh.NElements(); for (int64_t el=0; el<nel; el++) { TPZGeoEl *gel = fgmesh.Element(el); if(!gel) continue; if (gel->Neighbour(2).Element() != gel) { std::cout << "gel index " << el << " is overlapping with " << gel->Neighbour(2).Element()->Index() << std::endl; TPZGeoEl *neigh = gel->Neighbour(2).Element(); int matid = min(gel->MaterialId(),neigh->MaterialId()); if(gel->MaterialId() == neigh->MaterialId()) { matid = gel->MaterialId(); } else if(gel->MaterialId() == matid_BC || neigh->MaterialId() == matid_BC) { matid = matid_BC; } else if((gel->MaterialId() == matid_internal_frac && neigh->MaterialId() == matid_MHM_line) || (gel->MaterialId() == matid_MHM_line && neigh->MaterialId() == matid_internal_frac)) { matid = matid_MHM_frac; } else { DebugStop(); } gel->SetMaterialId(matid); neigh->SetMaterialId(matid); // remove the element with the lowest index if (gel->Index() > neigh->Index()) { // delete neigh neigh->RemoveConnectivities(); int64_t neighindex = neigh->Index(); delete neigh; fgmesh.ElementVec()[neighindex] = 0; std::string matname = fFractureVec[neighindex].fPhysicalName; fFractureVec[gel->Index()].fPhysicalName = matname + "_MHM"; } else { gel->RemoveConnectivities(); std::string matname = fFractureVec[gel->Index()].fPhysicalName; fFractureVec[neigh->Index()].fPhysicalName = matname + "_MHM"; delete gel; fgmesh.ElementVec()[el] = 0; } } } }
int SubStructure(TPZAutoPointer<TPZCompMesh> cmesh, REAL height) { int nelem = cmesh->NElements(); TPZManVector<int> subindex(nelem,-1); int iel; int nsub = 0; for (iel=0; iel<nelem; iel++) { TPZCompEl *cel = cmesh->ElementVec()[iel]; if (!cel) { continue; } TPZGeoEl *gel = cel->Reference(); if (!gel) { continue; } int nsides = gel->NSides(); TPZManVector<REAL> center(gel->Dimension(),0.), xco(3,0.); gel->CenterPoint(nsides-1,center); gel->X(center,xco); REAL z = xco[2]; int floor = (int) z/height; nsub = (floor+1) > nsub ? (floor+1) : nsub; subindex[iel] = floor; } #ifdef DEBUG { TPZGeoMesh *gmesh = cmesh->Reference(); int nelgeo = gmesh->NElements(); TPZVec<int> domaincolor(nelgeo,-999); int cel; int nel = cmesh->NElements(); for (cel=0; cel<nel; cel++) { TPZCompEl *compel = cmesh->ElementVec()[cel]; if(!compel) continue; TPZGeoEl *gel = compel->Reference(); if (!gel) { continue; } domaincolor[gel->Index()] = subindex[cel]; } ofstream vtkfile("partition.vtk"); TPZVTKGeoMesh::PrintGMeshVTK(gmesh, vtkfile, domaincolor); } #endif int isub; TPZManVector<TPZSubCompMesh *> submeshes(nsub,0); for (isub=0; isub<nsub; isub++) { int index; std::cout << '^'; std::cout.flush(); submeshes[isub] = new TPZSubCompMesh(cmesh,index); if (index < subindex.NElements()) { subindex[index] = -1; } } for (iel=0; iel<nelem; iel++) { int domindex = subindex[iel]; if (domindex >= 0) { TPZCompEl *cel = cmesh->ElementVec()[iel]; if (!cel) { continue; } submeshes[domindex]->TransferElement(cmesh.operator->(),iel); } } cmesh->ComputeNodElCon(); for (isub=0; isub<nsub; isub++) { submeshes[isub]->MakeAllInternal(); std::cout << '*'; std::cout.flush(); } cmesh->ComputeNodElCon(); cmesh->CleanUpUnconnectedNodes(); return nsub; }