Merge branch 'flat_boundarylayer_curving_support' into 'master'

Allow curving of mesh if boundarylayer is flat.

See merge request jschoeberl/netgen!323
This commit is contained in:
Joachim Schöberl 2020-06-24 06:41:06 +00:00
commit 2ee4095b42
3 changed files with 74 additions and 77 deletions

View File

@ -130,6 +130,7 @@ namespace netgen
Point<3> & newp, EdgePointGeomInfo & newgi) const Point<3> & newp, EdgePointGeomInfo & newgi) const
{ {
Point<3> hnewp = p1+secpoint*(p2-p1); Point<3> hnewp = p1+secpoint*(p2-p1);
//(*testout) << "hnewp " << hnewp << " s1 " << surfi1 << " s2 " << surfi2 << endl; //(*testout) << "hnewp " << hnewp << " s1 " << surfi1 << " s2 " << surfi2 << endl;
if (surfi1 != -1 && surfi2 != -1 && surfi1 != surfi2) if (surfi1 != -1 && surfi2 != -1 && surfi1 != surfi2)
{ {

View File

@ -159,7 +159,8 @@ namespace netgen
auto& old_fd = mesh.GetFaceDescriptor(si); auto& old_fd = mesh.GetFaceDescriptor(si);
int domout = blp.outside ? old_fd.DomainOut() : blp.new_matnrs[layer-1]; int domout = blp.outside ? old_fd.DomainOut() : blp.new_matnrs[layer-1];
int domin = blp.outside ? blp.new_matnrs[layer-1] : old_fd.DomainIn(); int domin = blp.outside ? blp.new_matnrs[layer-1] : old_fd.DomainIn();
FaceDescriptor fd(max_surface_index-1, // -1 surf nr is so that curving does not do anything
FaceDescriptor fd(-1,
domin, domout, -1); domin, domout, -1);
fd.SetBCProperty(max_surface_index); fd.SetBCProperty(max_surface_index);
mesh.AddFaceDescriptor(fd); mesh.AddFaceDescriptor(fd);
@ -271,14 +272,13 @@ namespace netgen
if(blp.grow_edges) if(blp.grow_edges)
for(SegmentIndex sei = 0; sei < nseg; sei++) for(SegmentIndex sei = 0; sei < nseg; sei++)
{ {
PointIndex seg_p1 = mesh[sei][0]; auto& segi = mesh[sei];
PointIndex seg_p2 = mesh[sei][1];
// Only go in if the segment is still active, and if both its // Only go in if the segment is still active, and if both its
// surface index is part of the "hit-list" // surface index is part of the "hit-list"
if(segsel.Test(sei)) if(segsel.Test(sei))
{ {
if(blp.surfid.Contains(mesh[sei].si)) if(blp.surfid.Contains(segi.si))
{ {
// clear the bit to indicate that this segment has been processed // clear the bit to indicate that this segment has been processed
segsel.Clear(sei); segsel.Clear(sei);
@ -286,40 +286,39 @@ namespace netgen
// Find matching segment pair on other surface // Find matching segment pair on other surface
for(SegmentIndex sej = 0; sej < nseg; sej++) for(SegmentIndex sej = 0; sej < nseg; sej++)
{ {
PointIndex segpair_p1 = mesh[sej][1]; auto& segj = mesh[sej];
PointIndex segpair_p2 = mesh[sej][0];
// Find the segment pair on the neighbouring surface element // Find the segment pair on the neighbouring surface element
// Identified by: seg1[0] = seg_pair[1] and seg1[1] = seg_pair[0] // Identified by: seg1[0] = seg_pair[1] and seg1[1] = seg_pair[0]
if(segsel.Test(sej) && ((segpair_p1 == seg_p1) && (segpair_p2 == seg_p2))) if(segsel.Test(sej) && ((segi[0] == segj[1]) && (segi[1] == segj[0])))
{ {
// clear bit to indicate that processing of this segment is done // clear bit to indicate that processing of this segment is done
segsel.Clear(sej); segsel.Clear(sej);
// Only worry about those surfaces which are not in the // if segj is not in surfel list we nned to add quads
// boundary layer list if(!blp.surfid.Contains(segj.si))
if(!blp.surfid.Contains(mesh[sej].si))
{ {
SurfaceElementIndex pnt_commelem; SurfaceElementIndex pnt_commelem;
SetInvalid(pnt_commelem); SetInvalid(pnt_commelem);
auto pnt1_elems = meshtopo.GetVertexSurfaceElements(segpair_p1); auto pnt1_elems = meshtopo.GetVertexSurfaceElements(segj[0]);
auto pnt2_elems = meshtopo.GetVertexSurfaceElements(segpair_p2); auto pnt2_elems = meshtopo.GetVertexSurfaceElements(segj[1]);
for(auto pnt1_sei : pnt1_elems) for(auto pnt1_sei : pnt1_elems)
if(mesh[pnt1_sei].GetIndex() == mesh[sej].si) if(mesh[pnt1_sei].GetIndex() == segj.si)
for(auto pnt2_sei : pnt2_elems) for(auto pnt2_sei : pnt2_elems)
if(pnt1_sei == pnt2_sei) if(pnt1_sei == pnt2_sei)
pnt_commelem = pnt1_sei; pnt_commelem = pnt1_sei;
if(IsInvalid(pnt_commelem)) if(IsInvalid(pnt_commelem))
throw Exception("Couldn't find element on other side for " + ToString(segpair_p1) + " to " + ToString(segpair_p2)); throw Exception("Couldn't find element on other side for " + ToString(segj[0]) + " to " + ToString(segj[1]));
const auto& commsel = mesh[pnt_commelem]; const auto& commsel = mesh[pnt_commelem];
auto surfelem_vect = GetSurfaceNormal(mesh, commsel); auto surfelem_vect = GetSurfaceNormal(mesh, commsel);
if(blp.outside) if(blp.outside)
surfelem_vect *= -1; surfelem_vect *= -1;
Element2d sel(QUAD); Element2d sel(QUAD);
auto seg_p1 = segi[0];
auto seg_p2 = segi[1];
if(blp.outside) if(blp.outside)
Swap(seg_p1, seg_p2); Swap(seg_p1, seg_p2);
sel[0] = seg_p1; sel[0] = seg_p1;
@ -332,7 +331,7 @@ namespace netgen
{ {
domains_to_surf_index[domains] = ++max_surface_index; domains_to_surf_index[domains] = ++max_surface_index;
domains_to_surf_index[make_tuple(max_surface_index, get<1>(domains), get<2>(domains))] = max_surface_index; domains_to_surf_index[make_tuple(max_surface_index, get<1>(domains), get<2>(domains))] = max_surface_index;
FaceDescriptor fd(max_surface_index-1, FaceDescriptor fd(-1,
get<1>(domains), get<1>(domains),
get<2>(domains), get<2>(domains),
-1); -1);
@ -367,44 +366,35 @@ namespace netgen
seg_2.edgenr = pi_to_edgenr[points]; seg_2.edgenr = pi_to_edgenr[points];
seg_2.si = new_index; seg_2.si = new_index;
mesh.AddSegment(seg_2); mesh.AddSegment(seg_2);
mesh[sej].si = new_index;
} }
// in last layer insert new segments // in last layer insert new segments
if(layer == blp.heights.Size()) if(layer == blp.heights.Size())
{ {
Segment s1 = mesh[sei]; Segment s1 = segi;
Segment s2 = mesh[sej]; Segment s2 = segj;
s1.edgenr = ++max_edge_nr; s1.edgenr = ++max_edge_nr;
s2.edgenr = max_edge_nr; s2.edgenr = max_edge_nr;
bool create_it = true; if(blp.surfid.Contains(segj.si))
if(blp.surfid.Contains(mesh[sej].si)) s2.si = map_surface_index(segj.si);
{
if(last_layer_surface_index_map.find(s1.si) != last_layer_surface_index_map.end() &&
last_layer_surface_index_map.find(s2.si) != last_layer_surface_index_map.end())
// edge already mapped
create_it = false;
s2.si = map_surface_index(s2.si);
}
else else
{ {
s2.si = domains_to_surf_index[make_tuple(s2.si, auto side_surf = domains_to_surf_index[make_tuple(s2.si, blp.new_matnrs[layer-1], mesh.GetFaceDescriptor(s2.si).DomainOut())];
blp.new_matnrs[layer-1], mesh.GetFaceDescriptor(s2.si).DomainOut())]; if(blp.outside)
s2.si = side_surf;
else
segj.si = side_surf;
} }
s1.si = map_surface_index(s1.si); s1.si = map_surface_index(s1.si);
if(create_it) s1.surfnr1 = s1.surfnr2 = s2.surfnr1 = s2.surfnr2 = -1;
{
mesh.AddSegment(s1); mesh.AddSegment(s1);
mesh.AddSegment(s2); mesh.AddSegment(s2);
} }
} // segi[0] = mapto[segi[0]] not working somehow?
mesh[sei][0] = mapto[segi[0]];
// remap the segments to the new points mesh[sei][1] = mapto[segi[1]];
mesh[sei][0] = mapto[mesh[sei][0]]; mesh[sej][0] = mapto[segj[0]];
mesh[sei][1] = mapto[mesh[sei][1]]; mesh[sej][1] = mapto[segj[1]];
mesh[sej][1] = mapto[mesh[sej][1]];
mesh[sej][0] = mapto[mesh[sej][0]];
} }
} }
} }
@ -456,10 +446,10 @@ namespace netgen
if(layer == blp.heights.Size()) if(layer == blp.heights.Size())
{ {
for(SurfaceElementIndex si = 0; si < nse; si++) for(SurfaceElementIndex si = 0; si < nse; si++)
{
if(blp.surfid.Contains(mesh[si].GetIndex()))
{ {
const auto& sel = mesh[si]; const auto& sel = mesh[si];
if(blp.surfid.Contains(sel.GetIndex()))
{
Element2d newel = sel; Element2d newel = sel;
newel.SetIndex(map_surface_index(sel.GetIndex())); newel.SetIndex(map_surface_index(sel.GetIndex()));
mesh.AddSurfaceElement(newel); mesh.AddSurfaceElement(newel);
@ -548,36 +538,28 @@ namespace netgen
for(SurfaceElementIndex sei : Range(nse)) for(SurfaceElementIndex sei : Range(nse))
{ {
auto& sel = mesh[sei]; auto& sel = mesh[sei];
bool to_move = blp.surfid.Contains(sel.GetIndex()); if(!blp.surfid.Contains(sel.GetIndex()))
if(blp.domains.Size())
{ {
if(blp.outside) const auto& fd = mesh.GetFaceDescriptor(sel.GetIndex());
to_move |= blp.domains[mesh.GetFaceDescriptor(sel.GetIndex()).DomainIn()]; if(blp.outside &&
else (!blp.domains[fd.DomainIn()] && !blp.domains[fd.DomainOut()]))
to_move |= !blp.domains[mesh.GetFaceDescriptor(sel.GetIndex()).DomainIn()]; continue;
if(!blp.outside &&
(blp.domains[fd.DomainIn()] || blp.domains[fd.DomainOut()]))
continue;
} }
if(to_move)
{
for(auto& pnum : sel.PNums()) for(auto& pnum : sel.PNums())
// Check (Doublecheck) if the corresponding point has a
// copy available for remapping
if(mapto[pnum].IsValid()) if(mapto[pnum].IsValid())
// Map the surface elements to the new points
pnum = mapto[pnum]; pnum = mapto[pnum];
} }
}
for(ElementIndex ei : Range(ne)) for(ElementIndex ei : Range(ne))
{ {
auto& el = mesh[ei]; auto& el = mesh[ei];
bool to_move = blp.outside ? blp.domains[el.GetIndex()] : !blp.domains[el.GetIndex()]; // only move the elements on the correct side
if(blp.domains.Size() == 0 || to_move) if(blp.outside ? blp.domains[el.GetIndex()] : !blp.domains[el.GetIndex()])
for(auto& pnum : el.PNums()) for(auto& pnum : el.PNums())
// Check (Doublecheck) if the corresponding point has a
// copy available for remapping
if(mapto[pnum].IsValid()) if(mapto[pnum].IsValid())
// Map the volume elements to the new points
pnum = mapto[pnum]; pnum = mapto[pnum];
} }

View File

@ -949,9 +949,23 @@ DLL_HEADER void ExportNetgenMeshing(py::module &m)
{ {
regex pattern(*get_if<string>(&boundary)); regex pattern(*get_if<string>(&boundary));
for(int i = 1; i<=self.GetNFD(); i++) for(int i = 1; i<=self.GetNFD(); i++)
if(regex_match(self.GetFaceDescriptor(i).GetBCName(), pattern)) {
auto& fd = self.GetFaceDescriptor(i);
if(regex_match(fd.GetBCName(), pattern))
{
auto dom_pattern = get_if<string>(&domain);
// only add if adjacent to domain
if(dom_pattern)
{
regex pattern(*dom_pattern);
if(regex_match(self.GetMaterial(fd.DomainIn()), pattern) || (fd.DomainOut() > 0 ? regex_match(self.GetMaterial(fd.DomainOut()), pattern) : false))
blp.surfid.Append(i); blp.surfid.Append(i);
} }
else
blp.surfid.Append(i);
}
}
}
if(double* pthickness = get_if<double>(&thickness); pthickness) if(double* pthickness = get_if<double>(&thickness); pthickness)
{ {