Source code for pysph.base.utils

try:
    from collections import OrderedDict
except ImportError:
    from ordereddict import OrderedDict

import numpy
from .particle_array import ParticleArray, \
    get_local_tag, get_remote_tag, get_ghost_tag

from pyzoltan.core.carray import LongArray

UINT_MAX = (1<<32) - 1

# Internal tags used in PySPH (defined in particle_array.pxd)
class ParticleTAGS:
    Local = get_local_tag()
    Remote = get_remote_tag()
    Ghost = get_ghost_tag()

[docs]def arange_long(start, stop=-1): """ Creates a LongArray working same as builtin range with upto 2 arguments both expected to be positive """ if stop == -1: arange = LongArray(start) for i in range(start): arange.data[i] = i return arange else: size = stop-start arange = LongArray(size) for i in range(size): arange.data[i] = start + i return arange
# A collection of default properties for all SPH arrays. DEFAULT_PROPS = set( ('x', 'y', 'z', 'u', 'v', 'w', 'm', 'h', 'rho', 'p', 'au', 'av', 'aw', 'gid', 'pid', 'tag') )
[docs]def get_particle_array(additional_props=None, constants=None, **props): """Create and return a particle array with default properties. The default properties are ['x', 'y', 'z', 'u', 'v', 'w', 'm', 'h', 'rho', 'p', 'au', 'av', 'aw', 'gid', 'pid', 'tag'], this set is available in `DEFAULT_PROPS`. Parameters ---------- additional_props : list If specified, add these properties. constants : dict Any constants to be added to the particle array. Other Parameters ---------------- props : dict Additional keywords passed are set as the property arrays. Examples -------- >>> x = linspace(0,1,10) >>> pa = get_particle_array(name='fluid', x=x) >>> pa.properties.keys() ['x', 'z', 'rho', 'pid', 'v', 'tag', 'm', 'p', 'gid', 'au', 'aw', 'av', 'y', 'u', 'w', 'h'] >>> pa1 = get_particle_array(name='fluid', additional_props=['xx', 'yy']) >>> pa = get_particle_array(name='fluid', x=x, constants={'alpha': 1.0}) >>> pa.constants.keys() ['alpha'] """ # handle the name separately if 'name' in props: name = props['name'] props.pop('name') else: name = "array" # default properties for an SPH particle default_props = set(DEFAULT_PROPS) # add any additional props to the default_props if additional_props: default_props = default_props.union(additional_props) np = 0 prop_dict = {} for prop in props.keys(): data = numpy.asarray(props[prop]) np = data.size if prop in ['tag', 'pid']: prop_dict[prop] = {'data':data, 'type':'int', 'name':prop} elif prop in ['gid']: prop_dict[prop] = {'data':data.astype(numpy.uint32), 'type':'unsigned int', 'name':prop} else: prop_dict[prop] = {'data':data, 'type':'double', 'name':prop} # Add the default props for prop in default_props: if not prop in prop_dict: if prop in ["pid"]: prop_dict[prop] = {'name':prop, 'type':'int', 'default':0} elif prop in ['tag']: prop_dict[prop] = {'name':prop, 'type':'int', 'default':ParticleTAGS.Local} elif prop in ['gid']: data = numpy.ones(shape=np, dtype=numpy.uint32) data[:] = UINT_MAX prop_dict[prop] = {'name':prop, 'type':'unsigned int', 'data':data, 'default':UINT_MAX} else: prop_dict[prop] = {'name':prop, 'type':'double', 'default':0} # create the particle array pa = ParticleArray(name=name, constants=constants, **prop_dict) # default property arrays to save out. Any reasonable SPH particle # should define these pa.set_output_arrays( ['x', 'y', 'z', 'u', 'v', 'w', 'rho', 'm', 'h', 'pid', 'gid', 'tag'] ) return pa
[docs]def get_particle_array_wcsph(constants=None, **props): """Return a particle array for the WCSPH formulation. This sets the default properties to be:: ['x', 'y', 'z', 'u', 'v', 'w', 'h', 'rho', 'm', 'p', 'cs', 'ax', 'ay', 'az', 'au', 'av', 'aw', 'x0','y0', 'z0','u0', 'v0','w0', 'arho', 'rho0', 'div', 'gid','pid', 'tag'] Parameters ---------- constants : dict Dictionary of constants Other Parameters ---------------- props : dict Additional keywords passed are set as the property arrays. See Also -------- get_particle_array """ wcsph_props = ['cs', 'ax', 'ay', 'az', 'arho', 'x0','y0', 'z0', 'u0', 'v0','w0', 'rho0', 'div'] pa = get_particle_array( constants=constants, additional_props=wcsph_props, **props ) # default property arrays to save out. pa.set_output_arrays( ['x', 'y', 'z', 'u', 'v', 'w', 'rho', 'm', 'h', 'pid', 'gid', 'tag', 'p'] ) return pa
[docs]def get_particle_array_iisph(constants=None, **props): """Get a particle array for the IISPH formulation. The default properties are:: ['x', 'y', 'z', 'u', 'v', 'w', 'm', 'h', 'rho', 'p', 'au', 'av', 'aw', 'gid', 'pid', 'tag' 'uadv', 'vadv', 'wadv', 'rho_adv', 'au', 'av', 'aw','ax', 'ay', 'az', 'dii0', 'dii1', 'dii2', 'V', 'aii', 'dijpj0', 'dijpj1', 'dijpj2', 'p', 'p0', 'piter', 'compression' ] Parameters ---------- constants : dict Dictionary of constants Other Parameters ---------------- props : dict Additional keywords passed are set as the property arrays. See Also -------- get_particle_array """ iisph_props = ['uadv', 'vadv', 'wadv', 'rho_adv', 'au', 'av', 'aw','ax', 'ay', 'az', 'dii0', 'dii1', 'dii2', 'V', 'aii', 'dijpj0', 'dijpj1', 'dijpj2', 'p', 'p0', 'piter', 'compression' ] # Used to calculate the total compression first index is count and second # the compression. consts = {'tmp_comp': [0.0, 0.0]} if constants: consts.update(constants) pa = get_particle_array( constants=consts, additional_props=iisph_props, **props ) pa.set_output_arrays( ['x', 'y', 'z', 'u', 'v', 'w', 'rho', 'h', 'm', 'p', 'pid', 'au', 'av', 'aw', 'tag', 'gid', 'V'] ) return pa
[docs]def get_particle_array_rigid_body(constants=None, **props): """Return a particle array for a rigid body motion. For multiple bodies, add a body_id property starting at index 0 with each index denoting the body to which the particle corresponds to. Parameters ---------- constants : dict Dictionary of constants Other Parameters ---------------- props : dict Additional keywords passed are set as the property arrays. See Also -------- get_particle_array """ extra_props = ['au', 'av', 'aw', 'V', 'fx', 'fy', 'fz', 'x0', 'y0', 'z0'] body_id = props.pop('body_id', None) nb = 1 if body_id is None else numpy.max(body_id) + 1 consts = {'total_mass':numpy.zeros(nb, dtype=float), 'num_body': numpy.asarray(nb, dtype=int), 'cm': numpy.zeros(3*nb, dtype=float), # The mi are also used to temporarily reduce mass (1), center of # mass (3) and the interia components (6), total force (3), total # torque (3). 'mi': numpy.zeros(16*nb, dtype=float), 'force': numpy.zeros(3*nb, dtype=float), 'torque': numpy.zeros(3*nb, dtype=float), # velocity, acceleration of CM. 'vc': numpy.zeros(3*nb, dtype=float), 'ac': numpy.zeros(3*nb, dtype=float), 'vc0': numpy.zeros(3*nb, dtype=float), # angular velocity, acceleration of body. 'omega': numpy.zeros(3*nb, dtype=float), 'omega0': numpy.zeros(3*nb, dtype=float), 'omega_dot': numpy.zeros(3*nb, dtype=float) } if constants: consts.update(constants) pa = get_particle_array(constants=consts, additional_props=extra_props, **props) pa.add_property('body_id', type='int', data=body_id) pa.set_output_arrays( ['x', 'y', 'z', 'u', 'v', 'w', 'rho', 'h', 'm', 'p', 'pid', 'au', 'av', 'aw', 'tag', 'gid', 'V', 'fx', 'fy', 'fz', 'body_id'] ) return pa
[docs]def get_particle_array_tvf_fluid(constants=None, **props): """Return a particle array for the TVF formulation for a fluid. Parameters ---------- constants : dict Dictionary of constants Other Parameters ---------------- props : dict Additional keywords passed are set as the property arrays. See Also -------- get_particle_array """ tv_props = ['uhat', 'vhat', 'what', 'auhat', 'avhat', 'awhat', 'vmag2', 'V'] pa = get_particle_array( constants=constants, additional_props=tv_props, **props ) pa.set_output_arrays( ['x', 'y', 'z', 'u', 'v', 'w', 'rho', 'p', 'h', 'm', 'au', 'av', 'aw', 'V', 'vmag2', 'pid', 'gid', 'tag'] ) return pa
[docs]def get_particle_array_tvf_solid(constants=None, **props): """Return a particle array for the TVF formulation for a solid. Parameters ---------- constants : dict Dictionary of constants Other Parameters ---------------- props : dict Additional keywords passed are set as the property arrays. See Also -------- get_particle_array """ tv_props = ['u0', 'v0', 'w0', 'V', 'wij', 'ax', 'ay', 'az', 'uf', 'vf', 'wf', 'ug', 'vg', 'wg'] pa = get_particle_array( constants=constants, additional_props=tv_props, **props ) pa.set_output_arrays( ['x', 'y', 'z', 'u', 'v', 'w', 'rho', 'p', 'h', 'm', 'V', 'pid', 'gid', 'tag'] ) return pa
[docs]def get_particle_array_gasd(constants=None, **props): """Return a particle array for a Gas Dynamics problem. Parameters ---------- constants : dict Dictionary of constants Other Parameters ---------------- props : dict Additional keywords passed are set as the property arrays. See Also -------- get_particle_array """ required_props = [ 'x', 'y', 'z', 'u', 'v', 'w', 'rho', 'h', 'm', 'cs', 'p', 'e', 'au', 'av', 'aw', 'arho', 'ae', 'am', 'ah', 'x0', 'y0', 'z0', 'u0', 'v0', 'w0', 'rho0', 'e0', 'h0', 'div', 'grhox', 'grhoy', 'grhoz', 'dwdh', 'omega', 'converged', 'alpha1', 'alpha10', 'aalpha1', 'alpha2', 'alpha20', 'aalpha2', 'del2e'] pa = get_particle_array( constants=constants, additional_props=required_props, **props ) # set the intial smoothing length h0 to the particle smoothing # length. This can result in an annoying error in the density # iterations which require the h0 array pa.h0[:] = pa.h[:] pa.set_output_arrays(['x', 'y', 'u', 'v', 'rho', 'm', 'h', 'cs', 'p', 'e', 'au', 'av', 'ae', 'pid', 'gid', 'tag', 'dwdh', 'alpha1', 'alpha2'] ) return pa
[docs]def get_particles_info(particles): """Return the array information for a list of particles. Returns ------- An OrderedDict containing the property information for a list of particles. This dict can be used for example to set-up dummy/empty particle arrays. """ info = OrderedDict() for parray in particles: prop_info = {} for prop_name, prop in parray.properties.items(): prop_info[prop_name] = { 'name':prop_name, 'type':prop.get_c_type(), 'default':parray.default_values[prop_name], 'data':None} const_info = {} for c_name, value in parray.constants.items(): const_info[c_name] = value.get_npy_array() info[ parray.name ] = dict( properties=prop_info, constants=const_info, output_property_arrays=parray.output_property_arrays ) return info
[docs]def create_dummy_particles(info): """Returns a replica (empty) of a list of particles""" particles = [] for name, pa_data in info.items(): prop_dict = pa_data['properties'] constants = pa_data['constants'] pa = ParticleArray(name=name, constants=constants, **prop_dict) pa.set_output_arrays(pa_data['output_property_arrays']) particles.append(pa) return particles