Skip to content
This repository was archived by the owner on Apr 23, 2021. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion examples/simple_nve/simple_nve.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
]
# The number of periodic images, or duplications of the unit cell in
# each cubic lattice direction
N_dup = [4, 4, 4]
N_dup = [2, 2, 2]
# total number of atoms after duplication
natoms = len(basis) * N_dup[0] * N_dup[1] * N_dup[2]

Expand Down Expand Up @@ -108,6 +108,7 @@
# mark all particles in pc to belong to mat:
for p in pc.iter(item_type=CUBA.PARTICLE):
p.data[CUBA.MATERIAL] = mat
pc.update([p])

# define a cuds to hold the computational model:
cuds = CUDS(name='fluid')
Expand Down
40 changes: 39 additions & 1 deletion simlammps/config/script_writer.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,45 @@ def get_boundary(BC, change_existing_boundary=False):
def get_initial_setup(self):
return INITIAL.format(get_lammps_string(self._atom_style))


# check http://lammps.sandia.gov/doc/Section_commands.html#input-script-structure
# for defining the structure of the input scripts.

# 1. Initialistion:
# The relevant commands are units, dimension, newton, processors,
# boundary, atom_style, atom_modify.

# 2. Atom definitions: There are 3 ways to define atoms in
# LAMMPS. Read them in from a data or restart file via the read_data
# or read_restart commands. These files can contain molecular topology
# information. Or create atoms on a lattice (with no molecular
# topology), using these commands: lattice, region, create_box,
# create_atoms. The entire set of atoms can be duplicated to make a
# larger simulation using the replicate command.

# 3. Settings: Once atoms and molecular topology are defined, a
# variety of settings can be specified: force field coefficients,
# simulation parameters, output options, etc. Force field
# coefficients are set by these commands (they can also be set in the
# read-in files): pair_coeff, bond_coeff, angle_coeff, dihedral_coeff,
# improper_coeff, kspace_style, dielectric, special_bonds.

# Various simulation parameters are set by these commands: neighbor,
# neigh_modify, group, timestep, reset_timestep, run_style, min_style,
# min_modify.

#Fixes impose a variety of boundary conditions, time integration, and
#diagnostic options. The fix command comes in many flavors.

#Various computations can be specified for execution during a
#simulation using the compute, compute_modify, and variable commands.

#Output options are set by the thermo, dump, and restart commands.

#4. Run a simulation: A molecular dynamics simulation is run using
#the run command. Energy minimization (molecular statics) is performed
#using the minimize command. A parallel tempering (replica-exchange)
#simulation can be run using the temper command.

INITIAL = """atom_style {}
atom_modify map array
neighbor 0.3 bin
Expand Down
14 changes: 12 additions & 2 deletions simlammps/internal/lammps_internal_data_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ def iter_material_uids(self):


class LammpsInternalDataManager(ABCDataManager):
""" Class managing LAMMPS data information using file-io
""" Class managing LAMMPS data information using internal

The class performs communicating the data to and from LAMMPS using the
internal interface (i.e. LAMMPS shared library).
Expand All @@ -94,7 +94,7 @@ class LammpsInternalDataManager(ABCDataManager):
----------
lammps :
lammps python wrapper
state_data : StateData
state_data : StateData, which is a whole CUDS
state data
atom_style : AtomStyle
atom_style
Expand All @@ -104,9 +104,16 @@ def __init__(self, lammps, state_data, atom_style):

self._lammps = lammps
self._state_data = state_data
# this is the whole CUDS. todo: infer the atom type form the
# wrappr type or from the information in the data sets itselg
self._atom_style = atom_style



materials = [m for m in state_data.iter(item_type=CUBA.MATERIAL)]

#here it takes materials which are objects, not uuids! while the
#material atom type manager expects uids!
self._material_atom_type_manager = MaterialAtomTypeManager(materials)

dummy_bc = {CUBAExtension.BOX_FACES: ("periodic",
Expand All @@ -116,6 +123,8 @@ def __init__(self, lammps, state_data, atom_style):
script_writer = ScriptWriter(self._atom_style)
commands = script_writer.get_initial_setup()

#todo: use actual boundary in cuds, for this the cuds has
# to be passed here instead of SD.
commands += ScriptWriter.get_boundary(dummy_bc)
for command in commands.splitlines():
self._lammps.command(command)
Expand All @@ -131,6 +140,7 @@ def __init__(self, lammps, state_data, atom_style):
# due to not being able to alter the number of types (issue #66),
# we set the number of supported types to a high number and then
# give dummy values for the unused types
# see http://lammps.sandia.gov/doc/create_box.html
self._lammps.command(
"create_box {} box".format(globals.MAX_NUMBER_TYPES))

Expand Down
66 changes: 59 additions & 7 deletions simlammps/lammps_wrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import os
import shutil
import tempfile
import sys

from io.lammps_fileio_data_manager import LammpsFileIoDataManager
from io.lammps_process import LammpsProcess
Expand Down Expand Up @@ -62,9 +63,16 @@ def __init__(self, use_internal_interface=False, **kwargs):
self.CM_extension = {}
self.SP_extension = {}
self.BC_extension = {}
# to do: rename self.SD to self.CUDS
self.SD = kwargs.get('cuds', CUDS())
# we already have the CUDS here! why do we need to reload it later too..
for i in self.SD.iter():
print i


self._use_internal_interface = use_internal_interface
# todo: atomic style can be deduced from the properties of the particles
# in the datasets in cuds.
atom_style = AtomStyle.ATOMIC
self._executable_name = 'lammps'
self._script_writer = ScriptWriter(atom_style)
Expand All @@ -86,10 +94,15 @@ def __init__(self, use_internal_interface=False, **kwargs):
self._dataset_uids = []

# Call the base class in order to load CUDS
# currently this is essenially getting cuds from super._cuds
super(LammpsWrapper, self).__init__(**kwargs)
# this is redundant as we already have it above near line 66.
# final version will only use one way.


def _count_of(self, cuds, item_type):
"""Workaround for broken CUDS counter."""
"""Workaround for broken CUDS counter.
for the non metadata generated classes (datasets)"""
count = 0
for c in cuds.iter():
if isinstance(c, item_type):
Expand Down Expand Up @@ -128,13 +141,16 @@ def _check_cuds(self, cuds):

def _load_cuds(self):
"""Load CUDS data into lammps engine."""

cuds = self.get_cuds()
if not cuds:
return

# Move checks to a separate method
self._check_cuds(cuds)

# assuming the number of different atom types = numbner of different
# materials:
material_to_atom = {}
number_atom_types = 0
for mat in cuds.iter(item_type=CUBA.MATERIAL):
Expand All @@ -143,10 +159,16 @@ def _load_cuds(self):
number_atom_types += 1
material_to_atom[mat.uid] = number_atom_types

# temporary hack:
# add depreciated material_id to each atom based on the MATERIAL objects
# to do: map material class directly to element number in lammps
# and get rid of cuba.material_id
for particle_container in cuds.iter(item_type=CUBA.PARTICLES):
update_list = []
for single_particle in particle_container.iter():
print '1. DBG', single_particle.data.keys()
single_particle.data[CUBA.MATERIAL_TYPE] = mat.uid
print '2. DBG', single_particle.data.keys()
update_list.append(single_particle)
particle_container.update(update_list)

Expand All @@ -157,17 +179,35 @@ def _load_cuds(self):
particle_sum = 0
for ds in cuds.iter(item_type=CUBA.PARTICLES):
particle_sum += len(ds)
ds.data = mat.data
# copy the mass to the dataset ''data'', this is the old way.
# in the new cuds, the mass of the ds is the total mass of the
# dataset, not of each particle inside of it.
#ds.data=DataContainer(MASS=mat.data[CUBA.MASS])
print type(ds), ds
print '3. DBG: ds.data to chekc if ds has the mass from mat', ds.data
d = ds.data
d[CUBA.MASS]=mat.data[CUBA.MASS]
ds.data = d
# to do: fix .data in particles and then just use line 189.
print '4. DBG: ds.data to chekc if ds has the mass from mat', ds.data
# ds.data.update(MASS=mat.data[CUBA.MASS])
# there should be a better way to do this, the update method
# of the data container does not seems to work properly

# add the box from the metadata to the hack in simphony
# lammps wrapper
# to do: map the metadata class Box directly to the box in
# lammps
ds.data_extension = {
CUBAExtension.BOX_VECTORS: b.vector}
# Add dataset when it is not already there. Rely on uid.
if ds.uid not in self._dataset_uids:
self.add_dataset(ds)
self._dataset_uids.append(ds.uid)
# Replace dataset in CUDS with proxy one.
# proxy_dataset = self.get_dataset(ds.name)
# proxy_dataset._uid = ds.uid
# cuds.update([self.get_dataset(ds.name)])
#proxy_dataset = self.get_dataset(ds.name)
#proxy_dataset._uid = ds.uid
#cuds.update([self.get_dataset(ds.name)])

if particle_sum == 0:
raise Exception('simlammps needs some particles')
Expand All @@ -182,14 +222,16 @@ def _load_cuds(self):
self.CM[CUBA.TIME_STEP] = i.step
self.CM[CUBA.NUMBER_OF_TIME_STEPS] = int(i.final / i.step)


# todo: this should be first a chekc of the condition on each box
for c in cuds.iter(item_type=CUBA.CONDITION):
if isinstance(c, api.Periodic):
self.BC_extension[CUBAExtension.BOX_FACES] = [
'periodic',
'periodic',
'periodic']
continue
raise Exception('Sorry, I am confused!')
raise Exception('check conditions on the box')

for ip in cuds.iter(item_type=CUBA.INTERATOMIC_POTENTIAL):
pass
Expand Down Expand Up @@ -306,6 +348,7 @@ def iter_datasets(self, names=None):

def run(self):
"""Run lammps-engine based on configuration and data."""
print 'run_count=', self._run_count
if self._run_count > 0:
self._load_cuds()

Expand Down Expand Up @@ -351,13 +394,22 @@ def run(self):
# A naive flag for the next run.
self._run_count += 1

_pds =[]
_cds=[]
# Replace datasets in CUDS with proxy ones.
for ds_name in self._data_manager:
proxy_dataset = self.get_dataset(ds_name)
cuds_dataset = self._cuds.get_by_name(ds_name)

#for _par in proxy_dataset.iter():
# _pds.append([ _par.uid, _par.coordinates[0], _par.data[CUBA.VELOCITY][0]])
#for _par in cuds_dataset.iter():
# _cds.append([ _par.uid, _par.coordinates[0], _par.data[CUBA.VELOCITY][0]])
proxy_dataset._uid = cuds_dataset.uid
self._cuds.update([self.get_dataset(ds_name)])
self._cuds.update([proxy_dataset])

# todo: return the missing attributes such as material and potentially others that the current lammps wrapper ignores (see the get attributes stuff).
# what exactly is the proxy here?

def _combine(data_container, data_container_extension):
"""Combine a the approved CUBA with non-approved CUBA key-values.
Expand Down