mirror of
https://github.com/NGSolve/netgen.git
synced 2024-11-15 10:28:34 +05:00
Some fixes in growth vector limitation
This commit is contained in:
parent
99be6bbc0e
commit
0a2479bf00
@ -121,10 +121,10 @@ struct GrowthVectorLimiter
|
|||||||
return mesh[pi_to] + GetVector(pi_to, shift, apply_limit);
|
return mesh[pi_to] + GetVector(pi_to, shift, apply_limit);
|
||||||
}
|
}
|
||||||
|
|
||||||
Point<3> GetMappedPoint (PointIndex pi_from, double shift = 1.)
|
Point<3> GetMappedPoint (PointIndex pi_from, double shift = 1., bool apply_limit = false)
|
||||||
{
|
{
|
||||||
auto pi_to = tool.mapto[pi_from].Last();
|
auto pi_to = tool.mapto[pi_from].Last();
|
||||||
return GetPoint(pi_to, shift);
|
return GetPoint(pi_to, shift, apply_limit);
|
||||||
}
|
}
|
||||||
|
|
||||||
Seg GetMappedSeg (PointIndex pi_from, double shift = 1.)
|
Seg GetMappedSeg (PointIndex pi_from, double shift = 1.)
|
||||||
@ -162,10 +162,39 @@ struct GrowthVectorLimiter
|
|||||||
auto index1 = (index + 1) % 3;
|
auto index1 = (index + 1) % 3;
|
||||||
if (!grow_first_vertex)
|
if (!grow_first_vertex)
|
||||||
index1 = (index + 2) % 3;
|
index1 = (index + 2) % 3;
|
||||||
trig[index] = GetMappedPoint(sel[index1], shift);
|
trig[index] = GetMappedPoint(sel[index1], shift, true);
|
||||||
return trig;
|
return trig;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
array<Trig, 4> GetSideTrigs (SurfaceElementIndex sei, int i0, double shift = 0.0)
|
||||||
|
{
|
||||||
|
auto trig = GetMappedTrig(sei, 0.0);
|
||||||
|
array<Trig, 4> trigs{trig, trig, trig, trig};
|
||||||
|
|
||||||
|
auto sel = Get(sei);
|
||||||
|
auto i1 = (i0 + 1) % 3;
|
||||||
|
auto i2 = (i0 + 2) % 3;
|
||||||
|
auto p1 = GetMappedPoint(sel[i1], shift, true);
|
||||||
|
auto p2 = GetMappedPoint(sel[i2], shift, true);
|
||||||
|
|
||||||
|
// create four trigs to span the quad from i1,i2 and their shifted points
|
||||||
|
// i1, i2, shifted i1
|
||||||
|
trigs[0][i0] = p1;
|
||||||
|
|
||||||
|
// i1, i2, shifted i2
|
||||||
|
trigs[1][i0] = p2;
|
||||||
|
|
||||||
|
// i1, shifted i1, shifted i2
|
||||||
|
trigs[2][i0] = p1;
|
||||||
|
trigs[2][i2] = p2;
|
||||||
|
|
||||||
|
// i2, shifted i1, shifted i2
|
||||||
|
trigs[2][i0] = p2;
|
||||||
|
trigs[2][i1] = p1;
|
||||||
|
|
||||||
|
return trigs;
|
||||||
|
}
|
||||||
|
|
||||||
static constexpr double INTERSECTION_SAFETY = .9;
|
static constexpr double INTERSECTION_SAFETY = .9;
|
||||||
bool LimitGrowthVector (PointIndex pi_to, SurfaceElementIndex sei, double trig_shift, double seg_shift, bool check_prism_sides = false)
|
bool LimitGrowthVector (PointIndex pi_to, SurfaceElementIndex sei, double trig_shift, double seg_shift, bool check_prism_sides = false)
|
||||||
{
|
{
|
||||||
@ -173,8 +202,6 @@ struct GrowthVectorLimiter
|
|||||||
if (!pi_from.IsValid())
|
if (!pi_from.IsValid())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
auto seg = GetSeg(pi_to, seg_shift, true);
|
|
||||||
|
|
||||||
for (auto pi : Get(sei).PNums())
|
for (auto pi : Get(sei).PNums())
|
||||||
{
|
{
|
||||||
if (pi == pi_from)
|
if (pi == pi_from)
|
||||||
@ -190,15 +217,37 @@ struct GrowthVectorLimiter
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
auto getTrigs = [&] (double scaling = 1.0) -> ArrayMem<Trig, 3> {
|
auto getTrigs = [&] (double scaling = 1.0) -> ArrayMem<Trig, 3> {
|
||||||
ArrayMem<Trig, 3> trigs;
|
ArrayMem<Trig, 12> trigs;
|
||||||
if (check_prism_sides)
|
if (check_prism_sides)
|
||||||
for (auto i : Range(3))
|
for (auto i : Range(3))
|
||||||
trigs.Append(GetSideTrig(sei, i, scaling * trig_shift, true));
|
for (auto trig : GetSideTrigs(sei, i, scaling * trig_shift))
|
||||||
|
trigs.Append(trig);
|
||||||
else
|
else
|
||||||
trigs.Append(GetTrig(sei, scaling * trig_shift, true));
|
trigs.Append(GetTrig(sei, scaling * trig_shift, true));
|
||||||
return trigs;
|
return trigs;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (!check_prism_sides)
|
||||||
|
{
|
||||||
|
// If the growth vectors of all points are pointing in the same direction,
|
||||||
|
// an intersection means, we also have an intersection with a prism side face
|
||||||
|
// this is an extra check and handled later
|
||||||
|
auto seg = GetSeg(pi_to, 1.0, false);
|
||||||
|
auto gw = seg[1] - seg[0];
|
||||||
|
/*auto gw = GetVector(pi_to, 1.0, false);*/
|
||||||
|
|
||||||
|
bool have_same_growth_direction = true;
|
||||||
|
for (auto pi : Get(sei).PNums())
|
||||||
|
{
|
||||||
|
/*auto p_gw = GetVector(pi, 1.0, false);*/
|
||||||
|
auto p_seg = GetSeg(pi, 1.0, false);
|
||||||
|
auto p_gw = p_seg[1] - p_seg[0];
|
||||||
|
have_same_growth_direction &= (gw * p_gw) > 0;
|
||||||
|
}
|
||||||
|
if (have_same_growth_direction)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
double scaling = 1.0;
|
double scaling = 1.0;
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
@ -221,18 +270,13 @@ struct GrowthVectorLimiter
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
auto seg = GetSeg(pi_to, seg_shift, false);
|
||||||
auto trig = GetTrig(sei, 0.0);
|
auto trig = GetTrig(sei, 0.0);
|
||||||
auto intersection = isIntersectingTrig(seg, trig);
|
auto intersection = isIntersectingTrig(seg, trig);
|
||||||
// checking with original surface elements -> allow only half the distance
|
// checking with original surface elements -> allow only half the distance
|
||||||
auto new_seg_limit = 0.40 * intersection.lam0 * seg_shift;
|
auto new_seg_limit = 0.40 * intersection.lam0 * seg_shift;
|
||||||
if (intersection && new_seg_limit < GetLimit(pi_from))
|
if (intersection && new_seg_limit < GetLimit(pi_from))
|
||||||
{
|
|
||||||
auto p0 = seg[0];
|
|
||||||
auto p1 = seg[1];
|
|
||||||
auto d = Dist(p0, p1);
|
|
||||||
auto [gw, height] = tool.growth_vector_map[pi_to];
|
|
||||||
return SetLimit(pi_from, new_seg_limit);
|
return SetLimit(pi_from, new_seg_limit);
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -258,25 +302,16 @@ struct GrowthVectorLimiter
|
|||||||
if (limit > 0.0)
|
if (limit > 0.0)
|
||||||
limits.Append(GetLimit(pi1));
|
limits.Append(GetLimit(pi1));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (limits.Size() == 0)
|
if (limits.Size() == 0)
|
||||||
continue;
|
continue;
|
||||||
QuickSort(limits);
|
|
||||||
|
|
||||||
double mean_limit = limits[limits.Size() / 2];
|
double average = 0.0;
|
||||||
// if mean limit is the maximum limit, take the average of second-highest
|
for (auto l : limits)
|
||||||
// and highest value
|
average += l;
|
||||||
if (mean_limit > limits[0] && mean_limit == limits.Last())
|
average /= limits.Size();
|
||||||
{
|
|
||||||
auto i = limits.Size() - 1;
|
|
||||||
while (limits[i] == limits.Last())
|
|
||||||
i--;
|
|
||||||
mean_limit = 0.5 * (limits[i] + limits.Last());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (limits.Size() % 2 == 0)
|
SetLimit(pi, factor * average + (1.0 - factor) * GetLimit(pi));
|
||||||
mean_limit = 0.5 * (mean_limit + limits[(limits.Size() - 1) / 2]);
|
|
||||||
|
|
||||||
SetLimit(pi, factor * mean_limit + (1.0 - factor) * GetLimit(pi));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -658,7 +693,7 @@ struct GrowthVectorLimiter
|
|||||||
|
|
||||||
for (auto i_pass : Range(safeties.size()))
|
for (auto i_pass : Range(safeties.size()))
|
||||||
{
|
{
|
||||||
PrintMessage(4, "GrowthVectorLimiter pass ", i_pass);
|
PrintMessage(0, "GrowthVectorLimiter pass ", i_pass);
|
||||||
double safety = safeties[i_pass];
|
double safety = safeties[i_pass];
|
||||||
CheckLimits();
|
CheckLimits();
|
||||||
// intersect segment with original surface elements
|
// intersect segment with original surface elements
|
||||||
@ -671,7 +706,7 @@ struct GrowthVectorLimiter
|
|||||||
LimitBoundaryLayer(safety);
|
LimitBoundaryLayer(safety);
|
||||||
CheckLimits();
|
CheckLimits();
|
||||||
|
|
||||||
for (auto i : Range(3))
|
for (auto i : Range(10))
|
||||||
EqualizeLimits(smoothing_factors[i_pass]);
|
EqualizeLimits(smoothing_factors[i_pass]);
|
||||||
CheckLimits();
|
CheckLimits();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user