For example I make an empty system and the default periodic boundary conditions are an arbitrary box:
Code: Select all
In [1]: import simtk.openmm as omm
In [3]: sys = omm.System()
In [4]: sys.getDefaultPeriodicBoxVectors()
Out[4]:
[Quantity(value=Vec3(x=2.0, y=0.0, z=0.0), unit=nanometer),
Quantity(value=Vec3(x=0.0, y=2.0, z=0.0), unit=nanometer),
Quantity(value=Vec3(x=0.0, y=0.0, z=2.0), unit=nanometer)]
I ask because if you do have a system that is not periodic and then run a getState on a context of this system with the enforcePeriodicBox set to True, then you get a system with the arbitrary default boundary conditions applied to them.
I understand that you should just set enforcePeriodicBox to False, but I think it makes sense to have a "Null" value for boundary conditions if possible. This is helpful when running many different systems in an automatic way (say openmmtools testsystems). If you can't have this configuration of Null box vectors in the system itself then you have to add an additional external configuration to ignore the boxes. I know this will only effect particular use cases but it was surprising and difficult to track down the root cause of because my expectation for non-periodic systems is that an enforcement of a null (or I guess the identity algebraically speaking) box is that it will be unchanged. Especially when the box vectors were never actually manually set. To take the idea a little further it could even be a "type" error of sorts to have a box when it is not used.
It also begs the question of what would be a good "default" for a System. From a usability perspective having an actual default that doesn't result in a type error could be could be confusing in creating new systems (for instance if you don't explicitly set the box). The options AFAI can see are: 1. A null box which always throws an error so that the user must always supply a perdiodic box, 2. the "zero" or identity box which when enforced always returns the same thing and is not accounted for in the force calculations i.e. no box at all, 3. some arbitrarily chosen box, or 4. an automatic box guesser. I think 2, 3, and 4 are bad ideas for defaults because they are likely to be wrong for any use case, in which case nothing should be assumed. Using option 1 as the default reduces the issue to a type error instead of having to run simulations, then incorrectly read the state and then try to figure out what went wrong. Because everyone makes mistakes!