/usr/lib/python2.7/dist-packages/PySPH-1.0a4.dev0-py2.7-linux-x86_64.egg/pysph/sph/acceleration_eval.py is in python-pysph 0~20160514.git91867dc-4build1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 | from collections import defaultdict
try:
from collections import OrderedDict
except ImportError:
from ordereddict import OrderedDict
from pysph.sph.equation import Group, get_arrays_used_in_equation
###############################################################################
def group_equations(equations):
"""Checks the given equations and ensures the following:
- Raises an error if the user mixes Groups and Equations.
- If only equations are given as a list, return a single group with all
these equations.
"""
only_groups = [x for x in equations if isinstance(x, Group)]
if len(only_groups) > 0 and len(only_groups) != len(equations):
raise ValueError('All elements must be Groups if you use groups.')
if len(only_groups) == 0:
return [Group(equations)]
else:
return equations
###############################################################################
def check_equation_array_properties(equation, particle_arrays):
"""Given an equation and the particle arrays, check if the particle arrays
have the necessary properties.
"""
#p_arrays = {x.name:x for x in particle_arrays}
p_arrays = dict((x.name, x) for x in particle_arrays)
_src, _dest = get_arrays_used_in_equation(equation)
eq_src = set([x[2:] for x in _src])
eq_dest = set([x[2:] for x in _dest])
def _check_array(array, eq_props, errors):
"""Updates the `errors` with any errors.
"""
props = set(list(array.properties.keys()) +
list(array.constants.keys()))
if not eq_props < props:
errors[array.name].update(eq_props - props)
errors = defaultdict(set)
_check_array(p_arrays[equation.dest], eq_dest, errors)
if equation.sources is not None:
for src in equation.sources:
_check_array(p_arrays[src], eq_src, errors)
if len(errors) > 0:
msg = "ERROR: Missing array properties for equation: %s\n"%equation.name
for name, missing in errors.items():
msg += "Array '%s' missing properties %s.\n"%(name, missing)
print(msg)
raise RuntimeError(msg)
###############################################################################
class MegaGroup(object):
"""A mega-group refactors actual equation Groups into a more
organized form as described below. They inherit all properties of the
Group so these can be used while generating code but delegate the tasks to
real groups underneath that are assembled from the original group.
MegaGroups are organized as:
{destination: (eqs_with_no_source, sources, all_eqs)}
eqs_with_no_source: Group([equations]) all SPH Equations with no source.
sources are {source: Group([equations...])}
all_eqs is a Group of all equations having this destination.
This is what is stored in the `data` attribute.
"""
def __init__(self, group):
self._orig_group = group
self._copy_props(group)
self.data = self._make_data(group)
def get_converged_condition(self):
return self._orig_group.get_converged_condition()
def _copy_props(self, group):
for key in ('real', 'update_nnps', 'iterate',
'max_iterations', 'min_iterations', 'has_subgroups'):
setattr(self, key, getattr(group, key))
def _make_data(self, group):
equations = group.equations
if group.has_subgroups:
return [MegaGroup(g) for g in equations]
dest_list = []
for equation in equations:
dest = equation.dest
if dest not in dest_list:
dest_list.append(dest)
dests = OrderedDict()
for dest in dest_list:
sources = defaultdict(list)
eqs_with_no_source = [] # For equations that have no source.
all_eqs = set()
for equation in equations:
if equation.dest != dest:
continue
all_eqs.add(equation)
if equation.no_source:
eqs_with_no_source.append(equation)
else:
for src in equation.sources:
sources[src].append(equation)
for src in sources:
eqs = sources[src]
sources[src] = Group(eqs)
# Sort the all_eqs set; so the order is deterministic. Without
# this a user may get a recompilation for no obvious reason.
all_equations = list(all_eqs)
all_equations.sort(key=lambda x:x.__class__.__name__)
dests[dest] = (Group(eqs_with_no_source), sources,
Group(all_equations))
return dests
###############################################################################
class AccelerationEval(object):
def __init__(self, particle_arrays, equations, kernel, mode='serial'):
"""
Parameters
----------
particle_arrays: list(ParticleArray): list of particle arrays to use.
equations: list: A list of equations/groups.
kernel: The kernel to use.
parallel: str: One of 'serial', 'mpi'.
"""
self.particle_arrays = particle_arrays
self.equation_groups = group_equations(equations)
self.kernel = kernel
self.nnps = None
self.mode = mode
all_equations = []
for group in self.equation_groups:
if group.has_subgroups:
for g in group.equations:
all_equations.extend(g.equations)
else:
all_equations.extend(group.equations)
self.all_group = Group(equations=all_equations)
for equation in all_equations:
check_equation_array_properties(equation, particle_arrays)
self.mega_groups = [MegaGroup(g) for g in self.equation_groups]
self.c_acceleration_eval = None
##########################################################################
# Public interface.
##########################################################################
def compute(self, t, dt):
"""Compute the accelerations given the current time, t, and the
timestep, dt.
"""
self.c_acceleration_eval.compute(t, dt)
def set_compiled_object(self, c_acceleration_eval):
"""Set the high-performance compiled object to call internally.
"""
self.c_acceleration_eval = c_acceleration_eval
def set_nnps(self, nnps):
self.nnps = nnps
self.c_acceleration_eval.set_nnps(nnps)
def update_particle_arrays(self, particle_arrays):
"""Call this to update the particle arrays with new ones. Make sure
though that the same properties exist in both or you will get a
segfault.
"""
self.c_acceleration_eval.update_particle_arrays(particle_arrays)
|