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 / std::numbers::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 "../../include/IO/TextFileParser.h"
#include "../../include/Lattices/BiCrystal.h"
#include "../../include/Lattices/LatticeModule.h"
#include <chrono>
#include <numbers>
using namespace oILAB;
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 / std::numbers::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 MatrixDimI LambdaA
Shift tensor describes the shift in the CSL when lattice is shifted by a DSCL vector.
Definition BiCrystal.h:119
const Lattice< dim > Bp
Lattice with basis .
Definition BiCrystal.h:114
const IntScalarType sigmaA
Signed ratio of the unit cell volume of to that of . .
Definition BiCrystal.h:68
const Lattice< dim > csl
CSL lattice .
Definition BiCrystal.h:102
const Lattice< dim > dscl
DCSL lattice .
Definition BiCrystal.h:106
const IntScalarType sigmaB
Signed ratio of the unit cell volume of to that of : .
Definition BiCrystal.h:73
const Lattice< dim > Ap
Lattice with basis .
Definition BiCrystal.h:110
Lattice class.
Definition Lattice.h:31
const MatrixDimD latticeBasis
Definition Lattice.h:41
LatticeVector class.
VectorDimD cartesian() const
const MatrixType & reducedBasis() const
Definition RLLL.cpp:185
int main(int argc, char **argv)
Definition main.cpp:12
Eigen::Matrix< IntScalarType, dim, 1 > VectorDimI
Definition LatticeCore.h:23
long long int IntScalarType
Definition LatticeCore.h:22