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
77b6b3cf
Commit
77b6b3cf
authored
12 years ago
by
Thomas Toulorge
Browse files
Options
Downloads
Patches
Plain Diff
Fixed 2D curvature calculation for "Eigendirections" mesh metric (3D still to be implemented)
parent
cad14976
No related branches found
No related tags found
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
Mesh/meshMetric.cpp
+32
-49
32 additions, 49 deletions
Mesh/meshMetric.cpp
with
32 additions
and
49 deletions
Mesh/meshMetric.cpp
+
32
−
49
View file @
77b6b3cf
...
...
@@ -482,62 +482,45 @@ void meshMetric::computeMetricEigenDir()
hessian
(
1
,
0
)
=
gradudy
(
0
);
hessian
(
1
,
1
)
=
gradudy
(
1
);
hessian
(
1
,
2
)
=
gradudy
(
2
);
hessian
(
2
,
0
)
=
gradudz
(
0
);
hessian
(
2
,
1
)
=
gradudz
(
1
);
hessian
(
2
,
2
)
=
gradudz
(
2
);
double
metric_value_hmax
=
1.
/
hmax
/
hmax
;
SVector3
g
r
=
grads
[
ver
];
double
norm
=
g
r
.
norm
alize
();
const
double
metric_value_hmax
=
1.
/
(
hmax
*
hmax
)
;
const
SVector3
g
Vec
=
grads
[
ver
];
// Gradient vector
const
double
norm
=
g
Vec
.
norm
();
SMetric3
metric
;
if
(
signed_dist
<
_E
&&
signed_dist
>
_E_moins
&&
norm
!=
0.0
){
// first, compute the eigenvectors of the hessian, for a curvature-based metric
fullMatrix
<
double
>
eigvec_hessian
(
3
,
3
);
fullVector
<
double
>
lambda_hessian
(
3
);
hessian
.
eig
(
eigvec_hessian
,
lambda_hessian
);
std
::
vector
<
SVector3
>
ti
;
ti
.
push_back
(
SVector3
(
eigvec_hessian
(
0
,
0
),
eigvec_hessian
(
1
,
0
),
eigvec_hessian
(
2
,
0
)));
ti
.
push_back
(
SVector3
(
eigvec_hessian
(
0
,
1
),
eigvec_hessian
(
1
,
1
),
eigvec_hessian
(
2
,
1
)));
ti
.
push_back
(
SVector3
(
eigvec_hessian
(
0
,
2
),
eigvec_hessian
(
1
,
2
),
eigvec_hessian
(
2
,
2
)));
// compute the required characteristic length relative to the curvature and the distance to iso
double
maxkappa
=
std
::
max
(
std
::
max
(
fabs
(
lambda_hessian
(
0
)),
fabs
(
lambda_hessian
(
1
))),
fabs
(
lambda_hessian
(
2
)));
// epsilon is set such that the characteristic element size in the tangent direction is h = 2pi R_min/_Np = sqrt(1/metric_maxmax) = sqrt(epsilon/kappa_max)
double
un_sur_epsilon
=
maxkappa
/
((
2.
*
3.14
/
_Np
)
*
(
2.
*
3.14
/
_Np
));
// metric curvature-based eigenvalues
std
::
vector
<
double
>
eigenvals_curvature
;
eigenvals_curvature
.
push_back
(
fabs
(
lambda_hessian
(
0
))
*
un_sur_epsilon
);
eigenvals_curvature
.
push_back
(
fabs
(
lambda_hessian
(
1
))
*
un_sur_epsilon
);
eigenvals_curvature
.
push_back
(
fabs
(
lambda_hessian
(
2
))
*
un_sur_epsilon
);
// metric distance-based eigenvalue, in gradient direction
double
metric_value_hmin
=
1.
/
hmin
/
hmin
;
double
eigenval_direction
;
const
double
metric_value_hmin
=
1.
/
(
hmin
*
hmin
);
const
SVector3
nVec
=
(
1.
/
norm
)
*
gVec
;
// Unit normal vector
double
lambda_n
;
// Eigenvalues of metric for normal & tangential directions
if
(
_technique
==
meshMetric
::
EIGENDIRECTIONS_LINEARINTERP_H
){
double
h_dist
=
hmin
+
((
hmax
-
hmin
)
/
_E
)
*
dist
;
// the c
harcteristic element size in the normal direction - linear interp between hmin and hmax
eigenval_directio
n
=
1.
/
h_dist
/
h_dist
;
const
double
h_dist
=
hmin
+
((
hmax
-
hmin
)
/
_E
)
*
dist
;
// C
har
a
cteristic element size in the normal direction - linear interp between hmin and hmax
lambda_
n
=
1.
/
(
h_dist
*
h_dist
)
;
}
else
if
(
_technique
==
meshMetric
::
EIGENDIRECTIONS
){
// ... or linear interpolation between 1/h_min^2 and 1/h_max^2
double
maximum_distance
=
(
signed_dist
>
0.
)
?
_E
:
fabs
(
_E_moins
);
eigenval_direction
=
metric_value_hmin
+
((
metric_value_hmax
-
metric_value_hmin
)
/
maximum_distance
)
*
dist
;
const
double
maximum_distance
=
(
signed_dist
>
0.
)
?
_E
:
fabs
(
_E_moins
);
// ... or linear interpolation between 1/h_min^2 and 1/h_max^2
lambda_n
=
metric_value_hmin
+
((
metric_value_hmax
-
metric_value_hmin
)
/
maximum_distance
)
*
dist
;
}
// now, consider only three eigenvectors (i.e. (grad(LS), u1, u2) with u1 and u2 orthogonal vectors in the tangent plane to the LS)
// and imposing directly eigenvalues and directions, instead of intersecting the two metrics based on direction and curvature
// need to find out which one of ti's is the closest to gr, to known which eigenvalue to discard...
std
::
vector
<
double
>
grad_dot_ti
;
for
(
int
i
=
0
;
i
<
3
;
i
++
)
grad_dot_ti
.
push_back
(
fabs
(
dot
(
gr
,
ti
[
i
])));
std
::
vector
<
double
>::
iterator
itbegin
=
grad_dot_ti
.
begin
();
std
::
vector
<
double
>::
iterator
itmax
=
std
::
max_element
(
itbegin
,
grad_dot_ti
.
end
());
int
grad_index
=
std
::
distance
(
itbegin
,
itmax
);
std
::
vector
<
int
>
ti_index
;
for
(
int
i
=
0
;
i
<
3
;
i
++
)
if
(
i
!=
grad_index
)
ti_index
.
push_back
(
i
);
// finally, creating the metric
std
::
vector
<
double
>
eigenvals
;
eigenvals
.
push_back
(
std
::
min
(
std
::
max
(
eigenval_direction
,
metric_value_hmax
),
metric_value_hmin
));
// in gradient direction
eigenvals
.
push_back
(
std
::
min
(
std
::
max
(
eigenvals_curvature
[
ti_index
[
0
]],
metric_value_hmax
),
metric_value_hmin
));
eigenvals
.
push_back
(
std
::
min
(
std
::
max
(
eigenvals_curvature
[
ti_index
[
1
]],
metric_value_hmax
),
metric_value_hmin
));
metric
=
SMetric3
(
eigenvals
[
0
],
eigenvals
[
1
],
eigenvals
[
2
],
gr
,
ti
[
ti_index
[
0
]],
ti
[
ti_index
[
1
]]);
setOfSizes
[
metricNumber
].
insert
(
std
::
make_pair
(
ver
,
std
::
min
(
std
::
min
(
1
/
sqrt
(
eigenvals
[
0
]),
1
/
sqrt
(
eigenvals
[
1
])),
1
/
sqrt
(
eigenvals
[
2
]))));
SVector3
tVec0
,
tVec1
=
SPoint3
(
0.
,
0.
,
1.
);
// Unit tangential vectors
double
kappa0
,
kappa1
=
0.
;
// Curvatures
if
(
_dim
==
2
)
{
// Curvature formulas: cf. R. Goldman, "Curvature formulas for implicit curves and surfaces", Computer Aided Geometric Design 22 (2005), pp. 632–658
tVec0
=
SPoint3
(
-
nVec
(
1
),
nVec
(
0
),
0.
);
kappa0
=
fabs
(
-
gVec
(
1
)
*
(
-
gVec
(
1
)
*
hessian
(
0
,
0
)
+
gVec
(
0
)
*
hessian
(
0
,
1
))
+
gVec
(
0
)
*
(
-
gVec
(
1
)
*
hessian
(
1
,
0
)
+
gVec
(
0
)
*
hessian
(
1
,
1
)))
/
pow
(
norm
,
3
);
}
else
{
// TODO: Implement 3D curvatures
tVec0
=
SPoint3
(
0.
,
0.
,
0.
);
tVec1
=
SPoint3
(
0.
,
0.
,
0.
);
kappa0
=
0.
;
kappa1
=
0.
;
}
const
double
invh_t0
=
(
_Np
*
kappa0
)
/
6.283185307
,
invh_t1
=
(
_Np
*
kappa1
)
/
6.283185307
;
// Inverse of tangential size 0
const
double
lambda_t0
=
invh_t0
*
invh_t0
,
lambda_t1
=
invh_t1
*
invh_t1
;
const
double
lambdaP_n
=
std
::
min
(
std
::
max
(
lambda_n
,
metric_value_hmax
),
metric_value_hmin
);
// Truncate eigenvalues
const
double
lambdaP_t0
=
std
::
min
(
std
::
max
(
lambda_t0
,
metric_value_hmax
),
metric_value_hmin
);
const
double
lambdaP_t1
=
(
_dim
==
2
)
?
1.
:
std
::
min
(
std
::
max
(
lambda_t1
,
metric_value_hmax
),
metric_value_hmin
);
metric
=
SMetric3
(
lambdaP_n
,
lambdaP_t0
,
lambdaP_t1
,
nVec
,
tVec0
,
tVec1
);
const
double
h_n
=
1.
/
sqrt
(
lambdaP_n
),
h_t0
=
1.
/
sqrt
(
lambdaP_t0
),
h_t1
=
1.
/
sqrt
(
lambdaP_t1
);
setOfSizes
[
metricNumber
].
insert
(
std
::
make_pair
(
ver
,
std
::
min
(
std
::
min
(
h_n
,
h_t0
),
h_t1
)));
}
else
{
// isotropic metric !
SMetric3
mymetric
(
metric_value_hmax
);
...
...
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