void WriteFile (int typ, const Mesh & mesh, const CSGeometry & geom, const char * filename, const char * geomfile, double h) { int inverttets = mparam.inverttets; int invertsurf = mparam.inverttrigs; if (typ == WRITE_EDGEELEMENT) { // write edge element file // Peter Harscher, ETHZ cout << "Write Edge-Element Format" << endl; ofstream outfile (filename); int i, j; int ned; // hash table representing edges; INDEX_2_HASHTABLE<int> edgeht(mesh.GetNP()); // list of edges Array<INDEX_2> edgelist; // edge (point) on boundary ? BitArray bedge, bpoint(mesh.GetNP()); static int eledges[6][2] = { { 1, 2 } , { 1, 3 } , { 1, 4 }, { 2, 3 } , { 2, 4 } , { 3, 4 } }; // fill hashtable (point1, point2) ----> edgenr for (i = 1; i <= mesh.GetNE(); i++) { const Element & el = mesh.VolumeElement (i); INDEX_2 edge; for (j = 1; j <= 6; j++) { edge.I1() = el.PNum (eledges[j-1][0]); edge.I2() = el.PNum (eledges[j-1][1]); edge.Sort(); if (!edgeht.Used (edge)) { edgelist.Append (edge); edgeht.Set (edge, edgelist.Size()); } } } // set bedges, bpoints bedge.SetSize (edgelist.Size()); bedge.Clear(); bpoint.Clear(); for (i = 1; i <= mesh.GetNSE(); i++) { const Element2d & sel = mesh.SurfaceElement(i); for (j = 1; j <= 3; j++) { bpoint.Set (sel.PNum(j)); INDEX_2 edge; edge.I1() = sel.PNum(j); edge.I2() = sel.PNum(j%3+1); edge.Sort(); bedge.Set (edgeht.Get (edge)); } } outfile << mesh.GetNE() << endl; // write element ---> point for (i = 1; i <= mesh.GetNE(); i++) { const Element & el = mesh.VolumeElement(i); outfile.width(8); outfile << i; for (j = 1; j <= 4; j++) { outfile.width(8); outfile << el.PNum(j); } outfile << endl; } // write element ---> edge for (i = 1; i <= mesh.GetNE(); i++) { const Element & el = mesh.VolumeElement (i); INDEX_2 edge; for (j = 1; j <= 6; j++) { edge.I1() = el.PNum (eledges[j-1][0]); edge.I2() = el.PNum (eledges[j-1][1]); edge.Sort(); outfile.width(8); outfile << edgeht.Get (edge); } outfile << endl; } // write points outfile << mesh.GetNP() << endl; outfile.precision (6); for (i = 1; i <= mesh.GetNP(); i++) { const Point3d & p = mesh.Point(i); for (j = 1; j <= 3; j++) { outfile.width(8); outfile << p.X(j); } outfile << " " << (bpoint.Test(i) ? "1" : 0) << endl; } // write edges outfile << edgelist.Size() << endl; for (i = 1; i <= edgelist.Size(); i++) { outfile.width(8); outfile << edgelist.Get(i).I1(); outfile.width(8); outfile << edgelist.Get(i).I2(); outfile << " " << (bedge.Test(i) ? "1" : "0") << endl; } } }
//protected: /// int HashValue (const INDEX_2 & ind) const { return (ind.I1() + ind.I2()) % hash.Size() + 1; }
bool Valid () const { return l.I1() != -1; }
void Invalidate () { l.I1() = -1; l.I2() = -1; lineclass = 1000; }
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()); } }