I checked bulk.py and realised there’s no support for tetragonal crystalstructure. Is this intended? The only mention of “tetragonal“ in bulk.py is just in the “structures“ dictionary. Else it seems to me it’s never used.
Hi bern,
`ase.build.bulk()` probably isn’t destined to support every type of crystal structure: It tries to do many things, and not all of those things are a good idea for just one function. If we were to add tetragonal to bulk(), we should equally well add RHL, ORCI, ORCF, MCL, MCLC and all the others, and add the corresponding parameters etc., and that’s too many parameters. It’s already questionable that the function takes something called `u`, which then makes a complicated matrix of which parameters can be used simultaneously.
A better approach is to split responsibilities into more basic things: One function to get the reference state of any element (that’s what I think bulk() does best), and one function to generate each kind of crystal structure when you know what structure it is.
If we want a function to build structures from every Bravais lattice, then we could make one based on the framework in `ase.lattice` which is a more complete set of definitions. Basically adding a function which combines a Bravais lattice with a basis.
What I don’t think bulk() should do is all the mixed types like zincblende, rocksalt, etc., because that’s not a well limited problem. We could have separate helper functions like `zincblende()` for common composite structures.
Best regards
Ask
There does seem to be an oversight here, as tetragonal is listed as an option in the docs
But doesn’t seem to be usable, e.g.
In [3]: bulk('Si', crystalstructure='tetragonal', a=2, c=4, orthorhombic=True)
---------------------------------------------------------------------------
RuntimeError Traceback (most recent call last)
Cell In[3], line 1
----> 1 bulk('Si', crystalstructure='tetragonal', a=2, c=4, orthorhombic=True)
File ~/src/ase/ase/build/bulk.py:182, in bulk(name, crystalstructure, a, b, c, alpha, covera, u, orthorhombic, cubic, basis)
180 atoms = Atoms(name, cell=[a, b, c], pbc=True)
181 elif orthorhombic:
--> 182 atoms = _orthorhombic_bulk(name, crystalstructure, a, covera, u)
183 elif cubic:
184 atoms = _cubic_bulk(name, crystalstructure, a)
File ~/src/ase/ase/build/bulk.py:267, in _orthorhombic_bulk(name, crystalstructure, a, covera, u)
265 atoms = Atoms(4 * name, cell=cell, scaled_positions=scaled_positions)
266 else:
--> 267 raise incompatible_cell(want='orthorhombic', have=crystalstructure)
269 atoms.pbc = True
271 return atoms
RuntimeError: Cannot create orthorhombic cell for tetragonal structure
(Without orthorhombic=True it complains it cannot create an orthorhombic primitive.)
We should be able to fix this with a case that sets a=b and then treats it as orthorhombic?
Or we can drop the tetragonal option and let users specify an “orthorhombic” cell with a=b. But then why support cubic, etc.
I think we should for now think of build.bulk() as a very basic tool. Its main daily usecase is “gimme some aluminium”. There are already many combinations of options that may or may not work. For example which specific set of crystals work with the orthorhombic or cubic booleans, and how will it behave if one requests a combination that was not anticipated. It is also difficult to loop over multiple things because it does not systematically expose the information that it uses internally.
If we want to expand the capabilities of bulk(), we should probably start by systematically tabulating the information it holds inside, like we have importable information about the Bravais lattices in `ase.lattice` (indeed bulk() could import things from that module).
In principle bulk() could be a thin lookup mechanism on top of tabulated data instead of a moderately Lovecraftian entity as now.
