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

ZBL short-range potential #335

Merged
merged 23 commits into from
Oct 9, 2024
Merged

ZBL short-range potential #335

merged 23 commits into from
Oct 9, 2024

Conversation

frostedoyster
Copy link
Collaborator

@frostedoyster frostedoyster commented Sep 11, 2024

Contributor (creator of pull-request) checklist

  • Tests updated (for new features and bugfixes)?
  • Documentation updated (for new features)?

📚 Documentation preview 📚: https://metatrain--335.org.readthedocs.build/en/335/

Copy link
Contributor

@PicoCentauri PicoCentauri left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wonderful and very useful addition. I think one can tackle the unit conversion.

@@ -71,7 +71,7 @@ def train(

logger.info("Subtracting composition energies")
# this acts in-place on train_y
remove_composition(
remove_additive(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you change the name? Isn't it really to remove the composition?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now it can remove any type of additive contribution (e.g. ZBL, which is handled in the same way as the composition)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, I thought about a better name, but makes sense now.

Comment on lines +42 to +45
if dataset_info.length_unit != "angstrom":
raise ValueError(
"ZBL only supports angstrom units, but a "
f"{dataset_info.length_unit} unit was provided."
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can do unit conversion in the end no? Should be fairly trivial. The values are there in metatensor atomistic.

Copy link
Collaborator Author

@frostedoyster frostedoyster Sep 16, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know... I think it's a bit tricky and I thought the best way for now would be to enforce Angstroms and eV. Where would you do the unit conversion (both at training time and at prediction time)? And what if the user doesn't specify any units?

I wonder if @Luthaf has any ideas for this

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I agree that it might be a bit painful, but since we have units in our config I think we should support them. I would pass the units when you actually compute the potential using get_pairwise_zbl. We could save the length unit and the energy unit as property.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could the ZBL class take the units as __init__ parameters, do the conversion when instantiating itself and then store values in the right units?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, metatrain gives you the opportunity to train without any units. Do we error out in that case? And do we want to have a units module in metatrain, or can we perhaps recycle the one from ASE?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, metatrain gives you the opportunity to train without any units. Do we error out in that case?

yes, I would error out in this case

And do we want to have a units module in metatrain, or can we perhaps recycle the one from ASE?

I don't really mind, we can also use the code from metatensor: https://docs.metatensor.org/latest/atomistic/reference/models/index.html#metatensor.torch.atomistic.unit_conversion_factor

Comment on lines +53 to +57
if target.unit != "eV":
raise ValueError(
"ZBL only supports eV units, but a "
f"{target.unit} output was provided."
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as above

src/metatrain/utils/additive/zbl.py Outdated Show resolved Hide resolved
@abmazitov
Copy link
Contributor

Looks good to me, I don't see any potential issues with PET at first glance
As the tests are fixed, we can merge this I think
But please wait until #344, it is once step from being merged

@frostedoyster frostedoyster changed the title ZBL potential (not integrated into any architecture yet) ZBL short-range potential Sep 24, 2024
@frostedoyster
Copy link
Collaborator Author

IMO, since multiple people need this, we should merge as is, without worrying about handling different units or neighbor lists. We can open issues however to keep track of those

@abmazitov
Copy link
Contributor

Okay, so I tried to run PET + ZBL, and there are a few things to note.

  1. ZBL only supports the cutoff which is 2x larger than the largest covalent radius in the dataset. In the case of MAD dataset, it results in the minimal cutoff of ~4.9 A, which is already large than our current 4.5 A cutoff. Maybe we should change the factor to at least 1.5? In this case the minimal cutoff will be 3.66, at it seems more reasonable.
  2. This check for ZBL minimal cutoff happens only during the evaluations, i.e. after the model was trained. Perhaps it should happen in the beginning of the training.
  3. There is a large block of converting the NL from half to full format in the ZBL code:
# convert to full NL
half_nl = system.get_neighbor_list(nl_option)
half_nl_samples = half_nl.samples.values
half_nl_values = half_nl.values
nl = TensorBlock(
    samples=Labels(
        names=half_nl.samples.names,
        values=torch.concatenate(
            [
                half_nl_samples,
                torch.concatenate(
                    [
                        half_nl_samples[:, 1].unsqueeze(-1),
                        half_nl_samples[:, 0].unsqueeze(-1),
                        -half_nl_samples[:, 2:5],
                    ],
                    dim=1,
                ),
            ]
        ),
    ),
    components=half_nl.components,
    properties=half_nl.properties,
    values=torch.concatenate(
        [
            half_nl_values,
            -half_nl_values,
        ],
    ),
)

Maybe it makes sense to transfer this code to utilities? It might be useful to have something like this as a utility for other applications, and clean-up the code a bit.

@frostedoyster
Copy link
Collaborator Author

Thanks a lot @abmazitov for testing this out. Unfortunately the factor of 2 is not something arbitrary but it's given by the necessity of making the potential continuous while re-using the neighbor list of the ML potential. I thought the values were pretty safe in a general case, but you have large atoms and a small cutoff so it goes over by a bit... I think the best solution is to make ZBL request its own NL, as painful as it might be, which would also spare us the NL conversion step that you highlighted.

Finally, the fact that the error is only raised after training is finished is a huge bug and I will be investigating it

@frostedoyster
Copy link
Collaborator Author

frostedoyster commented Sep 27, 2024

Things to be done:

  • ZBL needs to be able to request its own NL in case it's larger than the one from the model or a different kind (ZBL always wants full, right now we're using a slow converter)
  • Improve the covalent radii design that we're inheriting from ASE, i.e., the elements for which ASE devs didn't find a covalent radius are listed as "0.2 A". And find a solution in case the user wants to use ZBL with these elements
  • Carefully check the units. The lengthscales are reasonable but the height of the repulsive wall is suspicious

Copy link
Member

@Luthaf Luthaf left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good to me. Regarding unit conversion, since the code will currently error if the units are wrong there is no way to silently introduce mistakes, so I'm happy to merge as is for now and open an issue for unit conversion in ZBL.

Comment on lines 1 to 2
Data
====
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Title seems wrong for this section

# We have to import ``rascaline.torch`` even though it is not used explicitly in this
# tutorial. The SOAP-BPNN model contains compiled extensions and therefore the import
# is required.
#
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎉

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well spotted, thanks!

@frostedoyster frostedoyster merged commit cc84568 into main Oct 9, 2024
12 checks passed
@frostedoyster frostedoyster deleted the zbl branch October 9, 2024 16:12
@frostedoyster frostedoyster mentioned this pull request Oct 9, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants