def _OperatorVariableClass(self, baseClass=None): baseClass = Variable._OperatorVariableClass(self, baseClass=baseClass) class _MeshOperatorVariable(baseClass): def __init__(self, op, var, opShape=None, canInline=True, *args, **kwargs): mesh = reduce(lambda a, b: a or b, [getattr(v, "mesh", None) for v in var]) for shape in [opShape] + [getattr(v, "opShape", None) for v in var]: if shape is not None: opShape = shape break ## opShape = reduce(lambda a, b: a or b, ## [opShape] + [getattr(v, "opShape", None) for v in var]) if opShape is not None: elementshape = opShape[:-1] else: elementshape = reduce(lambda a, b: a or b, [getattr(v, "elementshape", None) for v in var]) baseClass.__init__(self, mesh=mesh, op=op, var=var, opShape=opShape, canInline=canInline, elementshape=elementshape, *args, **kwargs) def getRank(self): return len(self.opShape) - 1 return _MeshOperatorVariable
def _axisClass(self, axis): """ if we operate along the mesh elements, then this is no longer a `_MeshVariable`, otherwise we get back a `_MeshVariable` of the same class, but lower rank. """ if axis is None or axis == len(self.shape) - 1 or axis == -1: return Variable._OperatorVariableClass(self, baseClass=Variable) else: return self._OperatorVariableClass()
def _getitemClass(self, index): if not isinstance(index, tuple): if isinstance(index, list): index = tuple(index) else: index = (index, ) indexshape = numerix._indexShape(index=index, arrayShape=self.shape) if (len(indexshape) > 0 and indexshape[-1] == self.shape[-1] and numerix.obj2sctype(index[-1]) != numerix.obj2sctype(bool)): return self._OperatorVariableClass() else: return Variable._OperatorVariableClass(self, baseClass=Variable)
def _getitemClass(self, index): if not isinstance(index, tuple): if isinstance(index, list): index = tuple(index) else: index = (index,) indexshape = numerix._indexShape(index=index, arrayShape=self.shape) if (len(indexshape) > 0 and indexshape[-1] == self.shape[-1] and numerix.obj2sctype(index[-1]) != numerix.obj2sctype(bool)): return self._OperatorVariableClass() else: return Variable._OperatorVariableClass(self, baseClass=Variable)
def allequal(self, other): if self.getMesh().communicator.Nproc > 1: def allequalParallel(a, b): return self.getMesh().communicator.allequal(a, b) operatorClass = Variable._OperatorVariableClass(self, baseClass=Variable) return self._BinaryOperatorVariable(allequalParallel, other, operatorClass=operatorClass, opShape=(), canInline=False) else: return Variable.allequal(self, other)
def allclose(self, other, rtol=1.e-5, atol=1.e-8): if self.getMesh().communicator.Nproc > 1: def allcloseParallel(a, b): return self.getMesh().communicator.allclose(a, b, rtol=rtol, atol=atol) operatorClass = Variable._OperatorVariableClass(self, baseClass=Variable) return self._BinaryOperatorVariable(allcloseParallel, other, operatorClass=operatorClass, opShape=(), canInline=False) else: return Variable.allclose(self, other, rtol=rtol, atol=atol)
def allequal(self, other): if parallel.Nproc > 1: from mpi4py import MPI def allequalParallel(a, b): return MPI.COMM_WORLD.allreduce(numerix.allequal(a, b), op=MPI.LAND) operatorClass = Variable._OperatorVariableClass(self, baseClass=Variable) return self._BinaryOperatorVariable(allequalParallel, other, operatorClass=operatorClass, opShape=(), canInline=False) else: return Variable.allequal(self, other)
def allequal(self, other): if self.mesh.communicator.Nproc > 1: def allequalParallel(a, b): return self.mesh.communicator.allequal(a, b) operatorClass = Variable._OperatorVariableClass(self, baseClass=Variable) return self._BinaryOperatorVariable(allequalParallel, other, operatorClass=operatorClass, opShape=(), canInline=False) else: return Variable.allequal(self, other)
def _OperatorVariableClass(self, baseClass=None): baseClass = Variable._OperatorVariableClass(self, baseClass=baseClass) class _MeshOperatorVariable(baseClass): def __init__(self, op, var, opShape=None, canInline=True, *args, **kwargs): mesh = reduce(lambda a, b: a or b, [getattr(v, "mesh", None) for v in var]) for shape in [opShape ] + [getattr(v, "opShape", None) for v in var]: if shape is not None: opShape = shape break ## opShape = reduce(lambda a, b: a or b, ## [opShape] + [getattr(v, "opShape", None) for v in var]) if opShape is not None: elementshape = opShape[:-1] else: elementshape = reduce( lambda a, b: a or b, [getattr(v, "elementshape", None) for v in var]) baseClass.__init__(self, mesh=mesh, op=op, var=var, opShape=opShape, canInline=canInline, elementshape=elementshape, *args, **kwargs) @getsetDeprecated def getRank(self): return self.rank @property def rank(self): return len(self.opShape) - 1 return _MeshOperatorVariable
def allclose(self, other, rtol=1.e-5, atol=1.e-8): if self.mesh.communicator.Nproc > 1: def allcloseParallel(a, b): return self.mesh.communicator.allclose(a, b, rtol=rtol, atol=atol) operatorClass = Variable._OperatorVariableClass(self, baseClass=Variable) return self._BinaryOperatorVariable(allcloseParallel, other, operatorClass=operatorClass, opShape=(), canInline=False) else: return Variable.allclose(self, other, rtol=rtol, atol=atol)