Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

remake dopedxpy-sc-fermi #46

Open
wants to merge 48 commits into
base: develop
Choose a base branch
from
Open

remake dopedxpy-sc-fermi #46

wants to merge 48 commits into from

Conversation

alexsquires
Copy link
Member

@alexsquires alexsquires commented Jan 10, 2024

  • rename bulk_vasprun, not clear that this needs to be for a high quality dos
  • use _format_defect_name() in examples (is this still a private function? If it's externally useful, should it be changed?).
  • remove ..._and_save() from FermiSolver methods
  • defect_levels argument when annealing becomes a boolean
  • docstrings
  • multiprocessings
  • tests
  • suppress noisy warnings
  • tutorials
  • grid-searching
  • effective dopant response
  • "exceptions" for FermiSolverPyScFermi

@kavanase
Copy link
Member

Looking good @alexsquires. I like the mix-in/abstract class approach.

The _interpolate_chempots() function is quite nice, and I think will likely be one of the mostly-used features from these additions. From what we were discussing before in the #doped Slack, would it be possible to also integrate a grid-scanning approach too? As in, the current function linearly interpolates between two points (chem pot limits), which is nice and v useful in many cases, but if for instance we have a 3D chemical potential space, our min/max of the property of interest could also lie somewhere in the middle of this space, rather than along any linear path between two vertices/limits.

Ofc the user could iterate over all possible vertex/limit combinations if they knew what they were doing, which would be a good stab at this and get you most of the way there I imagine (kind of like a 'band structure path' approach), but still is only covering certain 'high-symmetry' paths in chem pot space. So if a grid approach was also possible (where e.g. the user can just set the chempot spacing in eV, or total number of grid points), that would also be v nice I think – should be doable with some of the scipy grid space interpolation functions I think? And/or pymatgen chemical potential diagram methods maybe?
If it was possible to implement relatively painlessly, could we add these two options? ☝️ 🙏

Sorry to be piling on the requests, but I guess the other main use case I'd imagine for this part of the code would be for the more complex defect thermodynamics analysis that py-sc-fermi allows, where you want to fix certain defect/species etc concentrations and perform some constrained solutions. Is it possible to integrate this to the fermi_solver code?

Also just fyi, about your earlier _format_defect_name() question, yes it is actually quite externally useful and I'll make it a public function in the next (minor) release.

@alexsquires
Copy link
Member Author

alexsquires commented Feb 15, 2024 via email

@alexsquires
Copy link
Member Author

@adair-nicolson , could you re-parse your Cu2SiSe3 data now that everything is relatively final and I can add the grid searching stuff back in?

@alexsquires
Copy link
Member Author

@kavanase proposing this as the full functionality - do you want to take a look at the example ipynb while I finish off the tests before I get to comfortable?

@alexsquires alexsquires marked this pull request as ready for review February 27, 2024 17:17
# Conflicts:
#	examples/CdTe/CdTe_example_thermo.json
@kavanase
Copy link
Member

@alexsquires sorry for the delay in getting to this! Busy time...

Looking very very nice, thanks very much for your work with this! 🙌

Some small queries from me:

  • Can multiplicity_scaling be handled internally by FermiSolverPyScFermi (but still retaining the option to set by the user), by just dividing the volume of the bulk supercell in defect_thermodynamics by that of bulk_dos_vr (and maybe a quick warning if this isn't close to an integer)? Would make it easier and remove a potential source of error if so.
py_fs = FermiSolverPyScFermi(defect_thermodynamics=thermodynamics, bulk_dos_vr=vasprun_path, multiplicity_scaling=32)
  • I updated the exceptions example to add one that matches better the example given in the text (i.e. mobile interstitials), to avoid confusion with this and give a relevant example. Can exceptions be reworded to something a bit more intuitive, like non_frozen or equilibrium_defects or something like that?
  • Some of the public functions (like scan_dopant_concentration, interpolate_chemical_potentials etc) don't have docstrings. Could you add these when you get a chance please? (Noticed when I was figuring out how exceptions worked, useful to have a quick help message for how parameters like this work)
  • When I went to commit, I got a load of pre-commit formatting warnings. Could you install pre-commit (running pre-commit install in the doped directory) to handle the remaining issues please? (Dealt with some here, but not all)

A general question: (will also look into the code in more detail myself)

  • How are metastable defects handled in FermiSolverPyScFermi? Is it equivalent to the way they're handled in the DefectThermodynamics functions (at equilibrium and upon cooling)? Might possibly be worth quickly checking, by setting e.g. the V_Cd^0 metastable state to only be 0.01 eV higher energy than the ground-state (to amplify the metastable effects), and see if the doped and FermiSolverPyScFermi results are consistent or differ in this case?

@kavanase
Copy link
Member

Fyi, the py-sc-fermi interface tutorial is now accessible here: https://doped.readthedocs.io/en/dopey_fermi/py_sc_fermi_interface_tutorial.html

@kavanase
Copy link
Member

@alexsquires just to flag, it seems like there are some unused files included here in the CdTe examples directory. Before merging can we check that only the ones needed are included, to avoid bloating the repo?
Also just fyi, I removed CdTe_Thesis_pyscfermi.ipynb, data/dos_vasprun.xml and vasprun_nsp.xml here as they weren't being used, but if they were intended to be used for something else then please revert!

…in `doped` concentration calcs, due to inefficient `defect.element_changes` in `pymatgen`; avoided now)
…functions, and fix bug in `generate_annealed_defect_system`
@kavanase
Copy link
Member

Hi @alexsquires!
Some notes on these changes from going through in more depth:

  • I added the effective_dopant_concentration parameter to the doped DefectThermodynamics functions as discussed (and verified it matches with py-sc-fermi). Also in the updated notebook, the effective dopant concentration is now plotted alongside, which I think nicely shows it's effects on the carrier/defect concentrations (ofc you can tell this anyway from reading off the axes, but nice to see it directly plotted I think)
image
  • In doing this, I noticed a bug in the FermiSolverPyScFermi code for effective_dopant_concentration with annealing & quenching. Previously this was giving flat concentrations for the native defects:
    image
    I realised this was related to the placement of the code which adds the effective dopant concentration in generate_annealed_defect_system. Fixed now, but also returns a stream of RuntimeWarnings, would you be able to update to ignore these (for the case where FermiSolverPyScFermi is being used for this)? Just not sure where/how you're handling warnings like this!
image
  • As a suggestion (open to being challenged on this!), I refactored fix_defect_species to (not) fix_charge_states as I think this is a bit more intuitive in general? I think in the field "species" is used both to mean defect type + charge, or just defect type (regardless of whether one is technically more correct), so best to rename to something like this?
  • Can we add to effective_dopant_concentration docstrings a note that negative means acceptor doping and positive means donor doping? Just there's no actual mention of this in the docstrings so could be confusing for the user, and isn't explicitly stated in the tutorial from what I can see. Also would be good to explicitly state that effective_dopant_concentration is in units of cm^-3
  • Would also be good to note in the docstrings and notebook the different chemical potential definitions / usages for doped/py-sc-fermi (formal vs DFT values)
  • Lastly, I tried using fs.scan_chemical_potential_grid() with FermiSolverDoped for the last bit with Cu2SiSe3 – as this should also work fine with the doped solver right? But it crashed out with a ValueError, which I think is probably related to how the chemical potentials are being fed to doped here (i.e. with this difference between how they should be handled for doped vs py-sc-fermi). I left this in the notebook, would you mind having a quick look at how this is integrated and if it's an easy fix?

@alexsquires
Copy link
Member Author

alexsquires commented Mar 20, 2024

todo:

  • chemical potential consistency with other parts of doped
  • default handling for multiplicity scaling
  • rename exceptions
  • finish docstrings
  • pre-commit checks
  • metastable defects check
  • consistency or highlighting of chempot handling
  • note for how the sign of the effective dopant concentration works
  • bugfix for grid scan in doped
  • handle warnings
  • retcon the default gridscan behaviour so that it seems like add chempots as a class attribute was deliberate, not just a way to cover up an awkward inconsistency between the codes

@kavanase kavanase added the enhancement New feature or request label Mar 29, 2024
alexsquires and others added 3 commits April 2, 2024 19:36
# Conflicts:
#	docs/Tutorials.rst
#	doped/core.py
#	doped/thermodynamics.py
@kavanase
Copy link
Member

kavanase commented Apr 6, 2024

@alexsquires are you still working away on this or do you want me to look over? Just checking!

@alexsquires
Copy link
Member Author

alexsquires commented Apr 6, 2024 via email

Copy link

coderabbitai bot commented May 13, 2024

Important

Review Skipped

Auto reviews are disabled on base/target branches other than the default branch. Please add the base/target branch pattern to the list of additional branches to be reviewed in the settings.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

Share
Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai generate interesting stats about this repository and render them as a table.
    • @coderabbitai show all the console.log statements in this repository.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (invoked as PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger a review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai help to get help.

Additionally, you can add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.

CodeRabbit Configration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@alexsquires
Copy link
Member Author

@kavanase has something changed with the chemical potentials? Cu2SiSe3 example no longer has limits wrt the elements, CdTe does?

@kavanase
Copy link
Member

@alexsquires I'm not totally sure what you're referring to here. I checked the chempots json files in the examples folders (examples/CdTe & examples/Cu2SiSe3), and they both seem to have the "limits_wrt_el_refs" subdict present:

CdTe:
image

Cu2SiSe3:
image

@kavanase
Copy link
Member

Also just to mention from looking through there, for consistency and reducing user confusion, it would be good to use the same chempots/el_refs/limit inputs format, nomenclature (chempots vs chemical_potentials) and handling as in the DefectThermodynamics methods. Should just be a copy and paste job to use them 🙏

e.g. from thermodynamics.py:

    def get_equilibrium_fermi_level(
        self,
        bulk_dos_vr: Union[str, Vasprun, FermiDos],
        chempots: Optional[dict] = None,
        limit: Optional[str] = None,
        el_refs: Optional[dict] = None,
        temperature: float = 300,
        return_concs: bool = False,
        effective_dopant_concentration: Optional[float] = None,
    ) -> Union[float, tuple[float, float, float]]:
        r"""
        ...
            chempots (dict):
                Dictionary of chemical potentials to use for calculating the defect
                formation energies (and thus concentrations and Fermi level).
                If ``None`` (default), will use ``self.chempots`` (= 0 for all chemical
                potentials by default).
                This can have the form of ``{"limits": [{'limit': [chempot_dict]}]}``
                (the format generated by ``doped``\'s chemical potential parsing
                functions (see tutorials)) and specific limits (chemical potential
                limits) can then be chosen using ``limit``.

                Alternatively this can be a dictionary of chemical potentials for a
                single limit (limit), in the format: ``{element symbol: chemical potential}``.
                If manually specifying chemical potentials this way, you can set the
                ``el_refs`` option with the DFT reference energies of the elemental phases,
                in which case it is the formal chemical potentials (i.e. relative to the
                elemental references) that should be given here, otherwise the absolute
                (DFT) chemical potentials should be given.
            limit (str):
                The chemical potential limit for which to
                determine the equilibrium Fermi level. Can be either:

                - ``None``, if ``chempots`` corresponds to a single chemical potential
                  limit - otherwise will use the first chemical potential limit in the
                  ``chempots`` dict.
                - ``"X-rich"/"X-poor"`` where X is an element in the system, in which
                  case the most X-rich/poor limit will be used (e.g. "Li-rich").
                - A key in the ``(self.)chempots["limits"]`` dictionary.

                The latter two options can only be used if ``chempots`` is in the
                ``doped`` format (see chemical potentials tutorial).
                (Default: None)
            el_refs (dict):
                Dictionary of elemental reference energies for the chemical potentials
                in the format:
                ``{element symbol: reference energy}`` (to determine the formal chemical
                potentials, when ``chempots`` has been manually specified as
                ``{element symbol: chemical potential}``). Unnecessary if ``chempots`` is
                provided/present in format generated by ``doped`` (see tutorials).
                (Default: None)
            ...
        """
        fermi_dos = self._parse_fermi_dos(bulk_dos_vr)
        chempots, el_refs = self._get_chempots(
            chempots, el_refs
        )  # returns self.chempots/self.el_refs if chempots is None
        ...

…np.isclose` over `assertAlmostEqual` etc), pull chempots from DefectThermodynamics if present and not supplied...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants