Mechanics of Defect Evolution Library
Loading...
Searching...
No Matches
MeshedDislocationLoop.cpp
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_MeshedDislocationLoop_cpp_
9#define model_MeshedDislocationLoop_cpp_
10
11#include <numbers>
13#include <TriangularMesh.h>
14
15
16namespace model
17{
18
19
20
21//MeshedDislocationLoop::MeshedDislocationLoop(const VectorDim& burgers_in,const DefectiveCrystalBase<3>& ddBase,const Plane<3>& plane,const std::vector<Eigen::Matrix<double,3,1>>& globalBndPts,const double& meshSize):
25//{
26//
27// std::deque<Eigen::Matrix<double,2,1>> localBndPts;
28// std::deque<Eigen::Matrix<double,2,1>> internalPts;
29// for(const auto& gpt : globalBndPts)
30// {
31// localBndPts.push_back(plane.localPosition(gpt));
32// }
33// TriangularMesh triMesh;
34// triMesh.reMesh(localBndPts,internalPts,meshSize);
35// triangles=triMesh.triangles();
36//
37// for(const auto& v : triMesh.vertices())
38// {
39// points.push_back(plane.globalPosition(v));
40// }
41//}
42
43 MeshedDislocationLoop::MeshedDislocationLoop(const VectorDim& burgers_in,const GlidePlane<3>& plane,const std::vector<Eigen::Matrix<double,3,1>>& globalBndPts,const DislocationNetwork<3>& DN,const double& meshSize,const double& localMeshSize):
44 //MeshedDislocationLoop::MeshedDislocationLoop(const VectorDim& burgers_in,const DefectiveCrystalBase<3>& ddBase,const GlidePlane<3>& plane,const std::vector<Eigen::Matrix<double,3,1>>& globalBndPts,const double& meshSize,const double& localMeshSize):
45 /* init */ burgers(burgers_in)
46 /* init */,periodicShifts(DN.ddBase.periodicShifts)
47 {
48 std::vector<Eigen::Matrix<double,2,1>> localBndPts;
49 localBndPts.reserve(globalBndPts.size());
50 for(const auto& gpt : globalBndPts)
51 {
52 const Eigen::Matrix<double,2,1> localPos(plane.localPosition(gpt));
53 const auto pointIter(uniquePointsIDs.find(localPos));
54 if(pointIter==uniquePointsIDs.end())
55 {// localPos does not exist
56 uniquePointsIDs.emplace(localPos,localBndPts.size());
57 localBndPts.emplace_back(localPos);
58 }
59 }
60 const auto originalBndPts(localBndPts);
61
62 std::vector<Eigen::Matrix<int,2,1>> segments;
63 segments.reserve(localBndPts.size());
64 for(size_t k=0;k<localBndPts.size();++k)
65 {
66 const size_t k1(k<localBndPts.size()-1? k+1 : 0); // cycle
67 const auto& pointK(localBndPts[k]);
68 const auto& pointK1(localBndPts[k1]);
69 const auto iterK(uniquePointsIDs.find(pointK));
70 const auto iterK1(uniquePointsIDs.find(pointK1));
71
72 if(iterK!=uniquePointsIDs.end() && iterK1!=uniquePointsIDs.end())
73 {// localPos exists
74 segments.emplace_back((Eigen::Matrix<int,2,1>()<<iterK->second,iterK1->second).finished());
75 }
76 else
77 {
78 throw std::runtime_error("iterK and iterK1 must exist");
79 }
80 }
81
82 if(localMeshSize>0.0)
83 {
84 const double L(std::pow(DN.ddBase.mesh.volume(),1.0/3.0));
85
86 for(const auto& otherWeakLoop : DN.loops())
87 {
88 for(const auto& otherPatchPair : otherWeakLoop.second.lock()->patches().localPatches())
89 {
90 const auto otherGlidePlane(otherPatchPair.first->glidePlane);
91 if(otherGlidePlane.get()!=&plane)
92 {// intersection of current plane with another plane
93 const PlanePlaneIntersection ppi(plane,*otherGlidePlane);
95 {
96 const auto localLineOrigin(plane.localPosition(ppi.P));
97 const auto localLineDir(plane.localDirection(ppi.d));
98
99 std::map<float,Eigen::Matrix<double,2,1>> patchLineIntersections;
100 for(size_t k=0;k<originalBndPts.size();++k)
101 {
102 const size_t k1(k<originalBndPts.size()-1? k+1 : 0); // cycle
103 const auto& pointK(originalBndPts[k]);
104 const auto& pointK1(originalBndPts[k1]);
105 SegmentSegmentDistance<2> ssd(localLineOrigin-2.0*L*localLineDir,localLineOrigin+2.0*L*localLineDir,pointK,pointK1);
106 if(ssd.dMin<FLT_EPSILON)
107 {
108 patchLineIntersections.emplace(ssd.t,0.5*(ssd.x0+ssd.x1));
109 }
110 }
111
112 if(patchLineIntersections.size()>=2)
113 {
114 const Eigen::Matrix<double,2,1>& p0(patchLineIntersections.begin()->second);
115 const Eigen::Matrix<double,2,1>& p1(patchLineIntersections.rbegin()->second);
116 const Eigen::Matrix<double,2,1> chord(p1-p0);
117 const int np=chord.norm()/localMeshSize;
118
119 bool oldPointIncluded=false;
120 size_t oldPointID=0;
121 //for(int n=0;n<np+1;++n)
122 for(int n=1;n<np;++n) // skip intersection with original polygon
123 {
124 const double u(double(n)/np);
125 const Eigen::Matrix<double,2,1> P(p0+u*chord);
126 const Eigen::Matrix<double,2,1> otherP(otherGlidePlane->localPosition(plane.globalPosition(P)));
127 const int wn(Polygon2D::windingNumber(otherP,otherPatchPair.second));
128 const bool newPointIncluded(wn!=0);
129 const auto pliIter(uniquePointsIDs.find(P));
130 const bool newPointFound(pliIter!=uniquePointsIDs.end());
131 const size_t newPointID(newPointFound? pliIter->second : localBndPts.size() );
132
133 if(newPointIncluded)
134 {
135 if(!newPointFound)
136 {// a new point
137 uniquePointsIDs.emplace(P,localBndPts.size());
138 localBndPts.emplace_back(P);
139 }
140 if(oldPointIncluded)
141 {// both new and old points are inlcuded, add segment
142 segments.emplace_back((Eigen::Matrix<int,2,1>()<<oldPointID,newPointID).finished());
143 }
144 }
145 oldPointIncluded=newPointIncluded;
146 oldPointID=newPointID;
147 }
148 }
149 }
150 }
151 }
152 }
153 }
154
155 TriangularMesh triMesh;
156 triMesh.reMesh(localBndPts,segments,meshSize,"pazq");
157 triangles=triMesh.triangles();
158
159 for(const auto& v : triMesh.vertices())
160 {
161 points.push_back(plane.globalPosition(v)); // initialize points
162 displacements.push_back(VectorDim::Zero()); // initialize displacements
163 }
164
165 for(const auto& tri : triMesh.triangles())
166 {
167 const auto& v0(points[tri(0)]);
168 const auto& v1(points[tri(1)]);
169 const auto& v2(points[tri(2)]);
170 const auto c(1.0/3.0*(v0+v1+v2));
171 const auto h(c+(v1-v0).cross(v2-v1));
172
173 MatrixDim vertexMatrix(MatrixDim::Zero());
174 vertexMatrix.col(0)=v0-h;
175 vertexMatrix.col(1)=v1-h;
176 vertexMatrix.col(2)=v2-h;
177
178 heightPoints.push_back(h); // initialize points
179 invVertexMatrix.push_back(vertexMatrix.inverse());
180 heightDisplacements.push_back(VectorDim::Zero()); // initialize displacements
181 }
182
183 defGradients.resize(triangles.size(),MatrixDim::Identity());
184 }
185
187{
188 for(size_t k=0;k<points.size();++k)
189 {
191 }
192
193 for(size_t k=0;k<heightPoints.size();++k)
194 {
196 }
197
198 MatrixDim vertexMatrix(MatrixDim::Zero());
199 for(size_t k=0;k<triangles.size();++k)
200 {
201 const auto& tri(triangles[k]);
202
203 const auto& v0(points[tri(0)]);
204 const auto& v1(points[tri(1)]);
205 const auto& v2(points[tri(2)]);
206 const auto h(heightPoints[k]);
207 vertexMatrix.col(0)=v0-h;
208 vertexMatrix.col(1)=v1-h;
209 vertexMatrix.col(2)=v2-h;
210 defGradients[k]=vertexMatrix*invVertexMatrix[k];
211 }
212}
213
214
216 {
217 VectorDim nA(VectorDim::Zero());
218 const VectorDim& Ps(points[tri(0)]);
219 for(int k0=0;k0<tri.size();++k0)
220 {
221 const size_t k1(k0+1<tri.size()? k0+1 : 0);
222 const VectorDim& P0(points[tri(k0)]);
223 const VectorDim& P1(points[tri(k1)]);
224 nA+= 0.5*(P0-Ps).cross(P1-P0);
225 }
226 return nA;
227 }
228
229 double MeshedDislocationLoop::solidAngle(const VectorDim& x,const size_t& triID) const
230 {
231 const double a2(1.0e-2);
232 const double oneA2=sqrt(1.0+a2);
233 double temp(0.0);
234 //for(const auto& tri : triangles)
235// for(size_t triID=0;triID<triangles.size();++triID)
236// {
237 const auto& tri(triangles[triID]);
238 const auto nA(triangleAreaVector(tri));
239 const double triangleArea(nA.norm());
240 if(triangleArea>FLT_EPSILON)
241 {
242 const VectorDim triangleNormal(nA/triangleArea);
243 const VectorDim& planePoint(points[tri(0)]);
244 const double posNorm((x-planePoint).norm());
245 const double dotProd((x-planePoint).dot(triangleNormal));
246 if(std::fabs(dotProd)>FLT_EPSILON*posNorm)
247 {
248 const VectorDim s(sgn(dotProd)*triangleNormal); // s points along +n for points above, and along -n for points below
249 for(int k=0;k<tri.size();++k)
250 {
251 const size_t k1(k+1<tri.size()? k+1 : 0);
252 VectorDim e1(points[tri(k)]-x);
253 const double e1Norm(e1.norm());
254 if(e1Norm>FLT_EPSILON)
255 {
256 e1/=e1Norm;
257 VectorDim Y1(points[tri(k1)]-x);
258 const double Y1norm(Y1.norm());
259 if(Y1norm>FLT_EPSILON)
260 {
261 Y1/=Y1norm;
262 VectorDim e3(e1.cross(Y1));
263 const double e3Norm(e3.norm());
264 if(e3Norm>FLT_EPSILON)
265 {// e1 and Y1 are not align. If they are the projection on the unit sphere is a point and therefore there is no contribution to solid angle
266 e3/=e3Norm; // normalize e3
267 const VectorDim e2(e3.cross(e1));
268 const double ydy(e1.dot(Y1));
269 const double w=sqrt((1.0-ydy)/(1.0+ydy));
270 const double s3(s.dot(e3));
271 const double s3A2=sqrt(std::pow(s3,2)+a2);
272 temp+=2.0*s3/oneA2/s3A2*atan(s3A2*w/(oneA2-s.dot(e1)-s.dot(e2)*w));
273 }
274
275 }
276 }
277 }
278 }
279 }
280// }
281 return temp;
282 }
283
284
286 {
287 VectorDim temp(VectorDim::Zero());
288 const bool applyDefGradient(true);
289 if(applyDefGradient)
290 {
291 for(const auto& shift : periodicShifts)
292 {
293 for(size_t triID=0;triID<triangles.size();++triID)
294 {
295 temp-=solidAngle(x+shift,triID)/4.0/std::numbers::pi*defGradients[triID]*burgers;
296 }
297 }
298 }
299 else
300 {
301 for(const auto& shift : periodicShifts)
302 {
303 for(size_t triID=0;triID<triangles.size();++triID)
304 {
305 temp-=solidAngle(x+shift,triID)/4.0/std::numbers::pi*burgers;
306 }
307 }
308 }
309 return temp;
310 }
311
312 Eigen::Matrix<double,Eigen::Dynamic,3> MeshedDislocationLoop::plasticDisplacement(Eigen::Ref<const Eigen::Matrix<double,Eigen::Dynamic,3>> points) const
313 {
314 Eigen::Matrix<double,Eigen::Dynamic,3> temp(Eigen::Matrix<double,Eigen::Dynamic,3>::Zero(points.rows(),3));
315 #ifdef _OPENMP
316 #pragma omp parallel for
317 #endif
318 for(long int k=0;k<points.rows();++k)
319 {
321 }
322 return temp;
323 }
324
325
326}
327#endif
void reMesh(const std::deque< Eigen::Matrix< double, 2, 1 > > &boundaryPts, const std::deque< Eigen::Matrix< double, 2, 1 > > &internalPts, const double &meshSize, const std::string &flags)
c
Definition int_R.m:15
x
Definition int_R.m:12
std::deque< VectorDim > heightDisplacements
MeshedDislocationLoop(const VectorDim &burgers_in, const GlidePlane< 3 > &plane, const std::vector< Eigen::Matrix< double, 3, 1 > > &globalBndPts, const DislocationNetwork< 3 > &DN, const double &meshSize, const double &localMeshSize)
VectorDim triangleAreaVector(const Eigen::Vector3i &) const
std::deque< MatrixDim > defGradients
std::deque< VectorDim > displacements
double solidAngle(const VectorDim &x, const size_t &triID) const
VectorDim plasticDisplacementKernel(const Eigen::Ref< const VectorDim > &x) const
Eigen::Matrix< double, Eigen::Dynamic, 3 > plasticDisplacement(Eigen::Ref< const Eigen::Matrix< double, Eigen::Dynamic, 3 > >) const
std::deque< VectorDim > heightPoints
std::vector< VectorDim > periodicShifts
std::deque< MatrixDim > invVertexMatrix
Eigen::Matrix< double, 3, 3 > MatrixDim
Eigen::Matrix< double, 3, 1 > VectorDim
std::deque< Eigen::Vector3i > triangles
static int windingNumber(const PointType &P, const std::vector< PointType > &V)
Definition Polygon2D.h:56
newotri tri
REAL w[16]
REAL u[4]
vertex p1
int k
REAL * h
vertex temp
REAL v[4]