oILAB
Loading...
Searching...
No Matches
testMoire.cpp

This example demonstrates the generation of strained moire superlattices from a 2D homostructure and calculation of the translational invariance of a moire

  1. Define types
    using VectorDimI = LatticeCore<2>::VectorDimI;
    using IntScalarType = LatticeCore<2>::IntScalarType;
  2. Instantiate a lattice \(\mathcal A\)
    const auto A(TextFileParser("bicrystal_2d.txt").readMatrix<double,2,2>("A",true));
    Lattice<2> lattice(A);
  3. Generate deformation gradients \(\mathbf F\) (with Lagrangian strain < 0.01) , such that lattices \(\mathcal A\) and \(\mathbf F\mathcal A\) form a moire superlattice
    //const auto& coincidentLattices= lattice.generateCoincidentLattices(1e-3,10,15);
    const auto& coincidentLattices= lattice.generateCoincidentLattices(1e-2,30,15);
  4. Loop over the deformations to form 2D homostructures, \(\mathcal A \cup \mathbf F\mathcal A\), and carry out SNF bicrystallography
    for (const auto& deformationGradient : coincidentLattices)
    {
    try
    {
    BiCrystal<2> bc(lattice,Lattice<2>(lattice.latticeBasis,deformationGradient),false);
    if (abs(bc.sigmaA) > 60000 || abs(bc.sigmaB) > 60000)
    continue;
    std::cout << std::endl;
    std::cout << "--------------------------------- SNF -------------------------------------" << std::endl;
    std::cout << "sigmaA = " << bc.sigmaA << "; sigmaB = " << bc.sigmaB << std::endl;
    std::cout << "Ap= " << std::endl;
    std::cout << std::setprecision(12) << bc.Ap.latticeBasis << std::endl;
    std::cout << "Bp= " << std::endl;
    std::cout << std::setprecision(12) << bc.Bp.latticeBasis << std::endl;
    std::cout << "CSL= " << std::endl;
    std::cout << std::setprecision(12) << bc.csl.latticeBasis << std::endl;
    std::cout << "DCSL= " << std::endl;
    std::cout << std::setprecision(12) << bc.dscl.latticeBasis << std::endl;
    std::cout << endl;
  5. Output the heterodeformation, its polar decomposition, and the corresponding elastic strain
    std::cout << "------Hetero-deformation -------" << std::endl;
    Eigen::Matrix2d F= deformationGradient;
    std::cout << "Deformation gradient, F=" << std::endl;
    std::cout << std::setprecision(12) << F << std::endl;
    Eigen::Matrix2d C= F.transpose()*F;
    Eigen::Matrix2d E= (C-Eigen::Matrix2d::Identity())/2.0;
    std::cout << endl;
    std::cout << "Polar decomposition of F:" << std::endl;
    double s= sqrt(C(0,0)*C(1,1)-pow(C(0,1),2));
    double t= sqrt(C(0,0)+C(1,1)+2*s);
    Eigen::Matrix2d U= (C+s*Eigen::Matrix2d::Identity())/t;
    Eigen::Matrix2d R= F*U.inverse();
    std::cout << "R(" << std::setprecision(12) << atan2(R(1,0),R(0,0))*180/M_PI << ")= " << std::endl;
    std::cout << R << std::endl;
    std::cout << "U= " << std::endl;
    std::cout << std::setprecision(12) << U << std::endl;
    std::cout << endl;
    std::cout << "Elastic strain:" << std::endl;
    std::cout << std::setprecision(12) << E << std::endl;
    std::cout << endl;
  6. Output the invariance property of the moire in the following steps: 1) compute reduced basis vectors \(\mathbf d_1\) and \(\mathbf d_2\) for the DSCL, 2) compute the moire shifts \(\mathbf s_1\) and \(\mathbf s_2\) when lattice \(\mathcal A\) is displaced by \(\mathbf d_1\) and \(\mathbf d_2\), respectively.
    std::cout << "------Invariance of the moire -------" << std::endl;
    auto reducedDsclBasis= RLLL(bc.dscl.latticeBasis,0.75);
    auto U_Dscl= reducedDsclBasis.unimodularMatrix();
    std::cout << "Reduced DSCL basis vectors:" << std::endl;
    std::cout << "d1 = ";
    std::cout << std::setprecision(20) << reducedDsclBasis.reducedBasis().col(0).transpose() << std::endl;
    std::cout << "Integer coordinates of d1:";
    LatticeVector<2> d1(bc.dscl);
    d1 << U_Dscl.col(0).template cast<IntScalarType>();
    std::cout << std::setprecision(20) << d1.transpose() << std::endl;
    std::cout << std::endl;
    LatticeVector<2> d2(bc.dscl);
    std::cout << "d2 = ";
    std::cout << std::setprecision(20) << reducedDsclBasis.reducedBasis().col(1).transpose() << std::endl;
    std::cout << "Integer coordinates of d2:";
    d2 << U_Dscl.col(1).template cast<IntScalarType>();
    std::cout << std::setprecision(20) << d2.transpose() << std::endl;
    std::cout << std::endl;
    // shift vectors corresponding to d1 and d2
    LatticeVector<2> s1(bc.dscl), s2(bc.dscl);
    s1 << bc.LambdaA * d1;
    s2 << bc.LambdaA * d2;
    Lattice<2> reducedCsl(RLLL(bc.csl.latticeBasis,0.75).reducedBasis());
    std::cout << "Reduced shift vectors: " << std::endl;
    Eigen::Vector2d s1_coordinates_in_reduced_csl= reducedCsl.latticeBasis.inverse()*s1.cartesian();
    Eigen::Vector2d s2_coordinates_in_reduced_csl= reducedCsl.latticeBasis.inverse()*s2.cartesian();
    Eigen::Vector2d s1_coordinates_modulo= s1_coordinates_in_reduced_csl.array()-s1_coordinates_in_reduced_csl.array().round();
    Eigen::Vector2d s2_coordinates_modulo= s2_coordinates_in_reduced_csl.array()-s2_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 << "---------------------------------------------------------------------------" << std::endl;
    Full code:
#include <LatticeModule.h>
#include <TextFileParser.h>
#include <BiCrystal.h>
#include <chrono>
using namespace gbLAB;
int main()
{
auto start = std::chrono::system_clock::now();
std::time_t startTime = std::chrono::system_clock::to_time_t(start);
std::cout << "Time stamp: " << std::ctime(&startTime) << std::endl;
using VectorDimI = LatticeCore<2>::VectorDimI;
using IntScalarType = LatticeCore<2>::IntScalarType;
const auto A(TextFileParser("bicrystal_2d.txt").readMatrix<double,2,2>("A",true));
Lattice<2> lattice(A);
//const auto& coincidentLattices= lattice.generateCoincidentLattices(1e-3,10,15);
const auto& coincidentLattices= lattice.generateCoincidentLattices(1e-2,30,15);
for (const auto& deformationGradient : coincidentLattices)
{
try
{
BiCrystal<2> bc(lattice,Lattice<2>(lattice.latticeBasis,deformationGradient),false);
if (abs(bc.sigmaA) > 60000 || abs(bc.sigmaB) > 60000)
continue;
std::cout << std::endl;
std::cout << "--------------------------------- SNF -------------------------------------" << std::endl;
std::cout << "sigmaA = " << bc.sigmaA << "; sigmaB = " << bc.sigmaB << std::endl;
std::cout << "Ap= " << std::endl;
std::cout << std::setprecision(12) << bc.Ap.latticeBasis << std::endl;
std::cout << "Bp= " << std::endl;
std::cout << std::setprecision(12) << bc.Bp.latticeBasis << std::endl;
std::cout << "CSL= " << std::endl;
std::cout << std::setprecision(12) << bc.csl.latticeBasis << std::endl;
std::cout << "DCSL= " << std::endl;
std::cout << std::setprecision(12) << bc.dscl.latticeBasis << std::endl;
std::cout << endl;
std::cout << "------Hetero-deformation -------" << std::endl;
Eigen::Matrix2d F= deformationGradient;
std::cout << "Deformation gradient, F=" << std::endl;
std::cout << std::setprecision(12) << F << std::endl;
Eigen::Matrix2d C= F.transpose()*F;
Eigen::Matrix2d E= (C-Eigen::Matrix2d::Identity())/2.0;
std::cout << endl;
std::cout << "Polar decomposition of F:" << std::endl;
double s= sqrt(C(0,0)*C(1,1)-pow(C(0,1),2));
double t= sqrt(C(0,0)+C(1,1)+2*s);
Eigen::Matrix2d U= (C+s*Eigen::Matrix2d::Identity())/t;
Eigen::Matrix2d R= F*U.inverse();
std::cout << "R(" << std::setprecision(12) << atan2(R(1,0),R(0,0))*180/M_PI << ")= " << std::endl;
std::cout << R << std::endl;
std::cout << "U= " << std::endl;
std::cout << std::setprecision(12) << U << std::endl;
std::cout << endl;
std::cout << "Elastic strain:" << std::endl;
std::cout << std::setprecision(12) << E << std::endl;
std::cout << endl;
std::cout << "------Invariance of the moire -------" << std::endl;
auto reducedDsclBasis= RLLL(bc.dscl.latticeBasis,0.75);
auto U_Dscl= reducedDsclBasis.unimodularMatrix();
std::cout << "Reduced DSCL basis vectors:" << std::endl;
std::cout << "d1 = ";
std::cout << std::setprecision(20) << reducedDsclBasis.reducedBasis().col(0).transpose() << std::endl;
std::cout << "Integer coordinates of d1:";
d1 << U_Dscl.col(0).template cast<IntScalarType>();
std::cout << std::setprecision(20) << d1.transpose() << std::endl;
std::cout << std::endl;
std::cout << "d2 = ";
std::cout << std::setprecision(20) << reducedDsclBasis.reducedBasis().col(1).transpose() << std::endl;
std::cout << "Integer coordinates of d2:";
d2 << U_Dscl.col(1).template cast<IntScalarType>();
std::cout << std::setprecision(20) << d2.transpose() << std::endl;
std::cout << std::endl;
// shift vectors corresponding to d1 and d2
LatticeVector<2> s1(bc.dscl), s2(bc.dscl);
s1 << bc.LambdaA * d1;
s2 << bc.LambdaA * d2;
Lattice<2> reducedCsl(RLLL(bc.csl.latticeBasis,0.75).reducedBasis());
std::cout << "Reduced shift vectors: " << std::endl;
Eigen::Vector2d s1_coordinates_in_reduced_csl= reducedCsl.latticeBasis.inverse()*s1.cartesian();
Eigen::Vector2d s2_coordinates_in_reduced_csl= reducedCsl.latticeBasis.inverse()*s2.cartesian();
Eigen::Vector2d s1_coordinates_modulo= s1_coordinates_in_reduced_csl.array()-s1_coordinates_in_reduced_csl.array().round();
Eigen::Vector2d s2_coordinates_modulo= s2_coordinates_in_reduced_csl.array()-s2_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 << "---------------------------------------------------------------------------" << std::endl;
}
catch(std::runtime_error& e)
{
std::cout << e.what() << "Moving on ..." << std::endl;
}
}
auto end= std::chrono::system_clock::now();
std::time_t endTime= std::chrono::system_clock::to_time_t(end);
std::chrono::duration<double> elapsedSeconds(end-start);
std::cout << "Elapsed time: " << elapsedSeconds.count() << " seconds" << std::endl;
std::cout << "End of simulation" << std::endl;
return 0;
}
const IntScalarType sigmaB
Signed ratio of the unit cell volume of to that of : .
Definition BiCrystal.h:77
const Lattice< dim > dscl
DCSL lattice .
Definition BiCrystal.h:90
const IntScalarType sigmaA
Signed ratio of the unit cell volume of to that of . .
Definition BiCrystal.h:72
const Lattice< dim > Ap
Lattice with basis .
Definition BiCrystal.h:94
const Lattice< dim > csl
CSL lattice .
Definition BiCrystal.h:86
const Lattice< dim > Bp
Lattice with basis .
Definition BiCrystal.h:98
const MatrixDimI LambdaA
Shift tensor describes the shift in the CSL when lattice is shifted by a DSCL vector.
Definition BiCrystal.h:103
Lattice class.
Definition Lattice.h:34
const MatrixDimD latticeBasis
Definition Lattice.h:46
LatticeVector class.
VectorDimD cartesian() const
const MatrixType & reducedBasis() const
Definition RLLL.cpp:192
int main(int argc, char **argv)
Definition main.cpp:11
long long int IntScalarType
Definition LatticeCore.h:26
Eigen::Matrix< IntScalarType, dim, 1 > VectorDimI
Definition LatticeCore.h:27