/// 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; }
/// 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; } } } }