static INDEX_3 Sort (int i1, int i2, int i3) { if (i1 > i2) Swap (i1, i2); if (i2 > i3) Swap (i2, i3); if (i1 > i2) Swap (i1, i2); return INDEX_3 (i1, i2, i3); }
float NoiseSampler::vnoise(const glm::vec3& p) { int ix = FLOOR(p[0]); int iy = FLOOR(p[1]); int iz = FLOOR(p[2]); float fy = p[1]-iy; float fx = p[0]-ix; float fz = p[2]-iz; float xp[4], yp[4], zp[4]; for(int k = -1; k <= 2; k++) { for(int j = -1; j <= 2; j++) { for(int i = -1; i <= 2; i++) { xp[i+1] = m_value_table[INDEX_3(ix+i, iy+j, iz+k)]; } yp[j+1] = catmull_rom4(fx, xp); } zp[k+1] = catmull_rom4(fy, yp); } return catmull_rom4(fz, zp); }
HPREF_ELEMENT_TYPE ClassifyPrism(HPRefElement & el, INDEX_2_HASHTABLE<int> & edges, INDEX_2_HASHTABLE<int> & edgepoint_dom, BitArray & cornerpoint, BitArray & edgepoint, INDEX_3_HASHTABLE<int> & faces, INDEX_2_HASHTABLE<int> & face_edges, INDEX_2_HASHTABLE<int> & surf_edges, Array<int, PointIndex::BASE> & facepoint) { HPREF_ELEMENT_TYPE type = HP_NONE; int p[6]; for(int m=1;m<=6;m++) { int point_sing[6]={0,0,0,0,0,0}; int face_sing[5]={0,0,0,0,0}; int edge_sing[9]={0,0,0,0,0,0,0,0,0}; if(m<4) { p[0]= m; p[1]=m%3+1; p[2]=(m%3+1)%3+1; for(int l=3;l<6;l++) p[l]=p[l-3]+3; } else { p[0] = m; p[1]=(m%3+1)%3+4; p[2]=m%3+4; for(int l=3;l<6;l++) p[l]=p[l-3]-3; } for(int j=0;j<6;j++) { if(cornerpoint.Test(el.PNum(p[j]))) { point_sing[p[j]-1]=3;} else if(edgepoint.Test(el.PNum(p[j]))) point_sing[p[j]-1]=2; else if (facepoint[el.PNum(p[j])] == -1 || facepoint[el.PNum(p[j])] == el.GetIndex()) point_sing[p[j]-1] = 1; } const ELEMENT_EDGE * eledges = MeshTopology::GetEdges (PRISM); for(int k=0;k<9;k++) { INDEX_2 i2 = INDEX_2 :: Sort(el.PNum(p[eledges[k][0]-1]),el.PNum(p[eledges[k][1]-1])); if (edges.Used(i2)) edge_sing[k] = 2; else edge_sing[k] = face_edges.Used(i2); } const ELEMENT_FACE * elfaces = MeshTopology::GetFaces (PRISM); for (int k=0;k<5;k++) { INDEX_3 i3; if(k<2) i3 = INDEX_3::Sort(el.pnums[p[elfaces[k][0]-1]-1], el.pnums[p[elfaces[k][1]-1]-1], el.pnums[p[elfaces[k][2]-1]-1]); else { INDEX_4 i4 = INDEX_4(el.pnums[p[elfaces[k][0]-1]-1], el.pnums[p[elfaces[k][1]-1]-1], el.pnums[p[elfaces[k][2]-1]-1],el.pnums[p[elfaces[k][3]-1]-1]); i4.Sort(); i3 = INDEX_3(i4.I1(), i4.I2(), i4.I3()); } if (faces.Used (i3)) { int domnr = faces.Get(i3); if (domnr == -1 || domnr == el.GetIndex()) face_sing[k] = 1; } } if (face_sing[1] > face_sing[0]) {m=m+2; continue;} //int cp = 0; int qfsing = face_sing[2] + face_sing[3] + face_sing[4]; int tfsing = face_sing[0] + face_sing[1]; int evsing = edge_sing[6] + edge_sing[7] + edge_sing[8]; int ehsing = edge_sing[0] + edge_sing[1] + edge_sing[2] + edge_sing[3] + edge_sing[4] + edge_sing[5]; if (qfsing + tfsing + evsing + ehsing == 0) { type = HP_PRISM; break;} HPREF_ELEMENT_TYPE types[] = {HP_NONE,HP_NONE,HP_NONE}; int fb = (1-face_sing[4])* face_sing[3] * (face_sing[2] + face_sing[3]) + 3*face_sing[4]*face_sing[3]*face_sing[2]; int sve[3] = {edge_sing[7] , edge_sing[8], edge_sing[6]}; if(fb!=qfsing) continue; switch(fb) { case 0: if (evsing == 0 && ehsing==3*tfsing) { types[0] = HP_PRISM; types[1] = HP_PRISM_1FA_0E_0V; types[2] = HP_PRISM_2FA_0E_0V; } if(evsing > 0 && sve[0] == evsing) // 1 vertical edge 1-4 { types[0] = HP_PRISM_SINGEDGE; types[1] = HP_PRISM_1FA_1E_0V; types[2] = HP_PRISM_2FA_1E_0V; } if(sve[0] > 0 && sve[1] > 0 && sve[2] == 0) { types[0] = HP_PRISM_SINGEDGE_V12; types[1] = HP_PRISM_1FA_2E_0V; types[2] = HP_PRISM_2FA_2E_0V; } if(sve[0] > 0 && sve[1] > 0 && sve[2] > 0) { types[0] = HP_PRISM_3E_0V; types[1] = HP_PRISM_1FA_3E_0V; types[2] = HP_PRISM_2FA_3E_0V; if ( edge_sing[0] > 1 && edge_sing[2] > 1 && edge_sing[4] > 1 && edge_sing[5] > 1 && tfsing==0) types[0] = HP_PRISM_3E_4EH; } break; case 1: if(sve[0] <= 1 && sve[1] <= 1) if(sve[2]==0) { types[0] = HP_PRISM_1FB_0E_0V; types[1] = HP_PRISM_1FA_1FB_0E_0V; types[2] = HP_PRISM_2FA_1FB_0E_0V; } else { types[0] = HP_PRISM_1FB_1EC_0V; types[1] = HP_PRISM_1FA_1FB_1EC_0V; types[2] = HP_PRISM_2FA_1FB_1EC_0V; } if(sve[0] > 1 && sve[2] >= 1 && sve[1] <= 1) { types[0] = HP_PRISM_1FB_2EB_0V; types[1] = HP_PRISM_1FA_1FB_2EB_0V; types[2] = HP_PRISM_2FA_1FB_2EB_0V; } if(sve[0] > 1 && sve[1] <= 1 && sve[2] == 0) // ea && !eb { types[0] = HP_PRISM_1FB_1EA_0V; types[1] = HP_PRISM_1FA_1FB_1EA_0V; types[2] = HP_PRISM_2FA_1FB_1EA_0V; } if(sve[0] <= 1 && sve[1] > 1 && sve[2] == 0) types[1] = HP_PRISM_1FA_1FB_1EB_0V; if(sve[0] > 1 && sve[1]>1) if(sve[2] == 0) // ea && eb { types[0] = HP_PRISM_1FB_2EA_0V; types[1] = HP_PRISM_1FA_1FB_2EA_0V; types[2] = HP_PRISM_2FA_1FB_2EA_0V; } if(sve[0] <= 1 && sve[1] > 1 && sve[2] >0) types[1] = HP_PRISM_1FA_1FB_2EC_0V; if(sve[0] > 1 && sve[1] > 1 && sve[2] >= 1) //sve[2] can also be a face-edge { types[0] = HP_PRISM_1FB_3E_0V; types[1] = HP_PRISM_1FA_1FB_3E_0V; types[2] = HP_PRISM_2FA_1FB_3E_0V; } break; case 2: if(sve[0] <= 1) cout << " **** WARNING: Edge between to different singular faces should be marked singular " << endl; if(sve[1] <= 1) if(sve[2] <=1) { types[0] = HP_PRISM_2FB_0E_0V; types[1] = HP_PRISM_1FA_2FB_0E_0V; types[2] = HP_PRISM_2FA_2FB_0E_0V; } else { types[0] = HP_PRISM_2FB_1EC_0V; types[1] = HP_PRISM_1FA_2FB_1EC_0V; types[2] = HP_PRISM_2FA_2FB_1EC_0V; } else if(sve[2] <= 1) types[1] = HP_PRISM_1FA_2FB_1EB_0V; else { types[0] = HP_PRISM_2FB_3E_0V; types[1] = HP_PRISM_1FA_2FB_3E_0V; types[2] = HP_PRISM_2FA_2FB_3E_0V; } break; case 3: types[0] = HP_PRISM_3FB_0V; types[1] = HP_PRISM_1FA_3FB_0V; types[2] = HP_PRISM_2FA_3FB_0V; break; } type = types[tfsing]; if(type != HP_NONE) break; } /* *testout << " Prism with pnums " << endl; for(int j=0;j<6;j++) *testout << el.pnums[j] << "\t"; *testout << endl; */ if(type != HP_NONE) { int pnums[6]; for(int j=0;j<6;j++) pnums[j] = el.PNum (p[j]); for(int k=0;k<6;k++) el.pnums[k] = pnums[k]; } /* *testout << " Classified Prism with pnums " << endl; for(int j=0;j<6;j++) *testout << el.pnums[j] << "\t"; *testout << endl; */ return(type); }
HPREF_ELEMENT_TYPE ClassifyPyramid(HPRefElement & el, INDEX_2_HASHTABLE<int> & edges, INDEX_2_HASHTABLE<int> & edgepoint_dom, BitArray & cornerpoint, BitArray & edgepoint, INDEX_3_HASHTABLE<int> & faces, INDEX_2_HASHTABLE<int> & face_edges, INDEX_2_HASHTABLE<int> & surf_edges, Array<int, PointIndex::BASE> & facepoint) { HPREF_ELEMENT_TYPE type = HP_NONE; // implementation only for HP_PYRAMID // HP_PYRAMID_0E_1V // HP_PYRAMID_EDGES // HP_PYRAMID_1FB_0E_1VA // up to now other cases are refine dummies // indices of bot,top-faces combinations // int index[6][2] = {{0,1},{1,0},{2,4},{4,2},{3,5},{5,3}}; const ELEMENT_FACE * elfaces = MeshTopology::GetFaces (PYRAMID); const ELEMENT_EDGE * eledges = MeshTopology::GetEdges (PYRAMID); int point_sing[5]={0,0,0,0,0}; int face_sing[5] = {0,0,0,0,0}; int edge_sing[8] = {0,0,0,0,0,0,0,0}; int spoint=0, sedge=0, sface=0; for(int m=0;m<4 && type == HP_NONE;m++) { int p[5] = {m%4, m%4+1, m%4+2, m%4+3, 4}; for(int l=0;l<5;l++) { if(cornerpoint.Test(el.pnums[p[l]])) point_sing[l]=3; else if(edgepoint.Test(el.pnums[p[l]])) point_sing[l]=2; else if (facepoint[el.pnums[p[l]]] == -1 || facepoint[el.pnums[p[l]]] == el.GetIndex()) point_sing[l] = 1; spoint += point_sing[l]; } for(int k=0;k<8;k++) { INDEX_2 i2 = INDEX_2 :: Sort(el.pnums[p[eledges[k][0]-1]], el.pnums[p[eledges[k][1]-1]]); if (edges.Used(i2)) edge_sing[k] = 2; else edge_sing[k] = face_edges.Used(i2); sedge += edge_sing[k]; } for (int k=0;k<5;k++) { INDEX_3 i3; INDEX_4 i4 = INDEX_4(el.pnums[p[elfaces[k][0]-1]], el.pnums[p[elfaces[k][1]-1]], el.pnums[p[elfaces[k][2]-1]], el.pnums[p[elfaces[k][3]-1]]); i4.Sort(); i3 = INDEX_3(i4.I1(), i4.I2(), i4.I3()); if (faces.Used (i3)) { int domnr = faces.Get(i3); if (domnr == -1 || domnr == el.GetIndex()) face_sing[k] = 1; } sface +=face_sing[k]; } if(!sface && !spoint && !sedge) return(HP_PYRAMID); if(!sface && !sedge && point_sing[p[0]] == spoint) type = HP_PYRAMID_0E_1V; if(!sface && edge_sing[0] + edge_sing[2] == sedge && spoint == point_sing[0] + point_sing[1] + point_sing[3]) type = HP_PYRAMID_EDGES; if(sface && sface == face_sing[0] && spoint == point_sing[4] + 2) type = HP_PYRAMID_1FB_0E_1VA; if(type != HP_NONE) { int pnums[8]; for(int l=0;l<5;l++) pnums[l] = el[p[l]]; for(int l=0;l<5;l++) el[l] = pnums[l]; el.type=type; break; } } return (type); }
HPREF_ELEMENT_TYPE ClassifyHex(HPRefElement & el, INDEX_2_HASHTABLE<int> & edges, INDEX_2_HASHTABLE<int> & edgepoint_dom, BitArray & cornerpoint, BitArray & edgepoint, INDEX_3_HASHTABLE<int> & faces, INDEX_2_HASHTABLE<int> & face_edges, INDEX_2_HASHTABLE<int> & surf_edges, Array<int, PointIndex::BASE> & facepoint) { HPREF_ELEMENT_TYPE type = HP_NONE; // implementation only for HP_HEX_1F_0E_0V // HP_HEX_1FA_1FB_0E_0V // HP_HEX // up to now other cases are refine dummies // indices of bot,top-faces combinations int index[6][2] = {{0,1},{1,0},{2,4},{4,2},{3,5},{5,3}}; int p[8]; const ELEMENT_FACE * elfaces = MeshTopology::GetFaces (HEX); const ELEMENT_EDGE * eledges = MeshTopology::GetEdges (HEX); for(int m=0;m<6 && type == HP_NONE;m++) for(int j=0;j<4 && type == HP_NONE;j++) { int point_sing[8]={0,0,0,0,0,0,0,0}; int face_sing[6] = {0,0,0,0,0,0}; int edge_sing[12] = {0,0,0,0,0,0,0,0,0,0,0,0}; int spoint=0, sface=0, sedge=0; for(int l=0;l<4;l++) { p[l] = elfaces[index[m][0]][(4-j-l)%4]; p[l+4] = elfaces[index[m][1]][(j+l)%4]; } for(int l=0;l<8;l++) if(cornerpoint.Test(el.PNum(p[l]))) { point_sing[p[l]-1]=3; spoint++; } else if(edgepoint.Test(el.PNum(p[l]))) point_sing[p[l]-1]=2; else if (facepoint[el.PNum(p[l])] == -1 || facepoint[el.PNum(p[l])] == el.GetIndex()) point_sing[p[l]-1] = 1; for(int k=0;k<12;k++) { INDEX_2 i2 = INDEX_2 :: Sort(el.PNum(p[eledges[k][0]-1]),el.PNum(p[eledges[k][1]-1])); if (edges.Used(i2)) { edge_sing[k] = 2; sedge++; } else edge_sing[k] = face_edges.Used(i2); } for (int k=0;k<6;k++) { INDEX_3 i3; INDEX_4 i4 = INDEX_4(el.pnums[p[elfaces[k][0]-1]-1], el.pnums[p[elfaces[k][1]-1]-1], el.pnums[p[elfaces[k][2]-1]-1],el.pnums[p[elfaces[k][3]-1]-1]); i4.Sort(); i3 = INDEX_3(i4.I1(), i4.I2(), i4.I3()); if (faces.Used (i3)) { int domnr = faces.Get(i3); if (domnr == -1 || domnr == el.GetIndex()) { face_sing[k] = 1; sface++; } } } if(!sface && !sedge && !spoint) type = HP_HEX; if(!sedge && !spoint) { if(face_sing[0] && face_sing[2] && sface==2) type = HP_HEX_1FA_1FB_0E_0V; if (face_sing[0] && sface==1) type = HP_HEX_1F_0E_0V; } el.type=type; if(type != HP_NONE) { int pnums[8]; for(int l=0;l<8;l++) pnums[l] = el[p[l]-1]; for(int l=0;l<8;l++) el[l] = pnums[l]; /* cout << " HEX with pnums " << pnums[0] << "\t" << pnums[1] << "\t" << pnums[2] << "\t" << pnums[3] << "\t" << pnums[4] << "\t" << pnums[5] << endl << " of type " << type << endl; */ break; } } return (type); }
void RefinePrisms (Mesh & mesh, const CSGeometry * geom, ZRefinementOptions & opt) { int i, j; bool found, change; int cnt = 0; // markers for z-refinement: p1, p2, levels // p1-p2 is an edge to be refined ARRAY<INDEX_3> ref_uniform; ARRAY<INDEX_3> ref_singular; ARRAY<INDEX_4 > ref_slices; BitArray first_id(geom->identifications.Size()); first_id.Set(); INDEX_2_HASHTABLE<int> & identpts = mesh.GetIdentifications().GetIdentifiedPoints (); if (&identpts) { for (i = 1; i <= identpts.GetNBags(); i++) for (j = 1; j <= identpts.GetBagSize(i); j++) { INDEX_2 pair; int idnr; identpts.GetData(i, j, pair, idnr); const CloseSurfaceIdentification * csid = dynamic_cast<const CloseSurfaceIdentification*> (geom->identifications.Get(idnr)); if (csid) { if (!csid->GetSlices().Size()) { if (first_id.Test (idnr)) { first_id.Clear(idnr); ref_uniform.Append (INDEX_3 (pair.I1(), pair.I2(), csid->RefLevels())); ref_singular.Append (INDEX_3 (pair.I1(), pair.I2(), csid->RefLevels1())); ref_singular.Append (INDEX_3 (pair.I2(), pair.I1(), csid->RefLevels2())); } } else { //const ARRAY<double> & slices = csid->GetSlices(); INDEX_4 i4; i4[0] = pair.I1(); i4[1] = pair.I2(); i4[2] = idnr; i4[3] = csid->GetSlices().Size(); ref_slices.Append (i4); } } } } ARRAY<EdgePointGeomInfo> epgi; while (1) { cnt++; PrintMessage (3, "Z-Refinement, level = ", cnt); INDEX_2_HASHTABLE<int> refedges(mesh.GetNSE()+1); found = 0; // mark prisms due to close surface flags: int oldsize = ref_uniform.Size(); for (i = 1; i <= oldsize; i++) { int pi1 = ref_uniform.Get(i).I1(); int pi2 = ref_uniform.Get(i).I2(); int levels = ref_uniform.Get(i).I3(); if (levels > 0) { const Point3d & p1 = mesh.Point(pi1); const Point3d & p2 = mesh.Point(pi2); int npi(0); INDEX_2 edge(pi1, pi2); edge.Sort(); if (!refedges.Used(edge)) { Point3d np = Center (p1, p2); npi = mesh.AddPoint (np); refedges.Set (edge, npi); found = 1; } ref_uniform.Elem(i) = INDEX_3(pi1, npi, levels-1); ref_uniform.Append (INDEX_3(pi2, npi, levels-1)); } } for (i = 1; i <= ref_singular.Size(); i++) { int pi1 = ref_singular.Get(i).I1(); int pi2 = ref_singular.Get(i).I2(); int levels = ref_singular.Get(i).I3(); if (levels > 0) { const Point3d & p1 = mesh.Point(pi1); const Point3d & p2 = mesh.Point(pi2); int npi; INDEX_2 edge(pi1, pi2); edge.Sort(); if (!refedges.Used(edge)) { Point3d np = Center (p1, p2); npi = mesh.AddPoint (np); refedges.Set (edge, npi); found = 1; } else npi = refedges.Get (edge); ref_singular.Elem(i) = INDEX_3(pi1, npi, levels-1); } } for (i = 1; i <= ref_slices.Size(); i++) { int pi1 = ref_slices.Get(i)[0]; int pi2 = ref_slices.Get(i)[1]; int idnr = ref_slices.Get(i)[2]; int slicenr = ref_slices.Get(i)[3]; if (slicenr > 0) { const Point3d & p1 = mesh.Point(pi1); const Point3d & p2 = mesh.Point(pi2); int npi; const CloseSurfaceIdentification * csid = dynamic_cast<const CloseSurfaceIdentification*> (geom->identifications.Get(idnr)); INDEX_2 edge(pi1, pi2); edge.Sort(); if (!refedges.Used(edge)) { const ARRAY<double> & slices = csid->GetSlices(); //(*testout) << "idnr " << idnr << " i " << i << endl; //(*testout) << "slices " << slices << endl; double slicefac = slices.Get(slicenr); double slicefaclast = (slicenr == slices.Size()) ? 1 : slices.Get(slicenr+1); Point3d np = p1 + (slicefac / slicefaclast) * (p2-p1); //(*testout) << "slicenr " << slicenr << " slicefac " << slicefac << " quot " << (slicefac / slicefaclast) << " np " << np << endl; npi = mesh.AddPoint (np); refedges.Set (edge, npi); found = 1; } else npi = refedges.Get (edge); ref_slices.Elem(i)[1] = npi; ref_slices.Elem(i)[3] --; } } for (i = 1; i <= mesh.GetNE(); i++) { Element & el = mesh.VolumeElement (i); if (el.GetType() != PRISM) continue; for (j = 1; j <= 3; j++) { int pi1 = el.PNum(j); int pi2 = el.PNum(j+3); const Point3d & p1 = mesh.Point(pi1); const Point3d & p2 = mesh.Point(pi2); bool ref = 0; /* if (Dist (p1, p2) > mesh.GetH (Center (p1, p2))) ref = 1; */ /* if (cnt <= opt.minref) ref = 1; */ /* if ((pi1 == 460 || pi2 == 460 || pi1 == 461 || pi2 == 461) && cnt <= 8) ref = 1; */ if (ref == 1) { INDEX_2 edge(pi1, pi2); edge.Sort(); if (!refedges.Used(edge)) { Point3d np = Center (p1, p2); int npi = mesh.AddPoint (np); refedges.Set (edge, npi); found = 1; } } } } if (!found) break; // build closure: PrintMessage (5, "start closure"); do { PrintMessage (5, "start loop"); change = 0; for (i = 1; i <= mesh.GetNE(); i++) { Element & el = mesh.VolumeElement (i); if (el.GetType() != PRISM) continue; bool hasref = 0, hasnonref = 0; for (j = 1; j <= 3; j++) { int pi1 = el.PNum(j); int pi2 = el.PNum(j+3); if (pi1 != pi2) { INDEX_2 edge(pi1, pi2); edge.Sort(); if (refedges.Used(edge)) hasref = 1; else hasnonref = 1; } } if (hasref && hasnonref) { // cout << "el " << i << " in closure" << endl; change = 1; for (j = 1; j <= 3; j++) { int pi1 = el.PNum(j); int pi2 = el.PNum(j+3); const Point3d & p1 = mesh.Point(pi1); const Point3d & p2 = mesh.Point(pi2); INDEX_2 edge(pi1, pi2); edge.Sort(); if (!refedges.Used(edge)) { Point3d np = Center (p1, p2); int npi = mesh.AddPoint (np); refedges.Set (edge, npi); } } } } } while (change); PrintMessage (5, "Do segments"); // (*testout) << "closure formed, np = " << mesh.GetNP() << endl; int oldns = mesh.GetNSeg(); for (i = 1; i <= oldns; i++) { const Segment & el = mesh.LineSegment(i); INDEX_2 i2(el.p1, el.p2); i2.Sort(); int pnew; EdgePointGeomInfo ngi; if (refedges.Used(i2)) { pnew = refedges.Get(i2); // ngi = epgi.Get(pnew); } else { continue; // Point3d pb; // /* // geom->PointBetween (mesh.Point (el.p1), // mesh.Point (el.p2), // el.surfnr1, el.surfnr2, // el.epgeominfo[0], el.epgeominfo[1], // pb, ngi); // */ // pb = Center (mesh.Point (el.p1), mesh.Point (el.p2)); // pnew = mesh.AddPoint (pb); // refedges.Set (i2, pnew); // if (pnew > epgi.Size()) // epgi.SetSize (pnew); // epgi.Elem(pnew) = ngi; } Segment ns1 = el; Segment ns2 = el; ns1.p2 = pnew; ns1.epgeominfo[1] = ngi; ns2.p1 = pnew; ns2.epgeominfo[0] = ngi; mesh.LineSegment(i) = ns1; mesh.AddSegment (ns2); } PrintMessage (5, "Segments done, NSeg = ", mesh.GetNSeg()); // do refinement int oldne = mesh.GetNE(); for (i = 1; i <= oldne; i++) { Element & el = mesh.VolumeElement (i); if (el.GetNP() != 6) continue; int npi[3]; for (j = 1; j <= 3; j++) { int pi1 = el.PNum(j); int pi2 = el.PNum(j+3); if (pi1 == pi2) npi[j-1] = pi1; else { INDEX_2 edge(pi1, pi2); edge.Sort(); if (refedges.Used (edge)) npi[j-1] = refedges.Get(edge); else { /* (*testout) << "ERROR: prism " << i << " has hanging node !!" << ", edge = " << edge << endl; cerr << "ERROR: prism " << i << " has hanging node !!" << endl; */ npi[j-1] = 0; } } } if (npi[0]) { Element nel1(6), nel2(6); for (j = 1; j <= 3; j++) { nel1.PNum(j) = el.PNum(j); nel1.PNum(j+3) = npi[j-1]; nel2.PNum(j) = npi[j-1]; nel2.PNum(j+3) = el.PNum(j+3); } nel1.SetIndex (el.GetIndex()); nel2.SetIndex (el.GetIndex()); mesh.VolumeElement (i) = nel1; mesh.AddVolumeElement (nel2); } } PrintMessage (5, "Elements done, NE = ", mesh.GetNE()); // do surface elements int oldnse = mesh.GetNSE(); // cout << "oldnse = " << oldnse << endl; for (i = 1; i <= oldnse; i++) { Element2d & el = mesh.SurfaceElement (i); if (el.GetType() != QUAD) continue; int index = el.GetIndex(); int npi[2]; for (j = 1; j <= 2; j++) { int pi1, pi2; if (j == 1) { pi1 = el.PNum(1); pi2 = el.PNum(4); } else { pi1 = el.PNum(2); pi2 = el.PNum(3); } if (pi1 == pi2) npi[j-1] = pi1; else { INDEX_2 edge(pi1, pi2); edge.Sort(); if (refedges.Used (edge)) npi[j-1] = refedges.Get(edge); else { npi[j-1] = 0; } } } if (npi[0]) { Element2d nel1(QUAD), nel2(QUAD); for (j = 1; j <= 4; j++) { nel1.PNum(j) = el.PNum(j); nel2.PNum(j) = el.PNum(j); } nel1.PNum(3) = npi[1]; nel1.PNum(4) = npi[0]; nel2.PNum(1) = npi[0]; nel2.PNum(2) = npi[1]; /* for (j = 1; j <= 2; j++) { nel1.PNum(j) = el.PNum(j); nel1.PNum(j+2) = npi[j-1]; nel2.PNum(j) = npi[j-1]; nel2.PNum(j+2) = el.PNum(j+2); } */ nel1.SetIndex (el.GetIndex()); nel2.SetIndex (el.GetIndex()); mesh.SurfaceElement (i) = nel1; mesh.AddSurfaceElement (nel2); int si = mesh.GetFaceDescriptor (index).SurfNr(); Point<3> hp = mesh.Point(npi[0]); geom->GetSurface(si)->Project (hp); mesh.Point (npi[0]).SetPoint (hp); hp = mesh.Point(npi[1]); geom->GetSurface(si)->Project (hp); mesh.Point (npi[1]).SetPoint (hp); // geom->GetSurface(si)->Project (mesh.Point(npi[0])); // geom->GetSurface(si)->Project (mesh.Point(npi[1])); } } PrintMessage (5, "Surface elements done, NSE = ", mesh.GetNSE()); } }