Repository navigation
Fix #5021 #5939: warn on ignored x/y magnetization and remove nspin=4 autoset - #8079
Merged
Merged
Conversation
…ation and remove nspin=4 autoset When nspin=4 with noncolin=0, the x/y components of the initial magnetization from STRU are silently zeroed. Now a warning is printed to both stdout and running_scf.log, telling the user that x/y are ignored and suggesting to set noncolin=1. When nspin=4 and no initial magnetization is set in STRU, the code previously auto-assigned (1,1,1) to all atoms. This is removed; the calculation now starts from zero magnetic moment with a warning, letting the user decide explicitly. nspin=2 autoset behavior is unchanged. Also adds unit tests for both behaviors and updates parameter docs.
docs/parameters.yaml is generated from item.description in C++ source. Commit 98e3f81 added two noncolin notes to the generated yaml and input-main.md but omitted the generator source, making the yaml consistency CI check fail. Add the same two notes to the noncolin description in read_inp_estruc.cpp so regeneration matches.
Follow-up to deepmodeling#5939: nspin=4 with no mag in STRU no longer autosets (1,1,1); the unit test still expected the old forced moments. Assert zero magnetization instead and verify the new warning on both stdout and the running log.
Move JudgeParallel, CalUx1 and CalUx2 to the new test_cal_ux.cpp / MODULE_CELL_cal_ux_test target, one test file per source file. The new target compiles ../cal_ux.cpp directly like the old target did; unitcell_test no longer needs it.
Move ReadOrbFile (kept under the __LCAO guard as before) and ReadOrbFileWarning to the new test_read_orb.cpp / MODULE_CELL_read_orb_test target. read_orb.cpp is already part of the test-only cell_info object library, so no extra source is compiled in.
…suite CompareAatomLabel and PrintUnitcellPseudo exercise read_pp_ucell.cpp, so move them from MODULE_CELL_unitcell_test into the existing MODULE_CELL_unitcell_test_readpp target. The rebuilt cell needed by PrintUnitcellPseudo uses the C1H2-Index prepare entry. Drop the now unused read_pp_ucell.h include from unitcell_test.cpp.
Move RemakeCell, RemakeCellWarnings, PeriodicBoundaryAdjustment2 and UpdateVel to the new test_update_cell.cpp / MODULE_CELL_update_cell_test target. The commented-out PeriodicBoundaryAdjustment1 block moves as well and stays commented. update_cell.cpp is already part of the test-only cell_info library. Drop the now unused update_cell.h include from unitcell_test.cpp.
PrintCell, PrintTauDirect and PrintTauCartesian exercise print_cell.cpp, the same source as the PrintSTRU tests already living in test_print_cell.cpp. Move them into that file/target and reuse the PrintCellTest fixture. Drop the now unused print_cell.h include and the stale PrintSTRU navigation comment from unitcell_test.cpp.
…l_test Add test_cell_tools.cpp / MODULE_CELL_cell_tools_test for the unitcell:: free functions in cell_tools.cpp: - new IfCellCanChange truth-table case over the lattice-axis flags - vector get_atomCounts/get_lnchiCounts cases split out of the mixed member/free GetAtomCounts and GetLnchiCounts tests (the member get_atom_Counts/get_lnchi_Counts map assertions stay in unitcell_test) - SelectiveDynamics (if_atoms_can_move) moved verbatim Setup keeps only the setup_from_input member assertions; its if_cell_can_change checks are now covered by the dedicated truth table. Drop the unused cell_tools.h include from unitcell_test.cpp.
Move the 7 STRU header-parsing cases (read_atom_species and read_lattice_constant, both in read_atom_species.cpp) to the new test_read_atom_species.cpp / MODULE_CELL_read_atom_species_test target, kept under the __LCAO guard as before. ReadAtomSpeciesWarning5 uses the death-test fixture alias; the rest use the new ReadAtomSpeciesTest fixture. Drop the stale doc entries from unitcell_test.cpp.
Move the 17 read_atom_positions cases (spin/coordinate modes plus the five warning cases) to the new test_read_atoms.cpp / MODULE_CELL_read_atoms_test target, kept under the __LCAO guard. This removes the LCAO block and UcellTestReadStru fixture from unitcell_test.cpp, which now holds only the 9 UnitCell member-function tests. Also de-duplicate the triple read_stru.h include. The 6 GlobalV references are migration-neutral (added = removed).
…_multik/scf_out_dos_spin4
Critsium-xy
reviewed
Oct 9, 2026
Critsium-xy
left a comment
Collaborator
There was a problem hiding this comment.
Three points on the magnetization changes.
The zero-moment warning added for deepmodeling#5939 was unreachable in the two cases that matter most: * autoset_magnetization() keyed the check on atom.mag, which for a three-component "magmom" holds the full norm including x/y. With nspin=4 and noncolin=0 the x/y components are projected away, leaving m_loc_ = (0,0,0) while mag stays non-zero, so the warning was skipped for exactly the silent zero-moment start it was meant to surface. * read_atom_positions() only calls autoset_magnetization() when symmetry != 1, and symmetry defaults to 1 for nspin=4 + noncolin=1 + lspinorb=0 scf runs with k-points, so the documented warning never appeared there either. Split the magnetization reporting out of autoset_magnetization(): * is_magnetization_all_zero() shares the all-zero test. * warn_zero_magnetization_nspin4() keys on m_loc_, the vector cal_ux() actually consumes, and read_atom_positions() calls it for every symmetry setting. * autoset_magnetization() now only handles the nspin=2 autoset. Also stop printing the x/y-discarded warning once per atom. The block right below it in process_magnetization() throttles its output for the same reason; a 2000-atom cell with tilted moments produced ~4000 lines of identical text before SCF started. process_magnetization() now returns whether the projection discarded anything and read_atom_positions() aggregates it per atom type, reporting the affected-atom count once. Both warnings now also go through ModuleBase::WARNING so they reach warning.log, and the multi-line text is written straight to ofs_running instead of through GlobalFunc::OUT, whose setw(40) key/value layout was broken by the embedded newlines. Finally, the "initial magmom is all zero and symmetry=1" message is no longer printed for an explicitly magnetized STRU. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DNd7fpeHXHuL9DKME85J44
docs/advanced/input_files/stru.md still told users that nspin=4 autosets "mag 1 1 1" on every atom, which this branch removes; that page is where the STRU "mag" field is looked up, so it contradicted the notes added to input-main.md. Rewrite the section to describe the zero-moment start, the explicit-mag example, the x/y discard under noncolin=0, and the symmetry=1 case in which the nspin=2 autoset is skipped as well. Also record the autoset rules under "nspin" itself rather than only under "noncolin": the behavior is a property of nspin. parameters.yaml and input-main.md are regenerated from the C++ Input_Item description so the documentation-consistency check stays satisfied. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DNd7fpeHXHuL9DKME85J44
* .ci/slurm/config.ini still registered case.080 as 01_PW/035_PW_15_SO, a directory this branch renamed to scf_spin4, so that GPU case looked for a path that no longer exists. (19 further entries in that file already point at missing directories from earlier renames; those are left alone.) * PrintCellTest.PrintCell and UcellTest.PrintUnitcellPseudo both used "printcell.log". Before the unitcell_test.cpp split they shared one translation unit and ran sequentially; they are now separate executables that AddTest runs in the same working directory, so under ctest -j each could read or delete the other's file. Give the print_cell test its own name. * Keep the #pragma omp parallel for adjacent to the loop it governs in noncolin_rho(): the explanatory comment sat between the two, which compiles but invites an edit that drops a statement into the gap. * Strip the trailing blanks added to the regenerated 03_NAO_multik/scf_out_dos_spin4 INPUT and STRU. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DNd7fpeHXHuL9DKME85J44
Critsium-xy
approved these changes
Oct 9, 2026
AsTonyshment
approved these changes
Oct 9, 2026
AsTonyshment
left a comment
Collaborator
There was a problem hiding this comment.
I didn't find any obvious issues, LGTM.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Linked Issues
Fixes Refactor: split the monolithic source_cell unitcell_test.cpp into one test file per source file #8083
Fixes The magnetic moment is wrong when set nspin=4 but noncolin=0 #5021
Fixes In SOC calculations, the atomic magnetic moments can be set according to the structure file. #5939
Problem Description
Issue #5021: x/y components of magnetization silently zeroed
When
nspin=4andnoncolin=0, the x/y components of the initial magnetizationset in STRU are silently zeroed, keeping only the z component. Users who provide
a 3-component magnetization vector (e.g.,
mag 1.0 0.5 0.3) get no indicationthat the x/y components are discarded, which can lead to confusion about why
the final magnetic moment differs from the input.
Issue #5939: nspin=4 auto-assigns (1,1,1) to all atoms
When
nspin=4and no initial magnetization is set in STRU, the codeautomatically assigns
(1.0, 1.0, 1.0)to all atoms regardless of elementtype. This is overly aggressive — non-magnetic elements (e.g., O, H) also get
a magnetic moment, which can alter the SCF convergence path and final results.
Solution
1. Warn when x/y components are