8#ifndef model_PeriodicDipoleGenerator_cpp_
9#define model_PeriodicDipoleGenerator_cpp_
19#include <Eigen/Cholesky>
28#include <LatticeModule.h>
56 if(spec.slipSystemIDs.size())
58 if(spec.slipSystemIDs.size()!=spec.exitFaceIDs.size())
60 throw std::runtime_error(
"slipSystemIDs.size()="+std::to_string(spec.slipSystemIDs.size())+
" NOT EQUAL TO exitFaceIDs.size()="+std::to_string(spec.exitFaceIDs.size()));
62 if(
int(spec.slipSystemIDs.size())!=spec.dipoleCenters.rows())
64 throw std::runtime_error(
"slipSystemIDs.size()="+std::to_string(spec.slipSystemIDs.size())+
" NOT EQUAL TO dipoleCenters.rows()="+std::to_string(spec.dipoleCenters.rows()));
66 if(spec.slipSystemIDs.size()!=spec.dipoleHeights.size())
68 throw std::runtime_error(
"slipSystemIDs.size()="+std::to_string(spec.slipSystemIDs.size())+
" NOT EQUAL TO dipoleHeights.size()="+std::to_string(spec.dipoleHeights.size()));
70 if(spec.slipSystemIDs.size()!=spec.nodesPerLine.size())
72 throw std::runtime_error(
"slipSystemIDs.size()="+std::to_string(spec.slipSystemIDs.size())+
" NOT EQUAL TO nodesPerLine.size()="+std::to_string(spec.nodesPerLine.size()));
74 if(spec.slipSystemIDs.size()!=spec.glideSteps.size())
76 throw std::runtime_error(
"slipSystemIDs.size()="+std::to_string(spec.slipSystemIDs.size())+
" NOT EQUAL TO periodicDipoleGlideSteps.size()="+std::to_string(spec.glideSteps.size()));
79 for(
size_t k=0;
k<spec.slipSystemIDs.size();++
k)
81 generateSingle(mg,spec.slipSystemIDs[
k],spec.dipoleCenters.row(
k),spec.exitFaceIDs[
k],spec.dipoleHeights[
k],spec.nodesPerLine[
k],spec.glideSteps[
k]);
91 if(spec.targetDensity>0.0)
93 std::mt19937 generator;
95 while(density<spec.targetDensity)
97 const std::pair<LatticeVector<3>,
int> rp(mg.
ddBase.
poly.randomLatticePointInMesh());
99 const size_t grainID=rp.second;
100 std::uniform_int_distribution<> ssDist(0,mg.
ddBase.
poly.grain(grainID)->slipSystems().size()-1);
101 const int rSS(ssDist(generator));
102 std::uniform_int_distribution<> fDist(0,mg.
ddBase.
poly.grain(grainID)->region.faces().size()-1);
103 const int rF(fDist(generator));
104 auto faceIter(mg.
ddBase.
poly.grain(grainID)->region.faces().begin());
105 std::advance(faceIter,rF);
109 generateSingle(mg,rSS,L0.
cartesian(),faceIter->first,100,0,20.0);
111 std::cout<<
"periodic dipole density="<<density<<std::endl;
113 catch(
const std::exception&
e)
121 bool PeriodicDipoleGenerator::generateSingle(
MicrostructureGenerator& mg,
const int& rSS,
const VectorDimD& dipolePoint,
const int& exitFaceID,
const int& dipoleHeight,
const int& dipoleNodes,
double glideStep)
127 std::pair<bool,const Simplex<3,3>*> found(mg.
ddBase.
mesh.
search(dipolePoint));
130 std::cout<<
"Point "<<dipolePoint.transpose()<<
" is outside mesh. EXITING."<<std::endl;
134 const int grainID(found.second->region->regionID);
135 assert(mg.
ddBase.
poly.grains.size()==1 &&
"Periodic dislocations only supported for single crystals");
136 const auto& grain(mg.
ddBase.
poly.grain(grainID));
138 if(rSS<
int(grain->slipSystems().size()))
140 const auto periodicFaceIter(grain->region.faces().find(exitFaceID));
141 if(periodicFaceIter!=grain->region.faces().end())
143 const auto periodicFaceA(periodicFaceIter->second);
144 const auto periodicFaceB(periodicFaceA->periodicFacePair.second);
146 if(periodicFaceB!=
nullptr)
149 const auto& faceAshift(periodicFaceA->periodicFacePair.first);
150 const auto faceAlatticeShift(grain->latticeVector(faceAshift));
152 const auto& slipSystem(*grain->slipSystems().at(rSS));
154 if(slipSystem.n.dot(faceAlatticeShift)==0)
159 const VectorDimD planePoint(dipolePoint-0.5*dipoleHeight*slipSystem.n.interplaneVector());
162 const long int planeIndex(slipSystem.n.closestPlaneIndexOfPoint(planePoint));
164 std::shared_ptr<PeriodicGlidePlane<3>> glidePlane(mg.
ddBase.
dislocationDynamics().periodicGlidePlaneFactory.get(glidePlaneKey));
167 const auto prismaticPlaneNormal(grain->reciprocalLatticeDirection(glidePlane->referencePlane->unitNormal.cross(faceAshift)));
168 const long int prismaticPlaneIndex(prismaticPlaneNormal.closestPlaneIndexOfPoint(dipolePoint));
169 GlidePlaneKey<3> prismaticPlaneKey(prismaticPlaneIndex, prismaticPlaneNormal);
170 std::shared_ptr<PeriodicGlidePlane<3>> prismaticGlidePlane(mg.
ddBase.
dislocationDynamics().periodicGlidePlaneFactory.get(prismaticPlaneKey));
172 PlanePlaneIntersection<3> ppi(*glidePlane->referencePlane,*prismaticGlidePlane->referencePlane);
173 Line<3> ppLine(ppi.P,ppi.d);
175 const VectorDimD P0(ppLine.snap(planePoint));
178 PlaneLineIntersection<3> pliA(periodicFaceA->center(),periodicFaceA->outNormal(),P0,faceAshift);
179 PlaneLineIntersection<3> pliB(periodicFaceB->center(),periodicFaceB->outNormal(),P0,faceAshift);
183 const VectorDimD AB(pliB.P-pliA.P);
184 if((AB-faceAshift).norm()<FLT_EPSILON)
187 GlidePlaneKey<3> parallelGlidePlaneKey(planeIndex+dipoleHeight, slipSystem.n);
188 std::shared_ptr<PeriodicGlidePlane<3>> parallelglidePlane(mg.
ddBase.
dislocationDynamics().periodicGlidePlaneFactory.get(parallelGlidePlaneKey));
191 if(parallelglidePlane && prismaticGlidePlane)
195 std::map<VectorDimD,size_t,CompareVectorsByComponent<double,3,float>> uniqueNetworkNodeMap;
198 const VectorDimD lShift(nShift*AB);
199 const VectorDimD rShift(lShift+AB);
200 const VectorDimD startPoint(0.5*(pliB.P+pliA.P));
201 std::vector<VectorDimD> prismaticNodePos;
202 prismaticNodePos.push_back(startPoint+lShift);
203 prismaticNodePos.push_back(startPoint+rShift);
204 prismaticNodePos.push_back(parallelglidePlane->referencePlane->snapToPlane(startPoint+rShift));
205 prismaticNodePos.push_back(parallelglidePlane->referencePlane->snapToPlane(startPoint+lShift));
207 const VectorDimD lineP0 = 0.5*(startPoint+lShift+parallelglidePlane->referencePlane->snapToPlane(startPoint+lShift));
208 const VectorDimD lineP1 = 0.5*(startPoint+rShift+parallelglidePlane->referencePlane->snapToPlane(startPoint+rShift));
211 slipSystem.s.cartesian(),prismaticGlidePlane->referencePlane->unitNormal,
214 if(std::fabs(glideStep)>FLT_EPSILON)
216 const int halfNodeNumber(dipoleNodes/2);
217 if(halfNodeNumber < 0)
219 throw std::runtime_error(
"dipoleNodes="+std::to_string(halfNodeNumber)+
"is smaller than 0");
221 const double halfDipoleLength(AB.norm()*0.5);
222 const VectorDimD dipoleDir(AB/AB.norm());
223 const VectorDimD shiftNodeLength(halfDipoleLength/(1.0*(halfNodeNumber+1))*dipoleDir);
227 std::vector<VectorDimD> firstNodePos;
228 firstNodePos.push_back(startPoint+lShift);
229 firstNodePos.push_back(startPoint+rShift);
230 if((rShift-lShift).cross(glideStep*prismaticGlidePlane->referencePlane->unitNormal).dot(glidePlane->referencePlane->unitNormal)>0.0)
234 firstNodePos.push_back(startPoint+rShift+glideStep*prismaticGlidePlane->referencePlane->unitNormal);
235 for(
int k=1;
k<=halfNodeNumber;
k++)
237 firstNodePos.push_back(startPoint+rShift-
k*shiftNodeLength+glideStep*prismaticGlidePlane->referencePlane->unitNormal);
239 for(
int k=halfNodeNumber;
k>0;
k--)
241 firstNodePos.push_back(startPoint+lShift+
k*shiftNodeLength+glideStep*prismaticGlidePlane->referencePlane->unitNormal);
243 firstNodePos.push_back(startPoint+lShift+glideStep*prismaticGlidePlane->referencePlane->unitNormal);
246 -slipSystem.s.cartesian(),glidePlane->referencePlane->unitNormal,
250 FiniteLineSegment<3> mirrowLine(lineP0,lineP1);
253 std::vector<VectorDimD> secondNodePos;
254 for(
const auto& pos : firstNodePos)
256 VectorDimD
c=mirrowLine.snapToInfiniteLine(pos);
257 secondNodePos.push_back(2.0*
c-pos);
263 slipSystem.s.cartesian(),parallelglidePlane->referencePlane->unitNormal,
271 std::cout<<
"Cannot create glide planes"<<std::endl;
276 throw std::runtime_error(
"periodic line intersection with faces is not the face shift vector");
281 throw std::runtime_error(
"periodic line direction does not form an incident intersecitn with periodic faces");
286 throw std::runtime_error(
"planeNormal of slipSystem "+std::to_string(rSS)+
" is not othogonal to facelatticeShift "+std::to_string(exitFaceID));
291 throw std::runtime_error(
"Mesh face "+std::to_string(exitFaceID)+
" is not a periodic face.");
296 throw std::runtime_error(
"Mesh face "+std::to_string(exitFaceID)+
" not found.");
301 throw std::runtime_error(
"slipSystem "+std::to_string(rSS)+
" not found, skipping.");
306 std::cout<<
"Skipping slip system "<<rSS<<std::endl;
VectorDimD cartesian() const
bool insertJunctionLoop(const std::vector< VectorDimD > &loopNodePos, const std::shared_ptr< PeriodicGlidePlane< 3 > > &periodicPlane, const VectorDimD &b, const VectorDimD &unitNormal, const VectorDimD &P0, const size_t &grainID, const DislocationLoopIO< dim >::DislocationLoopType &loopType)
DefectiveCrystalBase< 3 > & ddBase
PeriodicDipoleGenerator(const PeriodicDipoleDensitySpecification &spec, MicrostructureGenerator &mg)
std::pair< bool, const Simplex< _dim, _dim > * > search(const Eigen::Matrix< double, dim, 1 > &P) const
const double & volume() const
static std::string defaultColor
static std::string magentaBoldColor
LatticePlaneKey< dim > GlidePlaneKey
const Polycrystal< dim > & poly
const SimplicialMesh< dim > & mesh
DislocationDynamicsBase< dim > & dislocationDynamics() const