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

Addition of the MOFs core M6L8L12 #529

Closed
wants to merge 13 commits into from
1 change: 1 addition & 0 deletions docs/source/cage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ Metal-Organic
M4L8 <_autosummary/stk.cage.M4L8>
M6L2L3 Prism <_autosummary/stk.cage.M6L2L3Prism>
M6L12 Cube <_autosummary/stk.cage.M6L12Cube>
M6L8L12 Cuboctahedron <_autosummary/stk.cage.M6L8L12Cuboctahedron>
M8L6 Cube <_autosummary/stk.cage.M8L6Cube>
M12L24 <_autosummary/stk.cage.M12L24>
M24L48 <_autosummary/stk.cage.M24L48>
215 changes: 215 additions & 0 deletions src/stk/_internal/topology_graphs/cage/m6l8l12_cuboctahedron.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,215 @@
import numpy as np

from stk._internal.topology_graphs.edge import Edge

from .cage import Cage
from .vertices import LinearVertex, NonLinearVertex


class M6L8L12Cuboctahedron(Cage):
"""
Represents a cage topology graph.

Unoptimized construction

.. moldoc::

import moldoc.molecule as molecule
import stk

m1 = stk.BuildingBlock('[Ti](Br)(Br)(Br)(Br)(Br)(Br)(Br)(Br)', functional_groups=[stk.BromoFactory()])
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can you change all line lengths to be less than 72, even if in doc string?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Sorry, 79


bb1 = stk.BuildingBlock('C(OBr)=[O+]Br', functional_groups=[stk.BromoFactory()])

bb2 = stk.BuildingBlock('[O+](Br)(Br)(Br)', functional_groups=[stk.BromoFactory()])

cage = stk.ConstructedMolecule(
topology_graph = stk.cage.M6L8L12Cuboctahedron(
building_blocks = {
m1:range(0,6),
bb1:range(6,18),
bb2:range(18,26)
},
optimizer=stk.Collapser(),
)
)

moldoc_display_molecule = molecule.Molecule(
atoms=(
molecule.Atom(
atomic_number=atom.get_atomic_number(),
position=position,
) for atom, position in zip(
cage.get_atoms(),
cage.get_position_matrix(),
)
),
bonds=(
molecule.Bond(
atom1_id=bond.get_atom1().get_id(),
atom2_id=bond.get_atom2().get_id(),
order=(
1
if bond.get_order() == 9
else bond.get_order()
),
) for bond in cage.get_bonds()
),
)

:class:`.Collapser` optimized construction

.. moldoc::

import moldoc.molecule as molecule
import stk

m1 = stk.BuildingBlock('[Ti](Br)(Br)(Br)(Br)(Br)(Br)(Br)(Br)', functional_groups=[stk.BromoFactory()])

bb1 = stk.BuildingBlock('C(OBr)=[O+]Br', functional_groups=[stk.BromoFactory()])

bb2 = stk.BuildingBlock('[O+](Br)(Br)(Br)', functional_groups=[stk.BromoFactory()])

cage = stk.ConstructedMolecule(
topology_graph = stk.cage.M6L8L12Cuboctahedron(
building_blocks = {
m1:range(0,6),
bb1:range(6,18),
bb2:range(18,26)
},
optimizer=stk.Collapser(),
)
)

moldoc_display_molecule = molecule.Molecule(
atoms=(
molecule.Atom(
atomic_number=atom.get_atomic_number(),
position=position,
) for atom, position in zip(
cage.get_atoms(),
cage.get_position_matrix(),
)
),
bonds=(
molecule.Bond(
atom1_id=bond.get_atom1().get_id(),
atom2_id=bond.get_atom2().get_id(),
order=(
1
if bond.get_order() == 9
else bond.get_order()
),
) for bond in cage.get_bonds()
),
)

Metal building blocks with eight functional groups are
required for this topology.

One ligand building blocks with two functional groups and another ligand
building block with three functional groups are required for
this topology.

When using a :class:`dict` for the `building_blocks` parameter,
as in :ref:`cage-topology-graph-examples`:
*Multi-Building Block Cage Construction*, a
:class:`.BuildingBlock`, with the following number of functional
groups, needs to be assigned to each of the following vertex ids:

| 8-functional groups: 0 to 5
| 2-functional groups: 6 to 17
| 3-functional groups: 18 to 25

See :class:`.Cage` for more details and examples.

"""

_x = np.sqrt(2) / 2
_vertex_prototypes = (
# M
NonLinearVertex(0, np.array([1.5, 0, 0])),
NonLinearVertex(1, np.array([0, 1.5, 0])),
NonLinearVertex(2, np.array([-1.5, 0, 0])),
NonLinearVertex(3, np.array([0, -1.5, 0])),
NonLinearVertex(4, np.array([0, 0, 1.5])),
NonLinearVertex(5, np.array([0, 0, -1.5])),
# L1
LinearVertex(6, np.array([2, 2, 0]), False),
LinearVertex(7, np.array([2, -2, 0]), False),
LinearVertex(8, np.array([2, 0, 2]), False),
LinearVertex(9, np.array([2, 0, -2]), False),
LinearVertex(10, np.array([-2, 2, 0]), False),
LinearVertex(11, np.array([-2, -2, 0]), False),
LinearVertex(12, np.array([-2, 0, 2]), False),
LinearVertex(13, np.array([-2, 0, -2]), False),
LinearVertex(14, np.array([0, 2, 2]), False),
LinearVertex(15, np.array([0, 2, -2]), False),
LinearVertex(16, np.array([0, -2, 2]), False),
LinearVertex(17, np.array([0, -2, -2]), False),
# L2
LinearVertex(18, np.array([_x, _x, _x]), False),
LinearVertex(19, np.array([-_x, _x, _x]), False),
LinearVertex(20, np.array([-_x, -_x, _x]), False),
LinearVertex(21, np.array([_x, -_x, _x]), False),
LinearVertex(22, np.array([_x, _x, -_x]), False),
LinearVertex(23, np.array([-_x, _x, -_x]), False),
LinearVertex(24, np.array([-_x, -_x, -_x]), False),
LinearVertex(25, np.array([_x, -_x, -_x]), False),
)

_edge_prototypes = (
# Outer shell
Edge(0, _vertex_prototypes[0], _vertex_prototypes[6]),
Edge(1, _vertex_prototypes[0], _vertex_prototypes[7]),
Edge(2, _vertex_prototypes[0], _vertex_prototypes[8]),
Edge(3, _vertex_prototypes[0], _vertex_prototypes[9]),
Edge(4, _vertex_prototypes[1], _vertex_prototypes[6]),
Edge(5, _vertex_prototypes[1], _vertex_prototypes[10]),
Edge(6, _vertex_prototypes[1], _vertex_prototypes[14]),
Edge(7, _vertex_prototypes[1], _vertex_prototypes[15]),
Edge(8, _vertex_prototypes[2], _vertex_prototypes[10]),
Edge(9, _vertex_prototypes[2], _vertex_prototypes[11]),
Edge(10, _vertex_prototypes[2], _vertex_prototypes[12]),
Edge(11, _vertex_prototypes[2], _vertex_prototypes[13]),
Edge(12, _vertex_prototypes[3], _vertex_prototypes[7]),
Edge(13, _vertex_prototypes[3], _vertex_prototypes[11]),
Edge(14, _vertex_prototypes[3], _vertex_prototypes[16]),
Edge(15, _vertex_prototypes[3], _vertex_prototypes[17]),
Edge(16, _vertex_prototypes[4], _vertex_prototypes[8]),
Edge(17, _vertex_prototypes[4], _vertex_prototypes[12]),
Edge(18, _vertex_prototypes[4], _vertex_prototypes[14]),
Edge(19, _vertex_prototypes[4], _vertex_prototypes[16]),
Edge(20, _vertex_prototypes[5], _vertex_prototypes[9]),
Edge(21, _vertex_prototypes[5], _vertex_prototypes[13]),
Edge(22, _vertex_prototypes[5], _vertex_prototypes[15]),
Edge(23, _vertex_prototypes[5], _vertex_prototypes[17]),
# Inner shell
Edge(24, _vertex_prototypes[0], _vertex_prototypes[18]),
Edge(25, _vertex_prototypes[0], _vertex_prototypes[21]),
Edge(26, _vertex_prototypes[0], _vertex_prototypes[22]),
Edge(27, _vertex_prototypes[0], _vertex_prototypes[25]),
Edge(28, _vertex_prototypes[1], _vertex_prototypes[18]),
Edge(29, _vertex_prototypes[1], _vertex_prototypes[19]),
Edge(30, _vertex_prototypes[1], _vertex_prototypes[22]),
Edge(31, _vertex_prototypes[1], _vertex_prototypes[23]),
Edge(32, _vertex_prototypes[2], _vertex_prototypes[19]),
Edge(33, _vertex_prototypes[2], _vertex_prototypes[20]),
Edge(34, _vertex_prototypes[2], _vertex_prototypes[23]),
Edge(35, _vertex_prototypes[2], _vertex_prototypes[24]),
Edge(36, _vertex_prototypes[3], _vertex_prototypes[20]),
Edge(37, _vertex_prototypes[3], _vertex_prototypes[21]),
Edge(38, _vertex_prototypes[3], _vertex_prototypes[24]),
Edge(39, _vertex_prototypes[3], _vertex_prototypes[25]),
Edge(40, _vertex_prototypes[4], _vertex_prototypes[18]),
Edge(41, _vertex_prototypes[4], _vertex_prototypes[19]),
Edge(42, _vertex_prototypes[4], _vertex_prototypes[20]),
Edge(43, _vertex_prototypes[4], _vertex_prototypes[21]),
Edge(44, _vertex_prototypes[5], _vertex_prototypes[22]),
Edge(45, _vertex_prototypes[5], _vertex_prototypes[23]),
Edge(46, _vertex_prototypes[5], _vertex_prototypes[24]),
Edge(47, _vertex_prototypes[5], _vertex_prototypes[25]),
)

_num_windows = 8
_num_window_types = 1
4 changes: 4 additions & 0 deletions src/stk/cage.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@
from stk._internal.topology_graphs.cage.m4l8 import M4L8
from stk._internal.topology_graphs.cage.m6l2l3_prism import M6L2L3Prism
from stk._internal.topology_graphs.cage.m6l12_cube import M6L12Cube
from stk._internal.topology_graphs.cage.m6l8l12_cuboctahedron import (
M6L8L12Cuboctahedron,
)
from stk._internal.topology_graphs.cage.m8l6_cube import M8L6Cube
from stk._internal.topology_graphs.cage.m12l24 import M12L24
from stk._internal.topology_graphs.cage.m24l48 import M24L48
Expand Down Expand Up @@ -57,6 +60,7 @@
"M4L6TetrahedronSpacer",
"M6L2L3Prism",
"M6L12Cube",
"M6L8L12Cuboctahedron",
"M8L6Cube",
"M12L24",
"M24L48",
Expand Down
1 change: 1 addition & 0 deletions tests/molecular/molecules/molecule/fixtures/cage/cage.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
lazy_fixture("metal_cage_m4l8"),
lazy_fixture("metal_cage_m6l2l3_prism"),
lazy_fixture("metal_cage_m6l12_cube"),
lazy_fixture("metal_cage_m6l8l12_cuboctahedron"),
lazy_fixture("metal_cage_m8l6_cube"),
lazy_fixture("metal_cage_m12l24"),
lazy_fixture("metal_cage_m24l48"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from .m4l8 import * # noqa
from .m6l2l3_prism import * # noqa
from .m6l12_cube import * # noqa
from .m6l8l12_cuboctahedron import * # noqa
from .m8l6_cube import * # noqa
from .m12l24 import * # noqa
from .m24l48 import * # noqa
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import pytest
import stk

from ....case_data import CaseData
from ...building_blocks import get_linker, get_pd_atom


@pytest.fixture(
scope="session",
params=(
lambda name: CaseData(
molecule=stk.ConstructedMolecule(
topology_graph=stk.cage.M6L8L12Cuboctahedron(
building_blocks={
get_pd_atom(): range(6),
get_linker(): range(6, 18),
get_linker(): range(18, 26),
},
reaction_factory=stk.DativeReactionFactory(
reaction_factory=stk.GenericReactionFactory(
bond_orders={
frozenset(
{
stk.GenericFunctionalGroup,
stk.SingleAtom,
}
): 9,
},
),
),
),
),
smiles=(
"[H]C1=[O+][Zr]234567OC([H])=[O+][Zr]89%10%11%12%13O"
"C([H])=[O+][Zr]%14%15%16%17%18%19OC([H])=[O+][Hf]%2"
"0%21([O+]=C([H])O[Zr]%22%23(O1)(OC([H])=[O+]%14)(OC"
"([H])=[O+][Hf]([O+]=C([H])O2)([O+]=C([H])O8)([O+]=C"
"([H])O%15)([O+]%223)([O+]49)([O+]%23%16)[O+]%10%17)"
"([O+]5%20)[O+]%18%21)([O+]=C([H])O6)([O+]=C([H])O%1"
"1)([O+]7%12)[O+]%13%19"
),
name=name,
),
lambda name: CaseData(
molecule=stk.ConstructedMolecule(
topology_graph=stk.cage.M6L12Cube(
building_blocks={
get_pd_atom(): range(6),
get_linker(): range(6, 18),
get_linker(): range(18, 26),
},
reaction_factory=stk.DativeReactionFactory(
reaction_factory=stk.GenericReactionFactory(
bond_orders={
frozenset(
{
stk.GenericFunctionalGroup,
stk.SingleAtom,
}
): 9,
},
),
),
scale_multiplier=1.2,
),
),
smiles=(
"[H]C1=[O+][Zr]234567OC([H])=[O+][Zr]89%10%11%12%13O"
"C([H])=[O+][Zr]%14%15%16%17%18%19OC([H])=[O+][Hf]%2"
"0%21([O+]=C([H])O[Zr]%22%23(O1)(OC([H])=[O+]%14)(OC"
"([H])=[O+][Hf]([O+]=C([H])O2)([O+]=C([H])O8)([O+]=C"
"([H])O%15)([O+]%223)([O+]49)([O+]%23%16)[O+]%10%17)"
"([O+]5%20)[O+]%18%21)([O+]=C([H])O6)([O+]=C([H])O%1"
"1)([O+]7%12)[O+]%13%19"
),
name=name,
),
),
)
def metal_cage_m6l8l12_cuboctahedron(request) -> CaseData:
return request.param(
f"{request.fixturename}{request.param_index}",
)
Loading