def laplace_basis(self, point, cellidx=None, p=None): if p is None: p = self.p area = self.area ldof = self.number_of_local_dofs() shape = point.shape[:-1] + (ldof, ) lphi = np.zeros(shape, dtype=np.float) if p > 1: start = 3 r = np.arange(1, p + 1) r = r[0:-1] * r[1:] phi = self.basis(point, cellidx=cellidx) for i in range(2, p + 1): lphi[..., start:start + i - 1] += np.einsum( 'i, ...i->...i', r[i - 2::-1], phi[..., start - 2 * i + 1:start - i]) lphi[..., start + 2:start + i + 1] += np.eisum( 'i, ...i->...i', r[0:i - 1], phi[..., start - 2 * i + 1:start - i]) start += i + 1 if cellidx is None: return lphi / area.reshape(-1, 1) else: assert (point.shape[-2] == len(cellidx)) return lphi / area[cellidx].reshape(-1, 1)
def basis(self, bc): bc0 = bc[0] bc1 = bc[1] phi0 = self.lagranian_basis(bc0, 2) phi1 = self.lagranian_basis(bc1, 1) phi = np.eisum('', phi0, phi1) return phi