def vector2Multipole(vector, n): """ undo multipole2Vector result in a n multipole """ f = CompressedTensor(1, id=CompressedTensor(n - 1, id=0)) indices = symmetricVSflatIndices(n - 1) l = len(indices) for fi in [(0, (1, 0, 0)), (1, (0, 1, 0)), (2, (0, 0, 1))]: for i in indices: f.components[fi[1]].components[indices[i]] = vector[i + fi[0] * l] return f
def nablaOseen(): o = oseenTensor() res = CompressedTensor(2, id=OseenFunction([])) for i in res.indices: h = res.components[i] for d in [0, 1, 2]: h += o.components[i].nDerive([d, d]) res.components[i] = h return res
def vector2VelocityMultipole(vector, n): """ because of a symmetry shift, due to the application of the g-matrix velocity and force multipoles cannot be treated in the same way! """ f = CompressedTensor(1, id=CompressedTensor(n - 1, id=0)) indices = symmetricVSflatIndices(n - 1) l = len(indices) for fi in [(0, (1, 0, 0)), (1, (0, 1, 0)), (2, (0, 0, 1))]: for (i, ind) in zip(range(len(indices)), indices): f.components[fi[1]].components[indices[i]] = vector[3 * i + fi[0]] return f
def polynomTensor(p, r0=(0, 0, 0)): """ a tensor that contains polynoms (r-r0)^p. Such a tensor is symmetric, therefore the polynoms are saved within a compressed tensor. """ res = CompressedTensor(p, id=Polynom(0, 0, 0, 0)) if r0 == (0, 0, 0): for (nx, ny, nz) in res.indices: res.components[(nx, ny, nz)] = Polynom(1, nx, ny, nz) else: for (nx, ny, nz) in res.indices: x = (Polynom(1, 1, 0, 0) - Polynom(r0[0], 0, 0, 0))**nx y = (Polynom(1, 0, 1, 0) - Polynom(r0[1], 0, 0, 0))**ny z = (Polynom(1, 0, 0, 1) - Polynom(r0[2], 0, 0, 0))**nz res.components[(nx, ny, nz)] = x * y * z return res
def poseenTensor(eta=0.7): c = 1 / (4 * pi) res = CompressedTensor(1, id=Polynom(0, 0, 0, 0)) res.setComponent([0], OseenFunction([OseenTerm(3, Polynom(c, 1, 0, 0))])) res.setComponent([1], OseenFunction([OseenTerm(3, Polynom(c, 0, 1, 0))])) res.setComponent([2], OseenFunction([OseenTerm(3, Polynom(c, 0, 0, 1))])) return res
def oseenTensor(eta=0.7): """ due to the symmetry of the oseen tensor a tensor in compressed form should be returned? The derivatives of the oseen tensor are also symmetric to each other but the indizes of the oseen tensor and the derivatives are not. """ res = CompressedTensor(2, id=Polynom(0, 0, 0, 0)) c = 1 / 8 / pi / eta for (nx, ny, nz) in res.indices: p = Polynom(c, nx, ny, nz) t = OseenTerm(3, p) #res[i,j] = OseenFunction([t]) if 2 in (nx, ny, nz): q = Polynom(c, 0, 0, 0) s = OseenTerm(1, q) res.components[(nx, ny, nz)] = OseenFunction([s, t]) else: res.components[(nx, ny, nz)] = OseenFunction([t]) return res
def polyTimesOseenDerivative(n, p, r0=(0, 0, 0), r1=(0, 0, 0)): """ this results in a tensor of functions which is used very often: multipoles and mobility the outer product of a tensor of polynoms with the oseenDerivatives. This is a very efficient way to compute it because symmetries of tensors are used. """ rhn = polynomTensor(n, r0) ode = mapTensor(lambda c: c.shift(r1), oseenDerivative(p)) # as a first step create a CompressedTensor of rank rhn.rank # (because it is much smaller than ode.flatten().rank) with id # ode.flatten().id (OseenFunctions) # hhh will be a CompressedTensor of a CompressedTensor of a CompressedTensor. # As a result we need to perform much fewer integrations # TODO: this kind of optimization must be made in explicitMultipoles! res = CompressedTensor( rhn.rank, id=CompressedTensor(p, id=CompressedTensor(2, OseenFunction({}).shift(r1)))) for r in rhn.indices: oFunc = OseenFunction([OseenTerm(0, rhn.components[r])]) res.components[r] = mapTensor(lambda c: c * oFunc, ode) return res
def compressedOseenFunctionTensorDerivative(t, n): """ the nth derivative of a compressed tensor, containing elements that implement a nDerive method. The result is a compressed tensor of compressed tensors. """ if n == 0: return t res = CompressedTensor(n, id=CompressedTensor(t.rank, id=OseenFunction( []))) #OseenTerm(0,Polynom(0,0,0,0))]))) for (dx, dy, dz) in res.indices: h = CompressedTensor(t.rank, id=OseenFunction( [])) #OseenTerm(0,Polynom(0,0,0,0))])) for i in t.indices: h.components[i] = t.components[i].nDerive([0] * dx + [1] * dy + [2] * dz) res.components[(dx, dy, dz)] = h return res