• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

materialsproject / pymatgen / 4075885785

pending completion
4075885785

push

github

Shyue Ping Ong
Merge branch 'master' of github.com:materialsproject/pymatgen

96 of 96 new or added lines in 27 files covered. (100.0%)

81013 of 102710 relevant lines covered (78.88%)

0.79 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

92.9
/pymatgen/io/feff/sets.py
1
# Copyright (c) Pymatgen Development Team.
2
# Distributed under the terms of the MIT License.
3

4
"""
1✔
5
This module defines the FeffInputSet abstract base class and a concrete
6
implementation for the Materials Project. The basic concept behind an input
7
set is to specify a scheme to generate a consistent set of Feff inputs from a
8
structure without further user intervention. This ensures comparability across
9
runs.
10
"""
11

12
from __future__ import annotations
1✔
13

14
import abc
1✔
15
import logging
1✔
16
import os
1✔
17
import sys
1✔
18
import warnings
1✔
19
from copy import deepcopy
1✔
20

21
import numpy as np
1✔
22
from monty.json import MSONable
1✔
23
from monty.os.path import zpath
1✔
24
from monty.serialization import loadfn
1✔
25

26
from pymatgen.core.structure import Molecule, Structure
1✔
27
from pymatgen.io.feff.inputs import Atoms, Header, Potential, Tags
1✔
28

29
__author__ = "Kiran Mathew"
1✔
30
__credits__ = "Alan Dozier, Anubhav Jain, Shyue Ping Ong"
1✔
31
__version__ = "1.1"
1✔
32
__maintainer__ = "Kiran Mathew"
1✔
33
__email__ = "kmathew@lbl.gov"
1✔
34
__date__ = "Sept 10, 2016"
1✔
35

36
MODULE_DIR = os.path.dirname(os.path.abspath(__file__))
1✔
37

38
logger = logging.getLogger(__name__)
1✔
39
logger.setLevel(logging.DEBUG)
1✔
40
formatter = logging.Formatter("%(asctime)s: %(levelname)s: %(name)s: %(message)s")
1✔
41
sh = logging.StreamHandler(stream=sys.stdout)
1✔
42
sh.setFormatter(formatter)
1✔
43
logger.addHandler(sh)
1✔
44

45

46
class AbstractFeffInputSet(MSONable, metaclass=abc.ABCMeta):
1✔
47
    """
48
    Abstract base class representing a set of Feff input parameters.
49
    The idea is that using a FeffInputSet, a complete set of input files
50
    (feffPOT, feffXANES, feffEXAFS, ATOMS, feff.inp)set_
51
    can be generated in an automated fashion for any structure.
52
    """
53

54
    @abc.abstractmethod
1✔
55
    def header(self):
1✔
56
        """
57
        Returns header to be used in feff.inp file from a pymatgen structure
58
        """
59

60
    @property
1✔
61
    @abc.abstractmethod
1✔
62
    def atoms(self):
1✔
63
        """
64
        Returns Atoms string from a structure that goes in feff.inp file.
65

66
        Returns:
67
            Atoms object.
68
        """
69

70
    @property
1✔
71
    @abc.abstractmethod
1✔
72
    def tags(self):
1✔
73
        """
74
        Returns standard calculation parameters.
75
        """
76
        return
×
77

78
    @property
1✔
79
    @abc.abstractmethod
1✔
80
    def potential(self):
1✔
81
        """
82
        Returns POTENTIAL section used in feff.inp from a structure.
83
        """
84

85
    def all_input(self):
1✔
86
        """
87
        Returns all input files as a dict of {filename: feffio object}
88
        """
89
        d = {"HEADER": self.header(), "PARAMETERS": self.tags}
1✔
90

91
        if "RECIPROCAL" not in self.tags:
1✔
92
            d.update({"POTENTIALS": self.potential, "ATOMS": self.atoms})
1✔
93

94
        return d
1✔
95

96
    def write_input(self, output_dir=".", make_dir_if_not_present=True):
1✔
97
        """
98
        Writes a set of FEFF input to a directory.
99

100
        Args:
101
            output_dir: Directory to output the FEFF input files
102
            make_dir_if_not_present: Set to True if you want the directory (
103
                and the whole path) to be created if it is not present.
104
        """
105
        if make_dir_if_not_present and not os.path.exists(output_dir):
1✔
106
            os.makedirs(output_dir)
1✔
107

108
        feff = self.all_input()
1✔
109

110
        feff_input = "\n\n".join(str(feff[k]) for k in ["HEADER", "PARAMETERS", "POTENTIALS", "ATOMS"] if k in feff)
1✔
111

112
        for k, v in feff.items():
1✔
113
            with open(os.path.join(output_dir, k), "w") as f:
1✔
114
                f.write(str(v))
1✔
115

116
        with open(os.path.join(output_dir, "feff.inp"), "w") as f:
1✔
117
            f.write(feff_input)
1✔
118

119
        # write the structure to cif file
120
        if "ATOMS" not in feff:
1✔
121
            self.atoms.struct.to(fmt="cif", filename=os.path.join(output_dir, feff["PARAMETERS"]["CIF"]))
1✔
122

123

124
class FEFFDictSet(AbstractFeffInputSet):
1✔
125
    """
126
    Standard implementation of FeffInputSet, which can be extended by specific
127
    implementations.
128
    """
129

130
    def __init__(
1✔
131
        self,
132
        absorbing_atom: str | int,
133
        structure: Structure | Molecule,
134
        radius: float,
135
        config_dict: dict,
136
        edge: str = "K",
137
        spectrum: str = "EXAFS",
138
        nkpts=1000,
139
        user_tag_settings: dict | None = None,
140
        spacegroup_analyzer_settings: dict | None = None,
141
    ):
142
        """
143
        Args:
144
            absorbing_atom (str/int): absorbing atom symbol or site index
145
            structure: Structure or Molecule object. If a Structure, SpaceGroupAnalyzer is used to
146
                determine symmetrically-equivalent sites. If a Molecule, there is no symmetry
147
                checking.
148
            radius (float): cluster radius
149
            config_dict (dict): control tag settings dict
150
            edge (str): absorption edge
151
            spectrum (str): type of spectrum to calculate, available options :
152
                EXAFS, XANES, DANES, XMCD, ELNES, EXELFS, FPRIME, NRIXS, XES.
153
                The default is EXAFS.
154
            nkpts (int): Total number of kpoints in the brillouin zone. Used
155
                only when feff is run in the reciprocal space mode.
156
            user_tag_settings (dict): override default tag settings. To delete
157
                tags, set the key '_del' in the user_tag_settings.
158
                eg: user_tag_settings={"_del": ["COREHOLE", "EXCHANGE"]}
159
                To specify a net charge on the structure, pass an "IONS" tag containing a list
160
                    of tuples where the first element is the unique potential value (ipot value)
161
                    and the second element is the charge to be applied to atoms associated
162
                    with that potential, e.g. {"IONS": [(0, 0.1), (1, 0.1), (2, 0.1)]}
163
                    will result in
164

165
                    ION 0 0.1
166
                    ION 1 0.1
167
                    ION 2 0.1
168

169
                    being written to the input file.
170
            spacegroup_analyzer_settings (dict): parameters passed to SpacegroupAnalyzer.
171
                E.g., {"symprec": 0.01, "angle_tolerance": 4}
172
        """
173
        self.absorbing_atom = absorbing_atom
1✔
174
        self.user_tag_settings = user_tag_settings or {}
1✔
175
        # make sure there are no partial occupancies
176
        if structure.is_ordered:
1✔
177
            if isinstance(structure, Structure):
1✔
178
                # charged structures should never be supported b/c periodic boundaries
179
                # cause problems
180
                if structure.charge != 0:
1✔
181
                    raise ValueError("Structure objects with a net charge are not supported!")
1✔
182
            elif isinstance(structure, Molecule):
1✔
183
                # charged Molecules should eventually be supported. According to Joshua Kas (FEFF expert),
184
                # the correct approach is to divide the total charge on the Molecule equally among
185
                # all atoms. Then, add one ION card with that charge for each atom type (i.e., each
186
                # unique ipot value)
187
                # for example, for a cluster with a +1 charge and 10 atoms and 3 unique potentials, you
188
                # would add
189
                # ION 0 0.1
190
                # ION 1 0.1
191
                # ION 2 0.1
192
                # This is also most appropriate for self-consistent calculations like XANES.
193
                # For non-self-consistent calc types, the manual says its best to check results
194
                # with and without a net charge b/c it's often better not to use charge
195
                if structure.charge != 0 and not self.user_tag_settings.get("IONS"):
1✔
196
                    warnings.warn(
1✔
197
                        "For Molecule objects with a net charge it is recommended to set one or more"
198
                        " ION tags in the input file by modifying user_tag_settings."
199
                        " Consult the FEFFDictSet docstring and the FEFF10 User Guide for more information.",
200
                        UserWarning,
201
                    )
202
            else:
203
                raise ValueError("'structure' argument must be a Structure or Molecule!")
×
204
        else:
205
            raise ValueError("Structure with partial occupancies cannot be converted into atomic coordinates!")
×
206
        self.structure = structure
1✔
207
        self.radius = radius
1✔
208
        self.config_dict = deepcopy(config_dict)
1✔
209
        self.edge = edge
1✔
210
        self.spectrum = spectrum
1✔
211
        self.nkpts = nkpts
1✔
212
        self.config_dict["EDGE"] = self.edge
1✔
213
        self.config_dict.update(self.user_tag_settings)
1✔
214
        if "_del" in self.user_tag_settings:
1✔
215
            for tag in self.user_tag_settings["_del"]:
×
216
                if tag in self.config_dict:
×
217
                    del self.config_dict[tag]
×
218
            del self.config_dict["_del"]
×
219
        # k-space feff only for small systems. The hardcoded system size in
220
        # feff is around 14 atoms.
221
        self.small_system = len(self.structure) < 14 and "EXAFS" not in self.config_dict
1✔
222
        self.spacegroup_analyzer_settings = spacegroup_analyzer_settings or {}
1✔
223

224
    def header(self, source: str = "", comment: str = ""):
1✔
225
        """
226
        Creates header string from structure object
227

228
        Args:
229
            source: Source identifier used to create structure, can be defined
230
                however user wants to organize structures, calculations, etc.
231
                example would be Materials Project material ID number.
232
            comment: comment to include in header
233

234
        Returns:
235
            Header
236
        """
237
        return Header(self.structure, source, comment, spacegroup_analyzer_settings=self.spacegroup_analyzer_settings)
1✔
238

239
    @property
1✔
240
    def tags(self) -> Tags:
1✔
241
        """
242
        FEFF job parameters.
243

244
        Returns:
245
            Tags
246
        """
247
        if "RECIPROCAL" in self.config_dict:
1✔
248
            if self.small_system:
1✔
249
                self.config_dict["CIF"] = f"{self.structure.formula.replace(' ', '')}.cif"
1✔
250
                self.config_dict["TARGET"] = self.atoms.center_index + 1
1✔
251
                self.config_dict["COREHOLE"] = "RPA"
1✔
252
                logger.warning("Setting COREHOLE = RPA for K-space calculation")
1✔
253
                if not self.config_dict.get("KMESH", None):
1✔
254
                    abc = self.structure.lattice.abc
1✔
255
                    mult = (self.nkpts * abc[0] * abc[1] * abc[2]) ** (1 / 3)
1✔
256
                    self.config_dict["KMESH"] = [int(round(mult / l)) for l in abc]
1✔
257
            else:
258
                logger.warning(
1✔
259
                    "Large system(>=14 atoms) or EXAFS calculation, \
260
                                removing K-space settings"
261
                )
262
                del self.config_dict["RECIPROCAL"]
1✔
263
                self.config_dict.pop("CIF", None)
1✔
264
                self.config_dict.pop("TARGET", None)
1✔
265
                self.config_dict.pop("KMESH", None)
1✔
266
                self.config_dict.pop("STRFAC", None)
1✔
267

268
        return Tags(self.config_dict)
1✔
269

270
    @property
1✔
271
    def potential(self) -> Potential:
1✔
272
        """
273
        FEFF potential
274

275
        Returns:
276
            Potential
277
        """
278
        return Potential(self.structure, self.absorbing_atom)
1✔
279

280
    @property
1✔
281
    def atoms(self) -> Atoms:
1✔
282
        """
283
        absorber + the rest
284

285
        Returns:
286
            Atoms
287
        """
288
        return Atoms(self.structure, self.absorbing_atom, self.radius)
1✔
289

290
    def __str__(self):
1✔
291
        output = [self.spectrum]
×
292
        output.extend([f"{k} = {v}" for k, v in self.config_dict.items()])
×
293
        output.append("")
×
294
        return "\n".join(output)
×
295

296
    @staticmethod
1✔
297
    def from_directory(input_dir):
1✔
298
        """
299
        Read in a set of FEFF input files from a directory, which is
300
        useful when existing FEFF input needs some adjustment.
301
        """
302
        sub_d = {}
1✔
303
        for fname, ftype in [("HEADER", Header), ("PARAMETERS", Tags)]:
1✔
304
            fullzpath = zpath(os.path.join(input_dir, fname))
1✔
305
            sub_d[fname.lower()] = ftype.from_file(fullzpath)
1✔
306

307
        # Generation of FEFFDict set requires absorbing atom, need to search
308
        # the index of absorption atom in the structure according to the
309
        # distance matrix and shell species information contained in feff.inp
310

311
        absorber_index = []
1✔
312
        radius = None
1✔
313
        feffinp = zpath(os.path.join(input_dir, "feff.inp"))
1✔
314

315
        if "RECIPROCAL" not in sub_d["parameters"]:
1✔
316
            input_atoms = Atoms.cluster_from_file(feffinp)
1✔
317
            shell_species = np.array([x.species_string for x in input_atoms])
1✔
318

319
            # First row of distance matrix represents the distance from the absorber to
320
            # the rest atoms
321
            distance_matrix = input_atoms.distance_matrix[0, :]
1✔
322

323
            # Get radius value
324
            from math import ceil
1✔
325

326
            radius = int(
1✔
327
                ceil(
328
                    input_atoms.get_distance(
329
                        input_atoms.index(input_atoms[0]),
330
                        input_atoms.index(input_atoms[-1]),
331
                    )
332
                )
333
            )
334

335
            for site_index, site in enumerate(sub_d["header"].struct):
1✔
336
                if site.specie == input_atoms[0].specie:
1✔
337
                    site_atoms = Atoms(sub_d["header"].struct, absorbing_atom=site_index, radius=radius)
1✔
338
                    site_distance = np.array(site_atoms.get_lines())[:, 5].astype(np.float64)
1✔
339
                    site_shell_species = np.array(site_atoms.get_lines())[:, 4]
1✔
340
                    shell_overlap = min(shell_species.shape[0], site_shell_species.shape[0])
1✔
341

342
                    if np.allclose(distance_matrix[:shell_overlap], site_distance[:shell_overlap]) and np.all(
1✔
343
                        site_shell_species[:shell_overlap] == shell_species[:shell_overlap]
344
                    ):
345
                        absorber_index.append(site_index)
1✔
346

347
        if "RECIPROCAL" in sub_d["parameters"]:
1✔
348
            absorber_index = sub_d["parameters"]["TARGET"]
1✔
349
            absorber_index[0] = int(absorber_index[0]) - 1
1✔
350

351
        # Generate the input set
352
        if "XANES" in sub_d["parameters"]:
1✔
353
            CONFIG = loadfn(os.path.join(MODULE_DIR, "MPXANESSet.yaml"))
1✔
354
            if radius is None:
1✔
355
                radius = 10
1✔
356
            return FEFFDictSet(
1✔
357
                absorber_index[0],
358
                sub_d["header"].struct,
359
                radius=radius,
360
                config_dict=CONFIG,
361
                edge=sub_d["parameters"]["EDGE"],
362
                nkpts=1000,
363
                user_tag_settings=sub_d["parameters"],
364
            )
365

366
        raise ValueError("Bad input directory.")
×
367

368

369
class MPXANESSet(FEFFDictSet):
1✔
370
    """
371
    FeffDictSet for XANES spectroscopy.
372
    """
373

374
    CONFIG = loadfn(os.path.join(MODULE_DIR, "MPXANESSet.yaml"))
1✔
375

376
    def __init__(
1✔
377
        self,
378
        absorbing_atom,
379
        structure,
380
        edge: str = "K",
381
        radius: float = 10.0,
382
        nkpts: int = 1000,
383
        user_tag_settings: dict | None = None,
384
        **kwargs,
385
    ):
386
        r"""
387
        Args:
388
            absorbing_atom (str/int): absorbing atom symbol or site index
389
            structure (Structure): input
390
            edge (str): absorption edge
391
            radius (float): cluster radius in Angstroms.
392
            nkpts (int): Total number of kpoints in the brillouin zone. Used
393
                only when feff is run in the reciprocal space mode.
394
            user_tag_settings (dict): override default tag settings
395
            **kwargs: Passthrough to FEFFDictSet
396
        """
397
        super().__init__(
1✔
398
            absorbing_atom,
399
            structure,
400
            radius,
401
            MPXANESSet.CONFIG,
402
            edge=edge,
403
            spectrum="XANES",
404
            nkpts=nkpts,
405
            user_tag_settings=user_tag_settings,
406
            **kwargs,
407
        )
408

409

410
class MPEXAFSSet(FEFFDictSet):
1✔
411
    """
412
    FeffDictSet for EXAFS spectroscopy.
413
    """
414

415
    CONFIG = loadfn(os.path.join(MODULE_DIR, "MPEXAFSSet.yaml"))
1✔
416

417
    def __init__(
1✔
418
        self,
419
        absorbing_atom,
420
        structure,
421
        edge: str = "K",
422
        radius: float = 10.0,
423
        nkpts: int = 1000,
424
        user_tag_settings: dict | None = None,
425
        **kwargs,
426
    ):
427
        r"""
428
        Args:
429
            absorbing_atom (str/int): absorbing atom symbol or site index
430
            structure (Structure): input structure
431
            edge (str): absorption edge
432
            radius (float): cluster radius in Angstroms.
433
            nkpts (int): Total number of kpoints in the brillouin zone. Used
434
                only when feff is run in the reciprocal space mode.
435
            user_tag_settings (dict): override default tag settings
436
            **kwargs: Passthrough to FEFFDictSet
437
        """
438
        super().__init__(
1✔
439
            absorbing_atom,
440
            structure,
441
            radius,
442
            MPEXAFSSet.CONFIG,
443
            edge=edge,
444
            spectrum="EXAFS",
445
            nkpts=nkpts,
446
            user_tag_settings=user_tag_settings,
447
            **kwargs,
448
        )
449

450

451
class MPEELSDictSet(FEFFDictSet):
1✔
452
    """
453
    FeffDictSet for ELNES spectroscopy.
454
    """
455

456
    def __init__(
1✔
457
        self,
458
        absorbing_atom,
459
        structure,
460
        edge,
461
        spectrum,
462
        radius,
463
        beam_energy,
464
        beam_direction,
465
        collection_angle,
466
        convergence_angle,
467
        config_dict,
468
        user_eels_settings=None,
469
        nkpts: int = 1000,
470
        user_tag_settings: dict | None = None,
471
        **kwargs,
472
    ):
473
        """
474
        Args:
475
            absorbing_atom (str/int): absorbing atom symbol or site index
476
            structure (Structure): input structure
477
            edge (str): absorption edge
478
            spectrum (str): ELNES or EXELFS
479
            radius (float): cluster radius in Angstroms.
480
            beam_energy (float): Incident beam energy in keV
481
            beam_direction (list): Incident beam direction. If None, the
482
                cross section will be averaged.
483
            collection_angle (float): Detector collection angle in mrad.
484
            convergence_angle (float): Beam convergence angle in mrad.
485
            user_eels_settings (dict): override default EELS config.
486
                See MPELNESSet.yaml for supported keys.
487
            nkpts (int): Total number of kpoints in the brillouin zone. Used
488
                only when feff is run in the reciprocal space mode.
489
            user_tag_settings (dict): override default tag settings
490
            **kwargs: Passthrough to FEFFDictSet
491
        """
492
        self.beam_energy = beam_energy
1✔
493
        self.beam_direction = beam_direction
1✔
494
        self.collection_angle = collection_angle
1✔
495
        self.convergence_angle = convergence_angle
1✔
496
        self.user_eels_settings = user_eels_settings
1✔
497
        eels_config_dict = deepcopy(config_dict)
1✔
498

499
        if beam_direction:
1✔
500
            beam_energy_list = [beam_energy, 0, 1, 1]
1✔
501
            eels_config_dict[spectrum]["BEAM_DIRECTION"] = beam_direction
1✔
502
        else:
503
            beam_energy_list = [beam_energy, 1, 0, 1]
1✔
504
            del eels_config_dict[spectrum]["BEAM_DIRECTION"]
1✔
505
        eels_config_dict[spectrum]["BEAM_ENERGY"] = beam_energy_list
1✔
506
        eels_config_dict[spectrum]["ANGLES"] = [collection_angle, convergence_angle]
1✔
507

508
        if user_eels_settings:
1✔
509
            eels_config_dict[spectrum].update(user_eels_settings)
1✔
510

511
        super().__init__(
1✔
512
            absorbing_atom,
513
            structure,
514
            radius,
515
            eels_config_dict,
516
            edge=edge,
517
            spectrum=spectrum,
518
            nkpts=nkpts,
519
            user_tag_settings=user_tag_settings,
520
            **kwargs,
521
        )
522

523

524
class MPELNESSet(MPEELSDictSet):
1✔
525
    """
526
    FeffDictSet for ELNES spectroscopy.
527
    """
528

529
    CONFIG = loadfn(os.path.join(MODULE_DIR, "MPELNESSet.yaml"))
1✔
530

531
    def __init__(
1✔
532
        self,
533
        absorbing_atom,
534
        structure,
535
        edge: str = "K",
536
        radius: float = 10.0,
537
        beam_energy: float = 100,
538
        beam_direction=None,
539
        collection_angle: float = 1,
540
        convergence_angle: float = 1,
541
        user_eels_settings=None,
542
        nkpts: int = 1000,
543
        user_tag_settings: dict | None = None,
544
        **kwargs,
545
    ):
546
        r"""
547
        Args:
548
            absorbing_atom (str/int): absorbing atom symbol or site index
549
            structure (Structure): input structure
550
            edge (str): absorption edge
551
            radius (float): cluster radius in Angstroms.
552
            beam_energy (float): Incident beam energy in keV
553
            beam_direction (list): Incident beam direction. If None, the
554
                cross section will be averaged.
555
            collection_angle (float): Detector collection angle in mrad.
556
            convergence_angle (float): Beam convergence angle in mrad.
557
            user_eels_settings (dict): override default EELS config.
558
                See MPELNESSet.yaml for supported keys.
559
            nkpts (int): Total number of kpoints in the brillouin zone. Used
560
                only when feff is run in the reciprocal space mode.
561
            user_tag_settings (dict): override default tag settings
562
            **kwargs: Passthrough to FEFFDictSet
563
        """
564
        super().__init__(
1✔
565
            absorbing_atom,
566
            structure,
567
            edge,
568
            "ELNES",
569
            radius,
570
            beam_energy,
571
            beam_direction,
572
            collection_angle,
573
            convergence_angle,
574
            MPELNESSet.CONFIG,
575
            user_eels_settings=user_eels_settings,
576
            nkpts=nkpts,
577
            user_tag_settings=user_tag_settings,
578
            **kwargs,
579
        )
580

581

582
class MPEXELFSSet(MPEELSDictSet):
1✔
583
    """
584
    FeffDictSet for EXELFS spectroscopy.
585
    """
586

587
    CONFIG = loadfn(os.path.join(MODULE_DIR, "MPEXELFSSet.yaml"))
1✔
588

589
    def __init__(
1✔
590
        self,
591
        absorbing_atom,
592
        structure,
593
        edge="K",
594
        radius: float = 10.0,
595
        beam_energy: float = 100,
596
        beam_direction=None,
597
        collection_angle: float = 1,
598
        convergence_angle: float = 1,
599
        user_eels_settings=None,
600
        nkpts: int = 1000,
601
        user_tag_settings: dict | None = None,
602
        **kwargs,
603
    ):
604
        r"""
605
        Args:
606
            absorbing_atom (str/int): absorbing atom symbol or site index
607
            structure (Structure): input structure
608
            edge (str): absorption edge
609
            radius (float): cluster radius in Angstroms.
610
            beam_energy (float): Incident beam energy in keV
611
            beam_direction (list): Incident beam direction. If None, the
612
                cross section will be averaged.
613
            collection_angle (float): Detector collection angle in mrad.
614
            convergence_angle (float): Beam convergence angle in mrad.
615
            user_eels_settings (dict): override default EELS config.
616
                See MPEXELFSSet.yaml for supported keys.
617
            nkpts (int): Total number of kpoints in the brillouin zone. Used
618
                only when feff is run in the reciprocal space mode.
619
            user_tag_settings (dict): override default tag settings
620
            **kwargs: Passthrough to FEFFDictSet
621
        """
622
        super().__init__(
×
623
            absorbing_atom,
624
            structure,
625
            edge,
626
            "EXELFS",
627
            radius,
628
            beam_energy,
629
            beam_direction,
630
            collection_angle,
631
            convergence_angle,
632
            MPEXELFSSet.CONFIG,
633
            user_eels_settings=user_eels_settings,
634
            nkpts=nkpts,
635
            user_tag_settings=user_tag_settings,
636
            **kwargs,
637
        )
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc