Given a tilt-axis of a 3D lattice, this example demonstrates the construction of multiple tilt GBs of varying misorientations and inclinations, and the calculation of grain boundaries' disconnection modes
#include "../../include/IO/TextFileParser.h"
#include "../../include/Lattices/BiCrystal.h"
#include "../../include/Lattices/LatticeModule.h"
#include <numbers>
const auto A(
TextFileParser(
"bicrystal_3d.txt").readMatrix<double, 3, 3>(
"A",
true));
std::cout << "Lattice A = " << std::endl;
std::cout << lattice.latticeBasis << std::endl;
.readMatrix<double, 3, 1>("axis", true));
lattice.reciprocalLatticeDirection(axis).reciprocalLatticeVector());
std::cout << "Cartesian coordinates of axis = " << std::endl;
std::cout << rv.
cartesian().transpose() << std::endl;
const auto &coincidentLattices =
lattice.generateCoincidentLattices(rv, 150, 150);
for (const auto &rotation : coincidentLattices) {
std::cout << "###################################################"
<< std::endl;
try {
double theta =
acos((rotation.trace() - 1.0) / 2.0) * 180 / std::numbers::pi;
std::cout << "Misorientation angle = " << std::setprecision(20) << theta
<< "; ";
Lattice<3> latticeB(lattice.latticeBasis, rotation);
std::cout <<
"Sigma = " << std::setprecision(20) << bc.
sigma << std::endl;
std::cout << std::endl;
std::cout << "Lattice B = " << std::endl;
std::cout << std::setprecision(20) << rotation * lattice.latticeBasis
<< std::endl;
std::cout << std::endl;
std::cout << "Parallel CSL basis Cp= " << std::endl;
std::cout << std::setprecision(20) << bc.
csl.latticeBasis << std::endl;
std::cout << std::endl;
std::cout << "Parallel DSCL basis Dp = " << std::endl;
std::cout << std::setprecision(20) << bc.
dscl.latticeBasis << std::endl;
std::cout << std::endl;
auto reducedDsclBasis =
RLLL(bc.
dscl.latticeBasis, 0.75);
auto U_Dscl = reducedDsclBasis.unimodularMatrix();
d1 << U_Dscl.col(0).template cast<IntScalarType>();
std::cout << "Reduced DSCL basis vectors:" << std::endl;
std::cout << "d1 = ";
std::cout << std::setprecision(20) << d1.
cartesian().transpose()
<< std::endl;
std::cout << "Integer coordinates of d1:";
std::cout << std::setprecision(20) << d1.transpose() << std::endl;
std::cout << std::endl;
d2 << U_Dscl.col(1).template cast<IntScalarType>();
std::cout << "d2 = ";
std::cout << std::setprecision(20) << d2.
cartesian().transpose()
<< std::endl;
std::cout << "Integer coordinates of d2:";
std::cout << std::setprecision(20) << d2.transpose() << std::endl;
std::cout << std::endl;
d3 << U_Dscl.col(2).template cast<IntScalarType>();
std::cout << "d3 = ";
std::cout << std::setprecision(20) << d3.
cartesian().transpose()
<< std::endl;
std::cout << "Integer coordinates of d3:";
std::cout << std::setprecision(20) << d3.transpose() << std::endl;
std::cout << std::endl;
std::cout << "Reduced shift vectors: " << std::endl;
Eigen::Vector3d s1_coordinates_in_reduced_csl =
Eigen::Vector3d s2_coordinates_in_reduced_csl =
Eigen::Vector3d s3_coordinates_in_reduced_csl =
Eigen::Vector3d s1_coordinates_modulo =
s1_coordinates_in_reduced_csl.array() -
s1_coordinates_in_reduced_csl.array().round();
Eigen::Vector3d s2_coordinates_modulo =
s2_coordinates_in_reduced_csl.array() -
s2_coordinates_in_reduced_csl.array().round();
Eigen::Vector3d s3_coordinates_modulo =
s3_coordinates_in_reduced_csl.array() -
s3_coordinates_in_reduced_csl.array().round();
std::cout << "s1 = ";
std::cout << std::setprecision(20)
<< (reducedCsl.
latticeBasis * s1_coordinates_modulo).transpose()
<< std::endl;
std::cout << "s2 = ";
std::cout << std::setprecision(20)
<< (reducedCsl.
latticeBasis * s2_coordinates_modulo).transpose()
<< std::endl;
std::cout << "s3 = ";
std::cout << std::setprecision(20)
<< (reducedCsl.
latticeBasis * s3_coordinates_modulo).transpose()
<< std::endl;
std::cout << std::endl;
int gbCount = 0;
std::cout << "GBs of varying inclination (measured with respect to the "
"first grain boundary)"
<< std::endl;
std::cout << "-----------------------------------------------------------"
"------------------"
<< std::endl;
std::cout << "-- CAUTION: The integer coordinates of GB normals are "
"w.r.t the reciprocal --"
<< std::endl;
std::cout << "-- basis of the primitive unit cell. "
" --"
<< std::endl;
std::cout << "-----------------------------------------------------------"
"------------------"
<< std::endl;
for (const auto &gb : gbSet) {
try {
rv.
cross(gb.second.nA.reciprocalLatticeVector()).latticeVector());
gb.second.nA.reciprocalLatticeVector();
.reciprocalLatticeVector();
if (gbCount == 0)
refnA = gb.second.nA.reciprocalLatticeVector();
double epsilon = 1e-8;
if (gbCount == 0 || periodVector.
cartesian().norm() < 100) {
double cosAngle = refnA.
cartesian().normalized().dot(
gb.second.nA.cartesian().normalized());
if (cosAngle - 1 > -epsilon)
cosAngle = 1.0;
if (cosAngle + 1 < epsilon)
cosAngle = -1.0;
std::cout << gbCount + 1
<< ") Inclination = " << std::setprecision(20)
<< acos(cosAngle) * 180 / std::numbers::pi << std::endl;
Eigen::Vector3d nAglobalCoords = gb.second.nA.cartesian();
Eigen::Vector3d nBglobalCoords =
rotation.transpose() * gb.second.nB.cartesian();
std::cout << "nA = " << std::setprecision(20)
<< nAglobalCoords.transpose() << std::endl;
std::cout << "nB = " << std::setprecision(20)
<< nBglobalCoords.transpose() << std::endl;
nAglobalCoords = nAglobalCoords.array().round().cwiseAbs();
nBglobalCoords = nBglobalCoords.array().round().cwiseAbs();
std::sort(nAglobalCoords.data(), nAglobalCoords.data() + 3);
std::sort(nBglobalCoords.data(), nBglobalCoords.data() + 3);
if ((nAglobalCoords - nBglobalCoords).norm() < FLT_EPSILON)
std::cout << "STGB" << std::endl;
std::cout << "GB period = " << std::setprecision(20)
<< periodVector.
cartesian().norm() << std::endl;
std::cout << "CSL plane distance (Height)= "
<< std::setprecision(20)
<< 1.0 / rvInCsl.
cartesian().norm() << std::endl;
std::cout << "Glide disconnection Burgers vector = "
<< std::setprecision(20)
<<
"; norm = " << burgersVector.
cartesian().norm()
<< std::endl;
std::cout << "Step height of glide disconnection = "
<< std::setprecision(20)
<< gb.second.stepHeight(burgersVector) << std::endl;
std::cout << "Step height of disconnection with Burgers vector d1= "
<< std::setprecision(20) << gb.second.stepHeight(d1)
<< std::endl;
std::cout << "Step height of disconnection with Burgers vector d2= "
<< std::setprecision(20) << gb.second.stepHeight(d2)
<< std::endl;
std::cout << "Step height of disconnection with Burgers vector d3= "
<< std::setprecision(20) << gb.second.stepHeight(d3)
<< std::endl;
std::cout << "-----------------------------------------------------"
"------------------------"
<< std::endl;
gbCount++;
}
} catch (std::runtime_error &e) {
std::cout << e.what() << std::endl;
std::cout << "Moving onto the next inclination" << std::endl;
}
}
} catch (std::runtime_error &e) {
std::cout << e.what() << std::endl;
std::cout << "Moving on the the next misorientation" << std::endl;
}
}
return 0;
}
std::enable_if< dm==2||dm==3, std::map< IntScalarType, Gb< dm > > >::type generateGrainBoundaries(const LatticeDirection< dim > &d, int div=30) const
Given a tilt axis , that belongs to lattices or , this function generate a set of tilt GBs....
const MatrixDimI LambdaA
Shift tensor describes the shift in the CSL when lattice is shifted by a DSCL vector.
LatticeDirection< dim > getLatticeDirectionInD(const LatticeVector< dim > &v) const
LatticeDirection< dim > getLatticeDirectionInC(const LatticeVector< dim > &v) const
const Lattice< dim > csl
CSL lattice .
ReciprocalLatticeDirection< dim > getReciprocalLatticeDirectionInC(const ReciprocalLatticeVector< dim > &v) const
const Lattice< dim > dscl
DCSL lattice .
const MatrixDimD latticeBasis
VectorDimD cartesian() const
const MatrixType & reducedBasis() const
VectorDimD cartesian() const
std::enable_if< dm==2, LatticeDirection< dim > >::type cross(const ReciprocalLatticeVector< dim > &other) const
int main(int argc, char **argv)
Eigen::Matrix< IntScalarType, dim, 1 > VectorDimI
long long int IntScalarType