Allow curving of mesh if boundarylayer is flat.

If surfnr is larger than nr of surfaces then do linear interpolation
for PointInBetween and so on.
Some fixes in boundarylayer so that surface numbers are correct.
This commit is contained in:
Christopher Lackner 2020-06-24 06:41:06 +00:00 committed by Joachim Schöberl
parent c3441344fb
commit 177ecc7459
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,55 +272,53 @@ 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
segsel.Clear(sei);
// Find matching segment pair on other surface
for(SegmentIndex sej = 0; sej < nseg; sej++)
{ {
PointIndex segpair_p1 = mesh[sej][1]; // clear the bit to indicate that this segment has been processed
PointIndex segpair_p2 = mesh[sej][0]; segsel.Clear(sei);
// Find the segment pair on the neighbouring surface element // Find matching segment pair on other surface
// Identified by: seg1[0] = seg_pair[1] and seg1[1] = seg_pair[0] for(SegmentIndex sej = 0; sej < nseg; sej++)
if(segsel.Test(sej) && ((segpair_p1 == seg_p1) && (segpair_p2 == seg_p2)))
{ {
// clear bit to indicate that processing of this segment is done auto& segj = mesh[sej];
segsel.Clear(sej); // Find the segment pair on the neighbouring surface element
// Identified by: seg1[0] = seg_pair[1] and seg1[1] = seg_pair[0]
if(segsel.Test(sej) && ((segi[0] == segj[1]) && (segi[1] == segj[0])))
{
// clear bit to indicate that processing of this segment is done
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,46 +366,37 @@ 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]];
mesh[sei][1] = mapto[segi[1]];
mesh[sej][0] = mapto[segj[0]];
mesh[sej][1] = mapto[segj[1]];
} }
// remap the segments to the new points
mesh[sei][0] = mapto[mesh[sei][0]];
mesh[sei][1] = mapto[mesh[sei][1]];
mesh[sej][1] = mapto[mesh[sej][1]];
mesh[sej][0] = mapto[mesh[sej][0]];
} }
}
} }
else else
{ {
@ -457,9 +447,9 @@ namespace netgen
{ {
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];
if(blp.surfid.Contains(sel.GetIndex()))
{ {
const auto& sel = mesh[si];
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()]))
if(to_move) continue;
{
for(auto& pnum : sel.PNums())
// Check (Doublecheck) if the corresponding point has a
// copy available for remapping
if(mapto[pnum].IsValid())
// Map the surface elements to the new points
pnum = mapto[pnum];
} }
for(auto& pnum : sel.PNums())
if(mapto[pnum].IsValid())
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,8 +949,22 @@ 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)) {
blp.surfid.Append(i); 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);
}
else
blp.surfid.Append(i);
}
}
} }
if(double* pthickness = get_if<double>(&thickness); pthickness) if(double* pthickness = get_if<double>(&thickness); pthickness)