diff --git a/.bumpversion.cfg b/.bumpversion.cfg
index e7cf612..e34834e 100644
--- a/.bumpversion.cfg
+++ b/.bumpversion.cfg
@@ -1,5 +1,5 @@
[bumpversion]
-current_version = 0.8.16
+current_version = 0.9.0
commit = True
tag = False
diff --git a/CITATION.cff b/CITATION.cff
index d3b75bf..57f38cf 100644
--- a/CITATION.cff
+++ b/CITATION.cff
@@ -19,4 +19,4 @@ url: 'https://atomrdf.pyscal.org'
license: "MIT"
repository-code: https://github.com/pyscal/atomRDF
type: software
-version: 0.8.16
+version: 0.9.0
diff --git a/atomrdf/data/ldo.owl b/atomrdf/data/ldo.owl
new file mode 100644
index 0000000..f071855
--- /dev/null
+++ b/atomrdf/data/ldo.owl
@@ -0,0 +1,481 @@
+
+
+
+
+ Line Defect Ontology (LDO)
+ Line Defect Ontology
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Examples of a Contributor include a person, an organization, or a service. Typically, the name of a Contributor should be used to indicate the entity.
+ Contributor
+ An entity responsible for making contributions to the resource.
+
+
+
+
+
+
+
+
+ Examples of a Creator include a person, an organization, or a service. Typically, the name of a Creator should be used to indicate the entity.
+ Creator
+ An entity primarily responsible for making the resource.
+
+
+
+
+
+
+
+
+
+
+ Description may include but is not limited to: an abstract, a table of contents, a graphical representation, or a free-text account of the resource.
+ Description
+ An account of the resource.
+
+
+
+
+
+
+
+
+ Title
+ A name given to the resource.
+ In current practice, this term is used primarily with literal values; however, there are important uses with non-literal values as well. As of December 2007, the DCMI Usage Board is leaving this range unspecified pending an investigation of options.
+
+
+
+
+
+
+
+
+ The range of skos:altLabel is the class of RDF plain literals.
+ skos:prefLabel, skos:altLabel and skos:hiddenLabel are pairwise disjoint properties.
+
+ alternative label
+ An alternative lexical label for a resource.
+ Acronyms, abbreviations, spelling variants, and irregular plural/singular forms may be included among the alternative labels for a concept. Mis-spelled terms are normally included as hidden labels (see skos:hiddenLabel).
+
+
+
+
+
+
+
+
+
+ definition
+ A statement or formal explanation of the meaning of a concept.
+
+
+
+
+
+
+
+
+
+ example
+ An example of the use of a concept.
+
+
+
+
+
+
+
+
+ A general note, for any purpose.
+
+
+
+
+
+
+
+ A resource has no more than one value of skos:prefLabel per language tag, and no more than one value of skos:prefLabel without language tag.
+ The range of skos:prefLabel is the class of RDF plain literals.
+ skos:prefLabel, skos:altLabel and skos:hiddenLabel are pairwise
+ disjoint properties.
+
+ preferred label
+ The preferred lexical label for a resource, in a given language.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ belongs to system
+
+
+
+
+
+
+
+
+
+ has Burgers vector
+
+
+
+
+
+
+
+
+
+ has line direction
+
+
+
+
+
+
+
+
+
+ has normal vector
+
+
+
+
+
+
+
+
+
+ moves on
+
+
+
+
+
+
+
+
+
+ results in
+
+
+
+
+
+
+
+
+
+
+
+
+ has dislocation density
+
+
+
+
+
+
+
+
+
+ A data property linking a vector with its component on the x axis.
+ has component x
+
+
+
+
+
+
+
+
+
+ A data property linking a vector with its component on the y axis.
+ has component y
+
+
+
+
+
+
+
+
+
+ A data property linking a vector with its component on the z axis.
+ has component z
+
+
+
+
+
+
+
+
+
+
+
+
+ Angular Vector
+ Frank Vector
+
+
+
+
+
+
+
+
+ Burgers Vector
+ b
+
+
+
+
+
+
+
+
+ Disclination
+
+
+
+
+
+
+
+
+ Dislocation
+
+
+
+
+
+
+
+
+ Edge Dislocation
+
+
+
+
+
+
+
+ Lattice Plane
+
+
+
+
+
+
+
+ Linear or one-dimensional defect around which some of the atoms are misaligned.
+ Line Defect
+
+
+
+
+
+
+
+
+ Line Direction
+ Line Vector
+
+
+
+
+
+
+
+
+ Mixed Dislocation
+
+
+
+
+
+
+
+
+ Normal Vector
+
+
+
+
+
+
+
+
+ Partial Dislocation
+ Shockley Partial
+
+
+
+
+
+
+
+
+ Screw Dislocation
+
+
+
+
+
+
+
+ Slip
+
+
+
+
+
+
+
+
+ Slip Direction
+
+
+
+
+
+
+
+
+ Slip Plane
+
+
+
+
+
+
+
+ Slip System
+
+
+
+
+
+
+
+
+ Twist Disclination
+
+
+
+
+
+
+
+
+ Wedge Disclination
+
+
+
+
+
+
+
+ Vector is a quantity that has a magnitude and direction.
+ Vector
+
+
+
+
+
+
+
diff --git a/atomrdf/namespace.py b/atomrdf/namespace.py
index d453682..d6cb5ae 100644
--- a/atomrdf/namespace.py
+++ b/atomrdf/namespace.py
@@ -79,6 +79,7 @@ def __init__(self, infile, delimiter="/"):
file_location = os.path.dirname(__file__)
CMSO = Namespace(os.path.join(file_location, "data/cmso.owl"))
+LDO = Namespace(os.path.join(file_location, "data/ldo.owl"))
PLDO = Namespace(os.path.join(file_location, "data/pldo.owl"))
PODO = Namespace(os.path.join(file_location, "data/podo.owl"))
ASMO = Namespace(os.path.join(file_location, "data/asmo.owl"))
diff --git a/atomrdf/network/ontology.py b/atomrdf/network/ontology.py
index 8ec8459..ec24cc9 100644
--- a/atomrdf/network/ontology.py
+++ b/atomrdf/network/ontology.py
@@ -38,9 +38,10 @@ def read_ontology():
pldo = OntologyNetwork(os.path.join(file_location, "data/pldo.owl")) #d15d27712e3f64b405d75c70ad970c9d54ff0b51
podo = OntologyNetwork(os.path.join(file_location, "data/podo.owl")) #6a74d511c5b78042e1cb7a6e76e948fa56de598e
asmo = OntologyNetwork(os.path.join(file_location, "data/asmo.owl")) #c7e2da99b9126844f19f225c6a10cdb01aeb55e6
+ ldo = OntologyNetwork(os.path.join(file_location, "data/ldo.owl")) #52fc756d2e2f9baedfce478e7f8b790365648cea
# combine them
- combo = cmso + pldo + podo + asmo
+ combo = cmso + pldo + podo + asmo + ldo
# add namespaces
combo.add_namespace("prov", "http://www.w3.org/ns/prov#")
@@ -95,7 +96,12 @@ def read_ontology():
combo.add_path(("podo:InterstitialImpurity", "rdfs:label", "string"))
combo.add_path(("cmso:AtomicScaleSample", "podo:hasNumberOfImpurityAtoms", "int"))
combo.add_path(("cmso:AtomicScaleSample", "podo:hasImpurityConcentration", "float"))
-
+
+ #CMSO -> LDO DISL paths
+ combo.add_path(("cmso:Material", "cmso:hasDefect", "ldo:LineDefect"))
+ combo.add_path(("cmso:Material", "cmso:hasDefect", "ldo:Dislocation"))
+
+
combo.add_path(
("cmso:ComputationalSample", "prov:wasDerivedFrom", "cmso:ComputationalSample")
)
diff --git a/atomrdf/structure.py b/atomrdf/structure.py
index d5681d9..c135527 100644
--- a/atomrdf/structure.py
+++ b/atomrdf/structure.py
@@ -32,7 +32,7 @@
import atomrdf.properties as prp
from rdflib import Graph, Namespace, XSD, RDF, RDFS, BNode, URIRef
-from atomrdf.namespace import CMSO, PLDO, PODO, UNSAFEASMO, UNSAFECMSO, PROV, Literal
+from atomrdf.namespace import CMSO, LDO, PLDO, PODO, UNSAFEASMO, UNSAFECMSO, PROV, Literal
from atomman.defect.Dislocation import Dislocation
import atomman as am
@@ -175,10 +175,10 @@ def _make_general_lattice(
def _make_dislocation(
- burgers_vector,
- slip_vector,
+ slip_system,
dislocation_line,
elastic_constant_dict,
+ burgers_vector=None,
dislocation_type="monopole",
structure=None,
element=None,
@@ -190,20 +190,27 @@ def _make_dislocation(
graph=None,
names=False,
label=None,
+ return_atomman_dislocation=False,
):
"""
Generate a dislocation structure. Wraps the atomman.defect.Dislocation class.
Parameters
----------
- burgers_vector : numpy array of length 3
- The Burgers vector of the dislocation.
- slip_vector : numpy array of length 3
- The slip vector of the dislocation.
+ slip_system : list of lists, shape (2 x 3)
+ the slip system for the given system. The input should of type [[u, v, w], [h, k, l]].
+ [u, v, w] is the slip direction and [h, k, l] is the slip plane.
dislocation_line : numpy array of length 3
The dislocation line direction.
+ This determines the type of dislocation to generate, screw, edge or mixed.
+ burgers_vector : scalar or numpy array of length 3, optional
+ if a scalar value (b) is provided, the burgers vector is assumed to be b*[u, v, w].
+ if a numpy array is provided, the burgers vector is set to this value.
+ Default is equal to slip direction [u, v, w] from slip_system.
elastic_constant_dict : dict
- Dictionary of elastic constants.
+ Dictionary of elastic constants. The keys should be in Voigt notation.
+ burgers_vector : numpy array of length 3
+ The Burgers vector of the dislocation.
dislocation_type : str, optional
The type of dislocation to generate. Default is "monopole".
structure : crystal lattice to be used
@@ -247,6 +254,15 @@ def _make_dislocation(
will be generated. If set to "periodicarray", a periodic array of dislocations will be generated.
"""
+ slip_direction = slip_system[0]
+ slip_plane = slip_system[1]
+ if burgers_vector is None:
+ burgers_vector = slip_direction
+ elif np.isscalar(burgers_vector):
+ burgers_vector = burgers_vector * np.array(slip_direction)
+ elif len(burgers_vector) != 3:
+ raise ValueError('burgers vector should be None, scalar, or of length 3')
+
if structure is not None:
# create a structure with the info
@@ -298,7 +314,7 @@ def _make_dislocation(
C,
burgers_vector,
dislocation_line,
- slip_vector,
+ slip_plane,
)
if dislocation_type == "monopole":
disl_system = disc.monopole()
@@ -318,6 +334,20 @@ def _make_dislocation(
positions = np.column_stack(
(atom_df["pos[0]"].values, atom_df["pos[1]"].values, atom_df["pos[2]"].values)
)
+
+ #find dislocation character
+ angle = np.dot(dislocation_line, burgers_vector)/(np.linalg.norm(dislocation_line)*np.linalg.norm(burgers_vector))
+ angle_rad = np.arccos(angle)
+ angle_deg = np.degrees(angle_rad)
+
+ disl_dict = {
+ 'BurgersVector': burgers_vector,
+ 'SlipPlane': slip_plane,
+ 'SlipDirection': slip_direction,
+ 'DislocationLine': dislocation_line,
+ 'DislocationCharacter': angle_deg,
+ }
+
atom_dict = {"positions": positions, "types": types, "species": species}
atom_obj = Atoms()
atom_obj.from_dict(atom_dict)
@@ -326,7 +356,12 @@ def _make_dislocation(
output_structure.atoms = atom_obj
output_structure = output_structure.modify.remap_to_box()
output_structure.label = label
+ output_structure.graph = graph
+ output_structure.to_graph()
+ output_structure.add_dislocation(disl_dict)
+ if return_atomman_dislocation:
+ return output_structure, disc
return output_structure
@@ -1930,6 +1965,52 @@ def _add_atoms(self):
# force_identifier = uuid.uuid4()
# self.add((force, CMSO.hasIdentifier, Literal(force_identifier, datatype=XSD.string)))
+ def add_dislocation(self, disl_dict):
+ if self.graph is None:
+ return
+
+ #find what kind of disl is present
+ angle_deg = disl_dict['DislocationCharacter']
+ if (np.abs(angle_deg-0) < 1E-3) or (np.abs(angle_deg-180) < 1E-3) or (np.abs(angle_deg-360) < 1E-3):
+ disl_type = LDO.ScrewDislocation
+ elif (np.abs(angle_deg-90) < 1E-3) or (np.abs(angle_deg-270) < 1E-3):
+ disl_type = LDO.EdgeDislocation
+ else:
+ disl_type = LDO.MixedDislocation
+
+ line_defect = self.graph.create_node(f"{self._name}_Dislocation", disl_type)
+ self.graph.add((self.material, CMSO.hasDefect, line_defect))
+
+ line_direction = self.graph.create_node(f"{self._name}_DislocationLineDirection", LDO.LineDirection)
+ self.graph.add((line_direction, CMSO.hasComponent_x, Literal(disl_dict['DislocationLine'][0], datatype=XSD.float)))
+ self.graph.add((line_direction, CMSO.hasComponent_y, Literal(disl_dict['DislocationLine'][1], datatype=XSD.float)))
+ self.graph.add((line_direction, CMSO.hasComponent_z, Literal(disl_dict['DislocationLine'][2], datatype=XSD.float)))
+ self.graph.add((line_defect, LDO.hasLineDirection, line_direction))
+
+ burgers_vector = self.graph.create_node(f"{self._name}_DislocationBurgersVector", LDO.BurgersVector)
+ self.graph.add((burgers_vector, CMSO.hasComponent_x, Literal(disl_dict['BurgersVector'][0], datatype=XSD.float)))
+ self.graph.add((burgers_vector, CMSO.hasComponent_y, Literal(disl_dict['BurgersVector'][1], datatype=XSD.float)))
+ self.graph.add((burgers_vector, CMSO.hasComponent_z, Literal(disl_dict['BurgersVector'][2], datatype=XSD.float)))
+ self.graph.add((line_defect, LDO.hasBurgersVector, burgers_vector))
+
+ slip_direction = self.graph.create_node(f"{self._name}_DislocationSlipDirection", LDO.SlipDirection)
+ self.graph.add((slip_direction, CMSO.hasComponent_x, Literal(disl_dict['SlipDirection'][0], datatype=XSD.float)))
+ self.graph.add((slip_direction, CMSO.hasComponent_y, Literal(disl_dict['SlipDirection'][1], datatype=XSD.float)))
+ self.graph.add((slip_direction, CMSO.hasComponent_z, Literal(disl_dict['SlipDirection'][2], datatype=XSD.float)))
+
+ slip_plane = self.graph.create_node(f"{self._name}_DislocationSlipPlane", LDO.SlipPlane)
+ normal_vector = self.graph.create_node(f"{self._name}_DislocationNormalVector", LDO.NormalVector)
+ self.graph.add((normal_vector, CMSO.hasComponent_x, Literal(disl_dict['SlipPlane'][0], datatype=XSD.float)))
+ self.graph.add((normal_vector, CMSO.hasComponent_y, Literal(disl_dict['SlipPlane'][1], datatype=XSD.float)))
+ self.graph.add((normal_vector, CMSO.hasComponent_z, Literal(disl_dict['SlipPlane'][2], datatype=XSD.float)))
+ self.graph.add((slip_plane, LDO.hasNormalVector, normal_vector))
+
+ slip_system = self.graph.create_node(f"{self._name}_DislocationSlipSystem", LDO.SlipSystem)
+ self.graph.add((slip_direction, LDO.belongsToSystem, slip_system))
+ self.graph.add((slip_plane, LDO.belongsToSystem, slip_system))
+ self.graph.add((line_defect, LDO.movesOn, slip_system))
+
+
def add_gb(self, gb_dict):
"""
Add GB details which will be annotated using PLDO
diff --git a/examples/02_grain_boundaries.ipynb b/examples/02_grain_boundaries.ipynb
index 7b99f35..310253e 100644
--- a/examples/02_grain_boundaries.ipynb
+++ b/examples/02_grain_boundaries.ipynb
@@ -21,7 +21,20 @@
"execution_count": 1,
"id": "f88eacd6-1bdc-4321-9e80-3d2720d318a1",
"metadata": {},
- "outputs": [],
+ "outputs": [
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "c4f616c028b447b58dfe55c7d388eeee",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": []
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
"source": [
"from atomrdf import KnowledgeGraph, System"
]
@@ -1294,9 +1307,9 @@
}
},
"text/html": [
- "