Skip to content

Commit 5456ce4

Browse files
authored
Merge branch 'develop' into 2026-07-30-c
2 parents d8064f8 + d6ed1fc commit 5456ce4

104 files changed

Lines changed: 2795 additions & 781 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

Dockerfile.cuda

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,13 @@ RUN cd /tmp && \
2424
ln -s /usr/local/include/elpa_openmp-$ELPA_VER/elpa /usr/local/include/ && \
2525
cd /tmp && rm -rf elpa-$ELPA_VER
2626

27+
# RapidJSON
28+
RUN cd /tmp && wget --quiet https://codeload.github.com/Tencent/rapidjson/tar.gz/24b5e7a -O rapidjson-24b5e7a.tar.gz
29+
RUN tar -xzf rapidjson-24b5e7a.tar.gz && cd rapidjson-24b5e7a
30+
RUN cmake -B build -DRAPIDJSON_BUILD_DOC=OFF -DRAPIDJSON_BUILD_EXAMPLES=OFF -DRAPIDJSON_BUILD_TESTS=OFF
31+
RUN cmake --build build --target install
32+
RUN cd /tmp && rm -r rapidjson-24b5e7a
33+
2734
ADD https://api.github.com/repos/deepmodeling/abacus-develop/git/refs/heads/develop /dev/null
2835

2936
RUN git clone https://github.com/deepmodeling/abacus-develop.git --depth 1 && \

Dockerfile.gnu

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,13 @@ RUN wget https://download.pytorch.org/libtorch/cpu/libtorch-cxx11-abi-shared-wit
2626
--no-check-certificate --quiet -O libtorch.zip && \
2727
unzip -q libtorch.zip -d /opt && rm libtorch.zip
2828

29+
# RapidJSON
30+
RUN cd /tmp && wget --quiet https://codeload.github.com/Tencent/rapidjson/tar.gz/24b5e7a -O rapidjson-24b5e7a.tar.gz
31+
RUN tar -xzf rapidjson-24b5e7a.tar.gz && cd rapidjson-24b5e7a
32+
RUN cmake -B build -DRAPIDJSON_BUILD_DOC=OFF -DRAPIDJSON_BUILD_EXAMPLES=OFF -DRAPIDJSON_BUILD_TESTS=OFF
33+
RUN cmake --build build --target install
34+
RUN cd /tmp && rm -r rapidjson-24b5e7a
35+
2936
ENV CMAKE_PREFIX_PATH=/opt/libtorch/share/cmake
3037

3138
ADD https://api.github.com/repos/deepmodeling/abacus-develop/git/refs/heads/develop /dev/null

Dockerfile.intel

Lines changed: 10 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,63 +1,12 @@
1-
FROM ubuntu:22.04
1+
FROM intel/oneapi-hpckit:2025.2.2-0-devel-ubuntu22.04
22

33
RUN apt-get update && apt-get install -y \
44
bc cmake git gnupg gcc g++ python3-numpy sudo wget vim unzip \
55
libcereal-dev libxc-dev libgtest-dev libgmock-dev libbenchmark-dev \
66
pkg-config build-essential autoconf automake libtool
77

8-
# Following steps by https://software.intel.com/content/www/us/en/develop/documentation/installation-guide-for-intel-oneapi-toolkits-linux/top/installation/install-using-package-managers/apt.html .
9-
RUN wget -O- https://apt.repos.intel.com/intel-gpg-keys/GPG-PUB-KEY-INTEL-SW-PRODUCTS.PUB \
10-
| gpg --dearmor | sudo tee /usr/share/keyrings/oneapi-archive-keyring.gpg > /dev/null && \
11-
echo "deb [signed-by=/usr/share/keyrings/oneapi-archive-keyring.gpg] https://apt.repos.intel.com/oneapi all main" \
12-
| sudo tee /etc/apt/sources.list.d/oneAPI.list
13-
14-
# To save disk space, only install the essential components, but not the whole toolkit.
15-
RUN apt-get update && \
16-
apt-get install -y \
17-
intel-oneapi-compiler-dpcpp-cpp \
18-
intel-oneapi-compiler-fortran \
19-
intel-oneapi-mkl-devel \
20-
intel-oneapi-mkl-sycl-devel \
21-
intel-oneapi-mkl-sycl-distributed-dft-devel \
22-
intel-oneapi-mpi-devel \
23-
intel-oneapi-vtune && \
24-
apt-get clean && \
25-
rm -rf /var/lib/apt/lists/*
26-
27-
RUN ls -la /opt/intel/oneapi/mkl/latest/lib/intel64/*sycl*dft*
28-
RUN ls -la /opt/intel/oneapi/mkl/latest/lib/intel64/*dis*
29-
30-
# Set oneAPI environment variables
31-
ENV ONEAPI_ROOT=/opt/intel/oneapi
32-
ENV I_MPI_ROOT=${ONEAPI_ROOT}/mpi/latest
33-
ENV MKLROOT=${ONEAPI_ROOT}/mkl/latest
34-
ENV CMPLR_ROOT=${ONEAPI_ROOT}/compiler/latest
35-
36-
# Set library paths and include paths
37-
ENV LIBRARY_PATH=${ONEAPI_ROOT}/tbb/latest/lib/intel64/gcc4.8:${ONEAPI_ROOT}/mpi/latest/lib:${MKLROOT}/lib/intel64:${ONEAPI_ROOT}/compiler/latest/lib/:${LIBRARY_PATH}
38-
ENV LD_LIBRARY_PATH=${ONEAPI_ROOT}/tbb/latest/lib/intel64/gcc4.8:${ONEAPI_ROOT}/mpi/latest/lib:${MKLROOT}/lib/intel64:${ONEAPI_ROOT}/compiler/latest/lib/:${LD_LIBRARY_PATH}
39-
ENV PATH=${ONEAPI_ROOT}/vtune/latest/bin64:${ONEAPI_ROOT}/mpi/latest/bin:${MKLROOT}/bin/intel64:${ONEAPI_ROOT}/compiler/latest/bin:${PATH}
40-
ENV CPATH=${MKLROOT}/include:${ONEAPI_ROOT}/mpi/latest/include:${CPATH}
41-
ENV PKG_CONFIG_PATH=${MKLROOT}/lib/pkgconfig:${ONEAPI_ROOT}/mpi/latest/lib/pkgconfig:${PKG_CONFIG_PATH}
42-
43-
# Set CMAKE related paths
44-
ENV CMAKE_PREFIX_PATH=${ONEAPI_ROOT}/tbb/latest:${MKLROOT}/lib/cmake:${ONEAPI_ROOT}/dpl/latest/lib/cmake:${ONEAPI_ROOT}/dnnl/latest/lib/cmake:${ONEAPI_ROOT}/dal/latest:${ONEAPI_ROOT}/compiler/latest:${CMAKE_PREFIX_PATH}
45-
46-
SHELL ["/bin/bash", "-c"]
47-
ENV CC=mpiicx CXX=mpiicpx FC=mpiifx
48-
49-
# Verify oneAPI installation
50-
RUN source ${ONEAPI_ROOT}/setvars.sh && \
51-
echo "=== Verify compiler ===" && \
52-
which mpiicx && mpiicx --version && \
53-
echo "=== Verify MKL ===" && \
54-
ls ${MKLROOT}/lib/intel64/ && \
55-
echo "=== Verify MPI ===" && \
56-
which mpirun && mpirun --version
57-
588
# https://elpa.mpcdf.mpg.de/software/tarball-archive/ELPA_TARBALL_ARCHIVE.html
59-
RUN source /opt/intel/oneapi/setvars.sh && \
60-
cd /tmp && \
9+
RUN cd /tmp && \
6110
ELPA_VER=2022.11.001 && \
6211
wget -q https://elpa.mpcdf.mpg.de/software/tarball-archive/Releases/$ELPA_VER/elpa-$ELPA_VER.tar.gz && \
6312
tar xzf elpa-$ELPA_VER.tar.gz && rm elpa-$ELPA_VER.tar.gz && \
@@ -68,8 +17,14 @@ RUN source /opt/intel/oneapi/setvars.sh && \
6817
ln -s /usr/local/include/elpa_openmp-$ELPA_VER/elpa /usr/local/include/ && \
6918
cd /tmp && rm -rf elpa-$ELPA_VER
7019

71-
# rapidjson and libtorch
72-
RUN cd /tmp && git clone --depth 1 https://github.com/Tencent/rapidjson.git && cp -r rapidjson/include/rapidjson /usr/include/ && rm -rf rapidjson
20+
# RapidJSON
21+
RUN cd /tmp && wget --quiet https://codeload.github.com/Tencent/rapidjson/tar.gz/24b5e7a -O rapidjson-24b5e7a.tar.gz
22+
RUN tar -xzf rapidjson-24b5e7a.tar.gz && cd rapidjson-24b5e7a
23+
RUN cmake -B build -DRAPIDJSON_BUILD_DOC=OFF -DRAPIDJSON_BUILD_EXAMPLES=OFF -DRAPIDJSON_BUILD_TESTS=OFF
24+
RUN cmake --build build --target install
25+
RUN cd /tmp && rm -r rapidjson-24b5e7a
26+
27+
# LibTorch (Note: Using pre-built Torch library with MKL might cause issues)
7328
RUN wget -q https://download.pytorch.org/libtorch/cpu/libtorch-cxx11-abi-shared-with-deps-2.0.0%2Bcpu.zip -O /tmp/libtorch.zip && \
7429
unzip -q /tmp/libtorch.zip -d /opt && rm -f /tmp/libtorch.zip
7530
ENV CMAKE_PREFIX_PATH=/opt/libtorch/share/cmake:${CMAKE_PREFIX_PATH}

docs/advanced/input_files/input-main.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -614,7 +614,7 @@
614614
- **Description**: Takes value 1, 0 or -1.
615615
- -1: No symmetry will be considered. It is recommended to set -1 for non-colinear + soc calculations, where time reversal symmetry is broken sometimes.
616616
- 0: Only time reversal symmetry would be considered in symmetry operations, which implied k point and -k point would be treated as a single k point with twice the weight.
617-
- 1: Symmetry analysis will be performed to determine the type of Bravais lattice and associated symmetry operations. (point groups, space groups, primitive cells, and irreducible k-points)
617+
- 1: Symmetry analysis will be performed to determine the type of Bravais lattice and associated symmetry operations (point groups, space groups, primitive cells, and irreducible k-points). For a magnetic system, the symmetry of the initial magnetic structure will be analyzed and preserved.
618618

619619
> Note: When symmetry is enabled (value 1), k-points are reduced to the irreducible Brillouin zone (IBZ). For explicit k-point lists with custom weights (see KPT file), the custom weights are preserved during symmetry reduction. For Monkhorst-Pack grids, uniform weights are used.
620620
- **Default**: default

docs/parameters.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ parameters:
6363
Takes value 1, 0 or -1.
6464
* -1: No symmetry will be considered. It is recommended to set -1 for non-colinear + soc calculations, where time reversal symmetry is broken sometimes.
6565
* 0: Only time reversal symmetry would be considered in symmetry operations, which implied k point and -k point would be treated as a single k point with twice the weight.
66-
* 1: Symmetry analysis will be performed to determine the type of Bravais lattice and associated symmetry operations. (point groups, space groups, primitive cells, and irreducible k-points)
66+
* 1: Symmetry analysis will be performed to determine the type of Bravais lattice and associated symmetry operations (point groups, space groups, primitive cells, and irreducible k-points). For a magnetic system, the symmetry of the initial magnetic structure will be analyzed and preserved.
6767
6868
[NOTE] When symmetry is enabled (value 1), k-points are reduced to the irreducible Brillouin zone (IBZ). For explicit k-point lists with custom weights (see KPT file), the custom weights are preserved during symmetry reduction. For Monkhorst-Pack grids, uniform weights are used.
6969
default_value: default

python/pyabacus/src/ModuleDriver/py_driver.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -428,7 +428,8 @@ CalculationResult PyDriver::run(
428428
impl_->ucell_->setup_cell(PARAM.globalv.global_in_stru, GlobalV::ofs_running, PARAM.inp.symmetry_prec, PARAM.inp.dfthalf_type, PARAM.inp.pseudo_dir, PARAM.inp.nspin,
429429
PARAM.inp.basis_type, PARAM.inp.orbital_dir, PARAM.inp.init_wfc,
430430
PARAM.inp.onsite_radius, PARAM.globalv.deepks_setorb, PARAM.inp.rpa,
431-
PARAM.inp.fixed_atoms, PARAM.inp.noncolin, PARAM.inp.calculation, PARAM.inp.esolver_type);
431+
PARAM.inp.fixed_atoms, PARAM.inp.noncolin, PARAM.inp.calculation, PARAM.inp.esolver_type,
432+
std::stoi(PARAM.inp.symmetry));
432433

433434
// Check atomic structure
434435
unitcell::check_atomic_stru(*impl_->ucell_, PARAM.inp.min_dist_coef);

source/source_cell/k_vector_utils.cpp

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -539,7 +539,23 @@ void kvec_ibz_kpoint(K_Vectors& kv,
539539
kgmatrix[i] = symm.kgmatrix[i];
540540
}
541541

542-
if (!include_inv)
542+
if (symm.magnetic_nspin4)
543+
{
544+
// (nspin=4, magnetic) Time reversal Theta reverses the magnetization, so Theta alone is
545+
// NOT a symmetry and the blanket "-k is always equivalent" doubling below is invalid.
546+
// Only the antiunitary elements Theta*g with g in the moment-reversing coset belong to
547+
// the Shubnikov group; append exactly those, keeping the index convention
548+
// j + nrotk <-> Theta * gmatrix_anti[j] (decoded the same way in restore_dm).
549+
// (nspin=2 is unaffected: there the antiunitary operation is plain conjugation K, which
550+
// does not touch the spin, so D_s(-k)=D_s^*(k) holds even for a ferromagnet and the
551+
// generic branch below stays correct.)
552+
for (int j = 0; j < symm.nrotk_anti; ++j)
553+
{
554+
kgmatrix[j + symm.nrotk] = inv * symm.kgmatrix_anti[j];
555+
}
556+
nrotkm = symm.nrotk + symm.nrotk_anti;
557+
}
558+
else if (!include_inv)
543559
{
544560
for (int i = 0; i < symm.nrotk; ++i)
545561
{

source/source_cell/module_symmetry/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ add_library(
1212
symm_pricell.cpp
1313
symm_rho.cpp
1414
symmetry.cpp
15+
symmetry_rotation_spin.cpp
1516
)
1617

1718
if(ENABLE_COVERAGE)

source/source_cell/module_symmetry/symm_analysis.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,13 @@ void Symmetry::analy_sys(const Lattice& lat, const Statistics& st, Atom* atoms,
290290

291291
this->set_atom_map(atoms); // find the atom mapping according to the symmetry operations
292292

293+
// (nspin=4 / SOC) restrict to the unitary magnetic subgroup: drop operations that reverse
294+
// the magnetization (pseudovector), so they are not applied in k-reduction / density symmetrization.
295+
if (nspin == 4)
296+
{
297+
this->analyze_magnetic_group_nspin4(atoms, st, latvec1);
298+
}
299+
293300
// Do this here for debug
294301
if (calculation == "relax")
295302
{

source/source_cell/module_symmetry/symm_magnetic.cpp

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
#include "symmetry.h"
22
using namespace ModuleSymmetry;
33

4+
#include "symmetry_rotation_spin.h"
5+
#include "source_io/module_parameter/parameter.h"
6+
47
#include <set>
8+
#include <vector>
59

610
void Symmetry::analyze_magnetic_group(const Atom* atoms, const Statistics& st, int& nrot_out, int& nrotk_out)
711
{
@@ -74,6 +78,116 @@ void Symmetry::analyze_magnetic_group(const Atom* atoms, const Statistics& st, i
7478

7579
}
7680

81+
void Symmetry::analyze_magnetic_group_nspin4(const Atom* atoms, const Statistics& st, const ModuleBase::Matrix3& latvec)
82+
{
83+
// Restrict the space group to the unitary magnetic subgroup (nspin=4 / SOC):
84+
// operation g survives if it preserves the magnetic configuration as a pseudovector,
85+
// i.e. W(g) m_i = m_{g(i)} for every atom, with W(g) = spin_so3(gmatc).
86+
// Operations that reverse the moment (only symmetries together with time reversal) are dropped,
87+
// so they are no longer applied in k-reduction or density symmetrization.
88+
// Non-magnetic (m_i=0) keeps every operation.
89+
const ModuleBase::Matrix3 ilatvec = latvec.Inverse();
90+
std::vector<int> keep;
91+
keep.reserve(this->nrotk);
92+
int nrot_new = 0;
93+
94+
// Is the configuration actually magnetic? For m_i = 0 every operation both "preserves" and
95+
// "reverses" the moment, so the antiunitary coset is meaningless there:
96+
// Theta (TRS) itself is a symmetry and the grey group is handled by the usual -k shortcut in the k-reduction).
97+
bool has_moment = false;
98+
for (int iat = 0; iat < this->nat && !has_moment; ++iat)
99+
{
100+
const ModuleBase::Vector3<double>& m = atoms[st.iat2it[iat]].m_loc_[st.iat2ia[iat]];
101+
if (!this->equal(m.x, 0.0) || !this->equal(m.y, 0.0) || !this->equal(m.z, 0.0)) { has_moment = true; }
102+
}
103+
std::vector<int> anti; // operations that REVERSE the moment: Theta*g is a symmetry
104+
anti.reserve(this->nrotk);
105+
for (int isym = 0; isym < this->nrotk; ++isym)
106+
{
107+
const ModuleBase::Matrix3 gmatc = ilatvec * this->gmatrix[isym] * latvec;
108+
const ModuleBase::Matrix3 W = ModuleSymmetry::SpinRotation::spin_so3(gmatc);
109+
bool ok = true;
110+
for (int iat = 0; iat < this->nat && ok; ++iat)
111+
{
112+
const ModuleBase::Vector3<double>& m = atoms[st.iat2it[iat]].m_loc_[st.iat2ia[iat]];
113+
// pseudovector-rotated moment W*m (column-vector convention: m'^i = W_ij m^j)
114+
const ModuleBase::Vector3<double>& mrot = W * m;
115+
const int jat = this->get_rotated_atom(isym, iat);
116+
const ModuleBase::Vector3<double>& mj = atoms[st.iat2it[jat]].m_loc_[st.iat2ia[jat]];
117+
if (!this->equal(mrot.x, mj.x) || !this->equal(mrot.y, mj.y) || !this->equal(mrot.z, mj.z)) { ok = false; }
118+
}
119+
if (ok)
120+
{
121+
keep.push_back(isym);
122+
if (isym < this->nrot) { ++nrot_new; } // pure point-group rotations are the first nrot ops
123+
}
124+
else if (has_moment)
125+
{
126+
// g does not preserve m; check whether it exactly REVERSES it, i.e.
127+
// W(g) m_i = -m_{g(i)} for every atom. Then g alone is not a symmetry but the
128+
// antiunitary element Theta*g is, and it belongs to the Shubnikov group.
129+
bool anti_ok = true;
130+
for (int iat = 0; iat < this->nat && anti_ok; ++iat)
131+
{
132+
const ModuleBase::Vector3<double>& m = atoms[st.iat2it[iat]].m_loc_[st.iat2ia[iat]];
133+
const ModuleBase::Vector3<double>& mrot = W * m;
134+
const int jat = this->get_rotated_atom(isym, iat);
135+
const ModuleBase::Vector3<double>& mj = atoms[st.iat2it[jat]].m_loc_[st.iat2ia[jat]];
136+
if (!this->equal(mrot.x, -mj.x) || !this->equal(mrot.y, -mj.y) || !this->equal(mrot.z, -mj.z)) { anti_ok = false; }
137+
}
138+
if (anti_ok) { anti.push_back(isym); }
139+
}
140+
}
141+
142+
// Capture the antiunitary coset BEFORE the unitary arrays are compacted in place below
143+
// (the compaction overwrites gmatrix/kgmatrix/gtrans/isym_rotiat_ and would lose them).
144+
this->magnetic_nspin4 = has_moment;
145+
this->nrotk_anti = static_cast<int>(anti.size());
146+
if (this->nrotk_anti > 0)
147+
{
148+
this->isym_rotiat_anti_.resize(this->nrotk_anti);
149+
for (int j = 0; j < this->nrotk_anti; ++j)
150+
{
151+
const int isym = anti[j];
152+
this->gmatrix_anti[j] = this->gmatrix[isym];
153+
this->kgmatrix_anti[j] = this->kgmatrix[isym];
154+
this->gtrans_anti[j] = this->gtrans[isym];
155+
this->isym_rotiat_anti_[j] = this->isym_rotiat_[isym];
156+
}
157+
ModuleBase::GlobalFunc::OUT(GlobalV::ofs_running,
158+
"MAGNETIC ANTIUNITARY OPERATIONS (Theta*g)", this->nrotk_anti);
159+
}
160+
161+
const int nrotk_new = static_cast<int>(keep.size());
162+
if (nrotk_new == this->nrotk) { return; } // nothing removed (non-magnetic or fully-preserving group)
163+
164+
// compact the operation arrays in ascending order (keeps the rotations-first layout).
165+
for (int i = 0; i < nrotk_new; ++i)
166+
{
167+
const int isym = keep[i];
168+
if (i != isym)
169+
{
170+
this->gmatrix[i] = this->gmatrix[isym];
171+
this->kgmatrix[i] = this->kgmatrix[isym];
172+
this->gtrans[i] = this->gtrans[isym];
173+
this->isym_rotiat_[i] = this->isym_rotiat_[isym];
174+
}
175+
}
176+
this->isym_rotiat_.resize(nrotk_new);
177+
this->nrot = nrot_new;
178+
this->nrotk = nrotk_new;
179+
180+
// refresh the point-/space-group labels for the reduced (unitary magnetic) group
181+
this->pointgroup(this->nrot, this->pgnumber, this->pgname, this->gmatrix, GlobalV::ofs_running, nullptr);
182+
this->pointgroup(this->nrotk, this->spgnumber, this->spgname, this->gmatrix, GlobalV::ofs_running, nullptr);
183+
ModuleBase::GlobalFunc::OUT(GlobalV::ofs_running, "MAGNETIC POINT GROUP (unitary, nspin=4)", this->pgname);
184+
// space-group-consistent name of the unitary magnetic group (from nrotk, matching "POINT GROUP IN
185+
// SPACE GROUP"); pgname above is the pure-point-group-block name, which under-detects for hexagonal
186+
// (e.g. Co prints S_6 there but is C_6h here).
187+
ModuleBase::GlobalFunc::OUT(GlobalV::ofs_running, "MAGNETIC POINT GROUP IN SPACE GROUP", this->spgname);
188+
ModuleBase::GlobalFunc::OUT(GlobalV::ofs_running, "MAGNETIC SPACE GROUP OPERATIONS", this->nrotk);
189+
}
190+
77191
bool Symmetry::magmom_same_check(const Atom* atoms)const
78192
{
79193
ModuleBase::TITLE("Symmetry", "magmom_same_check");
@@ -96,3 +210,32 @@ bool Symmetry::magmom_same_check(const Atom* atoms)const
96210
return pricell_loop;
97211
}
98212

213+
int Symmetry::density_sym_ops(std::vector<ModuleBase::Matrix3>& kgmat,
214+
std::vector<ModuleBase::Vector3<double>>& gtr,
215+
std::vector<double>& trs_inv) const
216+
{
217+
// The density must be symmetrized with the SAME group that was used to fold the k-points
218+
// (see KVectorUtils::ibz_kpoint): otherwise the density accumulated over the IBZ is not
219+
// restored to the full BZ result. For nspin=4 with a non-zero moment that group is the
220+
// Shubnikov group H + Theta*A, so the antiunitary elements' spatial parts are appended here.
221+
// Theta leaves the charge invariant and reverses the magnetization, which is what `trs_inv`
222+
// encodes; the spatial bookkeeping (orbit grouping, phases) is identical for both kinds.
223+
const int nu = this->nrotk;
224+
const int na = (this->magnetic_nspin4 ? this->nrotk_anti : 0);
225+
kgmat.resize(nu + na);
226+
gtr.resize(nu + na);
227+
trs_inv.assign(nu + na, 1.0);
228+
for (int i = 0; i < nu; ++i)
229+
{
230+
kgmat[i] = this->kgmatrix[i];
231+
gtr[i] = this->gtrans[i];
232+
}
233+
for (int j = 0; j < na; ++j)
234+
{
235+
kgmat[nu + j] = this->kgmatrix_anti[j];
236+
gtr[nu + j] = this->gtrans_anti[j];
237+
trs_inv[nu + j] = -1.0;
238+
}
239+
return nu + na;
240+
}
241+

0 commit comments

Comments
 (0)