8#ifndef model_FrankLoopsGenerator_cpp_
9#define model_FrankLoopsGenerator_cpp_
19#include <Eigen/Cholesky>
26#include <LatticeModule.h>
59 if(spec.targetDensity>0.0)
66 std::normal_distribution<double> radiusDistribution(spec.radiusDistributionMean/mg.
ddBase.
poly.b_SI,spec.radiusDistributionStd/mg.
ddBase.
poly.b_SI);
67 std::mt19937 generator;
69 std::uniform_int_distribution<> allowedPlaneDist(0,spec.allowedPlaneIDs.size()-1);
71 std::set<int> allowedGrainIDsSet;
72 for(
const auto& gID : spec.allowedGrainIDs)
74 allowedGrainIDsSet.insert(gID);
76 const double allowAllGrains(allowedGrainIDsSet.size() ? (*allowedGrainIDsSet.begin())<0 :
true);
80 while(density<spec.targetDensity)
82 const std::pair<LatticeVector<3>,
int> rp(mg.
ddBase.
poly.randomLatticePointInMesh());
84 const size_t grainID=rp.second;
85 if(allowAllGrains || allowedGrainIDsSet.find(grainID)!=allowedGrainIDsSet.end())
87 std::uniform_int_distribution<> ssDist(0,mg.
ddBase.
poly.grain(grainID)->planeNormals().size()-1);
88 const int allowedIndex(allowedPlaneDist(generator));
89 const int allowedPlaneID(spec.allowedPlaneIDs[allowedIndex]);
91 const int pID(allowedPlaneID<0? ssDist(generator) : allowedPlaneID);
92 const double radius(radiusDistribution(generator));
95 const bool isVL(spec.areVacancyLoops>0);
96 generateSingle(mg,pID,L0.
cartesian(),radius,spec.numberOfSides,isVL);
98 std::cout<<
"Frank loop density="<<density<<std::endl;
100 catch(
const std::exception&
e)
113 if(spec.planeIDs.size())
120 if(spec.planeIDs.size()!=spec.loopRadii.size())
122 throw std::runtime_error(
"spec.planeIDs.size()="+std::to_string(spec.planeIDs.size())+
" NOT EQUAL TO spec.spec.spec.loopRadii.size()="+std::to_string(spec.loopRadii.size()));
124 if(
int(spec.planeIDs.size())!=spec.loopCenters.rows())
126 throw std::runtime_error(
"spec.planeIDs.size()="+std::to_string(spec.planeIDs.size())+
" NOT EQUAL TO spec.loopCenters.rows()="+std::to_string(spec.loopCenters.rows()));
128 if(spec.planeIDs.size()!=spec.loopSides.size())
130 throw std::runtime_error(
"spec.planeIDs.size()="+std::to_string(spec.planeIDs.size())+
" NOT EQUAL TO spec.loopSides.size()="+std::to_string(spec.loopSides.size()));
132 if(spec.planeIDs.size()!=spec.isVacancyLoop.size())
134 throw std::runtime_error(
"spec.planeIDs.size()="+std::to_string(spec.planeIDs.size())+
" NOT EQUAL TO spec.isVacancyLoop.size()="+std::to_string(spec.isVacancyLoop.size()));
136 for(
size_t k=0;
k<spec.planeIDs.size();++
k)
139 const bool isVL(spec.isVacancyLoop[
k]>0);
140 generateSingle(mg,spec.planeIDs[
k],spec.loopCenters.row(
k),spec.loopRadii[
k]/mg.
ddBase.
poly.b_SI,spec.loopSides[
k],isVL);
151 std::cout<<
"Point "<<center.transpose()<<
" is outside mesh. EXITING."<<std::endl;
155 const int grainID(found.second->region->regionID);
156 assert(mg.
ddBase.
poly.grains.size()==1 &&
"Periodic dislocations only supported for single crystals");
157 const auto& grain(mg.
ddBase.
poly.grain(grainID));
159 if(pID>=0 && pID<
int(grain->planeNormals().size()))
161 const auto& planeBase(*grain->planeNormals().at(pID));
164 const long int planeIndex(planeBase.closestPlaneIndexOfPoint(center));
166 std::shared_ptr<PeriodicGlidePlane<3>> glidePlane(mg.
ddBase.
dislocationDynamics().periodicGlidePlaneFactory.get(glidePlaneKey));
167 const VectorDimD P0(glidePlane->referencePlane->snapToPlane(center));
169 std::vector<VectorDimD> loopNodePos;
172 loopNodePos.push_back(P0+Eigen::AngleAxisd(
k*2.0*std::numbers::pi/
sides,planeBase.G2L.row(2).transpose())*planeBase.G2L.row(0).transpose()*radius);
177 ReciprocalLatticeDirection<3> rp(planeBase);
178 const VectorDimD
b(isVacancyLoop? (rp.cartesian().normalized()*rp.planeSpacing()).eval() : (-1.0*rp.cartesian().normalized()*rp.planeSpacing()).eval());
180 b,glidePlane->referencePlane->unitNormal,
187 std::cout<<
"Skipping planeID "<<pID<<std::endl;
191 throw std::runtime_error(
"planeID "+std::to_string(pID)+
" not found, skipping.");
FrankLoopsGenerator(const FrankLoopsDensitySpecification &, MicrostructureGenerator &)
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
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