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
Partial periodic boundary conditions #2429
Conversation
Thanks for this PR @gpetretto! I appreciate the write-up and detailed thoughts, I'll take some time to read it over and think about the concerns raised. |
Hi @mkhorton, sorry for the bothering, but do you have any update on this? |
Thanks for your patience @gpetretto and thank you for the reminder (it was necessary! apologies, been busy recently). I've had a look over the PR now and it looks good to me. I like this approach overall. I'm not familiar enough to guarantee the Cython code is correct so I will trust you and the tests on this. Do you have any remaining concerns? |
Thanks for the reply @mkhorton. Just to be sure, do you mean that the comments in the opening post do not need further discussion and things can stay roughly as they are in the current PR? |
Yes, I would agree with finalizing the PR and using this approach. If anyone disagrees however or has further input, now is the time to comment! |
I fixed a few points and added tests. If there are no other comments this sohuld be ready for a review and merge. |
pymatgen/core/lattice.py
Outdated
@@ -40,7 +40,7 @@ class Lattice(MSONable): | |||
|
|||
# Properties lazily generated for efficiency. | |||
|
|||
def __init__(self, matrix: ArrayLike): | |||
def __init__(self, matrix: ArrayLike, pbc: tuple[bool, bool, bool] | None = None): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is there a need to use None here? We can just default to (True, True, True)? This is a tuple, which is not mutable. It is allowed as an arg.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed. I think I did it because it was easier to avoid issues with some tests failing during the first draft. Then I didn't think of changing it. It should be fixed now
pymatgen/core/lattice.py
Outdated
@@ -64,6 +66,11 @@ def __init__(self, matrix: ArrayLike): | |||
self._diags = None | |||
self._lll_matrix_mappings = {} # type: Dict[float, Tuple[np.ndarray, np.ndarray]] | |||
self._lll_inverse = None | |||
if pbc is None: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not needed.
pymatgen/core/lattice.py
Outdated
@@ -206,49 +223,55 @@ def d_hkl(self, miller_index: ArrayLike) -> float: | |||
return 1 / ((dot(dot(hkl, gstar), hkl.T)) ** (1 / 2)) | |||
|
|||
@staticmethod | |||
def cubic(a: float) -> Lattice: | |||
def cubic(a: float, pbc: tuple[bool, bool, bool] | None = None) -> Lattice: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same comment as the __init__
.
Thanks |
Summary
As a follow up to #2364 I am opening this PR to discuss about the introduction of partial periodic boundary conditions (PPBC).
Details
This first draft is based on these main points:
Lattice
with a tuple of three bool in thepbc
attribute, defining the periodic boundary conditions along the three edges of the lattice.Lattice
get their periodic boundary conditions from it. This avoids inconsistencies among different objects. i.e.PeriodicSite
andStructure
have the same reference to define the PBC.Molecule
andStructure
stay on two different branches of the inheritance tree starting fromSiteCollection
, even thoughMolecule
could be thought of a subset of the case wherepbc=(False, False, False)
.PeriodicSite
. This ensures the backward compatibility with the serialised data and avoids the ambiguity of whatfrac_coords
would mean in PPBC. This implies that a somewhat meaningful 3D Lattice should be defined even with PPBC.Based on these, the changes required to the code are relative small and seems that backward compatibility could be easily preserved (at least, all the tests pass).
In practice, the main changes are the addition of the
pbc
attribute and the updates to take it into account in functions related to distances and whereto_unit_cell
is True. Since distances are calculated in a few key functions, the changes should propagate to all functions that rely on these.Being a first draft I did not add any test and changed the docstrings in just a few places. I also did not run the checks for the coding style.
I am not used to write cython code, so some additions in coord_cython.pyx could probably be optimised. Also, the standard implementation of
pbc_shortest_vectors
relies on the LLL reduced lattice and makes it incompatible with thepbc
. Is there a specific reason for that, aside from the use of thelll_frac_tol
argument? I switched to the standard lattice if the crystal is not 3D periodic.Example
gives 1.82756669, instead of 0.37416574 with
pbc=(True, True, True)
.Comments
Assuming that the main points listed above are fine, here are some more considerations.
It would be relevant to to decide if this new feature should stay directly in
Structure
(as implemented here) or a new intermediate class should be introduced betweenSiteCollection
andStructure
, withStructure
havingpbc=(True, True, True)
fixed.If the PPBC stay in
Structure
, how to handle its subclasses (e.g.Slab
,Interface
,SymmetrizedStructure
)? I suppose that for most of them PPBC would not make sense.How should all the objects that accept a
Structure
behave? For example running theSpacegroupAnalyzer
should not be meaningful for PPBC. Should these make checks onpbc
and raise?Could objects like the
StructureMatcher
be adapted to work with PPBC?Concering
Lattice
:pbc
attribute be immutable?pbc=(False, False, False)
be allowed?get_niggli_reduced_lattice
,get_wigner_seitz_cell
will keep working while ignoringpbc
, but are likely to return inconsistent results for PPBC. Should they raise an error? Methods likescale
should still act on the whole lattice, or modify only the periodic directions?Concerning
Structure
:get_primitive_structure
,get_orderings
could probably be adapted to work with PPBC, but I suppose it will not be straightforward. Should this be done?Structure
? Are there file formats that support PPBC?__mul__
)While it would not necessarily be the best option, I would say that allowing PPBC only in a new class, parent of
Structure
, should avoid easily all the problems related to checks in cases where a fully periodicStructure
is expected.