static void createPriPyrTet(std::vector<MVertex*> &v, GRegion *to, MElement* source) { int dup[3]; int j = 0; for(int i = 0; i < 3; i++) if(v[i] == v[i + 3]) dup[j++] = i; if(j == 2) { if(dup[0] == 0 && dup[1] == 1) addTetrahedron(v[0], v[1], v[2], v[5], to); else if(dup[0] == 1 && dup[1] == 2) addTetrahedron(v[0], v[1], v[2], v[3], to); else addTetrahedron(v[0], v[1], v[2], v[4], to); } else if(j == 1) { if(dup[0] == 0) addPyramid(v[1], v[4], v[5], v[2], v[0], to); else if(dup[0] == 1) addPyramid(v[0], v[2], v[5], v[3], v[1], to); else addPyramid(v[0], v[1], v[4], v[3], v[2], to); } else { addPrism(v[0], v[1], v[2], v[3], v[4], v[5], to); if(j) Msg::Error("Degenerated prism in extrusion of volume %d", to->tag()); } }
void FEMTetrahedronMesh::generateBlocks(unsigned xdim, unsigned ydim, unsigned zdim, float width, float height, float depth) { m_totalPoints = (xdim+1)*(ydim+1)*(zdim+1); m_X = new Vector3F[m_totalPoints]; m_Xi= new Vector3F[m_totalPoints]; m_mass = new float[m_totalPoints]; int ind=0; float hzdim = zdim/2.0f; for(unsigned x = 0; x <= xdim; ++x) { for (unsigned y = 0; y <= ydim; ++y) { for (unsigned z = 0; z <= zdim; ++z) { m_X[ind] = Vector3F(width*x, height*z, depth*y); m_Xi[ind] = m_X[ind]; ind++; } } } //offset the m_tetrahedronl mesh by 0.5 units on y axis //and 0.5 of the depth in z axis for(unsigned i=0;i< m_totalPoints;i++) { m_X[i].y += 2.5; m_X[i].z -= hzdim*depth; } m_totalTetrahedrons = 5 * xdim * ydim * zdim; m_tetrahedron = new Tetrahedron[m_totalTetrahedrons]; Tetrahedron * t = &m_tetrahedron[0]; for (unsigned i = 0; i < xdim; ++i) { for (unsigned j = 0; j < ydim; ++j) { for (unsigned k = 0; k < zdim; ++k) { unsigned p0 = (i * (ydim + 1) + j) * (zdim + 1) + k; unsigned p1 = p0 + 1; unsigned p3 = ((i + 1) * (ydim + 1) + j) * (zdim + 1) + k; unsigned p2 = p3 + 1; unsigned p7 = ((i + 1) * (ydim + 1) + (j + 1)) * (zdim + 1) + k; unsigned p6 = p7 + 1; unsigned p4 = (i * (ydim + 1) + (j + 1)) * (zdim + 1) + k; unsigned p5 = p4 + 1; // Ensure that neighboring tetras are sharing faces if ((i + j + k) % 2 == 1) { addTetrahedron(t++, p1,p2,p6,p3); addTetrahedron(t++, p3,p6,p4,p7); addTetrahedron(t++, p1,p4,p6,p5); addTetrahedron(t++, p1,p3,p4,p0); addTetrahedron(t++, p1,p6,p4,p3); } else { addTetrahedron(t++, p2,p0,p5,p1); addTetrahedron(t++, p2,p7,p0,p3); addTetrahedron(t++, p2,p5,p7,p6); addTetrahedron(t++, p0,p7,p5,p4); addTetrahedron(t++, p2,p0,p7,p5); } } } } }
TetrahedronSystem::TetrahedronSystem(ATetrahedronMesh * md) { m_hostTetrahedronVicinityInd = new BaseBuffer; m_hostTetrahedronVicinityStart = new BaseBuffer; m_hostElementValue = new BaseBuffer; create(md->numTetrahedrons() + 100, md->numTetrahedrons() * 4 + 400, md->numPoints() + 400); m_hostElementValue->create((md->numTetrahedrons() + 100) * 4); Vector3F * p = md->points(); unsigned i; for(i=0; i< md->numPoints(); i++) addPoint((float *)&p[i]); unsigned * ind = (unsigned *)md->indices(); for(i=0; i< md->numTetrahedrons(); i++) addTetrahedron(ind[i*4], ind[i*4+1], ind[i*4+2], ind[i*4+3]); unsigned * anchor = md->anchors(); for(i=0; i< md->numPoints(); i++) { //std::cout<<"a "<<anchor[i]; if(anchor[i] > 0) hostAnchor()[i] = anchor[i]; } // density of nylon = 1.15 g/cm^3 // very low density is unstable std::cout<<"\n initial volume "<<md->volume() <<"\n initial mass "<<(100.f * md->volume()) <<"\n"; setTotalMass(100.f * md->volume()); setInitialTotalMass(100.f * md->volume()); calculateMass(); createL2Vicinity(); }
void BlockBccMeshBuilder::addNorth(const Vector3F & cellCenter, float cellSize, float cellSizeH) { Vector3F tetV[4]; unsigned tetI[4]; tetV[0] = cellCenter - Vector3F::YAxis * cellSizeH; tetV[1] = tetV[0] + Vector3F::YAxis * cellSize; tetV[2] = cellCenter - Vector3F::XAxis * cellSizeH - Vector3F::ZAxis * cellSizeH; tetV[3] = tetV[2] + Vector3F::ZAxis * cellSize; addTetrahedron(tetV, tetI); tetV[2] = tetV[3]; tetV[3] = tetV[2] + Vector3F::XAxis * cellSize; addTetrahedron(tetV, tetI); tetV[2] = tetV[3]; tetV[3] = tetV[2] - Vector3F::ZAxis * cellSize; addTetrahedron(tetV, tetI); tetV[2] = tetV[3]; tetV[3] = tetV[2] - Vector3F::XAxis * cellSize; addTetrahedron(tetV, tetI); }
void BlockBccMeshBuilder::addDepth(const Vector3F & cellCenter, float cellSize, float cellSizeH, int i, int n) { Vector3F tetV[4]; unsigned tetI[4]; tetV[0] = cellCenter - Vector3F::ZAxis * cellSizeH; tetV[1] = tetV[0] + Vector3F::ZAxis * cellSize; if(i==0) { tetV[2] = cellCenter + Vector3F::XAxis * cellSizeH + Vector3F::YAxis * cellSizeH; tetV[3] = tetV[2] - Vector3F::XAxis * cellSize; addTetrahedron(tetV, tetI); } else if(i==n) { tetV[2] = cellCenter - Vector3F::XAxis * cellSizeH - Vector3F::YAxis * cellSizeH; tetV[3] = tetV[2] + Vector3F::XAxis * cellSize; addTetrahedron(tetV, tetI); } else { tetV[2] = cellCenter - Vector3F::XAxis * cellSizeH - Vector3F::YAxis * cellSizeH; tetV[3] = tetV[2] + Vector3F::XAxis * cellSize; addTetrahedron(tetV, tetI); tetV[2] = tetV[3]; tetV[3] = tetV[2] + Vector3F::YAxis * cellSize; addTetrahedron(tetV, tetI); tetV[2] = tetV[3]; tetV[3] = tetV[2] - Vector3F::XAxis * cellSize; addTetrahedron(tetV, tetI); tetV[2] = tetV[3]; tetV[3] = tetV[2] - Vector3F::YAxis * cellSize; addTetrahedron(tetV, tetI); } }
void FEMTetrahedronMesh::generateFromFile() { m_totalPoints = TetraNumVertices; m_X = new Vector3F[m_totalPoints]; m_Xi= new Vector3F[m_totalPoints]; m_mass = new float[m_totalPoints]; unsigned i; for(i=0; i<TetraNumVertices; i++) { m_X[i].set(TetraP[i][0], TetraP[i][1], TetraP[i][2]); m_Xi[i] = m_X[i]; } m_totalTetrahedrons = TetraNumTetrahedrons; m_tetrahedron = new Tetrahedron[m_totalTetrahedrons]; Tetrahedron * t = &m_tetrahedron[0]; for(i=0; i<m_totalTetrahedrons; i++) { addTetrahedron(t++, TetraIndices[i][0], TetraIndices[i][1], TetraIndices[i][2], TetraIndices[i][3]); } }
// Meshes either a prism or a hexahedral set of mesh vertices in a Transfinite Region with an internal vertex // that is created here in the function. void meshTransfElemWithInternalVertex( GRegion *gr, std::vector<MVertex *> v, std::set< std::pair<MVertex*, MVertex*> > *boundary_diags ) { int v_size = v.size(); int n_lat_tmp; if( v_size == 6 ) n_lat_tmp = 3; else if( v_size == 8 ) n_lat_tmp = 4; else{ Msg::Error("In meshTransfElemWithInternalVertex(), number of element vertices does not equal 6 or 8."); return; } const int n_lat = n_lat_tmp; // find vertex node indices for diagonalized faces std::vector<int> n1, n2; bool found_diags = false; int n_size = 0; if( n_lat == 3 ){ n1.assign(n_lat, -1); n2.assign(n_lat, -2); n_size = 3; } else if( n_lat == 4 ){ n1.assign(n_lat+2, -1); n2.assign(n_lat+2, -1); n_size = 6; } for( int p = 0; p < n_size; p++ ){ n1[p] = -p*p-p-1; n2[p] = -p*p-p-2; if( p < n_lat || n_lat == 3 ){ if( v[p] == v[p+n_lat] || v[(p+1)%n_lat] == v[(p+1)%n_lat+n_lat] ) continue; else if( edgeExists( v[p], v[(p+1)%n_lat+n_lat], (*boundary_diags) ) ){ n1[p] = p; n2[p] = (p+1)%n_lat+n_lat; found_diags = true; } else if( edgeExists( v[p+n_lat], v[(p+1)%n_lat], (*boundary_diags) ) ){ n1[p] = p+n_lat; n2[p] = (p+1)%n_lat; found_diags = true; } } else{ int add = ( p == n_lat ) ? 0 : n_lat; if( edgeExists( v[add], v[add+2], (*boundary_diags) ) ){ n1[p] = add; n2[p] = add+2; found_diags = true; } else if( edgeExists( v[add+1], v[add+3], (*boundary_diags) ) ){ n1[p] = add+1; n2[p] = add+3; found_diags = true; } } } if( !found_diags ){ if( n_lat == 3 ) addPrism( v[0], v[1], v[2], v[3], v[4], v[5], gr ); else if( n_lat ==4 ) addHexahedron( v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7], gr ); return; } // make the internal vertex std::vector<double> centroid = QtFindVertsCentroid(v); MVertex *v_int = new MVertex(centroid[0], centroid[1], centroid[2], gr); gr->mesh_vertices.push_back( v_int ); // build all pyramids/tetra for( int p = 0; p < n_lat; p++ ){ int p2 = (p+1)%n_lat; if( v[p] == v[p+n_lat] && v[p2] == v[p2+n_lat] ) continue; else if( v[p] == v[p+n_lat] || v[p2] == v[p2+n_lat] ){ MVertex *v_dup = (v[p] == v[p+n_lat]) ? v[p] : v[p2]; MVertex *v_non_dup = (v_dup == v[p]) ? v[p2] : v[p]; MVertex *v_non_dup2 = (v_non_dup == v[p]) ? v[p+n_lat] : v[p2+n_lat]; addTetrahedron( v_dup, v_non_dup, v_non_dup2, v_int, gr); } else if( n1[p] == p || n2[p] == p ){ addTetrahedron( v[p], v[p2], v[p2+n_lat], v_int, gr ); addTetrahedron( v[p], v[p2+n_lat], v[p+n_lat], v_int, gr ); } else if( n1[p] == p+n_lat || n2[p] == p+n_lat ){ addTetrahedron( v[p], v[p2], v[p+n_lat], v_int, gr ); addTetrahedron( v[p2], v[p2+n_lat], v[p+n_lat], v_int, gr ); } else addPyramid( v[p], v[p2], v[p2+n_lat], v[p+n_lat], v_int, gr ); } if( n_lat == 3){ // bottom and top addTetrahedron( v[0], v[1], v[2], v_int, gr ); addTetrahedron( v[3], v[5], v[4], v_int, gr ); } else if( n_lat == 4 ){ for( int p = 4; p < 6; p++ ){ int add = (p == 4) ? 0 : 4; if( n1[p] == 0+add || n2[p] == 0+add ){ addTetrahedron( v[add], v[1+add], v[2+add], v_int, gr ); addTetrahedron( v[add], v[2+add], v[3+add], v_int, gr ); } else if( n1[p] == 1+add || n2[p] == 1+add ){ addTetrahedron( v[1+add], v[2+add], v[3+add], v_int, gr ); addTetrahedron( v[1+add], v[3+add], v[add], v_int, gr ); } else addPyramid( v[add], v[1+add], v[2+add], v[3+add], v_int, gr ); } } } // End of meshTransfiniteWithInternalVertex()
static void createTet(MVertex *v1, MVertex *v2, MVertex *v3, MVertex *v4, GRegion *to, MElement* source) { if(v1 != v2 && v1 != v3 && v1 != v4 && v2 != v3 && v2 != v4 && v3 != v4) addTetrahedron(v1, v2, v3, v4, to); }
TetrahedronSystem::TetrahedronSystem() { m_hostTetrahedronVicinityInd = new BaseBuffer; m_hostTetrahedronVicinityStart = new BaseBuffer; m_hostElementValue = new BaseBuffer; create(NTET, NTET * 4, NPNT); m_hostElementValue->create(NTET * 4); float * hv = &hostV()[0]; unsigned i, j; float vy = 3.95f; float vrx, vry, vrz, vr, vs; for(j=0; j < GRDH; j++) { for(i=0; i<GRDW; i++) { vs = 1.75f + RandomF01() * 1.5f; Vector3F base(9.3f * i, 9.3f * j, 0.f * j); Vector3F right = base + Vector3F(1.75f, 0.f, 0.f) * vs; Vector3F front = base + Vector3F(0.f, 0.f, 1.75f) * vs; Vector3F top = base + Vector3F(0.f, 1.75f, 0.f) * vs; if((j&1)==0) { right.y = top.y-.1f; } else { base.x -= .085f * vs; } vrx = 0.725f * (RandomF01() - .5f); vry = 1.f * (RandomF01() + 1.f) * vy; vrz = 0.732f * (RandomF01() - .5f); vr = 0.13f * RandomF01(); addPoint(&base.x); hv[0] = vrx + vr; hv[1] = vry; hv[2] = vrz - vr; hv+=3; addPoint(&right.x); hv[0] = vrx - vr; hv[1] = vry; hv[2] = vrz + vr; hv+=3; addPoint(&top.x); hv[0] = vrx + vr; hv[1] = vry; hv[2] = vrz + vr; hv+=3; addPoint(&front.x); hv[0] = vrx - vr; hv[1] = vry; hv[2] = vrz - vr; hv+=3; unsigned b = (j * GRDW + i) * 4; addTetrahedron(b, b+1, b+2, b+3); } vy = -vy; } setTotalMass(100.f); setInitialTotalMass(100.f); calculateMass(); createL2Vicinity(); }