Mechanics of Defect Evolution Library
Loading...
Searching...
No Matches
SplineSegment.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
9#ifndef model_SplineSegment_H_
10#define model_SplineSegment_H_
11
12#include <math.h>
13#include <Eigen/Dense>
14
15
16
17
18//#include <NetworkLink.h>
19#include <NetworkLink.h>
20#include <ParametricCurve.h>
21//#include <SplineIntersection.h>
22#include <Coeff2Hermite.h>
23#include <SplineSegmentBase.h>
24//#include <EdgeFinder.h>
25//#include <Eigen/Sparse>
26#include <MatrixCompanion.h>
27
28namespace model
29{
30
65
66
67
68
69 /************************************************************************/
70 /* SplineSegment, general case **************************************/
71 /************************************************************************/
72 template <short unsigned int _dim,short unsigned int corder>
73 class SplineSegment : public ParametricCurve<SplineSegment<_dim,corder>,_dim>
74 {
75
76 static_assert(_dim>=1 && _dim <=3,"DIMENSION MUST BE 1, 2 or 3."); // requires c++11
77 static_assert(corder>=0 && corder <=2,"CONTINUITY ORDER MUST BE 0, 1 or 2."); // requires c++11
78
79
80 public:
81 //enum {dim=_dim};
82 static constexpr int dim= _dim;
83 static constexpr int Ncoeff= 2*(corder+1); // number of Hermite coefficients
84 static constexpr int pOrder= 2*corder+1;
85 static constexpr int Ndof = dim*Ncoeff; // number of Hermite dofs
86 static constexpr int eigenSize=pOrder*pOrder;
87
88 typedef Eigen::Matrix<double, 1, Ncoeff> RowNcoeff;
89 typedef Eigen::Matrix<double, 1, Ncoeff-1> RowNcoeffu;
90 typedef Eigen::Matrix<double, 1, Ncoeff-2> RowNcoeffuu;
91 typedef Eigen::Matrix<double, Ncoeff, Ncoeff> MatrixNcoeff;
92 typedef Eigen::Matrix<double, Ncoeff, dim> MatrixNcoeffDim;
93 typedef Eigen::Matrix<double, Ndof,1> VectorNdof;
94 typedef Eigen::Matrix<double,dim,dim> MatrixDim;
95 typedef Eigen::Matrix<double,dim,1> VectorDim;
96 typedef Eigen::Matrix<double, dim, Ndof> MatrixDimNdof;
97 typedef Eigen::Matrix<double,Ncoeff,1> VectorNcoeff;
98 typedef Eigen::Matrix<double,Ndof,Ndof> MatrixNdof;
101
102
103
106
107 private:
108
109 VectorDim _chord;
110 double _chordLength2;
111 double _chordLength;
112 VectorDim _unitDirection;
113
114 public:
115
116
117
118 static double alpha;
119
120
121 /**********************************************************************/
122 SplineSegment(const VectorDim& sourceP_in,
123 const VectorDim& sinkP_in) :
124 /* init */ sourceP(sourceP_in)
125 /* init */,sinkP(sinkP_in)
126 /* init */,_chord(sinkP-sourceP)
127 /* init */,_chordLength2(_chord.squaredNorm())
128 /* init */,_chordLength(sqrt(_chordLength2))
129 /* init */,_unitDirection(_chordLength>FLT_EPSILON? (_chord/_chordLength).eval() : VectorDim::Zero())
130 {
132
133 }
134
135 /**********************************************************************/
137 {
138 _chord=sinkP-sourceP;
139 _chordLength2=_chord.squaredNorm();
140 _chordLength=sqrt(_chordLength2);
141 _unitDirection=_chordLength>FLT_EPSILON? (_chord/_chordLength).eval() : VectorDim::Zero();
142 }
143
144 /**********************************************************************/
146 {
147 return SplineSegmentBaseType::hermiteDofs(*this);
148 }
149
150 /**********************************************************************/
151 std::pair<Eigen::Matrix<double,Ncoeff,Eigen::Dynamic>,Eigen::Matrix<double,Eigen::Dynamic,dim>> hermite2posMatrix() const
152 {
153 return SplineSegmentBaseType::hermite2posMatrix(*this);
154 }
155
156 /**********************************************************************/
157 typename SplineSegmentBaseType::H2PmapType hermite2posMap() const
158 {
159 return SplineSegmentBaseType::hermite2posMap(*this);
160 }
161
162 /**********************************************************************/
163 Eigen::Matrix<double,dim,Ncoeff> hermiteCoefficients() const
164 {
165 return SplineSegmentBaseType::hermiteCoefficients(*this);
166 }
167
168 /**********************************************************************/
169 Eigen::Matrix<double,dim,Ncoeff> polynomialCoeff() const
170 {
175 }
176
177 /**********************************************************************/
179 {
180 return SplineSegmentBaseType::sfCoeffs(parametricChordLength());
181 }
182
183// /**********************************************************************/
184// VectorDim chord() const
185// {/*!\returns the chord vector (source -> sink)
186// */
187// return this->sink->get_P()-this->source->get_P();
188// }
189//
190// /**********************************************************************/
191// double chordLength() const
192// {/*!\returns the length of the chord vector
193// */
194// return chord().norm();
195// }
196
197 /**********************************************************************/
198 const VectorDim& chord() const
199 {
201 return _chord;
202 }
203
204 /**********************************************************************/
205 const double& chordLength() const
206 {
208 return _chordLength;
209 }
210
211 /**********************************************************************/
212 const double& chordLengthSquared() const
213 {
215 return _chordLength2;
216 }
217
218 /**********************************************************************/
220 {
222 return _unitDirection;
223 }
224
225 /**********************************************************************/
227 {
228 return std::pow(chordLength(),alpha);
229 }
230
231 /**********************************************************************/
232 VectorDim get_r(const double & u) const
233 {
242 return sf(u)*hermiteDofs();
243 }
244
245 /**********************************************************************/
246 RowNcoeff sf(const double& u) const
247 {/*\param[in] uin parameter value in [0,1]
248 *\returns The row vector of shape function at uin
249 */
250 return SplineSegmentBaseType::sf(u,parametricChordLength());
251 }
252
253 /**********************************************************************/
254 VectorDim get_ru(const double & uin) const
255 {
256 return SplineSegmentBaseType::sfDiff1(uin,parametricChordLength())*hermiteDofs();
257 }
258
259 /**********************************************************************/
260 VectorDim get_rmu(const double & uin) const
261 {
262 return this->get_ru(uin)/parametricChordLength();
263 }
264
265 /**********************************************************************/
266 VectorDim get_ruu(const double & uin) const
267 {
268 return SplineSegmentBaseType::sfDiff2(uin,parametricChordLength())*hermiteDofs();
269 }
270
271 /**********************************************************************/
272 VectorDim get_rmumu(const double & uin) const
273 {
274 return this->get_ruu(uin)/std::pow(parametricChordLength(),2);
275 }
276
277 /**********************************************************************/
278 std::pair<double,std::pair<double,VectorDim> > closestPoint(const VectorDim& P0) const
279 {
286
287 // solve (P-P0)*dP/du=0
288
289 // The polynomial coefficients of this spine segment
290 Eigen::Matrix<double,dim,Ncoeff> coeffs(this->polynomialCoeff());
291 coeffs.col(0)-=P0;
292
293
294 // The derivative of the polynomial coefficients
295 Eigen::Matrix<double,dim,Ncoeff-1> dcoeffs(Eigen::Matrix<double,dim,Ncoeff-1>::Zero());
296 for (int i=0;i<Ncoeff-1;++i)
297 {
298 dcoeffs.col(i)=(i+1)*coeffs.col(i+1);
299 }
300
301 Eigen::Matrix<double,1,2*Ncoeff-2> pcoeffs(Eigen::Matrix<double,1,2*Ncoeff-2>::Zero()); // degree of product = pOrder+(pOrder-1)=2*pOrder-1. nCoeffs of product = 2*pOrder-1+1= 2*pOrder = 2*Ncoeff-2
302
303 // The polynomial coefficients of (P-P0)*dP/du, in reverse order
304 for (int i=0;i<Ncoeff;++i)
305 {
306 for (int j=0;j<Ncoeff-1;++j)
307 {
308 pcoeffs(2*Ncoeff-3-i-j) += coeffs.col(i).dot(dcoeffs.col(j));
309 }
310 }
311
312 // Compute roots using the eigenvalue method
313 MatrixCompanion<2*Ncoeff-3> mc(pcoeffs);
314
315 // sort roots according to distance to P0
316 std::map<double,std::pair<double,VectorDim>> rootMap;
317
318 // for (int k=0;k<2*Ncoeff-3;++k)
319 for (size_t k=0;k<mc.rootSize;++k)
320 {
321 if (std::fabs(mc.root(k).imag())<FLT_EPSILON && mc.root(k).real()>0.0 && mc.root(k).real()<1.0 )
322 {
323
324 VectorDim P(this->get_r(mc.root(k).real()));
325 rootMap.insert(std::make_pair((P-P0).norm(), std::make_pair(mc.root(k).real(),P) ));
326
327 }
328
329 }
330
331 // check distance to limits of interval
332 rootMap.insert(std::make_pair((sourceP-P0).norm(), std::make_pair(0.0,sourceP)));
333 rootMap.insert(std::make_pair((sinkP-P0).norm(), std::make_pair(1.0,sinkP)));
334
335 return *rootMap.begin();
336
337 }
338
339 };
340
341
342 //static data
343 template <short unsigned int dim,short unsigned int corder>
345
346}
347#endif
348
Class template that performs the transformation between the polynomial coefficient matrix and the He...
Class template that computes tangent, curvature and torsion of a parametric curve in arbitrary dimen...
std::pair< Eigen::Matrix< double, Ncoeff, Eigen::Dynamic >, Eigen::Matrix< double, Eigen::Dynamic, dim > > hermite2posMatrix() const
MatrixNcoeff sfCoeffs() const
Eigen::Matrix< double, 1, Ncoeff-2 > RowNcoeffuu
Eigen::Matrix< double, 1, Ncoeff > RowNcoeff
Eigen::Matrix< double, dim, dim > MatrixDim
std::pair< double, std::pair< double, VectorDim > > closestPoint(const VectorDim &P0) const
Eigen::Matrix< double, dim, Ncoeff > hermiteCoefficients() const
Eigen::Matrix< double, Ndof, Ndof > MatrixNdof
SplineSegmentBaseType::H2PmapType hermite2posMap() const
const VectorDim & unitDirection() const
Eigen::Matrix< double, Ncoeff, dim > MatrixNcoeffDim
ParametricCurve< SplineSegment< _dim, corder >, dim > ParametricCurveType
VectorDim get_ruu(const double &uin) const
SplineSegmentBase< dim, corder > SplineSegmentBaseType
const double & chordLengthSquared() const
Eigen::Matrix< double, dim, Ndof > MatrixDimNdof
Eigen::Matrix< double, dim, Ncoeff > polynomialCoeff() const
VectorDim get_rmu(const double &uin) const
Eigen::Matrix< double, 1, Ncoeff-1 > RowNcoeffu
static constexpr int eigenSize
MatrixNcoeffDim hermiteDofs() const
static constexpr int pOrder
double parametricChordLength() const
const VectorDim & chord() const
VectorDim get_ru(const double &uin) const
Eigen::Matrix< double, Ncoeff, 1 > VectorNcoeff
const double & chordLength() const
Eigen::Matrix< double, Ncoeff, Ncoeff > MatrixNcoeff
Eigen::Matrix< double, dim, 1 > VectorDim
static constexpr int Ndof
VectorDim get_rmumu(const double &uin) const
RowNcoeff sf(const double &u) const
Eigen::Matrix< double, Ndof, 1 > VectorNdof
VectorDim get_r(const double &u) const
SplineSegment(const VectorDim &sourceP_in, const VectorDim &sinkP_in)
static constexpr int Ncoeff
auto eval(const std::shared_ptr< T > &t)
int j
REAL u[4]
int k
int i