Skip to content

Commit 2e44194

Browse files
Merge pull request #2 from simphony/v2.4.0-dev
v2.4.0 dev
2 parents bb7f91d + 8635b1c commit 2e44194

13 files changed

+295
-33
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ __pycache__/
22
build/
33
dist/
44
*~*
5+
*.egg-info
56
.mypy_cache/
67
coverage.xml
78
.coverage

LICENSE

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
BSD 3-Clause
2+
Copyright 2020 SimPhoNy OSP-core developers
3+
4+
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
5+
6+
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7+
8+
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
9+
10+
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
11+
12+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
13+
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

README.md

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# Wrapper Development
2-
*Version*: 2.3.0
2+
*Version*: 2.4.0
33

44
The aim of this project is simplify as much as possible the development of a new Wrapper for __SimPhoNy v3__.
55
For this, the general folder and file structure of a wrapper is simulated here, and notes on what to do are provided.
@@ -14,13 +14,16 @@ Material Informatics team, Fraunhofer IWM.
1414

1515
## Compatibility
1616

17-
The following table describes the version compatibility between the [OSP core](https://gitlab.cc-asp.fraunhofer.de/simphony/osp-core) package and this project.
17+
The following table describes the version compatibility between the [OSP core](https://github.com/simphony/osp-core/) package and this project.
1818

1919
| __Wrapper development__ | __OSP core__ |
2020
|:-----------------------:|:------------:|
21+
| 2.4.0 | 3.5.0-beta |
2122
| 2.3.0 | 3.3.5-beta |
2223
| 2.2.0 | 3.3.0-beta |
2324
| 2.1.0 | 3.2.x-beta |
2425
| 2.0.0 | 3.1.x-beta |
2526

26-
The releases of OSP core are available [here](https://github.com/simphony/osp-core/releases).
27+
The releases of OSP core are available [here](https://github.com/simphony/osp-core/releases).
28+
29+
In `osp/wrappers/simple_simulation` you will find a minimalistic wrapper with the required elements implemented.

examples/simple_example.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# This code runs on the wrapper under ../osp/wrappers/simple_simulation
2+
3+
from osp.core.namespaces import simple_ontology
4+
from osp.wrappers.simple_simulation import SimpleSimulationSession
5+
from osp.core.utils import pretty_print
6+
import numpy as np
7+
8+
m = simple_ontology.Material()
9+
for i in range(3):
10+
a = m.add(simple_ontology.Atom())
11+
a.add(
12+
simple_ontology.Position(value=[i, i, i], unit="m"),
13+
simple_ontology.Velocity(value=np.random.random(3), unit="m/s")
14+
)
15+
16+
# Run a simulation
17+
with SimpleSimulationSession() as session:
18+
w = simple_ontology.Wrapper(session=session)
19+
m = w.add(m)
20+
w.session.run()
21+
22+
pretty_print(m)
23+
24+
for atom in m.get(rel=simple_ontology.hasPart):
25+
atom.get(oclass=simple_ontology.Velocity)[0].value = [0, 0, 0]
26+
w.session.run()
27+
28+
pretty_print(m)
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
from osp.wrappers.simple_simulation.simulation_engine import SimulationEngine
2+
from osp.wrappers.simple_simulation.simple_simulation_session import SimpleSimulationSession
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
---
2+
version: 0.0.2
3+
author: Me
4+
namespace: simple_ontology
5+
6+
ontology:
7+
8+
Atom:
9+
subclass_of:
10+
- cuba.Class
11+
- simple_ontology.hasPart:
12+
cardinality: some
13+
exclusive: false
14+
range: simple_ontology.Position
15+
- simple_ontology.hasPart:
16+
cardinality: some
17+
exclusive: false
18+
range: simple_ontology.Velocity
19+
20+
Material:
21+
subclass_of:
22+
- cuba.Class
23+
- simple_ontology.hasPart:
24+
cardinality: some
25+
exclusive: true
26+
range: simple_ontology.Atom
27+
28+
PhysicalQuantity:
29+
attributes:
30+
simple_ontology.unit: null
31+
simple_ontology.value: null
32+
subclass_of:
33+
- cuba.Class
34+
35+
Position:
36+
subclass_of:
37+
- simple_ontology.PhysicalQuantity
38+
39+
Velocity:
40+
subclass_of:
41+
- simple_ontology.PhysicalQuantity
42+
43+
Wrapper:
44+
subclass_of:
45+
- cuba.Wrapper
46+
- simple_ontology.hasPart:
47+
cardinality: some
48+
exclusive: true
49+
range: simple_ontology.Material
50+
51+
encloses:
52+
inverse: simple_ontology.isEnclosedBy
53+
subclass_of:
54+
- cuba.activeRelationship
55+
56+
hasPart:
57+
default_rel: true
58+
inverse: simple_ontology.isPartOf
59+
subclass_of:
60+
- simple_ontology.encloses
61+
62+
isEnclosedBy:
63+
inverse: simple_ontology.encloses
64+
subclass_of:
65+
- cuba.passiveRelationship
66+
67+
isPartOf:
68+
inverse: simple_ontology.hasPart
69+
subclass_of:
70+
- simple_ontology.isEnclosedBy
71+
72+
unit:
73+
datatype: STRING
74+
subclass_of:
75+
- cuba.attribute
76+
77+
value:
78+
datatype: VECTOR:3
79+
subclass_of:
80+
- cuba.attribute
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
from osp.core.session import SimWrapperSession
2+
from osp.wrappers.simple_simulation import SimulationEngine
3+
from osp.core.namespaces import simple_ontology
4+
5+
6+
class SimpleSimulationSession(SimWrapperSession):
7+
"""
8+
Session class for some engine.
9+
"""
10+
11+
def __init__(self, engine=None, **kwargs):
12+
super().__init__(engine or SimulationEngine(), **kwargs)
13+
self.mapper = dict() # maps uuid to index in the backend
14+
15+
def __str__(self):
16+
return "Simple sample Wrapper Session"
17+
18+
# OVERRIDE
19+
def _apply_added(self, root_obj, buffer):
20+
"""Adds the added cuds to the engine."""
21+
for obj in buffer.values():
22+
if obj.is_a(simple_ontology.Atom):
23+
self.mapper[obj.uid] = len(self.mapper)
24+
pos = obj.get(oclass=simple_ontology.Position)[0].value
25+
vel = obj.get(oclass=simple_ontology.Velocity)[0].value
26+
self._engine.add_atom(pos, vel)
27+
28+
# OVERRIDE
29+
def _apply_updated(self, root_obj, buffer):
30+
"""Updates the updated cuds in the engine."""
31+
for obj in buffer.values():
32+
33+
# case 1: we change the velocity
34+
if obj.is_a(simple_ontology.Velocity):
35+
atom = obj.get(rel=simple_ontology.isPartOf)[0]
36+
idx = self.mapper[atom.uid]
37+
self._engine.update_velocity(idx, obj.value)
38+
39+
# case 2: we change the position
40+
elif obj.is_a(simple_ontology.Position):
41+
atom = obj.get(rel=simple_ontology.isPartOf)[0]
42+
idx = self.mapper[atom.uid]
43+
self._engine.update_position(idx, obj.value)
44+
45+
# OVERRIDE
46+
def _apply_deleted(self, root_obj, buffer):
47+
"""Deletes the deleted cuds from the engine."""
48+
49+
# OVERRIDE
50+
def _load_from_backend(self, uids, expired=None):
51+
"""Loads the cuds object from the simulation engine"""
52+
for uid in uids:
53+
if uid in self._registry:
54+
obj = self._registry.get(uid)
55+
56+
# check whether user wants to load a position
57+
if obj.is_a(simple_ontology.Position):
58+
atom = obj.get(rel=simple_ontology.isPartOf)[0]
59+
idx = self.mapper[atom.uid]
60+
pos = self._engine.get_position(idx)
61+
obj.value = pos
62+
63+
# check whether user wants to load a velocity
64+
elif obj.is_a(simple_ontology.Velocity):
65+
atom = obj.get(rel=simple_ontology.isPartOf)[0]
66+
idx = self.mapper[atom.uid]
67+
vel = self._engine.get_velocity(idx)
68+
obj.value = vel
69+
70+
yield obj
71+
72+
# OVERRIDE
73+
def _run(self, root_cuds_object):
74+
"""Call the run command of the engine."""
75+
self._engine.run()
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
# This file contains simple code to emulate communication with an engine.
2+
# It acts like a dummy syntactic layer.
3+
4+
class Atom():
5+
6+
def __init__(self, position, velocity):
7+
self.position = position
8+
self.velocity = velocity
9+
10+
11+
class SimulationEngine:
12+
"""
13+
Simple engine sample code.
14+
"""
15+
16+
def __init__(self):
17+
self.atoms = list()
18+
print("Engine instantiated!")
19+
20+
def __str__(self):
21+
return "Some Engine Connection"
22+
23+
def run(self, timesteps=1):
24+
"""Call the run command of the engine."""
25+
print("Now the engine is running")
26+
for atom in self.atoms:
27+
atom.position += atom.velocity * timesteps
28+
29+
def add_atom(self, position, velocity):
30+
"""Add an atom to the engine.
31+
32+
Args:
33+
position (array): A 3D array for the position of the atom.
34+
velocity (array): A 3D array for the velocity of the atom.
35+
"""
36+
print("Add atom %s with position %s and velocity %s"
37+
% (len(self.atoms), position, velocity))
38+
self.atoms.append(Atom(position, velocity))
39+
40+
def update_position(self, idx, position):
41+
"""Update the position of the atom
42+
43+
Args:
44+
idx (int): The index of the atom to update
45+
position (array): The new position.
46+
"""
47+
print("Update atom %s. Setting position to %s"
48+
% (idx, position))
49+
self.atoms[idx].position = position
50+
51+
def update_velocity(self, idx, velocity):
52+
"""Update the velocity of an atom.
53+
54+
Args:
55+
idx (int): The index of the atom
56+
velocity (array): The new velocity.
57+
"""
58+
print("Update atom %s. Setting velocity to %s"
59+
% (idx, velocity))
60+
self.atoms[idx].velocity = velocity
61+
62+
def get_velocity(self, idx):
63+
"""Get the velocity of an atom.
64+
65+
Args:
66+
idx (int): The index of the atom.
67+
68+
Returns:
69+
array: The velocity of the atom.
70+
"""
71+
return self.atoms[idx].velocity
72+
73+
def get_position(self, idx):
74+
"""Get the position of the atom.
75+
76+
Args:
77+
idx (int): The index of the atom.
78+
79+
Returns:
80+
array: The position of the atom.
81+
"""
82+
return self.atoms[idx].position

osp/wrappers/some_database_session.py

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,4 @@
1-
# Copyright (c) 2014-2019, Adham Hashibon, Materials Informatics Team,
2-
# Fraunhofer IWM.
3-
# All rights reserved.
4-
# Redistribution and use are limited to the scope agreed with the end user.
5-
# No parts of this software may be used outside of this context.
6-
# No redistribution is allowed without explicit written permission.
7-
81
# TODO: Import the python connection to the DB
9-
102
from osp.core.session import DbWrapperSession
113

124

@@ -81,11 +73,7 @@ def _load_first_level(self):
8173
# that are direct neighbors of the wrapper
8274
pass
8375

76+
# OVERRIDE
8477
def _load_from_backend(self, uids, expired=None):
8578
# TODO load cuds objects from the backend
86-
print("WARNING: please override _load_from_backend method of your session")
87-
for uid in uids:
88-
if uid in self._registry:
89-
yield self._registry[uid]
90-
else:
91-
yield None
79+
pass

osp/wrappers/some_simulation_session.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
# Maybe some copyright stuff goes here
2-
31
# TODO: Import the python connection to the engine
42

53
from osp.core.session import SimWrapperSession
@@ -26,7 +24,6 @@ def _run(self, root_cuds_object):
2624
# OVERRIDE
2725
def _load_from_backend(self, uids, expired=None):
2826
"""Loads the cuds object from the simulation engine"""
29-
print("WARNING: please override _load_from_backend method of your session")
3027
for uid in uids:
3128
if uid in self._registry:
3229
yield self._registry[uid]

0 commit comments

Comments
 (0)