diff --git a/CMakeLists.txt b/CMakeLists.txt index c686513..4e537d5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -135,6 +135,7 @@ add_library(mpskit_common STATIC mpskit/models/spin_half/1d/spin_half_1d.cpp mpskit/models/spin_half/1d/transverse_ising_1d.cpp mpskit/models/spin_half/1d/vitagliano_2010.cpp + mpskit/models/spin_half/1d/xy_inhom.cpp mpskit/models/spin_half/1d/xy_spin_glass_1d.cpp mpskit/models/spin_half/2d/ising_lr_square.cpp mpskit/models/spin_half/2d/spin_half_square.cpp diff --git a/mpskit/models/spin_half/1d/xy_inhom.cpp b/mpskit/models/spin_half/1d/xy_inhom.cpp new file mode 100644 index 0000000..a176e97 --- /dev/null +++ b/mpskit/models/spin_half/1d/xy_inhom.cpp @@ -0,0 +1,87 @@ +#include "xy_inhom.hpp" +#include + +namespace XYInhom +{ +XYInhom::XYInhom(int L, const Real &J0, const CouplingDistribution &coupling_distribution, const Real &hx, + const Real &hy, const Real &hz) + : SpinHalf1D(L, false, false, false), m_J0(J0), m_coupling_distribution(coupling_distribution), m_hx(hx), m_hy(hy), + m_hz(hz) +{ + m_name = "XYInhom"; + if (m_L % 2) + { + throw std::domain_error("L must be even"); + } + + std::function dist; + switch (m_coupling_distribution) + { + case Uniform: + dist = [](int r) { + (void)r; + return 1.0; + }; + break; + case Exponential: + dist = [](int r) { return std::exp(-static_cast(r - 1)); }; + break; + case Gaussian: + dist = [](int r) { return std::exp(-static_cast((r - 1) * (r - 1))); }; + break; + case Logarithmic: + dist = [](int r) { return 1.0 / std::log2(static_cast(r + 1)); }; + break; + default: + throw std::domain_error("invalid coupling distribution"); + break; + } + + for (int i = 0; i < m_L; ++i) + { + for (int j = 0; j < i; ++j) + { + const auto J = m_J0 * dist(std::abs(i - j)); + m_two_body_terms.emplace_back(4.0 * J, "S+", i, "S-", j); + m_two_body_terms.emplace_back(4.0 * J, "S-", i, "S+", j); + } + } + + for (int i = 0; i < m_L; ++i) + { + m_one_body_terms.emplace_back(-2.0 * m_hx, "Sx", i); + m_one_body_terms.emplace_back(-2.0 * m_hy, "Sy", i); + m_one_body_terms.emplace_back(-2.0 * m_hz, "Sz", i); + } +} + +XYInhom::XYInhom(const json &js) + : XYInhom(js.at("L").get(), jsonGetDefault(js, "J0", 1.0), + jsonGetDefault(js, "coupling_distribution", CouplingDistribution::Uniform), + jsonGetDefault(js, "hx", 0.0), jsonGetDefault(js, "hy", 0.0), + jsonGetDefault(js, "hz", 0.0)) +{ +} + +const Real &XYInhom::getJ0() const +{ + return m_J0; +} +const CouplingDistribution &XYInhom::getCouplingDistribution() const +{ + return m_coupling_distribution; +} +const Real &XYInhom::getHx() const +{ + return m_hx; +} +const Real &XYInhom::getHy() const +{ + return m_hy; +} +const Real &XYInhom::getHz() const +{ + return m_hz; +} + +} // namespace XYInhom \ No newline at end of file diff --git a/mpskit/models/spin_half/1d/xy_inhom.hpp b/mpskit/models/spin_half/1d/xy_inhom.hpp new file mode 100644 index 0000000..367ae22 --- /dev/null +++ b/mpskit/models/spin_half/1d/xy_inhom.hpp @@ -0,0 +1,50 @@ +#ifndef MPSKIT_MODELS_SPIN_HALF_1D_XY_INHOM +#define MPSKIT_MODELS_SPIN_HALF_1D_XY_INHOM + +#include "../../../json.hpp" +#include "../../../types.hpp" +#include "spin_half_1d.hpp" + +namespace XYInhom +{ +enum CouplingDistribution : int +{ + Uniform, + Exponential, + Gaussian, + Logarithmic, + Invalid +}; + +NLOHMANN_JSON_SERIALIZE_ENUM(CouplingDistribution, { + {XYInhom::Invalid, nullptr}, + {XYInhom::Uniform, "uniform"}, + {XYInhom::Exponential, "exponential"}, + {XYInhom::Gaussian, "gaussian"}, + {XYInhom::Logarithmic, "logarithmic"}, + }) + +class XYInhom : public SpinHalf1D +{ + private: + Real m_J0; + CouplingDistribution m_coupling_distribution; + Real m_hx; + Real m_hy; + Real m_hz; + + public: + explicit XYInhom(int L, const Real &J0, const CouplingDistribution &coupling_distribution, const Real &hx = 0.0, + const Real &hy = 0.0, const Real &hz = 0.0); + explicit XYInhom(const json &js); + + const Real &getJ0() const; + const CouplingDistribution &getCouplingDistribution() const; + const Real &getHx() const; + const Real &getHy() const; + const Real &getHz() const; +}; + +} // namespace XYInhom + +#endif /* MPSKIT_MODELS_SPIN_HALF_1D_XY_INHOM */