Mechanics of Defect Evolution Library
Loading...
Searching...
No Matches
src/MicrostructureGeneration/microstructureGenerator.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_MicrostructureGenerator_cpp_
9#define model_MicrostructureGenerator_cpp_
10
12#include <fstream>
13#include <filesystem>
14
15#include <ShearLoopGenerator.h>
18//#include <PolyhedronInclusionsGenerator.h>
19//#include <VTKGenerator.h>
25#include <limits>
29#include <CrackMeshGenerator.h>
30#include <FrankLoopsGenerator.h>
31#include <PlanarLoopGenerator.h>
33#include <StrUtilities.h>
34#include <SutherlandHodgman.h>
35
36namespace model
37{
38
39std::shared_ptr<PeriodicPlanePatch<3>> PolyPoint::periodicPlanePatch() const
40{
41 return nullptr;
42}
43
45/* init*/ ddBase(ddBase_in)
46/* init*/,configIO(ddBase_in.simulationParameters.traitsIO.configFolder)
47/* init*/,auxIO(ddBase_in.simulationParameters.traitsIO.auxFolder)
48/* init*/,outputBinary(ddBase.simulationParameters.outputBinary)
49/* init*/,minSize(0.1*std::min(ddBase.mesh.xMax(0)-ddBase.mesh.xMin(0),std::min(ddBase.mesh.xMax(1)-ddBase.mesh.xMin(1),ddBase.mesh.xMax(2)-ddBase.mesh.xMin(2))))
50/* init*/,maxSize(std::max(ddBase.mesh.xMax(0)-ddBase.mesh.xMin(0),std::max(ddBase.mesh.xMax(1)-ddBase.mesh.xMin(1),ddBase.mesh.xMax(2)-ddBase.mesh.xMin(2))))
51{
52 std::cout<<greenBoldColor<<"Generating microstructure for folder "<<ddBase.simulationParameters.traitsIO.simulationFolder<<defaultColor<<std::endl;
53
54 // Some sanity checks
55 if(ddBase.mesh.volume()<FLT_EPSILON)
56 {
57 throw std::runtime_error("mesh "+ddBase.simulationParameters.traitsIO.meshFile+" is empty.");
58 }
59
60 // for(const auto& grain : ddBase.poly.grains)
61 // {
62 // std::cout<<"MicrostructureGenerator Grain "<<grain.first<<std::endl;
63 // for(const auto& pl : grain.second.planeNormals())
64 // {
65 // std::cout<<pl.second->lattice.latticeBasis<<"\n"<<std::endl;
66 // }
67 //
68 // std::cout<<"SlipSystems"<<std::endl;
69 // for(const auto& ss : grain.second.slipSystems())
70 // {
71 // std::cout<<ss.second->s.dir.lattice.latticeBasis<<"\n"<<std::endl;
72 // }
73 // }
74
75}
76
77
79{
80 ddBase.dislocationDynamics();
81 ShearLoopGenerator gen(spec,*this);
82}
83
85{
86 ddBase.dislocationDynamics();
87 ShearLoopGenerator gen(spec,*this);
88}
89
95
101
103{
104 ddBase.dislocationDynamics();
105 PrismaticLoopGenerator gen(spec,*this);
106}
107
109{
110 ddBase.dislocationDynamics();
111 PrismaticLoopGenerator gen(spec,*this);
112}
113
115{
116 ddBase.dislocationDynamics();
117 FrankLoopsGenerator gen(spec,*this);
118}
119
121{
122 ddBase.dislocationDynamics();
123 FrankLoopsGenerator gen(spec,*this);
124}
125
131
137
142
147
152
157
162
164{
165 ddBase.dislocationDynamics();
166 PlanarLoopGenerator gen(spec,*this);
167}
168
173
178
179
181{
182 configIO.clear();
183 auxIO.clear();
184
185 const auto microstructureFiles(TextFileParser(ddBase.simulationParameters.traitsIO.microstructureFile).readStringVector("microstructureFile"));
186 for(const auto& pair : microstructureFiles)
187 {
188 const std::string microstructureFileName(std::filesystem::path(ddBase.simulationParameters.traitsIO.microstructureFile).parent_path().string()+"/"+StrUtilities::removeSpaces(pair.first));
189 const std::string type(StrUtilities::removeSpaces(TextFileParser(microstructureFileName).readString("type",false)));
190 const std::string style(StrUtilities::removeSpaces(TextFileParser(microstructureFileName).readString("style",false)));
191
192 if(type=="ShearLoop")
193 {
194 if(style=="Density" || style=="density")
195 {
196 ShearLoopDensitySpecification spec(microstructureFileName);
198 }
199 else if(style=="Individual" || style=="individual")
200 {
201 ShearLoopIndividualSpecification spec(microstructureFileName);
203 }
204 else
205 {
206 throw std::runtime_error("Unkown style "+style+" for "+type);
207 }
208 }
209 else if(type=="PeriodicDipole")
210 {
211 if(style=="Density" || style=="density")
212 {
213 PeriodicDipoleDensitySpecification spec(microstructureFileName);
215 }
216 else if(style=="Individual" || style=="individual")
217 {
218 PeriodicDipoleIndividualSpecification spec(microstructureFileName);
220 }
221 else
222 {
223 throw std::runtime_error("Unkown style "+style+" for "+type);
224 }
225 }
226 else if(type=="PrismaticLoop")
227 {
228 if(style=="Density" || style=="density")
229 {
230 PrismaticLoopDensitySpecification spec(microstructureFileName);
232 }
233 else if(style=="Individual" || style=="individual")
234 {
235 PrismaticLoopIndividualSpecification spec(microstructureFileName);
237 }
238 else
239 {
240 throw std::runtime_error("Unkown style "+style+" for "+type);
241 }
242 }
243 else if(type=="FrankLoops")
244 {
245 if(style=="Density" || style=="density")
246 {
247 FrankLoopsDensitySpecification spec(microstructureFileName);
249 }
250 else if(style=="Individual" || style=="individual")
251 {
252 FrankLoopsIndividualSpecification spec(microstructureFileName);
254 }
255 else
256 {
257 throw std::runtime_error("Unkown style "+style+" for "+type);
258 }
259 }
260 else if(type=="StackingFaultTetrahedra" || type=="StackingFaultTetrahedron")
261 {
262 if(style=="Density" || style=="density")
263 {
264 StackingFaultTetrahedraDensitySpecification spec(microstructureFileName);
266 }
267 else if(style=="Individual" || style=="individual")
268 {
269 StackingFaultTetrahedraIndividualSpecification spec(microstructureFileName);
271 }
272 else
273 {
274 throw std::runtime_error("Unkown style "+style+" for "+type);
275 }
276 }
277 else if(type=="SphericalInclusions")
278 {
279 if(style=="Density" || style=="density")
280 {
281 SphericalInclusionDensitySpecification spec(microstructureFileName);
283 }
284 else if(style=="Individual" || style=="individual")
285 {
286 SphericalInclusionIndividualSpecification spec(microstructureFileName);
288 }
289 else
290 {
291 throw std::runtime_error("Unkown style "+style+" for "+type);
292 }
293 }
294 else if(type=="EllipsoidalInclusions")
295 {
296 if(style=="Density" || style=="density")
297 {
298 EllipsoidalInclusionDensitySpecification spec(microstructureFileName);
300 }
301 else if(style=="Individual" || style=="individual")
302 {
303 EllipsoidalInclusionIndividualSpecification spec(microstructureFileName);
305 }
306 else
307 {
308 throw std::runtime_error("Unknown style "+style+" for "+type);
309 }
310 }
311 else if(type=="PolyhedronInclusions")
312 {
313 if(style=="Density" || style=="density")
314 {
315 throw std::runtime_error("Unkown style "+style+" for "+type);
316 // PolyhedronInclusionDensitySpecification spec(microstructureFileName);
317 // addPolyhedronInclusionDensity(spec);
318 }
319 else if(style=="Individual" || style=="individual")
320 {
321 PolyhedronInclusionIndividualSpecification spec(microstructureFileName);
323 }
324 else
325 {
326 throw std::runtime_error("Unkown style "+style+" for "+type);
327 }
328 }
329 else if(type=="PlanarLoop")
330 {
331 if(style=="Individual" || style=="individual")
332 {
333 PlanarLoopIndividualSpecification spec(microstructureFileName);
335 }
336 else
337 {
338 throw std::runtime_error("Unkown style "+style+" for "+type);
339 }
340 }
341 else if(type=="CircularCrack")
342 {
343 if(style=="Individual" || style=="individual")
344 {
345 CircularCrackIndividualSpecification spec(microstructureFileName);
347 }
348 else
349 {
350 throw std::runtime_error("Unkown style "+style+" for "+type);
351 }
352 }
353 else if(type=="CrackMesh")
354 {
355 if(style=="Individual" || style=="individual")
356 {
357 CrackMeshIndividualSpecification spec(microstructureFileName);
359 }
360 else
361 {
362 throw std::runtime_error("Unkown style "+style+" for "+type);
363 }
364 }
365 else
366 {
367 throw std::runtime_error("Unkown microstructure type "+type+".");
368 }
369 }
370}
371
373{
374 return ddBase.simulationParameters.traitsIO;
375}
376
381
386
391
396
397bool MicrostructureGenerator::insertJunctionLoop(const std::vector<VectorDimD>& loopNodePos,
398 const std::shared_ptr<PeriodicGlidePlane<3>>& periodicPlane,
399 const VectorDimD& b,
400 const VectorDimD& unitNormal,
401 const VectorDimD& P0,
402 const size_t& grainID,
404{
405 ddBase.dislocationDynamics();
406 if(loopNodePos.size()<3)
407 {
408 return false;
409 }
410 std::vector<PolyPoint> dummyPolyPoints(loopNodePos.size());
411 std::vector<std::pair<VectorDimD, const PolyPoint *const>> loopNodePosTemp;
412 for(size_t k=0;k<loopNodePos.size();++k)
413 {
414 loopNodePosTemp.emplace_back(loopNodePos[k], &dummyPolyPoints[k]);
415 }
416 const auto ppi(periodicPlane->polygonPatchIntersection(loopNodePosTemp,true));
417 if(ppi.size()<3)
418 {
419 return false;
420 }
421 // The walk follows actual same-grain twins and clips physical interfaces.
422 // Require complete coverage of EACH original edge before committing IO;
423 // an area comparison alone can conceal missing pieces of a concave loop.
424 std::vector<double> retainedLength(loopNodePos.size(),0.0);
425 for(size_t k=0;k<ppi.size();++k)
426 {
427 const auto& provenance=std::get<6>(ppi[k]);
428 if(provenance.incomingOriginalSegment)
429 {
430 retainedLength.at(provenance.incomingOriginalSegment->sourceIndex)+=
431 (std::get<0>(ppi[k])-std::get<0>(ppi[(k+ppi.size()-1)%ppi.size()])).norm();
432 }
433 }
434 for(size_t k=0;k<loopNodePos.size();++k)
435 {
436 const double length=(loopNodePos[(k+1)%loopNodePos.size()]-loopNodePos[k]).norm();
437 if(std::abs(retainedLength[k]-length)>1.e-8*std::max(1.0,length))
438 {
439 return false;
440 }
441 }
442 const size_t loopID(insertLoop(b,unitNormal,P0,grainID,loopType));
443 std::vector<size_t> loopNodeIDs;
444 for(const auto &tup : ppi)
445 {
446 const VectorDimD loopNodePos(periodicPlane->referencePlane->globalPosition(std::get<0>(tup)));
447 const VectorDimD networkNodePos(loopNodePos+std::get<1>(tup));
448 const auto networkNodeIter(uniqueNetworkNodeMap.find(networkNodePos));
449 if(networkNodeIter==uniqueNetworkNodeMap.end())
450 {// no NetworkNode found at current position
451 uniqueNetworkNodeMap.emplace(networkNodePos,insertNetworkNode(networkNodePos)); // insert NetworkNode and store its ID
452 }
453 loopNodeIDs.push_back(insertLoopNode(loopID,loopNodePos,uniqueNetworkNodeMap.at(networkNodePos),std::get<1>(tup),std::get<2>(tup))); // insert LoopNode and store its ID
454 }
455 insertLoopLinks(loopID,loopNodeIDs);
456 return true;
457}
458
459size_t MicrostructureGenerator::insertLoop(const VectorDimD& b,const VectorDimD& unitNormal,const VectorDimD& P0,const size_t& grainID,const DislocationLoopType& loopType)
460{
461 ddBase.dislocationDynamics();
462 const size_t loopID(configIO.loops().size());
463 configIO.loops().emplace_back(loopID, b,unitNormal,P0,grainID,loopType);
464 return loopID;
465}
466
467size_t MicrostructureGenerator::insertLoopNode(const size_t& loopID,const VectorDimD& loopNodePos,const size_t& networkNodeID,const VectorDimD& loopNodeShift,const std::pair<short int,short int>& periodicEdgeIDs)
468{
469 ddBase.dislocationDynamics();
470 const size_t loopNodeID(configIO.loopNodes().size());
471 configIO.loopNodes().emplace_back(loopNodeID,loopID,loopNodePos,networkNodeID,loopNodeShift,periodicEdgeIDs);
472 return loopNodeID;
473}
474
475std::vector<size_t> MicrostructureGenerator::insertLoopLinks(const size_t& loopID,const std::vector<size_t>& loopNodeIDs)
476{
477 ddBase.dislocationDynamics();
478 std::vector<size_t> temp;
479 for(size_t k=0;k<loopNodeIDs.size();++k)
480 {
481 const size_t k1=(k+1)<loopNodeIDs.size()? k+1 : 0;
482 temp.push_back(configIO.loopLinks().size());
483 const size_t sourceNodeID(loopNodeIDs[k ]);
484 const size_t sinkNodeID(loopNodeIDs[k1]);
485 const auto sourceNode(configIO.loopNodes()[sourceNodeID]);
486 const auto sinkNode(configIO.loopNodes()[sinkNodeID]);
487 configIO.loopLinks().emplace_back(loopID,sourceNodeID,sinkNodeID,(sourceNode.P-sinkNode.P).norm()>FLT_EPSILON,0);
488 }
489 return temp;
490}
491
492size_t MicrostructureGenerator::insertNetworkNode(const VectorDimD& networkNodePos)
493{
494 ddBase.dislocationDynamics();
495 const size_t networkNodeID(configIO.nodes().size());
496 configIO.nodes().emplace_back(networkNodeID,networkNodePos,Eigen::Matrix<double,1,3>::Zero(),Eigen::Array<double,1,ClusterDynamicsParameters<3>::mSize>::Zero(),1.0,0);
497 return networkNodeID;
498}
499
500namespace
501{
502 size_t nextInclusionID(const DefectiveCrystalConfigIO<3>& config)
503 {
504 size_t next=0;
505 const auto scan=[&](const auto& inclusions)
506 {
507 for(const auto& inclusion : inclusions)
508 {
509 if(inclusion.inclusionID==std::numeric_limits<size_t>::max())
510 {
511 throw std::overflow_error("Inclusion IDs exhausted");
512 }
513 next=std::max(next,inclusion.inclusionID+1);
514 }
515 };
516 scan(config.sphericalInclusions());
517 scan(config.ellipsoidalInclusions());
518 scan(config.polyhedronInclusions());
519 return next;
520 }
521}
522
523size_t MicrostructureGenerator::insertInclusion(const VectorDimD& pos,const Eigen::Matrix3d& axes,
524 const Eigen::Matrix3d& eT,const double& vrc,const int& type)
525{
526 const size_t inclusionID=nextInclusionID(configIO);
527 configIO.ellipsoidalInclusions().emplace_back(inclusionID,pos,axes,eT,vrc,type);
528 return inclusionID;
529}
530
531size_t MicrostructureGenerator::insertInclusion(const VectorDimD& pos,const double& R, const Eigen::Matrix<double,dim,dim>& eT, const double& vrc,const int&type)
532{
533 const size_t inclusionID(nextInclusionID(configIO));
534 configIO.sphericalInclusions().emplace_back(inclusionID,pos,R,eT,vrc,type);
535 return inclusionID;
536}
537
538size_t MicrostructureGenerator::insertInclusion(const std::map<size_t,Eigen::Vector3d>& polyNodes,const std::map<size_t,std::vector<size_t>>& faceMap, const Eigen::Matrix<double,dim,dim>& eT, const double& vrc,const int&type)
539{
540 const size_t inclusionID(nextInclusionID(configIO));
541 configIO.polyhedronInclusions().emplace_back(inclusionID,eT,vrc,type);
542
543 const size_t startNodeID(configIO.polyhedronInclusionNodes().size());
544
545 size_t nodeCounter(0);
546 for(const auto& node : polyNodes)
547 {
548 configIO.polyhedronInclusionNodes().emplace_back(startNodeID+nodeCounter,node.second);
549 nodeCounter++;
550 }
551
552 for(const auto& pair : faceMap)
553 {
554 const size_t& faceID(pair.first);
555 for(size_t k=0;k<pair.second.size();++k)
556 {
557 const size_t k1(k<pair.second.size()-1? k+1 : 0);
558
559
560 const auto sourceIter(polyNodes.find(pair.second[k]));
561 const auto sinkIter(polyNodes.find(pair.second[k1]));
562 if(sourceIter!=polyNodes.end() && sinkIter!=polyNodes.end())
563 {
564 const size_t sourceID(startNodeID +std::distance(polyNodes.begin(),sourceIter));
565 const size_t sinkID(startNodeID +std::distance(polyNodes.begin(),sinkIter));
566 configIO.polyhedronInclusionEdges().emplace_back(inclusionID,faceID,sourceID,sinkID);
567 }
568 else
569 {
570 std::cout<<"inclusionID="<<inclusionID<<std::endl;
571 std::cout<<"faceID="<<faceID<<std::endl;
572 std::cout<<"node "<<pair.second[k]<<" found? "<<(sourceIter!=polyNodes.end())<<std::endl;
573 std::cout<<"node "<<pair.second[k1]<<" found? "<<(sinkIter!=polyNodes.end())<<std::endl;
574 throw std::runtime_error("Cannot insert polyhedronInclusionEdge.");
575 }
576 }
577 }
578 return inclusionID;
579}
580
581bool MicrostructureGenerator::insertCrackMesh(const std::vector<VectorDimD>& nodes,const std::vector<VectorDimD>& burgers,const std::vector<VectorDimI>& triangles)
582{
583 ddBase.dislocationDynamics();
584 bool success(false);
585 if(allPointsInMesh(nodes))
586 {
587
588 }
589 else
590 {
591 throw std::runtime_error("CrackMeshGenerator::generateSingle:: crack nodes outside mesh.");
592 }
593 return success;
594}
595
596
598{
599 if(outputBinary)
600 {
601 std::cout<<greenBoldColor<<"Writing configuration to "<<configIO.getBinFilename(fileID)<<defaultColor<<std::endl;
602 configIO.writeBin(fileID);
603 auxIO.writeBin(fileID);
604 }
605 else
606 {
607 std::cout<<greenBoldColor<<"Writing configuration to "<<configIO.getTxtFilename(fileID)<<defaultColor<<std::endl;
608 configIO.writeTxt(fileID);
609 auxIO.writeTxt(fileID);
610 }
611}
612
613bool MicrostructureGenerator::allPointsInGrain(const std::vector<VectorDimD>& points,const int& grainID)
614{
615 bool temp=true;
616 for(const auto& point : points)
617 {
618 temp*=ddBase.mesh.searchRegion(grainID,point).first;
619 if(!temp)
620 {
621 break;
622 }
623 }
624 return temp;
625}
626
627bool MicrostructureGenerator::allPointsInMesh(const std::vector<VectorDimD>& points)
628{
629 const auto* guess=ddBase.mesh.simplices().begin()->second.get();
630 bool temp=true;
631 for(const auto& point : points)
632 {
633 const auto pair(ddBase.mesh.searchWithGuess(point,guess));
634 guess=pair.second;
635 temp*=pair.first;
636 if(!temp)
637 {
638 break;
639 }
640 }
641 return temp;
642}
643
644}
645#endif
const std::vector< SphericalInclusionIO< dim > > & sphericalInclusions() const
const std::vector< PolyhedronInclusionIO< dim > > & polyhedronInclusions() const
const std::vector< EllipsoidalInclusionIO< dim > > & ellipsoidalInclusions() const
void addFrankLoopsIndividual(const FrankLoopsIndividualSpecification &spec)
void addPrismaticLoopIndividual(const PrismaticLoopIndividualSpecification &spec)
void addSphericalInclusionIndividual(const SphericalInclusionIndividualSpecification &spec)
size_t insertLoopNode(const size_t &loopID, const VectorDimD &loopNodePos, const size_t &networkNodeID, const VectorDimD &loopNodeShift, const std::pair< short int, short int > &periodicEdgeIDs)
void addSphericalInclusionDensity(const SphericalInclusionDensitySpecification &spec)
void addPeriodicDipoleDensity(const PeriodicDipoleDensitySpecification &spec)
void addPlanarLoopIndividual(const PlanarLoopIndividualSpecification &spec)
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)
std::vector< size_t > insertLoopLinks(const size_t &loopID, const std::vector< size_t > &loopNodeIDs)
void addEllipsoidalInclusionIndividual(const EllipsoidalInclusionIndividualSpecification &spec)
std::map< VectorDimD, size_t, CompareVectorsByComponent< double, dim, float > > uniqueNetworkNodeMap
bool allPointsInMesh(const std::vector< VectorDimD > &points)
void addStackingFaultTetrahedraDensity(const StackingFaultTetrahedraDensitySpecification &spec)
DefectiveCrystalBase< 3 > & ddBase
void addCrackMeshIndividual(const CrackMeshIndividualSpecification &spec)
size_t insertLoop(const VectorDimD &b, const VectorDimD &unitNormal, const VectorDimD &P0, const size_t &grainID, const DislocationLoopType &loopType)
DefectiveCrystalConfigIO< 3 > configIO
void addCircularCrackIndividual(const CircularCrackIndividualSpecification &spec)
void addPrismaticLoopDensity(const PrismaticLoopDensitySpecification &spec)
bool insertCrackMesh(const std::vector< VectorDimD > &nodes, const std::vector< VectorDimD > &burgers, const std::vector< VectorDimI > &triangles)
void addStackingFaultTetrahedraIndividual(const StackingFaultTetrahedraIndividualSpecification &spec)
void addFrankLoopsDensity(const FrankLoopsDensitySpecification &spec)
void addEllipsoidalInclusionDensity(const EllipsoidalInclusionDensitySpecification &spec)
void addPolyhedronInclusionIndividual(const PolyhedronInclusionIndividualSpecification &spec)
bool allPointsInGrain(const std::vector< VectorDimD > &points, const int &grainID)
void addPeriodicDipoleIndividual(const PeriodicDipoleIndividualSpecification &spec)
void addShearLoopDensity(const ShearLoopDensitySpecification &spec)
void addShearLoopIndividual(const ShearLoopIndividualSpecification &spec)
size_t insertInclusion(const VectorDimD &pos, const double &R, const Eigen::Matrix< double, dim, dim > &eT, const double &vrc, const int &type)
std::vector< std::pair< std::string, std::string > > readStringVector(const std::string &key)
b
Definition int_R.m:16
static std::string greenBoldColor
static std::string defaultColor
std::shared_ptr< PeriodicPlanePatch< 3 > > periodicPlanePatch() const
static std::string removeSpaces(std::string key)
int k
enum insertvertexresult success
vertex temp