8#ifndef model_StackingFaultTetrahedraGenerator_cpp_
9#define model_StackingFaultTetrahedraGenerator_cpp_
19#include <Eigen/Cholesky>
26#include <LatticeModule.h>
59 generateDensityFCC(spec,mg);
63 throw std::runtime_error(
"StackingFaultTetrahedraGenerator requires FCC crystal structure");
71 generateIndividualFCC(spec,mg);
75 throw std::runtime_error(
"StackingFaultTetrahedraGenerator requires FCC crystal structure");
104bool StackingFaultTetrahedraGenerator::generateSingleSFT(
MicrostructureGenerator& mg,
const int& planeID,
const VectorDimD& basePoint,
const bool& inverted,
const int& sftSize)
111 const int grainID=found.second->region->regionID;
112 const auto& grain(mg.
ddBase.
poly.grain(grainID));
115 if(planeID>=0 && planeID<4)
117 const auto basePlane(inverted? std::shared_ptr<GlidePlaneBase>(
new GlidePlaneBase(grain->planeNormals().at(planeID)->primitiveVectors.second,grain->planeNormals().at(planeID)->primitiveVectors.first,
nullptr)) : grain->planeNormals().at(planeID));
118 const auto unitNormal(basePlane->cartesian().normalized());
119 const auto faceBaryShift((basePlane->primitiveVectors.first+basePlane->primitiveVectors.second).cartesian()*sftSize/3.0);
120 const VectorDimD corner(grain->snapToLattice(basePoint-faceBaryShift).cartesian());
122 std::vector<VectorDimD> nodePos;
123 nodePos.push_back(
corner);
124 nodePos.push_back(
corner+basePlane->primitiveVectors.first.cartesian()*sftSize);
125 nodePos.push_back(
corner+basePlane->primitiveVectors.second.cartesian()*sftSize);
126 nodePos.push_back((nodePos[0]+nodePos[1]+nodePos[2])/3.0-unitNormal*sftSize*sqrt(2.0/3.0));
149 std::vector<VectorDimD> facePos012;
150 facePos012.push_back(nodePos[0]);
151 facePos012.push_back(nodePos[1]);
152 facePos012.push_back(nodePos[2]);
153 const auto n012(grain->reciprocalLatticeDirection((nodePos[1]-nodePos[0]).cross(nodePos[2]-nodePos[1])));
154 const VectorDimD b012(n012.interplaneVector());
156 if(!heightPair012.first)
158 throw std::runtime_error(
"Cannot determine plane of SFT face 012.");
161 std::shared_ptr<PeriodicGlidePlane<3>> glidePlane012(mg.
ddBase.
dislocationDynamics().periodicGlidePlaneFactory.get(basePlaneKey012));
163 b012,n012.cartesian().normalized(),
169 std::vector<VectorDimD> facePos230;
170 facePos230.push_back(nodePos[2]);
171 facePos230.push_back(nodePos[3]);
172 facePos230.push_back(nodePos[0]);
173 const auto n230(grain->reciprocalLatticeDirection((nodePos[3]-nodePos[2]).cross(nodePos[0]-nodePos[3])));
174 const VectorDimD b230((0.5*(nodePos[2]+nodePos[0])-nodePos[3]).normalized()*sqrt(3.0)/3.0);
176 if(!heightPair230.first)
178 throw std::runtime_error(
"Cannot determine plane of SFT face 230.");
181 std::shared_ptr<PeriodicGlidePlane<3>> glidePlane230(mg.
ddBase.
dislocationDynamics().periodicGlidePlaneFactory.get(basePlaneKey230));
183 b230,n230.cartesian().normalized(),
189 std::vector<VectorDimD> facePos031;
190 facePos031.push_back(nodePos[0]);
191 facePos031.push_back(nodePos[3]);
192 facePos031.push_back(nodePos[1]);
193 const auto n031(grain->reciprocalLatticeDirection((nodePos[3]-nodePos[0]).cross(nodePos[1]-nodePos[3])));
194 const VectorDimD b031((0.5*(nodePos[0]+nodePos[1])-nodePos[3]).normalized()*sqrt(3.0)/3.0);
196 if(!heightPair031.first)
198 throw std::runtime_error(
"Cannot determine plane of SFT face 031.");
201 std::shared_ptr<PeriodicGlidePlane<3>> glidePlane031(mg.
ddBase.
dislocationDynamics().periodicGlidePlaneFactory.get(basePlaneKey031));
203 b031,n031.cartesian().normalized(),
209 std::vector<VectorDimD> facePos132;
210 facePos132.push_back(nodePos[1]);
211 facePos132.push_back(nodePos[3]);
212 facePos132.push_back(nodePos[2]);
213 const auto n132(grain->reciprocalLatticeDirection((nodePos[3]-nodePos[1]).cross(nodePos[2]-nodePos[3])));
214 const VectorDimD b132((0.5*(nodePos[1]+nodePos[2])-nodePos[3]).normalized()*sqrt(3.0)/3.0);
216 if(!heightPair132.first)
218 throw std::runtime_error(
"Cannot determine plane of SFT face132.");
221 std::shared_ptr<PeriodicGlidePlane<3>> glidePlane132(mg.
ddBase.
dislocationDynamics().periodicGlidePlaneFactory.get(basePlaneKey132));
223 b132,n132.cartesian().normalized(),
230 std::cout<<
"SFT points outside mesh, skipping generation."<<std::endl;
236 std::cout<<
"SFT planeID not a valid index into planeNormals, skipping generation."<<std::endl;
242 std::cout<<
"SFT basePoint outside mesh, skipping generation."<<std::endl;
248 std::cout<<
"SFT size <1b, skipping generation."<<std::endl;
285 for(
size_t k=0;
k<
spec.planeIDs.size();++
k)
288 const VectorDimD basePoint(
spec.basePoints.row(
k));
289 const bool inverted(
spec.areInverted[
k]);
290 const int sftSize(std::round(
spec.sizes[
k]/mg.ddBase.poly.b_SI));
291 ndefects+=generateSingleSFT(mg,planeID,basePoint,inverted,sftSize);
293 std::cout<<
"Generated "<<ndefects<<
" STFs"<<std::endl;
305 if(
spec.targetDensity>0.0)
308 std::uniform_int_distribution<> planeNormalDistribution(0,3);
309 std::uniform_int_distribution<> invertedThompsonTetrahedronDistribution(0,1);
310 std::normal_distribution<double> sftSizeDistribution(
spec.sizeDistributionMean,
spec.sizeDistributionStd);
314 double defectsDensity=ndefects/mg.ddBase.mesh.volume()/std::pow(mg.ddBase.poly.b_SI,3);
315 while(defectsDensity<
spec.targetDensity)
317 const int sftSize(std::round(sftSizeDistribution(generator)/mg.ddBase.poly.b_SI));
318 ndefects+=generateSingleSFT(mg,planeNormalDistribution(generator),mg.ddBase.poly.randomPoint(),invertedThompsonTetrahedronDistribution(generator),sftSize);
319 defectsDensity=ndefects/mg.ddBase.mesh.volume()/std::pow(mg.ddBase.poly.b_SI,3);
320 std::cout<<
"SFT density="<<defectsDensity<<std::endl;
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
bool allPointsInGrain(const std::vector< VectorDimD > &points, const int &grainID)
std::pair< bool, const Simplex< _dim, _dim > * > search(const Eigen::Matrix< double, dim, 1 > &P) const
StackingFaultTetrahedraGenerator(const StackingFaultTetrahedraDensitySpecification &, MicrostructureGenerator &mg)
static std::string defaultColor
static std::string magentaBoldColor
LatticePlaneKey< dim > GlidePlaneKey
const Polycrystal< dim > & poly
const SimplicialMesh< dim > & mesh
DislocationDynamicsBase< dim > & dislocationDynamics() const
static std::pair< bool, long int > computeHeight(const ReciprocalLatticeDirection< dim > &r, const VectorDimD &P)