def mpi1d_exp_pb(m: int, n: int, f: Expression, ft: Expression, fx: Expression) -> (np.array, np.array): # Define mesh and function space. mesh = UnitSquareMesh(m - 1, n - 1) V = dh.create_function_space(mesh, 'periodic') # Compute velocity. v, k = mpi1d_weak_solution(V, f, ft, fx) # Convert back to array and return. v = dh.funvec2img_pb(v.vector().get_local(), m, n) k = dh.funvec2img_pb(k.vector().get_local(), m, n) return v, k
def cm1d_exp_pb(m: int, n: int, f: Expression, ft: Expression, fx: Expression, alpha0: float, alpha1: float) -> np.array: """Computes the L2-H1 mass conserving flow for a 1D image sequence with periodic boundary. Args: m (int): Number of temporal sampling points. n (int): Number of spatial sampling points. f (Expression): 1D image sequence. ft (Expression): Partial derivative of f wrt. time. fx (Expression): Partial derivative of f wrt. space. alpha0 (float): Spatial regularisation parameter. alpha1 (float): Temporal regularisation parameter. Returns: v (np.array): A velocity array of shape (m, n). res (float): The residual. func (float): The value of the functional. """ # Define mesh and function space. mesh = UnitSquareMesh(m - 1, n - 1) V = dh.create_function_space(mesh, 'periodic') # Compute velocity. v, res, fun = cm1d_weak_solution(V, f, ft, fx, alpha0, alpha1) # Convert to array and return. return dh.funvec2img_pb(v.vector().get_local(), m, n), res, fun
def cm1d_img_pb(img: np.array, alpha0: float, alpha1: float, deriv='mesh') -> np.array: """Computes the L2-H1 mass conserving flow for a 1D image sequence with periodic spatial boundary. Allows to specify how to approximate partial derivatives of f numerically. Note that the last column of img is ignored. Args: img (np.array): 1D image sequence of shape (m, n), where m is the number of time steps and n is the number of pixels. alpha0 (float): Spatial regularisation parameter. alpha1 (float): Temporal regularisation parameter. deriv (str): Specifies how to approximate pertial derivatives. When set to 'mesh' it uses FEniCS built in function. Returns: v (np.array): A velocity array of shape (m, n). res (float): The residual. func (float): The value of the functional. """ # Check for valid arguments. valid = {'mesh'} if deriv not in valid: raise ValueError("Argument 'deriv' must be one of %r." % valid) # Create mesh. m, n = img.shape mesh = UnitSquareMesh(m - 1, n - 1) # Define function space. V = dh.create_function_space(mesh, 'periodic') # Convert array to function. f = Function(V) f.vector()[:] = dh.img2funvec_pb(img) # Compute partial derivatives. ft, fx = f.dx(0), f.dx(1) # Compute velocity. v, res, fun = cm1d_weak_solution(V, f, ft, fx, alpha0, alpha1) # Convert to array and return. return dh.funvec2img_pb(v.vector().get_local(), m, n), res, fun
def test_funvec2img_pb(self): m, n = 10, 20 # Define mesh. mesh = UnitSquareMesh(m - 1, n - 1) # Define function spaces V = FunctionSpace(mesh, 'CG', 1, constrained_domain=dh.PeriodicBoundary()) class MyUserExpression(UserExpression): def eval(self, value, x): value[0] = x[0] def value_shape(self): return (1, ) f = interpolate(MyUserExpression(element=V.ufl_element()), V) v = dh.funvec2img_pb(f.vector().get_local(), m, n) np.testing.assert_allclose(v.shape, (m, n)) np.testing.assert_allclose(v[:, 0], v[:, -1])
mesh = UnitSquareMesh(m - 1, n - 1) V = dh.create_function_space(mesh, 'default') W = dh.create_function_space(mesh, 'periodic') # Run experiments with decaying data. f = f_decay(degree=2) ft = f_decay_t(degree=1) fx = f_decay_x(degree=1) datastr = DecayingData().string() # Interpolate function. fa = interpolate(f, V) fa = dh.funvec2img(fa.vector().get_local(), m, n) fa_pb = interpolate(f, W) fa_pb = dh.funvec2img_pb(fa_pb.vector().get_local(), m, n) v, res, fun = cm1d_exp_pb(m, n, f, ft, fx, alpha0, alpha1) saveresults(resultpath, 'decay_cm1d_l2h1_exp_pb', 'l2h1', fa_pb, v) v, k, res, fun, converged = cmscr1d_exp_pb(m, n, f, ft, fx, alpha0, alpha1, alpha2, alpha3, beta) saveresults(resultpath, 'decay_cmscr1d_l2h1h1cr_exp_pb', 'l2h1h1cr', fa_pb, v, k, (c0 - fa_pb) / tau) # The next example shows that for the initial concentration used in the # mechanical models the algorithm picks up the source well. class f_decay(UserExpression): def eval(self, value, x): value[0] = 20 - np.sin(10 * np.pi * x[1] +
def test_img2fun_fun2img_pb(self): m, n = 7, 13 img = np.random.rand(m, n) v = dh.img2funvec_pb(img) np.testing.assert_allclose( dh.funvec2img_pb(v, m, n)[:, 1:], img[:, 1:])