Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
gmsh
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Model registry
Operate
Environments
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Larry Price
gmsh
Commits
4a79340a
Commit
4a79340a
authored
9 years ago
by
Amaury Johnen
Browse files
Options
Downloads
Patches
Plain Diff
Some improvement in computation of the anisotropy measure
parent
89673b3f
No related branches found
No related tags found
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
Mesh/qualityMeasuresJacobian.cpp
+57
-37
57 additions, 37 deletions
Mesh/qualityMeasuresJacobian.cpp
Mesh/qualityMeasuresJacobian.h
+2
-2
2 additions, 2 deletions
Mesh/qualityMeasuresJacobian.h
with
59 additions
and
39 deletions
Mesh/qualityMeasuresJacobian.cpp
+
57
−
37
View file @
4a79340a
...
...
@@ -37,6 +37,8 @@ void minMaxJacobianDeterminant(MElement *el, double &min, double &max)
const
JacobianBasis
*
jfs
=
el
->
getJacobianFuncSpace
();
if
(
!
jfs
)
{
Msg
::
Error
(
"Jacobian function space not implemented for type of element %d"
,
el
->
getTypeForMSH
());
min
=
99
;
max
=
-
99
;
return
;
}
...
...
@@ -116,7 +118,7 @@ double minScaledJacobian(MElement *el)
double
minAnisotropyMeasure
(
MElement
*
el
,
int
n
)
{
if
(
_CoeffDataAnisotropy
::
noMoreComputationPlease
())
return
-
9
;
if
(
_CoeffDataAnisotropy
::
noMoreComputationPlease
())
return
-
9
;
//fordebug
// double minSampled = minSampledAnisotropyMeasure(el, n); //fordebug
...
...
@@ -129,9 +131,14 @@ double minAnisotropyMeasure(MElement *el, int n)
const
GradientBasis
*
gradBasis
;
const
JacobianBasis
*
jacBasis
=
NULL
;
const
int
metricOrder
=
_CoeffDataAnisotropy
::
metricOrder
(
el
);
if
(
metricOrder
==
-
1
)
{
Msg
::
Error
(
"Anisotropy measure not implemented for type of element %d"
,
el
->
getType
());
return
-
1
;
}
// Metric Coefficients
fullMatrix
<
double
>
coeffMetricBez
;
const
int
metricOrder
=
_CoeffDataAnisotropy
::
metricOrder
(
el
);
{
FuncSpaceData
*
metricSpace
=
NULL
;
if
(
type
!=
TYPE_PYR
)
...
...
@@ -187,9 +194,9 @@ double minAnisotropyMeasure(MElement *el, int n)
);
_subdivideDomains
(
domains
);
//
if (domains.size()/7+1 >
2
0) {//fordebug
//
Msg::Info("
%d: %d", el->getNum()
, domains.size()/7+1);
//
}
if
(
domains
.
size
()
/
7
+
1
>
1
0
)
{
//fordebug
Msg
::
Info
(
"
too much subdivision: %d (el %d)"
,
domains
.
size
()
/
7
+
1
,
el
->
getNum
()
);
}
double
min
=
domains
[
0
]
->
minB
();
delete
domains
[
0
];
...
...
@@ -465,7 +472,6 @@ double _CoeffDataAnisotropy::_computeLowerBound() const
double
slope
=
-
p_dRda
/
p_dRdK
;
double
gamma
=
.5
*
(
3
*
minK
/
mina
-
slope
);
double
beta
;
_computeBoundingCurve
(
beta
,
gamma
,
true
);
/*{//fordebug
double beta = (minK/mina-c)/mina/mina;
...
...
@@ -475,15 +481,18 @@ double _CoeffDataAnisotropy::_computeLowerBound() const
}*/
double
a_int
=
mina
,
K_int
=
minK
;
if
(
_intersectionCurveLeftCorner
(
beta
,
gamma
,
a_int
,
K_int
))
{
int
where
=
_intersectionCurveLeftCorner
(
beta
,
gamma
,
a_int
,
K_int
);
if
(
where
==
1
)
{
// the minimum is on the curve, long to compute, we return this for now:
return
std
::
sqrt
(
_R3Dsafe
(
mina
,
minK
));
}
//Msg::Info("int (%g, %g) (beta %g, gamma %g)", a_int, K_int, beta, gamma);//fordebug
// Let a0 be the point at which R(a, minK) takes its minimum. If a_int < a0,
// the minimum is at (a_int, minK), otherwise it is at (a0, minK).
// Let a0 be the point at which R(a, minK) takes its minimum. If there is
// an intersection and if a_int < a0, the minimum is at (a_int, minK),
// otherwise it is at (a0, minK).
bool
minIsAta0
;
if
(
_moveInsideDomain
(
a_int
,
K_int
,
false
))
{
if
(
where
==
-
1
||
_moveInsideDomain
(
a_int
,
K_int
,
false
))
{
minIsAta0
=
true
;
}
else
{
...
...
@@ -516,23 +525,20 @@ double _CoeffDataAnisotropy::_computeLowerBound() const
_computeBoundingCurve
(
beta
,
gamma
,
false
);
double
a_int
=
mina
,
K_int
=
minK
;
if
(
_intersectionCurveLeftCorner
(
beta
,
gamma
,
a_int
,
K_int
))
{
// Let K0 be the point at which R(mina, K) takes its minimum.
// If K_int < K0, the minimum is at (mina, K_int),
// otherwise it is at (mina, K0).
double
K0
=
2
*
std
::
cos
(
3
*
std
::
acos
(
-
1
/
mina
)
-
M_PI
)
+
(
mina
*
mina
-
3
)
*
mina
;
return
std
::
sqrt
(
_R3Dsafe
(
mina
,
std
::
min
(
K0
,
K_int
)));
}
else
{
int
where
=
_intersectionCurveLeftCorner
(
beta
,
gamma
,
a_int
,
K_int
);
if
(
where
==
0
)
{
// the minimum is on the curve, long to compute, we return this for now:
return
std
::
sqrt
(
_R3Dsafe
(
mina
,
minK
));
/*if (_moveInsideDomain(a_int, K_int, false))
return std::sqrt(_R3Dsafe(a_int, K_int));
else
// the minimum is on the curve, long to compute, we return this for now:
return std::sqrt(_R3Dsafe(mina, minK));
//return std::sqrt(_computeMinRAlongCurve(beta, c, a_int, -1));*/
}
// Let K0 be the point at which R(mina, K) takes its minimum. If there is
// an intersection and if K_int < K0, the minimum is at (mina, K_int),
// otherwise it is at (mina, K0).
double
K0
=
2
*
std
::
cos
(
3
*
std
::
acos
(
-
1
/
mina
)
-
M_PI
)
+
(
mina
*
mina
-
3
)
*
mina
;
if
(
where
==
-
1
)
return
std
::
sqrt
(
_R3Dsafe
(
mina
,
K0
));
else
return
std
::
sqrt
(
_R3Dsafe
(
mina
,
std
::
min
(
K0
,
K_int
)));
}
else
{
return
std
::
sqrt
(
_R3Dsafe
(
mina
,
minK
));
...
...
@@ -712,6 +718,11 @@ bool _CoeffDataAnisotropy::_moveInsideDomain(double &a,
// NB: When moving 'a', we use N-R to compute the root of
// f(a) = .5 * (K - a^3 + 3*a) - 'w' where 'w' is -1 or 1.
if
(
bottomleftCorner
)
{
K
=
std
::
max
(
K
,
.0
);
a
=
std
::
max
(
a
,
1.
);
}
double
w
=
_w
(
a
,
K
);
if
(
std
::
abs
(
w
)
<=
1
)
return
false
;
...
...
@@ -807,13 +818,15 @@ bool _CoeffDataAnisotropy::_computeDerivatives(double a, double K,
return
true
;
}
bool
_CoeffDataAnisotropy
::
_intersectionCurveLeftCorner
(
double
beta
,
double
gamma
,
double
&
a
,
double
&
K
)
int
_CoeffDataAnisotropy
::
_intersectionCurveLeftCorner
(
double
beta
,
double
gamma
,
double
&
a
,
double
&
K
)
{
// curve K = beta * a^3 + c * a
// on input, a and K are the bottom left corner
// on output, a and K are the intersection
// return true if the intersection is on the vertical
// return 0 if the intersection is on the horizontal
// 1 if the intersection is on the vertical
// -1 if there is no intersection
// if (beta < 0) {
// Msg::Warning("Negative curvature, there are 2 or 0 intersections... Is it "
...
...
@@ -823,7 +836,7 @@ bool _CoeffDataAnisotropy::_intersectionCurveLeftCorner(double beta, double gamm
const
double
minK
=
K
;
K
=
(
beta
*
a
*
a
+
gamma
)
*
a
;
if
(
K
>=
minK
)
return
true
;
if
(
K
>=
minK
)
return
1
;
// Find the root by Newton-Raphson.
// When beta < 0, check if the intersection exists:
...
...
@@ -831,8 +844,9 @@ bool _CoeffDataAnisotropy::_intersectionCurveLeftCorner(double beta, double gamm
if
(
beta
<
0
)
{
double
aMaximum
=
std
::
sqrt
(
-
gamma
/
3
/
beta
);
double
KMaximum
=
(
beta
*
aMaximum
*
aMaximum
+
gamma
)
*
aMaximum
;
if
(
aMaximum
<
a
||
KMaximum
<
K
)
{
Msg
::
Error
(
"Sorry but, there is no intersection"
);
// Msg::Info("max (%g, %g)", aMaximum, KMaximum); //fordebug
if
(
gamma
<
0
||
aMaximum
<
a
||
KMaximum
<
K
)
{
// Msg::Warning("Sorry but there is no intersection");
return
false
;
}
}
...
...
@@ -850,11 +864,15 @@ bool _CoeffDataAnisotropy::_intersectionCurveLeftCorner(double beta, double gamm
a3
=
(
3
-
a
*
a
)
*
a
;
da3
-=
a3
;
}
return
false
;
return
0
;
}
double
_CoeffDataAnisotropy
::
_computeAbscissaMinR
(
double
aStart
,
double
K
)
{
// If K == 0, then R == 0. Note, there are less numerical problems when
// computing R(2, 0) than R(1, 0), so return 2:
if
(
K
==
0
)
return
2
;
double
a
=
aStart
;
double
a3
=
(
3
-
a
*
a
)
*
a
;
double
da3
=
std
::
numeric_limits
<
double
>::
infinity
();
...
...
@@ -971,7 +989,7 @@ double _CoeffDataAnisotropy::_R3Dsafe(double a, double K)
return
std
::
max
(
.0
,
std
::
min
(
1.
,
R
));
}
else
{
Msg
::
Fatal
(
"Wrong argument for 3d Raniso (%g, %g)"
,
a
,
K
);
Msg
::
Error
(
"Wrong argument for 3d Raniso (%g, %g)"
,
a
,
K
);
_CoeffDataAnisotropy
::
youReceivedAnError
();
return
-
1
;
}
...
...
@@ -986,14 +1004,14 @@ double _CoeffDataAnisotropy::_wSafe(double a, double K) {
}
const
double
w
=
_w
(
a
,
K
);
if
(
w
>
1
)
{
if
(
w
<
1
+
1e-5
)
return
1
;
if
(
w
<
1
+
1e-5
||
w
<
1
+
K
*
1e-14
)
return
1
;
else
{
Msg
::
Error
(
"outside the domain w(%g, %g) = %g"
,
a
,
K
,
w
);
hasError
=
true
;
}
}
else
if
(
w
<
-
1
)
{
if
(
w
>
-
1
-
1e-5
)
return
-
1
;
if
(
w
>
-
1
-
1e-5
||
w
>
-
1
-
K
*
1e-14
)
return
-
1
;
else
{
Msg
::
Error
(
"outside the domain w(%g, %g) = %g"
,
a
,
K
,
w
);
hasError
=
true
;
...
...
@@ -1025,8 +1043,8 @@ int _CoeffDataAnisotropy::metricOrder(MElement *el)
case
TYPE_HEX
:
return
2
*
order
;
default
:
Msg
::
Error
(
"Unknown element type %d, returning
order 0
"
,
el
->
getType
());
return
0
;
Msg
::
Error
(
"Unknown element type %d, returning
-1
"
,
el
->
getType
());
return
-
1
;
}
}
...
...
@@ -1165,7 +1183,8 @@ void _subdivideDomainsMinOrMax(std::vector<_CoeffData*> &domains,
{
std
::
vector
<
_CoeffData
*>
subs
;
make_heap
(
domains
.
begin
(),
domains
.
end
(),
Comp
());
while
(
!
domains
[
0
]
->
boundsOk
(
minL
,
maxL
))
{
int
k
=
0
;
while
(
!
domains
[
0
]
->
boundsOk
(
minL
,
maxL
)
&&
++
k
<
100
)
{
_CoeffData
*
cd
=
domains
[
0
];
pop_heap
(
domains
.
begin
(),
domains
.
end
(),
Comp
());
domains
.
pop_back
();
...
...
@@ -1179,6 +1198,7 @@ void _subdivideDomainsMinOrMax(std::vector<_CoeffData*> &domains,
push_heap
(
domains
.
begin
(),
domains
.
end
(),
Comp
());
}
}
if
(
k
==
100
)
Msg
::
Warning
(
"Max subdivision (100)"
);
}
void
_subdivideDomains
(
std
::
vector
<
_CoeffData
*>
&
domains
)
...
...
This diff is collapsed.
Click to expand it.
Mesh/qualityMeasuresJacobian.h
+
2
−
2
View file @
4a79340a
...
...
@@ -133,8 +133,8 @@ private:
static
bool
_computeDerivatives
(
double
a
,
double
K
,
double
&
dRda
,
double
&
dRdK
,
double
&
dRdaa
,
double
&
dRdaK
,
double
&
dRdKK
);
static
bool
_intersectionCurveLeftCorner
(
double
beta
,
double
gamma
,
double
&
mina
,
double
&
minK
);
static
int
_intersectionCurveLeftCorner
(
double
beta
,
double
gamma
,
double
&
mina
,
double
&
minK
);
static
double
_computeAbscissaMinR
(
double
aStart
,
double
K
);
static
double
_R2Dsafe
(
double
q
,
double
p
);
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment