/// 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; }
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); } } } }
/// Compute the mesh size at the nodes void TPZFracSet::ComputeMeshSizeAtNodes() { REAL minsize = this->fMinElementSize; REAL normalsize = this->fElementSize; ToGeoMesh(); fMeshSizeAtNodes.Resize(fNodeVec.NElements(), normalsize); fMeshSizeAtNodes.Fill(normalsize); int64_t nel = fgmesh.NElements(); for (int64_t el=0; el<nel; el++) { TPZGeoEl *gel = fgmesh.Element(el); if (!gel) { continue; } REAL length = Length(gel); if (length < normalsize) { REAL meshsize = length < minsize ? minsize : length; int64_t inode0 = gel->NodeIndex(0); int64_t inode1 = gel->NodeIndex(1); fMeshSizeAtNodes[inode0] = min(fMeshSizeAtNodes[inode0],meshsize); fMeshSizeAtNodes[inode1] = min(fMeshSizeAtNodes[inode1],meshsize); } } int64_t nnode = fgmesh.NodeVec().NElements(); for (int64_t node = 0; node < nnode; node++) { TPZManVector<REAL,3> co(3); fgmesh.NodeVec()[node].GetCoordinates(co); for (int ico =0; ico < 2; ico++) { int mhm = co[ico]/fMHMSpacing[ico]; REAL mhm_min = mhm*fMHMSpacing[ico]; REAL mhm_max = (mhm+1)*fMHMSpacing[ico]; REAL dist = min(co[ico]-mhm_min,mhm_max-co[ico]); if (dist > 1.e-6 && dist < normalsize) { dist = max(dist,minsize); fMeshSizeAtNodes[node] = min(fMeshSizeAtNodes[node],dist); } } } int64_t nhor = fHorizontalLines.NElements(); for (int64_t hr=0; hr<nhor; hr++) { for (auto it = fHorizontalLines[hr].begin(); it != fHorizontalLines[hr].end(); it++) { auto it2 = it; it2++; if (it2 == fHorizontalLines[hr].end()) { continue; } int64_t node0 = it->second; int64_t node1 = it2->second; REAL length = it2->first - it->first; if (length > normalsize) { continue; } if (length < minsize) { length = minsize; } fMeshSizeAtNodes[node0] = min(fMeshSizeAtNodes[node0],length); fMeshSizeAtNodes[node1] = min(fMeshSizeAtNodes[node1],length); } } int64_t nver = fVerticalLines.NElements(); for (int64_t vr=0; vr<nver; vr++) { for (auto it = fVerticalLines[vr].begin(); it != fVerticalLines[vr].end(); it++) { auto it2 = it; it2++; if (it2 == fVerticalLines[vr].end()) { continue; } int64_t node0 = it->second; int64_t node1 = it2->second; REAL length = it2->first - it->first; if (length > normalsize) { continue; } if (length < minsize) { length = minsize; } fMeshSizeAtNodes[node0] = min(fMeshSizeAtNodes[node0],length); fMeshSizeAtNodes[node1] = min(fMeshSizeAtNodes[node1],length); } } FromGeoMesh(); }
/// 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; }
TPZGeoMesh *MalhaCubo() { int numnodes=-1; int numelements=-1; string FileName, dirname = PZSOURCEDIR; FileName = dirname + "/Projects/Substruct_Viscoelastic/"; FileName += "cube1.txt"; { bool countnodes = false; bool countelements = false; ifstream read (FileName.c_str()); while(read) { char buf[1024]; read.getline(buf, 1024); std::string str(buf); if(str == "Coordinates") countnodes = true; if(str == "end coordinates") countnodes = false; if(countnodes) numnodes++; if(str == "Elements") countelements = true; if(str == "end elements") countelements = false; if(countelements) numelements++; } } TPZGeoMesh * gMesh = new TPZGeoMesh; gMesh -> NodeVec().Resize(numnodes); TPZManVector <int> TopolTetra(4); const int Qnodes = numnodes; TPZVec <TPZGeoNode> Node(Qnodes); //setting nodes coords int nodeId = 0, elementId = 0, matElId = 1; ifstream read; read.open(FileName.c_str()); double nodecoordX , nodecoordY , nodecoordZ ; char buf[1024]; read.getline(buf, 1024); read.getline(buf, 1024); std::string str(buf); int in; for(in=0; in<numnodes; in++) { read >> nodeId; read >> nodecoordX; read >> nodecoordY; read >> nodecoordZ; Node[nodeId-1].SetNodeId(nodeId); Node[nodeId-1].SetCoord(0,nodecoordX); Node[nodeId-1].SetCoord(1,nodecoordY); Node[nodeId-1].SetCoord(2,nodecoordZ); gMesh->NodeVec()[nodeId-1] = Node[nodeId-1]; } { read.close(); read.open(FileName.c_str()); int l , m = numnodes+5; for(l=0; l<m; l++) { read.getline(buf, 1024); } int el; int neumann1 = -4, neumann2 = -5; //std::set<int> ncoordz; //jeitoCaju for(el=0; el<numelements; el++) { read >> elementId; read >> TopolTetra[0]; //node 1 read >> TopolTetra[1]; //node 2 read >> TopolTetra[2]; //node 3 read >> TopolTetra[3]; //node 4 // O GID comeca com 1 na contagem dos nodes, e nao zero como no PZ, assim o node 1 na verdade é o node 0 TopolTetra[0]--; TopolTetra[1]--; TopolTetra[2]--; TopolTetra[3]--; int index = el; TPZGeoEl * tetra = new TPZGeoElRefPattern< pzgeom::TPZGeoTetrahedra> (index, TopolTetra, matElId, *gMesh); } gMesh->BuildConnectivity(); // Colocando as condicoes de contorno for(el=0; el<numelements; el++) { TPZManVector <TPZGeoNode,4> Nodefinder(4); TPZManVector <REAL,3> nodecoord(3); TPZGeoEl *tetra = gMesh->ElementVec()[el]; // na face x = 1 TPZVec<int> ncoordzVec(0); int sizeOfVec = 0; for (int i = 0; i < 4; i++) { int pos = tetra->NodeIndex(i); Nodefinder[i] = gMesh->NodeVec()[pos]; Nodefinder[i].GetCoordinates(nodecoord); if (nodecoord[0] == 1.) { sizeOfVec++; ncoordzVec.Resize(sizeOfVec); ncoordzVec[sizeOfVec-1] = pos; } } if(ncoordzVec.NElements() == 3) { int lado = tetra->WhichSide(ncoordzVec); TPZGeoElSide tetraSide(tetra, lado); TPZGeoElBC(tetraSide,neumann1); } // Na face x = -1 ncoordzVec.Resize(0); sizeOfVec = 0; for (int i = 0; i < 4; i++) { int pos = tetra->NodeIndex(i); Nodefinder[i] = gMesh->NodeVec()[pos]; Nodefinder[i].GetCoordinates(nodecoord); if (nodecoord[0] == -1.) { sizeOfVec++; ncoordzVec.Resize(sizeOfVec); ncoordzVec[sizeOfVec-1] = pos; } } if(ncoordzVec.NElements() == 3) { int lado = tetra->WhichSide(ncoordzVec); TPZGeoElSide tetraSide(tetra, lado); TPZGeoElBC(tetraSide,neumann2); } } TPZVec <REAL> xyz(3,-1.), yz(3,-1.), z(3,1.); yz[0] = 1.; z[2] = -1; int bcidxyz = -1, bcidyz = -2, bcidz = -3; SetPointBC(gMesh, xyz, bcidxyz); SetPointBC(gMesh, yz, bcidyz); SetPointBC(gMesh, z, bcidz); } ofstream arg("malhaPZ1BC.txt"); gMesh->Print(arg); std::ofstream out("Cube.vtk"); TPZVTKGeoMesh::PrintGMeshVTK(gMesh, out, true); return gMesh; }
TPZGeoMesh *PyramidalMesh::CreateGMeshCubeWithPyramids(int64_t nelem, int MaterialId) { TPZGeoMesh *gmesh = new TPZGeoMesh; GenerateNodesforPyramidalMesh(gmesh,nelem); int posicao = 0; for (int64_t i=0; i<=nelem; i++) { for (int64_t j=0; j<=nelem; j++) { for (int64_t k=0; k<=nelem; k++) { posicao = i*(nelem+1)*(nelem+1)+j*(nelem+1)+k; } } } for (int64_t i=0; i<nelem; i++) { for (int64_t j=0; j<nelem; j++) { for (int64_t k=0; k<nelem; k++) { TPZManVector<int64_t,9> nodes(9,0); nodes[0] = k*(nelem+1)*(nelem+1)+j*(nelem+1)+i; nodes[1] = k*(nelem+1)*(nelem+1)+j*(nelem+1)+i+1; nodes[2] = k*(nelem+1)*(nelem+1)+(j+1)*(nelem+1)+i+1; nodes[3] = k*(nelem+1)*(nelem+1)+(j+1)*(nelem+1)+i; nodes[4] = (k+1)*(nelem+1)*(nelem+1)+j*(nelem+1)+i; nodes[5] = (k+1)*(nelem+1)*(nelem+1)+j*(nelem+1)+i+1; nodes[6] = (k+1)*(nelem+1)*(nelem+1)+(j+1)*(nelem+1)+i+1; nodes[7] = (k+1)*(nelem+1)*(nelem+1)+(j+1)*(nelem+1)+i; nodes[8] = posicao + (k)*(nelem)*(nelem)+(j)*(nelem)+i+1; for (int el=0; el<6; el++) { TPZManVector<int64_t,5> elnodes(5); int64_t index; for (int il=0; il<5; il++) { elnodes[il] = nodes[piramide_2[el][il]]; } gmesh->CreateGeoElement(EPiramide, elnodes, MaterialId, index); } } } } gmesh->BuildConnectivity(); // Boundary Conditions const int numelements = gmesh->NElements(); // const int bczMinus = -3, bczplus = -2, bcids = -1; // const int bczMinus = -1, bczplus = -1, bcids = -1; for(int el=0; el<numelements; el++) { TPZManVector <TPZGeoNode,5> Nodefinder(5); TPZManVector <REAL,3> nodecoord(3); TPZGeoEl *piramide = gmesh->ElementVec()[el]; TPZVec<int64_t> ncoordVec(0); int64_t sizeOfVec = 0; // na face z = 0 for (int i = 0; i < 5; i++) { int64_t pos = piramide->NodeIndex(i); Nodefinder[i] = gmesh->NodeVec()[pos]; Nodefinder[i].GetCoordinates(nodecoord); if (DoubleComparer(nodecoord[2],0.)) { sizeOfVec++; ncoordVec.Resize(sizeOfVec); ncoordVec[sizeOfVec-1] = pos; } } if(ncoordVec.NElements() == 4) { int lado = piramide->WhichSide(ncoordVec); TPZGeoElSide piramideSide(piramide, lado); TPZGeoElBC(piramideSide,bc0); } ncoordVec.clear(); sizeOfVec = 0; // na face y = 0 for (int i = 0; i < 5; i++) { int64_t pos = piramide->NodeIndex(i); Nodefinder[i] = gmesh->NodeVec()[pos]; Nodefinder[i].GetCoordinates(nodecoord); if (DoubleComparer(nodecoord[1],0.)) { sizeOfVec++; ncoordVec.Resize(sizeOfVec); ncoordVec[sizeOfVec-1] = pos; } } if(ncoordVec.NElements() == 4) { int lado = piramide->WhichSide(ncoordVec); TPZGeoElSide piramideSide(piramide, lado); TPZGeoElBC(piramideSide,bc1); } ncoordVec.clear(); sizeOfVec = 0; // na face x = 1 for (int i = 0; i < 5; i++) { int64_t pos = piramide->NodeIndex(i); Nodefinder[i] = gmesh->NodeVec()[pos]; Nodefinder[i].GetCoordinates(nodecoord); if (DoubleComparer(nodecoord[0],1.)) { sizeOfVec++; ncoordVec.Resize(sizeOfVec); ncoordVec[sizeOfVec-1] = pos; } } if(ncoordVec.NElements() == 4) { int lado = piramide->WhichSide(ncoordVec); TPZGeoElSide piramideSide(piramide, lado); TPZGeoElBC(piramideSide,bc2); } ncoordVec.clear(); sizeOfVec = 0; // na face y = 1 for (int i = 0; i < 5; i++) { int64_t pos = piramide->NodeIndex(i); Nodefinder[i] = gmesh->NodeVec()[pos]; Nodefinder[i].GetCoordinates(nodecoord); if (DoubleComparer(nodecoord[1],1.)) { sizeOfVec++; ncoordVec.Resize(sizeOfVec); ncoordVec[sizeOfVec-1] = pos; } } if(ncoordVec.NElements() == 4) { int lado = piramide->WhichSide(ncoordVec); TPZGeoElSide piramideSide(piramide, lado); TPZGeoElBC(piramideSide,bc3); } ncoordVec.clear(); sizeOfVec = 0; // na face x = 0 for (int i = 0; i < 5; i++) { int64_t pos = piramide->NodeIndex(i); Nodefinder[i] = gmesh->NodeVec()[pos]; Nodefinder[i].GetCoordinates(nodecoord); if (DoubleComparer(nodecoord[0],0.)) { sizeOfVec++; ncoordVec.Resize(sizeOfVec); ncoordVec[sizeOfVec-1] = pos; } } if(ncoordVec.NElements() == 4) { int lado = piramide->WhichSide(ncoordVec); TPZGeoElSide piramideSide(piramide, lado); TPZGeoElBC(piramideSide,bc4); } ncoordVec.clear(); sizeOfVec = 0; // na face z = 1 for (int i = 0; i < 5; i++) { int64_t pos = piramide->NodeIndex(i); Nodefinder[i] = gmesh->NodeVec()[pos]; Nodefinder[i].GetCoordinates(nodecoord); if (DoubleComparer(nodecoord[2],1.)) { sizeOfVec++; ncoordVec.Resize(sizeOfVec); ncoordVec[sizeOfVec-1] = pos; } } if(ncoordVec.NElements() == 4) { int lado = piramide->WhichSide(ncoordVec); TPZGeoElSide piramideSide(piramide, lado); TPZGeoElBC(piramideSide,bc5); } } std::ofstream out("CubeWithPyramidswithBcs.vtk"); TPZVTKGeoMesh::PrintGMeshVTK(gmesh, out, true); return gmesh; }