Skip to content
Snippets Groups Projects
Commit 77b6b3cf authored by Thomas Toulorge's avatar Thomas Toulorge
Browse files

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
...@@ -482,62 +482,45 @@ void meshMetric::computeMetricEigenDir() ...@@ -482,62 +482,45 @@ void meshMetric::computeMetricEigenDir()
hessian(1,0) = gradudy(0); hessian(1,1) = gradudy(1); hessian(1,2) = gradudy(2); 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); hessian(2,0) = gradudz(0); hessian(2,1) = gradudz(1); hessian(2,2) = gradudz(2);
double metric_value_hmax = 1./hmax/hmax; const double metric_value_hmax = 1./(hmax*hmax);
SVector3 gr = grads[ver]; const SVector3 gVec = grads[ver]; // Gradient vector
double norm = gr.normalize(); const double norm = gVec.norm();
SMetric3 metric; SMetric3 metric;
if (signed_dist < _E && signed_dist > _E_moins && norm != 0.0){ if (signed_dist < _E && signed_dist > _E_moins && norm != 0.0){
// first, compute the eigenvectors of the hessian, for a curvature-based metric const double metric_value_hmin = 1./(hmin*hmin);
fullMatrix<double> eigvec_hessian(3,3); const SVector3 nVec = (1./norm)*gVec; // Unit normal vector
fullVector<double> lambda_hessian(3); double lambda_n; // Eigenvalues of metric for normal & tangential directions
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;
if (_technique==meshMetric::EIGENDIRECTIONS_LINEARINTERP_H){ if (_technique==meshMetric::EIGENDIRECTIONS_LINEARINTERP_H){
double h_dist = hmin + ((hmax-hmin)/_E)*dist;// the charcteristic element size in the normal direction - linear interp between hmin and hmax const double h_dist = hmin + ((hmax-hmin)/_E)*dist; // Characteristic element size in the normal direction - linear interp between hmin and hmax
eigenval_direction = 1./h_dist/h_dist; lambda_n = 1./(h_dist*h_dist);
} }
else if(_technique==meshMetric::EIGENDIRECTIONS){ else if(_technique==meshMetric::EIGENDIRECTIONS){
// ... or linear interpolation between 1/h_min^2 and 1/h_max^2 const double maximum_distance = (signed_dist>0.) ? _E : fabs(_E_moins); // ... or linear interpolation between 1/h_min^2 and 1/h_max^2
double maximum_distance = (signed_dist>0.) ? _E : fabs(_E_moins); lambda_n = metric_value_hmin + ((metric_value_hmax-metric_value_hmin)/maximum_distance)*dist;
eigenval_direction = metric_value_hmin + ((metric_value_hmax-metric_value_hmin)/maximum_distance)*dist;
} }
SVector3 tVec0, tVec1 = SPoint3(0.,0.,1.); // Unit tangential vectors
// now, consider only three eigenvectors (i.e. (grad(LS), u1, u2) with u1 and u2 orthogonal vectors in the tangent plane to the LS) double kappa0, kappa1 = 0.; // Curvatures
// and imposing directly eigenvalues and directions, instead of intersecting the two metrics based on direction and curvature if (_dim == 2) { // Curvature formulas: cf. R. Goldman, "Curvature formulas for implicit curves and surfaces", Computer Aided Geometric Design 22 (2005), pp. 632–658
// need to find out which one of ti's is the closest to gr, to known which eigenvalue to discard... tVec0 = SPoint3(-nVec(1),nVec(0),0.);
std::vector<double> grad_dot_ti; kappa0 = fabs(-gVec(1)*(-gVec(1)*hessian(0,0)+gVec(0)*hessian(0,1))+
for (int i=0;i<3;i++) gVec(0)*(-gVec(1)*hessian(1,0)+gVec(0)*hessian(1,1)))/pow(norm,3);
grad_dot_ti.push_back(fabs(dot(gr,ti[i]))); }
std::vector<double>::iterator itbegin = grad_dot_ti.begin(); else {
std::vector<double>::iterator itmax = std::max_element(itbegin,grad_dot_ti.end()); // TODO: Implement 3D curvatures
int grad_index = std::distance(itbegin,itmax); tVec0 = SPoint3(0.,0.,0.);
std::vector<int> ti_index; tVec1 = SPoint3(0.,0.,0.);
for (int i=0;i<3;i++) kappa0 = 0.;
if (i!=grad_index) ti_index.push_back(i); kappa1 = 0.;
// finally, creating the metric }
std::vector<double> eigenvals; const double invh_t0 = (_Np*kappa0)/6.283185307, invh_t1 = (_Np*kappa1)/6.283185307; // Inverse of tangential size 0
eigenvals.push_back(std::min(std::max(eigenval_direction,metric_value_hmax),metric_value_hmin));// in gradient direction const double lambda_t0 = invh_t0*invh_t0, lambda_t1 = invh_t1*invh_t1;
eigenvals.push_back(std::min(std::max(eigenvals_curvature[ti_index[0]],metric_value_hmax),metric_value_hmin)); const double lambdaP_n = std::min(std::max(lambda_n,metric_value_hmax),metric_value_hmin); // Truncate eigenvalues
eigenvals.push_back(std::min(std::max(eigenvals_curvature[ti_index[1]],metric_value_hmax),metric_value_hmin)); const double lambdaP_t0 = std::min(std::max(lambda_t0,metric_value_hmax),metric_value_hmin);
metric = SMetric3(eigenvals[0],eigenvals[1],eigenvals[2],gr,ti[ti_index[0]],ti[ti_index[1]]); const double lambdaP_t1 = (_dim == 2) ? 1. : std::min(std::max(lambda_t1,metric_value_hmax),metric_value_hmin);
setOfSizes[metricNumber].insert(std::make_pair(ver, std::min(std::min(1/sqrt(eigenvals[0]),1/sqrt(eigenvals[1])),1/sqrt(eigenvals[2])))); 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 ! else{// isotropic metric !
SMetric3 mymetric(metric_value_hmax); SMetric3 mymetric(metric_value_hmax);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment