Mechanics of Defect Evolution Library
Loading...
Searching...
No Matches
PlanarSplineImplicitization.h
Go to the documentation of this file.
1/* This file is part of MoDELib, the Mechanics Of Defects Evolution Library.
2 *
3 *
4 * MoDELib is distributed without any warranty under the
5 * GNU General Public License (GPL) v2 <http://www.gnu.org/licenses/>.
6 */
7
8#ifndef model_PLANARSPLINEIMPLICITIZATION_H_
9#define model_PLANARSPLINEIMPLICITIZATION_H_
10
11#include <set>
12#include <map>
13#include <utility> // for std::pair
14#include <cfloat> // for FLT_EPSILON
15#include <Eigen/Dense>
16#include <Eigen/Eigenvalues>
17#include <Eigen/Jacobi>
18//#include <GeneralizedEigenSolver.h>
19
20namespace model
21{
22 /**********************************************************************************************************************/
23 /* PlanarSplineImplicitization<polyDegree> class template *************************************************************/
24 /**********************************************************************************************************************/
31 template<short unsigned int polyDegree>
33 {
34
35 enum {polyCoeff=polyDegree+1};
36 typedef Eigen::Matrix<double,polyDegree,polyDegree> MatrixPolyDeg;
37
38 /*********************************************************************/
39 MatrixPolyDeg fill_Mx() const {
40 MatrixPolyDeg temp;
41 temp << coeffs(1,1), coeffs(1,2), coeffs(1,3),
42 /*****/ coeffs(1,2), coeffs(1,3), 0.0,
43 /*****/ coeffs(1,3), 0.0, 0.0;
44 return temp;
45 }
46
47 /*********************************************************************/
48 MatrixPolyDeg fill_My() const {
49 MatrixPolyDeg temp;
50 temp << -coeffs(0,1), -coeffs(0,2), -coeffs(0,3),
51 /*****/ -coeffs(0,2), -coeffs(0,3), 0.0,
52 /*****/ -coeffs(0,3), 0.0, 0.0;
53 return temp;
54 }
55
56 /*********************************************************************/
57 MatrixPolyDeg fill_Mc() const {
58 MatrixPolyDeg temp;
59 temp << coeffs(0,1)*coeffs(1,0)-coeffs(0,0)*coeffs(1,1), coeffs(0,2)*coeffs(1,0)-coeffs(0,0)*coeffs(1,2), coeffs(0,3)*coeffs(1,0)-coeffs(0,0)*coeffs(1,3),
60 /*****/ coeffs(0,2)*coeffs(1,0)-coeffs(0,0)*coeffs(1,2), coeffs(0,3)*coeffs(1,0)-coeffs(0,0)*coeffs(1,3)+coeffs(0,2)*coeffs(1,1)-coeffs(0,1)*coeffs(1,2), coeffs(0,3)*coeffs(1,1)-coeffs(0,1)*coeffs(1,3),
61 /*****/ coeffs(0,3)*coeffs(1,0)-coeffs(0,0)*coeffs(1,3), coeffs(0,3)*coeffs(1,1)-coeffs(0,1)*coeffs(1,3), coeffs(0,3)*coeffs(1,2)-coeffs(0,2)*coeffs(1,3);
62 return temp;
63 }
64
65
66 public:
67
68 const Eigen::Matrix<double,2,polyCoeff> coeffs;
69 const MatrixPolyDeg Mx;
70 const MatrixPolyDeg My;
71 const MatrixPolyDeg Mc;
72
73 static double compTol;
74 static double physTol;
75
76
77 /*********************************************************************/
78 PlanarSplineImplicitization(const Eigen::Matrix<double,2,polyCoeff>& coeffs_in) : coeffs(coeffs_in),
79 /* */ Mx(fill_Mx()),
80 /* */ My(fill_My()),
81 /* */ Mc(fill_Mc())
82 {
191
192
194 assert(polyDegree==3 && "GENERALIZE HERE IN THE WAY WE FILL Mx My M0!!!!");
195
196 }
197
198 // /*********************************************************************/
199 // std::pair<bool,double> isOnSpline(const Eigen::Matrix<double,2,1>& P, const double& tol=FLT_EPSILON) const {
200 //
201 // std::pair<bool,double> temp=std::make_pair(false,-1.0);
202 // MatrixPolyDeg M=Mx*P(0)+My*P(1)+M0;
203 // if (std::fabs(M.determinant())<tol){
204 // temp.first=true;
205 // //Eigen::SelfAdjointEigenSolver<MatrixPolyDeg> eigensolver(M);
206 // //temp.second=...
207 // assert(0 && "FINISH HERE!!!!");
208 // }
209 // return temp;
210 // }
211
212 /*********************************************************************/
213 template<short unsigned int otherPolyDegree>
214 std::set<std::pair<double,double> > intersectWith(const Eigen::Matrix<double,2,otherPolyDegree+1>& otherCoeffs) const
215 {
315
316 // assert((!SplineDegeneracy<dim,polyDegree>::isLine(coeffs,tol)) && "Spline1 is degenerate."); // make sure that spline1 is not a line
317 // assert((!SplineDegeneracy<dim,polyDegree>::isLine(otherCoeffs,tol)) && "Spline2 is degenerate."); // make sure that spline2 is not a line
318
321 enum {eigenSize=polyDegree*otherPolyDegree};
322 typedef Eigen::Matrix< double, eigenSize,eigenSize> EigenSizeMatrixType;
323
324
325 std::set<std::pair<double,double> > intersectionParameters;
326
327
328 const MatrixPolyDeg Mn(otherCoeffs(0,otherPolyDegree)*Mx+otherCoeffs(1,otherPolyDegree)*My);
329 const Eigen::JacobiSVD<MatrixPolyDeg> jsvd(Mn, Eigen::ComputeFullU | Eigen::ComputeFullV);
330 const double condNumber(jsvd.singularValues().maxCoeff()/jsvd.singularValues().minCoeff()); // singular values are positive
331
332
333 // std::cout<<"conditionNumber"<<condNumber<<std::endl;
334
335 if (condNumber<1.0/FLT_EPSILON)
336 {
337 // Assemble the matrix C=inv(B)*A
338 EigenSizeMatrixType C(Eigen::Matrix<double, eigenSize,eigenSize>::Zero());
339 if (otherPolyDegree>1)
340 {
341 C.template block<polyDegree*(otherPolyDegree-1),polyDegree*(otherPolyDegree-1)>(0,polyDegree).setIdentity();
342 }
343 C.template block<polyDegree,polyDegree>(polyDegree*(otherPolyDegree-1),0*polyDegree)= -jsvd.solve(otherCoeffs(0,0)*Mx+otherCoeffs(1,0)*My+Mc);
344 for (int p=1; p<otherPolyDegree;++p)
345 {
346 C.template block<polyDegree,polyDegree>(polyDegree*(otherPolyDegree-1),p*polyDegree)= -jsvd.solve(otherCoeffs(0,p)*Mx+otherCoeffs(1,p)*My);
347 }
348
349 // std::cout<<"C="<<C<<std::endl;
350
351 // Compute the eigenvalues and eigenvectors of C
352 const Eigen::EigenSolver<EigenSizeMatrixType> es(C);
353
354 // std::cout<<std::setprecision(15)<<std::scientific<<es.eigenvalues()<<std::endl;
355 // std::cout<<std::setprecision(15)<<std::scientific<<es.eigenvectors()<<std::endl;
356 // std::cout<<es.eigenvalues()<<std::endl;
357
358#ifdef _MODEL_BENCH_SPLINEINTERSECTION_
359
360 EigenSizeMatrixType A(EigenSizeMatrixType::Identity());
361 A.template block<polyDegree,polyDegree>(0,0)=-(otherCoeffs(0,0)*Mx+otherCoeffs(1,0)*My+Mc);
362
363 EigenSizeMatrixType B(EigenSizeMatrixType::Zero());
364 if (otherPolyDegree>1)
365 {
366 B.template block<polyDegree*(otherPolyDegree-1),polyDegree*(otherPolyDegree-1)>(polyDegree,0).setIdentity();
367 }
368 for (int p=0; p<otherPolyDegree;++p)
369 {
370 B.template block<polyDegree,polyDegree>(0,p*polyDegree)=otherCoeffs(0,p+1)*Mx+otherCoeffs(1,p+1)*My;
371 }
372
373 Eigen::GeneralizedEigenSolver<EigenSizeMatrixType> ges(A,B);
374 // ges.compute(A,B);
375
376 std::cout<<"geav"<<ges.eigenvalues()<<std::endl<<std::endl;
377
378 std::ofstream ABfile;
379 ABfile.open ("AB.txt");
380 //ABfile << "Writing this to a file.\n";
381 ABfile<< std::scientific<<std::setprecision(15)<<A<<std::endl<<B<<std::endl;
382 ABfile.close();
383
384 std::ofstream coeffFile;
385 coeffFile.open ("coeffFile.txt");
386 //ABfile << "Writing this to a file.\n";
387 coeffFile<< std::scientific<<std::setprecision(15)<<coeffs<<std::endl<<otherCoeffs<<std::endl;
388 coeffFile.close();
389
391 // model::GeneralizedEigenSolver<double,eigenSize> GES;
392 // GES.solve(A,B);
393 //
394 // //! 3- Clear and fill intersectionParameters if each real eigenvalue s in [0,1] has eigenvator ratio t=v(1)/v(0) also in [0,1]
395 // for (int i=0; i<eigenSize; ++i) {
396 // if (std::fabs(GES.D(i).imag())<tol) { // consider only eigenvectors with 0 imaginary part
397 // const double t=GES.V(1,i).real()/GES.V(0,i).real();
398 // const double s=GES.D(i).real();
399 // if ((s>=0.0 && s<=1.0) && (t>=0.0 && t<=1.0)) { // t and s must be in [0,1]
400 // Eigen::Matrix<double,2,1> Pt(coeffs.col(0));
401 // for(int k=1;k<polyDegree+1;++k){
402 // Pt+=coeffs.col(k)*std::pow(t,k);
403 // }
404 // Eigen::Matrix<double,2,1> Ps(otherCoeffs.col(0));
405 // for(int k=1;k<otherPolyDegree+1;++k){
406 // Ps+=otherCoeffs.col(k)*std::pow(s,k);
407 // }
408 // if((Pt-Ps).norm()<physTol){
409 // intersectionParameters.insert(std::make_pair(t,s));
410 // }
411 // }
412 // }
413 // }
414
415 for(int i=0;i<eigenSize;++i)
416 {
417 const std::complex<double> s(es.eigenvalues()(i));
418 const std::complex<double> t( es.eigenvectors().col(i)(1)/es.eigenvectors().col(i)(0) ); // the root for the spline defined by "coeffs"
419 std::cout<<t<<", "<<s<<std::endl;
420 }
421#endif
422
423 if (es.info() == Eigen::Success)
424 {
425 // std::cout<<"eigenvalues="<<std::endl<<std::setprecision(15)<<es.eigenvalues()<<std::endl;
426 // std::cout<<"eigenvectors="<<std::endl<<std::setprecision(15)<<es.eigenvectors()<<std::endl;
427
428 // Sort real eigenvalues
429 std::map<double,const int> sMap;
430 for (int i=0; i<eigenSize; ++i)
431 {
432 if (std::fabs(es.eigenvalues()(i).imag())<compTol)
433 { // consider only eigenvectors with 0 imaginary part
434 // const double t( (es.eigenvectors().col(i)(1)/es.eigenvectors().col(i)(0)).real() ); // the root for the spline defined by "coeffs"
435 // const double s( es.eigenvalues()(i).real() ); // the root for the spline defined by "otherCoeffs"
436 // if ((s>=0.0 && s<=1.0) && (t>=0.0 && t<=1.0))
437 // if ((s>=0.0-compTol && s<=1.0+compTol) && (t>=0.0-compTol && t<=1.0+compTol))
438 // { // t and s must be in [0,1]
439 sMap.emplace(es.eigenvalues()(i).real(),i);
440 // const double s( ); // the root for the spline defined by "otherCoeffs"
441
442 // Eigen::Matrix<double,2,1> Pt(coeffs.col(0));
443 // for(int k=1;k<polyDegree+1;++k)
444 // {
445 // Pt+=coeffs.col(k)*std::pow(t,k);
446 // }
447 // Eigen::Matrix<double,2,1> Ps(otherCoeffs.col(0));
448 // for(int k=1;k<otherPolyDegree+1;++k)
449 // {
450 // Ps+=otherCoeffs.col(k)*std::pow(s,k);
451 // }
452 // if((Pt-Ps).norm()<physTol)
453 // { // TO DO: COMPARE THE squaredNorm to avoid computing the root
454 // intersectionParameters.insert(std::make_pair(t,s));
455 // }
456 //intersectionParameters.insert(std::make_pair(t,s));
457 // }
458 }
459 }
460
461 // Remove multiple eigenvalues
462 for(std::map<double,const int>::const_iterator last=sMap.begin();last!=sMap.end();)
463 {
464 std::map<double,const int>::const_iterator first = last;
465 std::map<double,const int>::const_iterator next = last;
466 next++;
467 last = sMap.upper_bound(first->first+FLT_EPSILON); // jump to the first element grater than current + FLT_EPSILON
468 // std::cout<<"first="<<&first<<std::endl;
469 // std::cout<<"next="<<&next<<std::endl;
470 // std::cout<<"last="<<&last<<std::endl;
471 //std::cout<<"end="<<&sMap.end()<<std::endl;
472 if(last!=next) // more than one equal elements exist
473 {
474 sMap.erase(first,last); // remove all ements between first (included) and last (excluded)
475 }
476 }
477
478 // Check that simple eigenvlaues are in range
479 for (auto pair : sMap)
480 {
481 const double& s=pair.first;
482 const int& i=pair.second;
483 const double t( (es.eigenvectors().col(i)(1)/es.eigenvectors().col(i)(0)).real() ); // the root for the spline defined by "coeffs"
484
485 if ((s>=0.0-compTol && s<=1.0+compTol) && (t>=0.0-compTol && t<=1.0+compTol))
486 { // t and s must be in [0,1]
487 Eigen::Matrix<double,2,1> Pt(coeffs.col(0));
488 for(int k=1;k<polyDegree+1;++k)
489 {
490 Pt+=coeffs.col(k)*std::pow(t,k);
491 }
492 Eigen::Matrix<double,2,1> Ps(otherCoeffs.col(0));
493 for(int k=1;k<otherPolyDegree+1;++k)
494 {
495 Ps+=otherCoeffs.col(k)*std::pow(s,k);
496 }
497 if((Pt-Ps).norm()<physTol)
498 { // TO DO: COMPARE THE squaredNorm to avoid computing the root
499 intersectionParameters.insert(std::make_pair(t,s));
500 }
501 }
502 }
503 }
504 }
505 else{
506 // std::cout<<"ILL_CONDITIONED INTERSECTION"<<std::endl;
507 }
508
510 return intersectionParameters;
511 }
512
513 };
514
515
516
517 // Declare static data members;
518 template<short unsigned int polyDegree>
520
521 // Declare static data members;
522 template<short unsigned int polyDegree>
524
525
526
527 /**************************************************************************/
528 /**************************************************************************/
529}// namespace model
530#endif
531
532
533
534
const Eigen::Matrix< double, 2, polyCoeff > coeffs
PlanarSplineImplicitization(const Eigen::Matrix< double, 2, polyCoeff > &coeffs_in)
std::set< std::pair< double, double > > intersectWith(const Eigen::Matrix< double, 2, otherPolyDegree+1 > &otherCoeffs) const
initial point of the source segment B
function infiniteDisplacement syms Ax Ay Az Bx By Bz qx qy qz u L x y z real A
final point of the source segment t
vertex p[3]
int k
int i
vertex temp
vertex first