From f8587b28ec67100cc3de7638fba4b0aad4e91301 Mon Sep 17 00:00:00 2001 From: seshasaibehara Date: Thu, 26 Feb 2026 14:18:18 -0800 Subject: [PATCH 1/2] write magmoms in incar --- casm/tools/shared/ase_utils.py | 72 +++++++++++++++++++++++++++++++++- 1 file changed, 70 insertions(+), 2 deletions(-) diff --git a/casm/tools/shared/ase_utils.py b/casm/tools/shared/ase_utils.py index a424625..762c34f 100644 --- a/casm/tools/shared/ase_utils.py +++ b/casm/tools/shared/ase_utils.py @@ -57,6 +57,58 @@ def make_ase_atoms(casm_structure: xtal.Structure) -> ase.Atoms: ) +def make_magnetic_ase_atoms( + casm_structure: xtal.Structure, magmom_dict: dict +) -> ase.Atoms: + """Given a CASM Structure and magnetic moments to be used for each specific species, + convert it to an ASE Atoms. If a magnetic moment is not provided for a species, it is + set to 1.0 + + .. attention:: + + This method only works for atomic structures where magnetic moments are not explicit + degrees of freedom and are only added at the setup stage. + If the structure contains molecular information, an error will be raised. + + Notes + ----- + + This method converts a CASM Structure object to an ASE Atoms object. It includes: + + - the lattice vectors + - the atomic positions + - the atomic types + + Parameters + ---------- + casm_structure : libcasm.xtal.Structure + magmom_dict : dict + + Returns + ------- + ase.Atoms + + """ + if len(casm_structure.mol_type()): + raise ValueError( + "Error: only non-magnetic atomic structures may be converted using " + "to_ase_atoms" + ) + + symbols = casm_structure.atom_type() + positions = casm_structure.atom_coordinate_cart().transpose() + cell = casm_structure.lattice().column_vector_matrix().transpose() + + magmoms = [ + magmom_dict[symbol] if symbol in magmom_dict.keys() else 1.0 + for symbol in symbols + ] + + return ase.Atoms( + symbols=symbols, positions=positions, cell=cell, pbc=True, magmoms=magmoms + ) + + def make_casm_structure(ase_atoms: ase.Atoms) -> xtal.Structure: """Given an ASE Atoms, convert it to a CASM Structure @@ -351,11 +403,16 @@ def __init__( incar_path = None kpoints_path = None settings = {} + species_settings = {} if self.calctype_settings_dir is not None: settings = json_io.read_required( path=self.calctype_settings_dir / "calc.json" ) + species_settings = json_io.read_optional( + path=self.calctype_settings_dir / "species.json" + ) + incar_path = calctype_settings_dir / "INCAR" if not incar_path.exists(): incar_path = None @@ -369,6 +426,8 @@ def __init__( calctype_settings_dir, which will be passed to the :class:`ase.calculators.vasp.Vasp` calculator constructor.""" + self.species_settings = species_settings + self.incar_path = incar_path """Optional[pathlib.Path]: Path to the template INCAR file, if it exists.""" @@ -376,8 +435,11 @@ def __init__( """Optional[pathlib.Path]: Path to the template KPOINTS file, if it exists.""" ### Functions to convert between CASM Structure and ASE Atoms + if "magmoms" in species_settings.keys(): + self._make_ase_atoms_f = make_magnetic_ase_atoms - self._make_ase_atoms_f = make_ase_atoms_f + else: + self._make_ase_atoms_f = make_ase_atoms_f """Callable[[libcasm.xtal.Structure], ase.Atoms]: Function to convert CASM Structure to ASE Atoms.""" @@ -447,7 +509,13 @@ def setup( vasp_calculator: ase.calculators.vasp.Vasp The ASE VASP calculator object. """ - ase_atoms = self._make_ase_atoms_f(casm_structure) + if "magmoms" in self.species_settings.keys(): + ase_atoms = self._make_ase_atoms_f( + casm_structure, magmom_dict=self.species_settings["magmoms"] + ) + + else: + ase_atoms = self._make_ase_atoms_f(casm_structure) vasp_calculator = self.make_calculator(ase_atoms=ase_atoms, calc_dir=calc_dir) # Write INCAR, KPOINTS, POTCAR, POSCAR From 7fff735baac77962b03eb7c45ed9b42ede39b0e6 Mon Sep 17 00:00:00 2001 From: seshasaibehara Date: Thu, 26 Feb 2026 14:39:41 -0800 Subject: [PATCH 2/2] add empty species dict as default --- casm/tools/shared/ase_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/casm/tools/shared/ase_utils.py b/casm/tools/shared/ase_utils.py index 762c34f..36922b9 100644 --- a/casm/tools/shared/ase_utils.py +++ b/casm/tools/shared/ase_utils.py @@ -410,7 +410,7 @@ def __init__( ) species_settings = json_io.read_optional( - path=self.calctype_settings_dir / "species.json" + path=self.calctype_settings_dir / "species.json", default={} ) incar_path = calctype_settings_dir / "INCAR"