nomad-coe / electronic-parsers

Apache License 2.0
18 stars 7 forks source link

Core hole vasp #181

Closed ndaelman-hu closed 6 months ago

ndaelman-hu commented 8 months ago

Identification of the core-hole (location + orbital level) with appropriate references to run.system.atoms_group so topology view is leveraged. This will be further extended to FHIaims and ATOMPAW in separate PRs.

ndaelman-hu commented 8 months ago

Left to do:

ondracka commented 7 months ago

I can't comment much on the VASP parser changes, but rather on the general metainfo changes (doing this here due to no access to the upstream github). In general this would suit my needs, but at least for Wien2k for states with n>1 where a spin-orbit splitting happens, like 2p states, I can actually specify if I want the corehole for 2p1/2 or 2p3/2, and equivalently for d and f states. I could likely also specify up and down spin state with Wien2k (but I never did that). I checked the VASP docs and there is seems this is not possible, but I would expect that maybe other all-electron codes can do this as well. My another favorite code OpenMX also allows all kinds of core-holes (there is nice table at https://www.openmx-square.org/openmx_man3.9/node192.html) there it also depends whether one has collinear or non-collinear spin polarization. So maybe we need more quantum numbers...

ondracka commented 7 months ago

One question is if we also want to somehow explicitly include somewhere the charge info at this point. Together with with the corehole usually also comes the question about where to put the extra charge. I.e., if the electron was removed from the cell (and a homogeneous background change was added so that the calculations behave in a sane way) but it is actually a charged cell (this is usually done for insulators) or if the electron was placed at the Fermi level (this would make sense for core-hole in metals). This is not related just to the core-hole and is relevant also for other methods (for charged-defect calculations in insulators, etc.). I believe VASP always adds the background charge automatically for example (and it will probably diverge for a true charged cell anyway).)

ndaelman-hu commented 7 months ago

I can't comment much on the VASP parser changes, but rather on the general metainfo changes (doing this here due to no access to the upstream github). In general this would suit my needs, but at least for Wien2k for states with n>1 where a spin-orbit splitting happens, like 2p states, I can actually specify if I want the corehole for 2p1/2 or 2p3/2, and equivalently for d and f states. I could likely also specify up and down spin state with Wien2k (but I never did that). I checked the VASP docs and there is seems this is not possible, but I would expect that maybe other all-electron codes can do this as well. My another favorite code OpenMX also allows all kinds of core-holes (there is nice table at https://www.openmx-square.org/openmx_man3.9/node192.html) there it also depends whether one has collinear or non-collinear spin polarization. So maybe we need more quantum numbers...

Thank you for pointing that out! I'll open up tickets for OpenMX then, and merge the schema after having working parsers for both parsers.

ndaelman-hu commented 7 months ago

One question is if we also want to somehow explicitly include somewhere the charge info at this point. Together with with the corehole usually also comes the question about where to put the extra charge. I.e., if the electron was removed from the cell (and a homogeneous background change was added so that the calculations behave in a sane way) but it is actually a charged cell (this is usually done for insulators) or if the electron was placed at the Fermi level (this would make sense for core-hole in metals). This is not related just to the core-hole and is relevant also for other methods (for charged-defect calculations in insulators, etc.). I believe VASP always adds the background charge automatically for example (and it will probably diverge for a true charged cell anyway).)

Very good point! We keep track of the no. (valence) electrons and overall system charge under run.method.electronic. We could just improve the normalizers here and make this information more visible in the Entry Overview. This would allow for finding core-holes with the electron exited to the Fermi level or the vacuum.

But maybe we want something more explicit when core-holes are being used? VASP also allows partial core-holes, as well as initial and final state approximations. @ondracka Are these also used in Wien2k or OpenMX? That would help me decide on their placement in the schema.

ondracka commented 7 months ago

Thank you for pointing that out! I'll open up tickets for OpenMX then, and merge the schema after having working parsers for both parsers.

Let me know if you need some test-cases. Here is a simple C 1s corehole in OpenMX: https://nomad-lab.eu/prod/v1/staging/gui/search/calculations/entry/id/zLqikxv-mfCrI3sC9EuXmqfEX04T but I can also produce something simpler and more suitable for eventual inclusion in parser unit tests (or also for the other core-holes than 1s). For Wien2k I have some N1s core-hole: https://nomad-lab.eu/prod/v1/staging/gui/search/entries/entry/id/Fbk7yucgh7CxMsp0RKdR263J_OIj , O1s https://nomad-lab.eu/prod/v1/staging/gui/search/entries/entry/id/1GH5Rvm-t2tAYPrL9UdtkShaas3s, or Ti2p3/2 https://nomad-lab.eu/prod/v1/staging/gui/search/entries/entry/id/s5W753xr30EulmEUzsu75HMtxZMh coreholes in NOMAD already.

ondracka commented 7 months ago

Very good point! We keep track of the no. (valence) electrons and overall system charge under run.method.electronic. We could just improve the normalizers here and make this information more visible in the Entry Overview. This would allow for finding core-holes with the electron exited to the Fermi level or the vacuum.

But maybe we want something more explicit when core-holes are being used? VASP also allows partial core-holes, as well as initial and final state approximations. @ondracka Are these also used in Wien2k or OpenMX? That would help me decide on their placement in the schema.

Partial core-holes with arbitrary fraction are easy in Wien2k (and probably other LAPW all electron codes), however I'm not aware that this would be possible in OpenMX. Regarding the "initial" states, i.e., I assume you are referring to what VASP would be doing with ICORELEVEL=1 this is what all-electron codes do by default (and at that point there is no core-hole at all actually, just VASP includes the core-levels in the calculations instead of using pseudopotential), so for all-electron codes this is just standard groundstate. For OpenMX "initial state" one actually needs specific pseudopotential and basis set for the atom with the core-hole that include the core-level in question, but no other setting are needed. So I think that for VASP run with ICORELEVEL=1 there would be no CoreHole section and the fact that the extra core electron are explicitly included would be encoded somehow in the pseudopotential section. "Final state" is the true core-hole calculation.

ndaelman-hu commented 7 months ago

but at least for Wien2k for states with n>1 where a spin-orbit splitting happens, like 2p states, I can actually specify if I want the corehole for 2p1/2 or 2p3/2, and equivalently for d and f states. I could likely also specify up and down spin state with Wien2k (but I never did that).

This is supported now.

My another favorite code OpenMX also allows all kinds of core-holes (there is nice table at https://www.openmx-square.org/openmx_man3.9/node192.html) there it also depends whether one has collinear or non-collinear spin polarization. So maybe we need more quantum numbers...

Let me look into this. Maybe support for non-collinear calculations requires its own PR. Feel free to make any suggestions.

ndaelman-hu commented 7 months ago

Let me know if you need some test-cases. Here is a simple C 1s corehole in OpenMX: https://nomad-lab.eu/prod/v1/staging/gui/search/calculations/entry/id/zLqikxv-mfCrI3sC9EuXmqfEX04T but I can also produce something simpler and more suitable for eventual inclusion in parser unit tests (or also for the other core-holes than 1s).

@ondracka It seems that OpenMX reads the pseudopotentials from a different folder. Since the files are not copied over to the calculation folder, I guess it's unlikely that people will upload them.

Personally, I prefer reading the original pseudopotential file, but I guess that here it's better to build out an interpreter of the filename. Do you agree? How reliable is this approach?

ndaelman-hu commented 7 months ago

Regarding the "initial" states, i.e., I assume you are referring to what VASP would be doing with ICORELEVEL=1

Indeed, this is the terminology they use in the VASP Wiki.

this is what all-electron codes do by default (and at that point there is no core-hole at all actually, just VASP includes the core-levels in the calculations instead of using pseudopotential), so for all-electron codes this is just standard groundstate.

@ondracka I fully agree with your explanation of the methodology. However, in most contexts, ICORELEVEL=1is employed with Koopmans theorem or Slater's Transition method to produce CLBEs. One such example (not with VASP) would be here. An overview of the various approaches is given in the first 2 paragraphs on page 2.

So, I see 2 options:

  1. I infer that anyone using ICORELEVEL=1, does so with the intention of computing a core-level. There are several ways to approximate this (Koopman, or any of the fractional occupations listed above). If I know which state is targeted, I could even produce all the numbers.
  2. I leave it up to the user to specify if they used the orbitals for computing the core-hole, as well as the actual scheme they used. This would come closer to what you proposed.

Let me know what you think.

ondracka commented 7 months ago

Let me look into this. Maybe support for non-collinear calculations requires its own PR. Feel free to make any suggestions.

I think this is OK for now, lets revisit the non-collinear case when we actually have some use cases...

ondracka commented 7 months ago

Personally, I prefer reading the original pseudopotential file, but I guess that here it's better to build out an interpreter of the filename. Do you agree? How reliable is this approach?

I'm only aware of the one set of pseudos provided by the OpenMX developers (versioned by the releases), so it should be quite reliable (unless people really handcraft their own pseudos, but that should be not too common).

ondracka commented 7 months ago

I went quickly through the actual code changes and while I was not reviewing the logic per se, the general idea how things are done now looks fine, so I'm happy with how this turned out in general.

ndaelman-hu commented 7 months ago

@ladinesa @lauri-codes Design question: core-holes are kind of connected to various other sections (too much interconnectivity):

  1. Each run.method.CoreHole has to reference an run.system.AtomsGroup (this also applies to other sections, such as CoreHoleSpectra). Atm, I set these manually in the parsers, but I get the feeling that this could be done by a normalizer. I guess one could loop over all AtomParameters which contain CoreHole, but it sounds suboptimal: it requires the atom indexes too... Moreover, they might be other sections that do not fall under AtomsParameters. I'd rather have a push-system that works for any AtomsGroup - Methods.subs_section pair. Any ideas?
  2. The computation of Method.charge is contingent on CoreHole. Same remark as above.
  3. CoreHole is in many cases specified in the same parsed blocks / files as Pseudopotential. I'm trying to package both together in each new implementation now.
lauri-codes commented 7 months ago

I think the parser is ultimately responsible for setting all connections in place. A normalizer could very well be used to e.g. check the validity of the data or to add new derived data.

Note that it is of course fine to have a single unified function in e.g. nomad or in the electronicparsers package that is shared between all parsers and resolves all the references. I think this approach is often used in the atomisticparsers package, where several tasks are common for the parsers.

ndaelman-hu commented 7 months ago

I think the parser is ultimately responsible for setting all connections in place. A normalizer could very well be used to e.g. check the validity of the data or to add new derived data.

Note that it is of course fine to have a single unified function in e.g. nomad or in the electronicparsers package that is shared between all parsers and resolves all the references. I think this approach is often used in the atomisticparsers package, where several tasks are common for the parsers.

I get your point, in that the logical structure of the output may vary and this is where the parser has to jump in, of course. However, the schema on our side will always be AtomsGroup pointing to CoreHole, where the latter may alter the overall charge (and is often set along with the Pseudopotential).

For anyone extending the parsers, this structure is far from obvious, nor is it clearly communicated anywhere. My first instinct, for example, was to extend AtomsGroup, rather than Method. I think we have to communicate these kinds of designs better to other (external) devs, since we're headed in the direction of a modular platform.

Maybe a normalizer is not appropriate here. Another option that come to mind is a FactoryMethod, which delivers (maybe even sets) a AtomsGroup - CoreHole pair. If we go this route, where would this best be added? In util.py?

lauri-codes commented 7 months ago

My first suggestion would be to include the method in the electronicparsers repo if it is only relevant for these parsers. But if the implementation should be shared across different parser repos, then util.py is an option.

ndaelman-hu commented 7 months ago

@ondracka From the OpenMX documentation, I'm understanding that CLBEs are computed using $\Delta$-SCF between the initial (containing the corrected pseudopotential) and final state (corrected pseudopotential + electron removed). Is this correct?

I'm asking, since the terminology is confusing with VASP's, where initial-state approximation (icorelevel = 1) is a single SCF with Koopman. There, the $\Delta$-SCF is between a regular groundstate (same pseudopotential) and a final-state approximation (icorelevel = 2).

ondracka commented 7 months ago

@ondracka From the OpenMX documentation, I'm understanding that CLBEs are computed using Δ-SCF between the initial (containing the corrected pseudopotential) and final state (corrected pseudopotential + electron removed). Is this correct?

That is my understanding as well.

ndaelman-hu commented 7 months ago

@ondracka From the OpenMX documentation, I'm understanding that CLBEs are computed using Δ-SCF between the initial (containing the corrected pseudopotential) and final state (corrected pseudopotential + electron removed). Is this correct?

That is my understanding as well.

Okay, great! I'm close to finishing with OpenMX too, will request you to review then.

JosePizarro3 commented 7 months ago

Btw, is something included in the TBStudio parser regarding the active atom?

ndaelman-hu commented 7 months ago

Btw, is something included in the TBStudio parser regarding the active atom?

Hey, thx for mentioning TBStudio. I had to rebase first, now I can see that parser too. Atm, it does not assign any atoms_groups, so it won't break with any of my changes. I will add support when extending core_hole to atomic orbitals in general. I'll open an issue this evening.

ndaelman-hu commented 7 months ago

Very nice. Please, don't forget to change also workflowparsers/quantum_espresso_xspectra with the new CoreHoleSpectra.

I will keep up with the discussion about nesting AtomsGroup.

Btw, can you share some examples and add testing?

@JosePizarro3 Can you pls lift the change request in your review. That applied to an old version. Your suggestions have been incorporated.