def compute_projection_error(mesh_resolution=20, p_order=1):
    # Define domain and mesh
    a, b = 0, 1
    mesh = IntervalMesh(mesh_resolution, a, b)

    # Define finite element function space
    V = FunctionSpace(mesh, "CG", p_order)

    # Extract vertices of the mesh
    x = V.dofmap().tabulate_all_coordinates(mesh)
    indices = np.argsort(x)

    # Express the analytical function
    u = Expression("1 + 4 * x[0] * x[0] - 5 * x[0] * x[0] * x[0]", degree=5)

    # Project u onto V and extract the values in the mesh nodes
    Pu = project(u, V)
    Pua = Pu.vector().array()

    # Create a function in the finite element function space V
    Eu = Function(V)
    Eua = Eu.vector().array()

    # Evaluate function in the mesh nodes
    for j in indices:
        Eua[j] = 1 + 4 * x[j] * x[j] - 5 * x[j] * x[j] * x[j]

    # Compute sum of projection error in the nodes
    e = Eua - Pua
    error = 0
    for i in range(len(e)):
        error += abs(e[i])
    return error
def compute_interpolation_error(mesh_resolution=20):
    # Define domain and mesh
    a, b = 0, 1
    mesh = IntervalMesh(mesh_resolution, a, b)

    # Define finite element function space
    p_order = 1
    V = FunctionSpace(mesh, "CG", p_order)

    # Extract vertices of the mesh
    x = V.tabulate_dof_coordinates()
    # Note: Not the same as x = mesh.coordinates() (apparently has been re-ordered)

    # Express the analytical function
    u = Expression("1 + x[0] * sin(10 * x[0])", degree=5)

    # Interpolate u onto V and extract the values in the mesh nodes
    Iu = interpolate(u, V)
    Iua = Iu.vector().array()

    # Evaluate u at the mesh vertices
    Eua = np.empty(len(x))
    for i in range(len(x)):
        Eua[i] = 1 + x[i] * math.sin(10 * x[i])

    # Compute max interpolation error in the nodes
    e = Eua - Iua
    e_abs = np.absolute(e)
    error = np.amax(e_abs)
    return error
def compute_projection_error(mesh_resolution=20, p_order=1):
    # Define domain and mesh
    a, b = 0, 1
    mesh = IntervalMesh(mesh_resolution, a, b)

    # Define finite element function space
    V = FunctionSpace(mesh, "CG", p_order)

    # Extract vertices of the mesh
    x = V.tabulate_dof_coordinates()
    # Note: Not the same as x = mesh.coordinates() (apparently has been re-ordered)

    # Express the analytical function
    u = Expression("1 + 4 * x[0] * x[0] - 5 * x[0] * x[0] * x[0]", degree=5)

    # Project u onto V and extract the values in the mesh nodes
    Pu = project(u, V)
    Pua = Pu.vector().array()

    # Create a function in the finite element function space V
    Eu = Function(V)
    Eua = Eu.vector().array()

    # Evaluate function in the mesh nodes
    for i in range(len(x)):
        Eua[i] = 1 + 4 * x[i]**2 - 5 * x[i]**3

    # Compute sum of projection error in the nodes
    e = Eua - Pua
    error = 0
    for i in range(len(e)):
        error += abs(e[i])
    return error
Beispiel #4
0
def setup_module(module=None):
    # define the mesh
    x_max = 20e-9  # m
    simplexes = 10
    mesh = IntervalMesh(simplexes, 0, x_max)

    def m_gen(coords):
        x = coords[0]
        mx = min(1.0, 2.0 * x / x_max - 1.0)
        my = np.sqrt(1.0 - mx**2)
        mz = 0.0
        return np.array([mx, my, mz])

    Ms = 0.86e6
    A = 1.3e-11

    global sim
    sim = Sim(mesh, Ms)
    sim.alpha = 0.2
    sim.set_m(m_gen)
    sim.pins = [0, 10]
    exchange = Exchange(A)
    sim.add(exchange)

    # Save H_exc and m at t0 for comparison with nmag
    global H_exc_t0, m_t0
    H_exc_t0 = exchange.compute_field()
    m_t0 = sim.m

    t = 0
    t1 = 5e-10
    dt = 1e-11
    # s

    av_f = open(os.path.join(MODULE_DIR, "averages.txt"), "w")
    tn_f = open(os.path.join(MODULE_DIR, "third_node.txt"), "w")

    global averages
    averages = []
    global third_node
    third_node = []

    while t <= t1:
        mx, my, mz = sim.m_average
        averages.append([t, mx, my, mz])
        av_f.write(
            str(t) + " " + str(mx) + " " + str(my) + " " + str(mz) + "\n")

        mx, my, mz = h.components(sim.m)
        m2x, m2y, m2z = mx[2], my[2], mz[2]
        third_node.append([t, m2x, m2y, m2z])
        tn_f.write(
            str(t) + " " + str(m2x) + " " + str(m2y) + " " + str(m2z) + "\n")

        t += dt
        sim.run_until(t)

    av_f.close()
    tn_f.close()
Beispiel #5
0
def fit1d(x0, y0, a, b, n, eps, degree=1, verbose=False):
    mesh = IntervalMesh(n, a, b)
    Eps = numpy.array([[eps]])
    return fit(x0[:, numpy.newaxis],
               y0,
               mesh,
               Eps,
               degree=degree,
               verbose=verbose)
Beispiel #6
0
def _test_linear_solver_sparse(callback_type):
    # Create mesh and define function space
    mesh = IntervalMesh(132, 0, 2 * pi)
    V = FunctionSpace(mesh, "Lagrange", 1)

    # Define Dirichlet boundary (x = 0 or x = 2*pi)
    def boundary(x):
        return x[0] < 0 + DOLFIN_EPS or x[0] > 2 * pi - 10 * DOLFIN_EPS

    # Define exact solution
    exact_solution_expression = Expression("x[0] + sin(2*x[0])",
                                           element=V.ufl_element())
    exact_solution = project(exact_solution_expression, V)

    # Define variational problem
    u = TrialFunction(V)
    v = TestFunction(V)
    g = Expression("4*sin(2*x[0])", element=V.ufl_element())
    a = inner(grad(u), grad(v)) * dx
    f = g * v * dx
    x = inner(u, v) * dx

    # Assemble inner product matrix
    X = assemble(x)

    # Define boundary condition
    bc = [DirichletBC(V, exact_solution_expression, boundary)]

    # Defin solution
    sparse_solution = Function(V)

    # Define linear solver depending on callback type, and solve the problem
    assert callback_type in ("form callbacks", "tensor callbacks")
    if callback_type == "form callbacks":
        A = None
        F = None
        sparse_solver = SparseLinearSolver(a, sparse_solution, f, bc)
    elif callback_type == "tensor callbacks":
        A = assemble(a)
        F = assemble(f)
        sparse_solver = SparseLinearSolver(A, sparse_solution, F, bc)
    sparse_solver.solve()

    # Compute the error
    sparse_error = Function(V)
    sparse_error.vector().add_local(+sparse_solution.vector().get_local())
    sparse_error.vector().add_local(-exact_solution.vector().get_local())
    sparse_error.vector().apply("")
    sparse_error_norm = sparse_error.vector().inner(X * sparse_error.vector())
    print("SparseLinearSolver error (" + callback_type + "):",
          sparse_error_norm)
    assert isclose(sparse_error_norm, 0., atol=1.e-5)
    return (sparse_error_norm, V, A, F, X, exact_solution)
Beispiel #7
0
def _test_time_stepping_1_sparse(callback_type, integrator_type):
    # Create mesh and define function space
    mesh = IntervalMesh(132, 0, 2*pi)
    V = FunctionSpace(mesh, "Lagrange", 1)

    # Define Dirichlet boundary (x = 0 or x = 2*pi)
    def boundary(x):
        return x[0] < 0 + DOLFIN_EPS or x[0] > 2*pi - 10*DOLFIN_EPS
        
    # Define time step
    dt = 0.01
    T = 1.

    # Define exact solution
    exact_solution_expression = Expression("sin(x[0]+t)", t=0, element=V.ufl_element())
    # ... and interpolate it at the final time
    exact_solution_expression.t = T
    exact_solution = project(exact_solution_expression, V)

    # Define exact solution dot
    exact_solution_dot_expression = Expression("cos(x[0]+t)", t=0, element=V.ufl_element())
    # ... and interpolate it at the final time
    exact_solution_dot_expression.t = T
    exact_solution_dot = project(exact_solution_dot_expression, V)

    # Define variational problem
    du = TrialFunction(V)
    du_dot = TrialFunction(V)
    v = TestFunction(V)
    u = Function(V)
    u_dot = Function(V)
    g = Expression("sin(x[0]+t) + cos(x[0]+t)", t=0., element=V.ufl_element())
    r_u = inner(grad(u), grad(v))*dx
    j_u = derivative(r_u, u, du)
    r_u_dot = inner(u_dot, v)*dx
    j_u_dot = derivative(r_u_dot, u_dot, du_dot)
    r = r_u_dot + r_u - g*v*dx
    x = inner(du, v)*dx
    def bc(t):
        exact_solution_expression.t = t
        return [DirichletBC(V, exact_solution_expression, boundary)]

    # Assemble inner product matrix
    X = assemble(x)
    
    # Define callback function depending on callback type
    assert callback_type in ("form callbacks", "tensor callbacks")
    if callback_type == "form callbacks":
        def callback(arg):
            return arg
    elif callback_type == "tensor callbacks":
        def callback(arg):
            return assemble(arg)
            
    # Define problem wrapper
    class SparseProblemWrapper(TimeDependentProblem1Wrapper):
        # Residual and jacobian functions
        def residual_eval(self, t, solution, solution_dot):
            g.t = t
            return callback(r)
        def jacobian_eval(self, t, solution, solution_dot, solution_dot_coefficient):
            return callback(Constant(solution_dot_coefficient)*j_u_dot + j_u)
            
        # Define boundary condition
        def bc_eval(self, t):
            return bc(t)
            
        # Define initial condition
        def ic_eval(self):
            exact_solution_expression.t = 0.
            return project(exact_solution_expression, V)
            
        # Define custom monitor to plot the solution
        def monitor(self, t, solution, solution_dot):
            if matplotlib.get_backend() != "agg":
                plt.subplot(1, 2, 1).clear()
                plot(solution, title="u at t = " + str(t))
                plt.subplot(1, 2, 2).clear()
                plot(solution_dot, title="u_dot at t = " + str(t))
                plt.show(block=False)
                plt.pause(DOLFIN_EPS)
            else:
                print("||u|| at t = " + str(t) + ": " + str(solution.vector().norm("l2")))
                print("||u_dot|| at t = " + str(t) + ": " + str(solution_dot.vector().norm("l2")))

    # Solve the time dependent problem
    sparse_problem_wrapper = SparseProblemWrapper()
    (sparse_solution, sparse_solution_dot) = (u, u_dot)
    sparse_solver = SparseTimeStepping(sparse_problem_wrapper, sparse_solution, sparse_solution_dot)
    sparse_solver.set_parameters({
        "initial_time": 0.0,
        "time_step_size": dt,
        "final_time": T,
        "exact_final_time": "stepover",
        "integrator_type": integrator_type,
        "problem_type": "linear",
        "linear_solver": "mumps",
        "monitor": sparse_problem_wrapper.monitor,
        "report": True
    })
    all_sparse_solutions_time, all_sparse_solutions, all_sparse_solutions_dot = sparse_solver.solve()
    assert len(all_sparse_solutions_time) == int(T/dt + 1)
    assert len(all_sparse_solutions) == int(T/dt + 1)
    assert len(all_sparse_solutions_dot) == int(T/dt + 1)

    # Compute the error
    sparse_error = Function(V)
    sparse_error.vector().add_local(+ sparse_solution.vector().get_local())
    sparse_error.vector().add_local(- exact_solution.vector().get_local())
    sparse_error.vector().apply("")
    sparse_error_norm = sparse_error.vector().inner(X*sparse_error.vector())
    sparse_error_dot = Function(V)
    sparse_error_dot.vector().add_local(+ sparse_solution_dot.vector().get_local())
    sparse_error_dot.vector().add_local(- exact_solution_dot.vector().get_local())
    sparse_error_dot.vector().apply("")
    sparse_error_dot_norm = sparse_error_dot.vector().inner(X*sparse_error_dot.vector())
    print("SparseTimeStepping error (" + callback_type + ", " + integrator_type + "):", sparse_error_norm, sparse_error_dot_norm)
    assert isclose(sparse_error_norm, 0., atol=1.e-4)
    assert isclose(sparse_error_dot_norm, 0., atol=1.e-4)
    return ((sparse_error_norm, sparse_error_dot_norm), V, dt, T, u, u_dot, g, r, j_u, j_u_dot, X, exact_solution_expression, exact_solution, exact_solution_dot)
Beispiel #8
0
from dolfin import IntervalMesh
from dolfin.fem.interpolation import interpolate
from dolfin.functions import FunctionSpace, TestFunction, Function, Expression

# Define domain and mesh
a, b = 0, 1
mesh_resolution = 20
mesh = IntervalMesh(mesh_resolution, a, b)

# Define finite element function space
p_order = 1
V = FunctionSpace(mesh, "CG", p_order)

# Interpolate function
u = Expression("1 + 4.0 * x[0] * x[0] - 5.0 * x[0] * x[0] * x[0]", degree=5)
Iu = interpolate(u, V)
Iua = Iu.vector().array()
print(Iua.max())
def test_eim_approximation_14(expression_type, basis_generation):
    """
    The aim of this script is to test EIM/DEIM for nonlinear problems, extending test 13.
    The difference with respect to test 13 is that a parametrized problem is defined but it is not
    reduced any further. See the description of EIM and DEIM for test 13, taking care of the fact
    that the high fidelity solution is used in place of the reduced order one.
    """
    @StoreMapFromProblemNameToProblem
    @StoreMapFromProblemToTrainingStatus
    @StoreMapFromSolutionToProblem
    class MockProblem(ParametrizedProblem):
        def __init__(self, V, **kwargs):
            # Call parent
            ParametrizedProblem.__init__(
                self,
                os.path.join("test_eim_approximation_14_tempdir",
                             expression_type, basis_generation,
                             "mock_problem"))
            # Minimal subset of a ParametrizedDifferentialProblem
            self.V = V
            self._solution = Function(V)
            self.components = ["u", "s", "p"]
            # Parametrized function to be interpolated
            x = SpatialCoordinate(V.mesh())
            mu = SymbolicParameters(self, V, (1., ))
            self.f00 = (1 - x[0]) * cos(3 * pi * mu[0] *
                                        (1 + x[0])) * exp(-mu[0] * (1 + x[0]))
            self.f01 = (1 - x[0]) * sin(3 * pi * mu[0] *
                                        (1 + x[0])) * exp(-mu[0] * (1 + x[0]))
            # Inner product
            f = TrialFunction(self.V)
            g = TestFunction(self.V)
            self.inner_product = assemble(inner(f, g) * dx)
            # Collapsed vector and space
            self.V0 = V.sub(0).collapse()
            self.V00 = V.sub(0).sub(0).collapse()
            self.V1 = V.sub(1).collapse()

        def name(self):
            return "MockProblem_14_" + expression_type + "_" + basis_generation

        def init(self):
            pass

        def solve(self):
            print("solving mock problem at mu =", self.mu)
            assert not hasattr(self, "_is_solving")
            self._is_solving = True
            f00 = project(self.f00, self.V00)
            f01 = project(self.f01, self.V00)
            assign(self._solution.sub(0).sub(0), f00)
            assign(self._solution.sub(0).sub(1), f01)
            delattr(self, "_is_solving")
            return self._solution

    @StoreMapFromProblemToReductionMethod
    class MockReductionMethod(ReductionMethod):
        def __init__(self, truth_problem, **kwargs):
            # Call parent
            ReductionMethod.__init__(
                self,
                os.path.join("test_eim_approximation_14_tempdir",
                             expression_type, basis_generation,
                             "mock_problem"))
            # Minimal subset of a DifferentialProblemReductionMethod
            self.truth_problem = truth_problem
            self.reduced_problem = None

        def initialize_training_set(self,
                                    ntrain,
                                    enable_import=True,
                                    sampling=None,
                                    **kwargs):
            return ReductionMethod.initialize_training_set(
                self, self.truth_problem.mu_range, ntrain, enable_import,
                sampling, **kwargs)

        def initialize_testing_set(self,
                                   ntest,
                                   enable_import=False,
                                   sampling=None,
                                   **kwargs):
            return ReductionMethod.initialize_testing_set(
                self, self.truth_problem.mu_range, ntest, enable_import,
                sampling, **kwargs)

        def offline(self):
            pass

        def update_basis_matrix(self, snapshot):
            pass

        def error_analysis(self, N=None, **kwargs):
            pass

        def speedup_analysis(self, N=None, **kwargs):
            pass

    class ParametrizedFunctionApproximation(EIMApproximation):
        def __init__(self, truth_problem, expression_type, basis_generation):
            self.V = truth_problem.V1
            (f0, _) = split(truth_problem._solution)
            #
            folder_prefix = os.path.join("test_eim_approximation_14_tempdir",
                                         expression_type, basis_generation)
            assert expression_type in ("Function", "Vector", "Matrix")
            if expression_type == "Function":
                # Call Parent constructor
                EIMApproximation.__init__(self, truth_problem,
                                          ParametrizedExpressionFactory(f0),
                                          folder_prefix, basis_generation)
            elif expression_type == "Vector":
                v = TestFunction(self.V)
                form = f0[0] * v * dx + f0[1] * v.dx(0) * dx
                # Call Parent constructor
                EIMApproximation.__init__(self, truth_problem,
                                          ParametrizedTensorFactory(form),
                                          folder_prefix, basis_generation)
            elif expression_type == "Matrix":
                u = TrialFunction(self.V)
                v = TestFunction(self.V)
                form = f0[0] * u * v * dx + f0[1] * u.dx(0) * v * dx
                # Call Parent constructor
                EIMApproximation.__init__(self, truth_problem,
                                          ParametrizedTensorFactory(form),
                                          folder_prefix, basis_generation)
            else:  # impossible to arrive here anyway thanks to the assert
                raise AssertionError("Invalid expression_type")

    # 1. Create the mesh for this test
    mesh = IntervalMesh(100, -1., 1.)

    # 2. Create Finite Element space (Lagrange P1)
    element_0 = VectorElement("Lagrange", mesh.ufl_cell(), 2, dim=2)
    element_1 = FiniteElement("Lagrange", mesh.ufl_cell(), 1)
    element = MixedElement(element_0, element_1)
    V = FunctionSpace(mesh, element, components=[["u", "s"], "p"])

    # 3. Create a parametrized problem
    problem = MockProblem(V)
    mu_range = [
        (1., pi),
    ]
    problem.set_mu_range(mu_range)

    # 4. Create a reduction method, but postpone generation of the reduced problem
    MockReductionMethod(problem)

    # 5. Allocate an object of the ParametrizedFunctionApproximation class
    parametrized_function_approximation = ParametrizedFunctionApproximation(
        problem, expression_type, basis_generation)
    parametrized_function_approximation.set_mu_range(mu_range)

    # 6. Prepare reduction with EIM
    parametrized_function_reduction_method = EIMApproximationReductionMethod(
        parametrized_function_approximation)
    parametrized_function_reduction_method.set_Nmax(12)
    parametrized_function_reduction_method.set_tolerance(0.)

    # 7. Perform EIM offline phase
    parametrized_function_reduction_method.initialize_training_set(
        51, sampling=EquispacedDistribution())
    reduced_parametrized_function_approximation = parametrized_function_reduction_method.offline(
    )

    # 8. Perform EIM online solve
    online_mu = (1., )
    reduced_parametrized_function_approximation.set_mu(online_mu)
    reduced_parametrized_function_approximation.solve()

    # 9. Perform EIM error analysis
    parametrized_function_reduction_method.initialize_testing_set(100)
    parametrized_function_reduction_method.error_analysis()
Beispiel #10
0
def test_eim_approximation_12(expression_type, basis_generation):
    """
    The aim of this script is to test EIM/DEIM for nonlinear problems, extending test 11.
    The difference with respect to test 11 is that a parametrized problem is defined but it is not
    reduced any further.
    Thus, the high fidelity solution will be used inside the parametrized expression/tensor, while
    in test 11 the reduced order solution was being used.
    * EIM: the expression to be interpolated is the solution of the nonlinear high fidelity problem.
    * DEIM: the form to be interpolated contains the solution of the nonlinear high fidelity problem.
    """

    @StoreMapFromProblemNameToProblem
    @StoreMapFromProblemToTrainingStatus
    @StoreMapFromSolutionToProblem
    class MockProblem(ParametrizedProblem):
        def __init__(self, V, **kwargs):
            # Call parent
            ParametrizedProblem.__init__(self, os.path.join("test_eim_approximation_12_tempdir", expression_type, basis_generation, "mock_problem"))
            # Minimal subset of a ParametrizedDifferentialProblem
            self.V = V
            self._solution = Function(V)
            self.components = ["u"]
            # Parametrized function to be interpolated
            x = SpatialCoordinate(V.mesh())
            mu = SymbolicParameters(self, V, (1., ))
            self.f = (1-x[0])*cos(3*pi*mu[0]*(1+x[0]))*exp(-mu[0]*(1+x[0]))
            # Inner product
            f = TrialFunction(self.V)
            g = TestFunction(self.V)
            self.inner_product = assemble(f*g*dx)
            
        def name(self):
            return "MockProblem_12_" + expression_type + "_" + basis_generation
            
        def init(self):
            pass
            
        def solve(self):
            print("solving mock problem at mu =", self.mu)
            assert not hasattr(self, "_is_solving")
            self._is_solving = True
            project(self.f, self.V, function=self._solution)
            delattr(self, "_is_solving")
            return self._solution
            
    class ParametrizedFunctionApproximation(EIMApproximation):
        def __init__(self, truth_problem, expression_type, basis_generation, function):
            self.V = truth_problem.V
            #
            folder_prefix = os.path.join("test_eim_approximation_12_tempdir", expression_type, basis_generation)
            assert expression_type in ("Function", "Vector", "Matrix")
            if expression_type == "Function":
                # Call Parent constructor
                EIMApproximation.__init__(self, truth_problem, ParametrizedExpressionFactory(truth_problem._solution), folder_prefix, basis_generation)
            elif expression_type == "Vector":
                v = TestFunction(self.V)
                form = truth_problem._solution*v*dx
                # Call Parent constructor
                EIMApproximation.__init__(self, truth_problem, ParametrizedTensorFactory(form), folder_prefix, basis_generation)
            elif expression_type == "Matrix":
                u = TrialFunction(self.V)
                v = TestFunction(self.V)
                form = truth_problem._solution*u*v*dx
                # Call Parent constructor
                EIMApproximation.__init__(self, truth_problem, ParametrizedTensorFactory(form), folder_prefix, basis_generation)
            else: # impossible to arrive here anyway thanks to the assert
                raise AssertionError("Invalid expression_type")

    # 1. Create the mesh for this test
    mesh = IntervalMesh(100, -1., 1.)

    # 2. Create Finite Element space (Lagrange P1)
    V = FunctionSpace(mesh, "Lagrange", 1)

    # 3. Create a parametrized problem
    problem = MockProblem(V)
    mu_range = [(1., pi), ]
    problem.set_mu_range(mu_range)

    # 4. Postpone generation of the reduced problem

    # 5. Allocate an object of the ParametrizedFunctionApproximation class
    parametrized_function_approximation = ParametrizedFunctionApproximation(problem, expression_type, basis_generation, lambda u: exp(u))
    parametrized_function_approximation.set_mu_range(mu_range)

    # 6. Prepare reduction with EIM
    parametrized_function_reduction_method = EIMApproximationReductionMethod(parametrized_function_approximation)
    parametrized_function_reduction_method.set_Nmax(12)
    parametrized_function_reduction_method.set_tolerance(0.)

    # 7. Perform EIM offline phase
    parametrized_function_reduction_method.initialize_training_set(51, sampling=EquispacedDistribution())
    reduced_parametrized_function_approximation = parametrized_function_reduction_method.offline()

    # 8. Perform EIM online solve
    online_mu = (1., )
    reduced_parametrized_function_approximation.set_mu(online_mu)
    reduced_parametrized_function_approximation.solve()

    # 9. Perform EIM error analysis
    parametrized_function_reduction_method.initialize_testing_set(100)
    parametrized_function_reduction_method.error_analysis()
Beispiel #11
0
def test_eim_approximation_23(expression_type, basis_generation):
    """
    This test is an extension of test 23, which splits the parameter independent part of the expression into
    an auxiliary (non-parametrized) function. In contrast to tests 11-22, the auxiliary function is not the
    solution of a problem: a corresponding auxiliary problem is created automatically.
    """

    class MockProblem(ParametrizedProblem):
        def __init__(self, V, **kwargs):
            ParametrizedProblem.__init__(self, "")
            self.V = V

        def name(self):
            return "MockProblem_23_" + expression_type + "_" + basis_generation

    class ParametrizedFunctionApproximation(EIMApproximation):
        def __init__(self, V, expression_type, basis_generation):
            self.V = V
            # Parametrized function to be interpolated
            mock_problem = MockProblem(V)
            f = project(Expression("(1-x[0])", element=V.ufl_element()), V)
            g = ParametrizedExpression(mock_problem, "cos(3*pi*mu[0]*(1+x[0]))*exp(-mu[0]*(1+x[0]))", mu=(1., ),
                                       element=V.ufl_element())
            #
            folder_prefix = os.path.join("test_eim_approximation_23_tempdir", expression_type, basis_generation)
            assert expression_type in ("Function", "Vector", "Matrix")
            if expression_type == "Function":
                # Call Parent constructor
                EIMApproximation.__init__(
                    self, mock_problem, ParametrizedExpressionFactory(f * g), folder_prefix, basis_generation)
            elif expression_type == "Vector":
                v = TestFunction(V)
                form = f * g * v * dx
                # Call Parent constructor
                EIMApproximation.__init__(
                    self, mock_problem, ParametrizedTensorFactory(form), folder_prefix, basis_generation)
            elif expression_type == "Matrix":
                u = TrialFunction(V)
                v = TestFunction(V)
                form = f * g * u * v * dx
                # Call Parent constructor
                EIMApproximation.__init__(
                    self, mock_problem, ParametrizedTensorFactory(form), folder_prefix, basis_generation)
            else:  # impossible to arrive here anyway thanks to the assert
                raise AssertionError("Invalid expression_type")

    # 1. Create the mesh for this test
    mesh = IntervalMesh(100, -1., 1.)

    # 2. Create Finite Element space (Lagrange P1)
    V = FunctionSpace(mesh, "Lagrange", 1)

    # 3. Allocate an object of the ParametrizedFunctionApproximation class
    parametrized_function_approximation = ParametrizedFunctionApproximation(V, expression_type, basis_generation)
    mu_range = [(1., pi), ]
    parametrized_function_approximation.set_mu_range(mu_range)

    # 4. Prepare reduction with EIM
    parametrized_function_reduction_method = EIMApproximationReductionMethod(parametrized_function_approximation)
    parametrized_function_reduction_method.set_Nmax(30)
    parametrized_function_reduction_method.set_tolerance(0.)

    # 5. Perform the offline phase
    parametrized_function_reduction_method.initialize_training_set(51, sampling=EquispacedDistribution())
    reduced_parametrized_function_approximation = parametrized_function_reduction_method.offline()

    # 6. Perform an online solve
    online_mu = (1., )
    reduced_parametrized_function_approximation.set_mu(online_mu)
    reduced_parametrized_function_approximation.solve()

    # 7. Perform an error analysis
    parametrized_function_reduction_method.initialize_testing_set(100)
    parametrized_function_reduction_method.error_analysis()
Beispiel #12
0
def _test_linear_solver_sparse(callback_type):
    from dolfin import Function
    from rbnics.backends.dolfin import LinearSolver

    # Create mesh and define function space
    mesh = IntervalMesh(132, 0, 2 * pi)
    V = FunctionSpace(mesh, "Lagrange", 1)

    # Define Dirichlet boundary (x = 0 or x = 2 * pi)
    def boundary(x):
        return x[0] < 0 + DOLFIN_EPS or x[0] > 2 * pi - 10 * DOLFIN_EPS

    # Define exact solution
    exact_solution_expression = Expression("x[0] + sin(2 * x[0])", element=V.ufl_element())
    exact_solution = project(exact_solution_expression, V)

    # Define variational problem
    u = TrialFunction(V)
    v = TestFunction(V)
    g = Expression("4 * sin(2 * x[0])", element=V.ufl_element())
    a = inner(grad(u), grad(v)) * dx
    f = g * v * dx
    x = inner(u, v) * dx

    # Assemble inner product matrix
    X = assemble(x)

    # Define boundary condition
    bc = [DirichletBC(V, exact_solution_expression, boundary)]

    # Define callback function depending on callback type
    assert callback_type in ("form callbacks", "tensor callbacks")
    if callback_type == "form callbacks":
        def callback(arg):
            return arg
    elif callback_type == "tensor callbacks":
        def callback(arg):
            return assemble(arg)

    # Define problem wrapper
    class ProblemWrapper(LinearProblemWrapper):
        # Vector function
        def vector_eval(self):
            return callback(f)

        # Matrix function
        def matrix_eval(self):
            return callback(a)

        # Define boundary condition
        def bc_eval(self):
            return bc

        # Define custom monitor to plot the solution
        def monitor(self, solution):
            if matplotlib.get_backend() != "agg":
                plot(solution, title="u")
                plt.show(block=False)
                plt.pause(1)
            else:
                print("||u|| = " + str(solution.vector().norm("l2")))

    # Solve the linear problem
    problem_wrapper = ProblemWrapper()
    solution = Function(V)
    solver = LinearSolver(problem_wrapper, solution)
    solver.solve()

    # Compute the error
    error = Function(V)
    error.vector().add_local(+ solution.vector().get_local())
    error.vector().add_local(- exact_solution.vector().get_local())
    error.vector().apply("")
    error_norm = error.vector().inner(X * error.vector())
    print("Sparse error (" + callback_type + "):", error_norm)
    assert isclose(error_norm, 0., atol=1.e-5)
    return (error_norm, V, a, f, X, exact_solution)
Beispiel #13
0
def _test_nonlinear_solver_sparse(callback_type):
    # Create mesh and define function space
    mesh = IntervalMesh(132, 0, 2*pi)
    V = FunctionSpace(mesh, "Lagrange", 1)

    # Define Dirichlet boundary (x = 0 or x = 2*pi)
    def boundary(x):
        return x[0] < 0 + DOLFIN_EPS or x[0] > 2*pi - 10*DOLFIN_EPS
        
    # Define exact solution
    exact_solution_expression = Expression("x[0] + sin(2*x[0])", element=V.ufl_element())
    exact_solution = project(exact_solution_expression, V)

    # Define variational problem
    du = TrialFunction(V)
    v = TestFunction(V)
    u = Function(V)
    g = Expression("4*sin(2*x[0])*(pow(x[0]+sin(2*x[0]), 2)+1)-2*(x[0]+sin(2*x[0]))*pow(2*cos(2*x[0])+1, 2)", element=V.ufl_element())
    r = inner((1+u**2)*grad(u), grad(v))*dx - g*v*dx
    j = derivative(r, u, du)
    x = inner(du, v)*dx

    # Assemble inner product matrix
    X = assemble(x)
    
    # Define initial guess
    def sparse_initial_guess():
        initial_guess_expression = Expression("0.1 + 0.9*x[0]", element=V.ufl_element())
        return project(initial_guess_expression, V)

    # Define boundary condition
    bc = [DirichletBC(V, exact_solution_expression, boundary)]
    
    # Define callback function depending on callback type
    assert callback_type in ("form callbacks", "tensor callbacks")
    if callback_type == "form callbacks":
        def callback(arg):
            return arg
    elif callback_type == "tensor callbacks":
        def callback(arg):
            return assemble(arg)
    
    # Define problem wrapper
    class SparseFormProblemWrapper(NonlinearProblemWrapper):
        # Residual function
        def residual_eval(self, solution):
            return callback(r)
            
        # Jacobian function
        def jacobian_eval(self, solution):
            return callback(j)
            
        # Define boundary condition
        def bc_eval(self):
            return bc
        
    # Solve the nonlinear problem
    sparse_problem_wrapper = SparseFormProblemWrapper()
    sparse_solution = u
    assign(sparse_solution, sparse_initial_guess())
    sparse_solver = SparseNonlinearSolver(sparse_problem_wrapper, sparse_solution)
    sparse_solver.set_parameters({
        "linear_solver": "mumps",
        "maximum_iterations": 20,
        "report": True
    })
    sparse_solver.solve()

    # Compute the error
    sparse_error = Function(V)
    sparse_error.vector().add_local(+ sparse_solution.vector().get_local())
    sparse_error.vector().add_local(- exact_solution.vector().get_local())
    sparse_error.vector().apply("")
    sparse_error_norm = sparse_error.vector().inner(X*sparse_error.vector())
    print("SparseNonlinearSolver error (" + callback_type + "):", sparse_error_norm)
    assert isclose(sparse_error_norm, 0., atol=1.e-5)
    return (sparse_error_norm, V, u, r, j, X, sparse_initial_guess, exact_solution)
 def initMesh(self, n):
     self.mesh = IntervalMesh(n, 0., 10.)
    writer.writeheader()

for step in range(steps):
    exec_time = time()
    if model == 'AsianCall':
        # Set discretization level
        fac = 2**step
        nt = 40 * fac
        nx = 20 * fac
        ny = 20 * fac
        T = [0.0, .25]
        Xmax = 200
        Ymax = 200

        # Mesh for stochastic part
        mx = IntervalMesh(nx, 0, Xmax)
        C = 100
        mx = refineMesh(mx, C - 10, C + 10)
        mx = refineMesh(mx, C - 25, C + 25)
        mx = refineMesh(mx, C - 50, C + 50)

        # Mesh for deterministic part
        my = IntervalMesh(ny, 0, Ymax)
        my = refineMesh(my, C - 10, C + 10)
        my = refineMesh(my, C - 25, C + 25)
        my = refineMesh(my, C - 50, C + 50)

        x = SpatialCoordinate(mx)[0]
        y = SpatialCoordinate(my)[0]

        # Set up variables for t and y
def test_eim_approximation_13(expression_type, basis_generation):
    """
    The aim of this script is to test EIM/DEIM for nonlinear problems on mixed function spaces.
    This test is an extension of test 11. The main difference with respect to test 11 is that a only a component
    of the reduced order solution is required to define the parametrized expression/tensor.
    * EIM: the expression to be interpolated is a component of the solution of the nonlinear reduced problem.
      This results in a parametrized expression of type ListTensor.
    * DEIM: the form to be interpolated contains a component of the solution of the nonlinear reduced problem,
      split between x and y. This results in two coefficients in the integrand (denoted by f0[0] and f1[0] below)
      which are of type Indexed.
    """
    @StoreMapFromProblemNameToProblem
    @StoreMapFromProblemToTrainingStatus
    @StoreMapFromSolutionToProblem
    class MockProblem(ParametrizedProblem):
        def __init__(self, V, **kwargs):
            # Call parent
            ParametrizedProblem.__init__(
                self,
                os.path.join("test_eim_approximation_13_tempdir",
                             expression_type, basis_generation,
                             "mock_problem"))
            # Minimal subset of a ParametrizedDifferentialProblem
            self.V = V
            self._solution = Function(V)
            self.components = ["u", "s", "p"]
            # Parametrized function to be interpolated
            x = SpatialCoordinate(V.mesh())
            mu = SymbolicParameters(self, V, (1., ))
            self.f00 = (1 - x[0]) * cos(3 * pi * mu[0] *
                                        (1 + x[0])) * exp(-mu[0] * (1 + x[0]))
            self.f01 = (1 - x[0]) * sin(3 * pi * mu[0] *
                                        (1 + x[0])) * exp(-mu[0] * (1 + x[0]))
            # Inner product
            f = TrialFunction(self.V)
            g = TestFunction(self.V)
            self.inner_product = assemble(inner(f, g) * dx)
            # Collapsed vector and space
            self.V0 = V.sub(0).collapse()
            self.V00 = V.sub(0).sub(0).collapse()
            self.V1 = V.sub(1).collapse()

        def name(self):
            return "MockProblem_13_" + expression_type + "_" + basis_generation

        def init(self):
            pass

        def solve(self):
            assert not hasattr(self, "_is_solving")
            self._is_solving = True
            f00 = project(self.f00, self.V00)
            f01 = project(self.f01, self.V00)
            assign(self._solution.sub(0).sub(0), f00)
            assign(self._solution.sub(0).sub(1), f01)
            delattr(self, "_is_solving")
            return self._solution

    @UpdateMapFromProblemToTrainingStatus
    class MockReductionMethod(ReductionMethod):
        def __init__(self, truth_problem, **kwargs):
            # Call parent
            ReductionMethod.__init__(
                self,
                os.path.join("test_eim_approximation_13_tempdir",
                             expression_type, basis_generation,
                             "mock_problem"))
            # Minimal subset of a DifferentialProblemReductionMethod
            self.truth_problem = truth_problem
            self.reduced_problem = None
            # I/O
            self.folder["basis"] = os.path.join(
                self.truth_problem.folder_prefix, "basis")
            # Gram Schmidt
            self.GS = GramSchmidt(self.truth_problem.inner_product)

        def initialize_training_set(self,
                                    ntrain,
                                    enable_import=True,
                                    sampling=None,
                                    **kwargs):
            return ReductionMethod.initialize_training_set(
                self, self.truth_problem.mu_range, ntrain, enable_import,
                sampling, **kwargs)

        def initialize_testing_set(self,
                                   ntest,
                                   enable_import=False,
                                   sampling=None,
                                   **kwargs):
            return ReductionMethod.initialize_testing_set(
                self, self.truth_problem.mu_range, ntest, enable_import,
                sampling, **kwargs)

        def offline(self):
            self.reduced_problem = MockReducedProblem(self.truth_problem)
            if self.folder["basis"].create(
            ):  # basis folder was not available yet
                for (index, mu) in enumerate(self.training_set):
                    self.truth_problem.set_mu(mu)
                    print("solving mock problem at mu =",
                          self.truth_problem.mu)
                    f = self.truth_problem.solve()
                    component = "u" if index % 2 == 0 else "s"
                    self.reduced_problem.basis_functions.enrich(f, component)
                    self.GS.apply(
                        self.reduced_problem.basis_functions[component], 0)
                self.reduced_problem.basis_functions.save(
                    self.folder["basis"], "basis")
            else:
                self.reduced_problem.basis_functions.load(
                    self.folder["basis"], "basis")
            self._finalize_offline()
            return self.reduced_problem

        def error_analysis(self, N=None, **kwargs):
            pass

        def speedup_analysis(self, N=None, **kwargs):
            pass

    @StoreMapFromProblemToReducedProblem
    class MockReducedProblem(ParametrizedProblem):
        @sync_setters("truth_problem", "set_mu", "mu")
        @sync_setters("truth_problem", "set_mu_range", "mu_range")
        def __init__(self, truth_problem, **kwargs):
            # Call parent
            ParametrizedProblem.__init__(
                self,
                os.path.join("test_eim_approximation_13_tempdir",
                             expression_type, basis_generation,
                             "mock_problem"))
            # Minimal subset of a ParametrizedReducedDifferentialProblem
            self.truth_problem = truth_problem
            self.basis_functions = BasisFunctionsMatrix(self.truth_problem.V)
            self.basis_functions.init(self.truth_problem.components)
            self._solution = None

        def solve(self):
            print("solving mock reduced problem at mu =", self.mu)
            assert not hasattr(self, "_is_solving")
            self._is_solving = True
            f = self.truth_problem.solve()
            f_N = transpose(
                self.basis_functions) * self.truth_problem.inner_product * f
            # Return the reduced solution
            self._solution = OnlineFunction(f_N)
            delattr(self, "_is_solving")
            return self._solution

    class ParametrizedFunctionApproximation(EIMApproximation):
        def __init__(self, truth_problem, expression_type, basis_generation):
            self.V = truth_problem.V1
            (f0, _) = split(truth_problem._solution)
            #
            folder_prefix = os.path.join("test_eim_approximation_13_tempdir",
                                         expression_type, basis_generation)
            assert expression_type in ("Function", "Vector", "Matrix")
            if expression_type == "Function":
                # Call Parent constructor
                EIMApproximation.__init__(self, truth_problem,
                                          ParametrizedExpressionFactory(f0),
                                          folder_prefix, basis_generation)
            elif expression_type == "Vector":
                v = TestFunction(self.V)
                form = f0[0] * v * dx + f0[1] * v.dx(0) * dx
                # Call Parent constructor
                EIMApproximation.__init__(self, truth_problem,
                                          ParametrizedTensorFactory(form),
                                          folder_prefix, basis_generation)
            elif expression_type == "Matrix":
                u = TrialFunction(self.V)
                v = TestFunction(self.V)
                form = f0[0] * u * v * dx + f0[1] * u.dx(0) * v * dx
                # Call Parent constructor
                EIMApproximation.__init__(self, truth_problem,
                                          ParametrizedTensorFactory(form),
                                          folder_prefix, basis_generation)
            else:  # impossible to arrive here anyway thanks to the assert
                raise AssertionError("Invalid expression_type")

    # 1. Create the mesh for this test
    mesh = IntervalMesh(100, -1., 1.)

    # 2. Create Finite Element space (Lagrange P1)
    element_0 = VectorElement("Lagrange", mesh.ufl_cell(), 2, dim=2)
    element_1 = FiniteElement("Lagrange", mesh.ufl_cell(), 1)
    element = MixedElement(element_0, element_1)
    V = FunctionSpace(mesh, element, components=[["u", "s"], "p"])

    # 3. Create a parametrized problem
    problem = MockProblem(V)
    mu_range = [
        (1., pi),
    ]
    problem.set_mu_range(mu_range)

    # 4. Create a reduction method and run the offline phase to generate the corresponding
    #    reduced problem
    reduction_method = MockReductionMethod(problem)
    reduction_method.initialize_training_set(12,
                                             sampling=EquispacedDistribution())
    reduction_method.offline()

    # 5. Allocate an object of the ParametrizedFunctionApproximation class
    parametrized_function_approximation = ParametrizedFunctionApproximation(
        problem, expression_type, basis_generation)
    parametrized_function_approximation.set_mu_range(mu_range)

    # 6. Prepare reduction with EIM
    parametrized_function_reduction_method = EIMApproximationReductionMethod(
        parametrized_function_approximation)
    parametrized_function_reduction_method.set_Nmax(12)
    parametrized_function_reduction_method.set_tolerance(0.)

    # 7. Perform EIM offline phase
    parametrized_function_reduction_method.initialize_training_set(
        51, sampling=EquispacedDistribution())
    reduced_parametrized_function_approximation = parametrized_function_reduction_method.offline(
    )

    # 8. Perform EIM online solve
    online_mu = (1., )
    reduced_parametrized_function_approximation.set_mu(online_mu)
    reduced_parametrized_function_approximation.solve()

    # 9. Perform EIM error analysis
    parametrized_function_reduction_method.initialize_testing_set(100)
    parametrized_function_reduction_method.error_analysis()
Beispiel #17
0
def fit1d(x0, y0, a, b, n, lmbda, solver="dense-direct", degree=1):
    mesh = IntervalMesh(n, a, b)
    V = FunctionSpace(mesh, "CG", degree)
    return fit(x0[:, numpy.newaxis], y0, V, lmbda, solver=solver)
def test_eim_approximation_01(expression_type, basis_generation):
    """
    This is the first basic test for EIM/DEIM, based on the test case of section 3.3.1 of
        S. Chaturantabut and D. C. Sorensen
        Nonlinear Model Reduction via Discrete Empirical Interpolation
        SIAM Journal on Scientific Computing 2010 32:5, 2737-2764
    * EIM: test interpolation of a scalar function
    * DEIM: test interpolation of form with scalar integrand on a scalar space
    """
    
    class MockProblem(ParametrizedProblem):
        def __init__(self, V, **kwargs):
            ParametrizedProblem.__init__(self, "")
            self.V = V
            
        def name(self):
            return "MockProblem_01_" + expression_type + "_" + basis_generation
    
    class ParametrizedFunctionApproximation(EIMApproximation):
        def __init__(self, V, expression_type, basis_generation):
            self.V = V
            # Parametrized function to be interpolated
            mock_problem = MockProblem(V)
            f = ParametrizedExpression(mock_problem, "(1-x[0])*cos(3*pi*mu[0]*(1+x[0]))*exp(-mu[0]*(1+x[0]))", mu=(1., ), element=V.ufl_element())
            #
            folder_prefix = os.path.join("test_eim_approximation_01_tempdir", expression_type, basis_generation)
            assert expression_type in ("Function", "Vector", "Matrix")
            if expression_type == "Function":
                # Call Parent constructor
                EIMApproximation.__init__(self, mock_problem, ParametrizedExpressionFactory(f), folder_prefix, basis_generation)
            elif expression_type == "Vector":
                v = TestFunction(V)
                form = f*v*dx
                # Call Parent constructor
                EIMApproximation.__init__(self, mock_problem, ParametrizedTensorFactory(form), folder_prefix, basis_generation)
            elif expression_type == "Matrix":
                u = TrialFunction(V)
                v = TestFunction(V)
                form = f*u*v*dx
                # Call Parent constructor
                EIMApproximation.__init__(self, mock_problem, ParametrizedTensorFactory(form), folder_prefix, basis_generation)
            else: # impossible to arrive here anyway thanks to the assert
                raise AssertionError("Invalid expression_type")

    # 1. Create the mesh for this test
    mesh = IntervalMesh(100, -1., 1.)

    # 2. Create Finite Element space (Lagrange P1)
    V = FunctionSpace(mesh, "Lagrange", 1)

    # 3. Allocate an object of the ParametrizedFunctionApproximation class
    parametrized_function_approximation = ParametrizedFunctionApproximation(V, expression_type, basis_generation)
    mu_range = [(1., pi), ]
    parametrized_function_approximation.set_mu_range(mu_range)

    # 4. Prepare reduction with EIM
    parametrized_function_reduction_method = EIMApproximationReductionMethod(parametrized_function_approximation)
    parametrized_function_reduction_method.set_Nmax(30)
    parametrized_function_reduction_method.set_tolerance(0.)

    # 5. Perform the offline phase
    parametrized_function_reduction_method.initialize_training_set(51, sampling=EquispacedDistribution())
    reduced_parametrized_function_approximation = parametrized_function_reduction_method.offline()

    # 6. Perform an online solve
    online_mu = (1., )
    reduced_parametrized_function_approximation.set_mu(online_mu)
    reduced_parametrized_function_approximation.solve()

    # 7. Perform an error analysis
    parametrized_function_reduction_method.initialize_testing_set(100)
    parametrized_function_reduction_method.error_analysis()
Beispiel #19
0
def _test_nonlinear_solver_sparse(callback_type):
    from dolfin import Function
    from rbnics.backends.dolfin import NonlinearSolver

    # Create mesh and define function space
    mesh = IntervalMesh(132, 0, 2 * pi)
    V = FunctionSpace(mesh, "Lagrange", 1)

    # Define Dirichlet boundary (x = 0 or x = 2 * pi)
    def boundary(x):
        return x[0] < 0 + DOLFIN_EPS or x[0] > 2 * pi - 10 * DOLFIN_EPS

    # Define exact solution
    exact_solution_expression = Expression("x[0] + sin(2*x[0])",
                                           element=V.ufl_element())
    exact_solution = project(exact_solution_expression, V)

    # Define variational problem
    du = TrialFunction(V)
    v = TestFunction(V)
    u = Function(V)
    g = Expression(
        "4 * sin(2 * x[0]) * (pow(x[0] + sin(2 * x[0]), 2) + 1)" +
        " - 2 * (x[0] + sin(2 * x[0])) * pow(2 * cos(2 * x[0]) + 1," + " 2)",
        element=V.ufl_element())
    r = inner((1 + u**2) * grad(u), grad(v)) * dx - g * v * dx
    j = derivative(r, u, du)
    x = inner(du, v) * dx

    # Assemble inner product matrix
    X = assemble(x)

    # Define initial guess
    def initial_guess():
        initial_guess_expression = Expression("0.1 + 0.9 * x[0]",
                                              element=V.ufl_element())
        return project(initial_guess_expression, V)

    # Define boundary condition
    bc = [DirichletBC(V, exact_solution_expression, boundary)]

    # Define callback function depending on callback type
    assert callback_type in ("form callbacks", "tensor callbacks")
    if callback_type == "form callbacks":

        def callback(arg):
            return arg
    elif callback_type == "tensor callbacks":

        def callback(arg):
            return assemble(arg)

    # Define problem wrapper
    class ProblemWrapper(NonlinearProblemWrapper):
        # Residual function
        def residual_eval(self, solution):
            return callback(r)

        # Jacobian function
        def jacobian_eval(self, solution):
            return callback(j)

        # Define boundary condition
        def bc_eval(self):
            return bc

        # Define custom monitor to plot the solution
        def monitor(self, solution):
            if matplotlib.get_backend() != "agg":
                plot(solution, title="u")
                plt.show(block=False)
                plt.pause(1)
            else:
                print("||u|| = " + str(solution.vector().norm("l2")))

    # Solve the nonlinear problem
    problem_wrapper = ProblemWrapper()
    solution = u
    assign(solution, initial_guess())
    solver = NonlinearSolver(problem_wrapper, solution)
    solver.set_parameters({
        "linear_solver": "mumps",
        "maximum_iterations": 20,
        "report": True
    })
    solver.solve()

    # Compute the error
    error = Function(V)
    error.vector().add_local(+solution.vector().get_local())
    error.vector().add_local(-exact_solution.vector().get_local())
    error.vector().apply("")
    error_norm = error.vector().inner(X * error.vector())
    print("Sparse error (" + callback_type + "):", error_norm)
    assert isclose(error_norm, 0., atol=1.e-5)
    return (error_norm, V, u, r, j, X, initial_guess, exact_solution)
Beispiel #20
0
def test_eim_approximation_10(expression_type, basis_generation):
    """
    This test is an extension of test 01.
    The aim of this script is to test the detection of time dependent parametrized expression.
    * EIM: test the case when the expression to be interpolated is time dependent.
    * DEIM: test interpolation of form with a time dependent integrand function.
    """
    class MockTimeDependentProblem(ParametrizedProblem):
        def __init__(self, V, **kwargs):
            ParametrizedProblem.__init__(self, "")
            self.V = V

            # Minimal subset of a time dependent ParametrizedDifferentialProblem
            self.t0 = 0.
            self.t = 0.
            self.dt = 0.
            self.T = 0.

        def name(self):
            return "MockTimeDependentProblem_10_" + expression_type + "_" + basis_generation

        def set_initial_time(self, t0):
            self.t0 = t0

        def set_time(self, t):
            self.t = t

        def set_time_step_size(self, dt):
            self.dt = dt

        def set_final_time(self, T):
            self.T = T

    class ParametrizedFunctionApproximation(TimeDependentEIMApproximation):
        def __init__(self, V, expression_type, basis_generation):
            self.V = V
            # Parametrized function to be interpolated
            mock_time_dependent_problem = MockTimeDependentProblem(V)
            f = ParametrizedExpression(
                mock_time_dependent_problem,
                "(1-x[0])*cos(3*pi*(1+t)*(1+x[0]))*exp(-(1+t)*(1+x[0]))",
                mu=(),
                t=0.,
                element=V.ufl_element())
            #
            folder_prefix = os.path.join("test_eim_approximation_10_tempdir",
                                         expression_type, basis_generation)
            assert expression_type in ("Function", "Vector", "Matrix")
            if expression_type == "Function":
                # Call Parent constructor
                TimeDependentEIMApproximation.__init__(
                    self, mock_time_dependent_problem,
                    ParametrizedExpressionFactory(f), folder_prefix,
                    basis_generation)
            elif expression_type == "Vector":
                v = TestFunction(V)
                form = f * v * dx
                # Call Parent constructor
                TimeDependentEIMApproximation.__init__(
                    self, mock_time_dependent_problem,
                    ParametrizedTensorFactory(form), folder_prefix,
                    basis_generation)
            elif expression_type == "Matrix":
                u = TrialFunction(V)
                v = TestFunction(V)
                form = f * u * v * dx
                # Call Parent constructor
                TimeDependentEIMApproximation.__init__(
                    self, mock_time_dependent_problem,
                    ParametrizedTensorFactory(form), folder_prefix,
                    basis_generation)
            else:  # impossible to arrive here anyway thanks to the assert
                raise AssertionError("Invalid expression_type")

    # 1. Create the mesh for this test
    mesh = IntervalMesh(100, -1., 1.)

    # 2. Create Finite Element space (Lagrange P1)
    V = FunctionSpace(mesh, "Lagrange", 1)

    # 3. Allocate an object of the ParametrizedFunctionApproximation class
    parametrized_function_approximation = ParametrizedFunctionApproximation(
        V, expression_type, basis_generation)
    mu_range = []
    parametrized_function_approximation.set_mu_range(mu_range)
    parametrized_function_approximation.set_time_step_size(1.e-10)
    parametrized_function_approximation.set_final_time(pi - 1)

    # 4. Prepare reduction with EIM
    parametrized_function_reduction_method = TimeDependentEIMApproximationReductionMethod(
        parametrized_function_approximation)
    parametrized_function_reduction_method.set_Nmax(30)
    parametrized_function_reduction_method.set_tolerance(0.)

    # 5. Perform the offline phase
    parametrized_function_reduction_method.initialize_training_set(
        51, time_sampling=EquispacedDistribution())
    reduced_parametrized_function_approximation = parametrized_function_reduction_method.offline(
    )

    # 6. Perform an online solve
    online_mu = ()
    online_t = 0.
    reduced_parametrized_function_approximation.set_mu(online_mu)
    reduced_parametrized_function_approximation.set_time(online_t)
    reduced_parametrized_function_approximation.solve()

    # 7. Perform an error analysis
    parametrized_function_reduction_method.initialize_testing_set(100)
    parametrized_function_reduction_method.error_analysis()
def test_eim_approximation_11(expression_type, basis_generation):
    """
    The aim of this script is to test EIM/DEIM for nonlinear problems. A parametrized problem is defined
    and reduced by means of a reduction method. Then:
    * EIM: the expression to be interpolated is the solution of the nonlinear reduced problem.
    * DEIM: the form to be interpolated contains the solution of the nonlinear reduced problem.
    """
    @StoreMapFromProblemNameToProblem
    @StoreMapFromProblemToTrainingStatus
    @StoreMapFromSolutionToProblem
    class MockProblem(ParametrizedProblem):
        def __init__(self, V, **kwargs):
            # Call parent
            ParametrizedProblem.__init__(
                self,
                os.path.join("test_eim_approximation_11_tempdir",
                             expression_type, basis_generation,
                             "mock_problem"))
            # Minimal subset of a ParametrizedDifferentialProblem
            self.V = V
            self._solution = Function(V)
            self.components = ["u"]
            # Parametrized function to be interpolated
            x = SpatialCoordinate(V.mesh())
            mu = SymbolicParameters(self, V, (1., ))
            self.f = (1 - x[0]) * cos(3 * pi * mu[0] *
                                      (1 + x[0])) * exp(-mu[0] * (1 + x[0]))
            # Inner product
            f = TrialFunction(self.V)
            g = TestFunction(self.V)
            self.inner_product = assemble(f * g * dx)

        def name(self):
            return "MockProblem_11_" + expression_type + "_" + basis_generation

        def init(self):
            pass

        def solve(self):
            assert not hasattr(self, "_is_solving")
            self._is_solving = True
            project(self.f, self.V, function=self._solution)
            delattr(self, "_is_solving")
            return self._solution

    @StoreMapFromProblemToReductionMethod
    @UpdateMapFromProblemToTrainingStatus
    class MockReductionMethod(ReductionMethod):
        def __init__(self, truth_problem, **kwargs):
            # Call parent
            ReductionMethod.__init__(
                self,
                os.path.join("test_eim_approximation_11_tempdir",
                             expression_type, basis_generation,
                             "mock_problem"))
            # Minimal subset of a DifferentialProblemReductionMethod
            self.truth_problem = truth_problem
            self.reduced_problem = None
            # I/O
            self.folder["basis"] = os.path.join(
                self.truth_problem.folder_prefix, "basis")
            # Gram Schmidt
            self.GS = GramSchmidt(self.truth_problem.inner_product)

        def initialize_training_set(self,
                                    ntrain,
                                    enable_import=True,
                                    sampling=None,
                                    **kwargs):
            return ReductionMethod.initialize_training_set(
                self, self.truth_problem.mu_range, ntrain, enable_import,
                sampling, **kwargs)

        def initialize_testing_set(self,
                                   ntest,
                                   enable_import=False,
                                   sampling=None,
                                   **kwargs):
            return ReductionMethod.initialize_testing_set(
                self, self.truth_problem.mu_range, ntest, enable_import,
                sampling, **kwargs)

        def offline(self):
            self.reduced_problem = MockReducedProblem(self.truth_problem)
            if self.folder["basis"].create(
            ):  # basis folder was not available yet
                for mu in self.training_set:
                    self.truth_problem.set_mu(mu)
                    print("solving mock problem at mu =",
                          self.truth_problem.mu)
                    f = self.truth_problem.solve()
                    self.update_basis_matrix(f)
                self.reduced_problem.basis_functions.save(
                    self.folder["basis"], "basis")
            else:
                self.reduced_problem.basis_functions.load(
                    self.folder["basis"], "basis")
            self._finalize_offline()
            return self.reduced_problem

        def update_basis_matrix(self, snapshot):
            self.reduced_problem.basis_functions.enrich(snapshot)
            self.GS.apply(self.reduced_problem.basis_functions, 0)

        def error_analysis(self, N=None, **kwargs):
            pass

        def speedup_analysis(self, N=None, **kwargs):
            pass

    @StoreMapFromProblemToReducedProblem
    class MockReducedProblem(ParametrizedProblem):
        @sync_setters("truth_problem", "set_mu", "mu")
        @sync_setters("truth_problem", "set_mu_range", "mu_range")
        def __init__(self, truth_problem, **kwargs):
            # Call parent
            ParametrizedProblem.__init__(
                self,
                os.path.join("test_eim_approximation_11_tempdir",
                             expression_type, basis_generation,
                             "mock_problem"))
            # Minimal subset of a ParametrizedReducedDifferentialProblem
            self.truth_problem = truth_problem
            self.basis_functions = BasisFunctionsMatrix(self.truth_problem.V)
            self.basis_functions.init(self.truth_problem.components)
            self._solution = None

        def solve(self):
            print("solving mock reduced problem at mu =", self.mu)
            assert not hasattr(self, "_is_solving")
            self._is_solving = True
            f = self.truth_problem.solve()
            f_N = transpose(
                self.basis_functions) * self.truth_problem.inner_product * f
            # Return the reduced solution
            self._solution = OnlineFunction(f_N)
            delattr(self, "_is_solving")
            return self._solution

    class ParametrizedFunctionApproximation(EIMApproximation):
        def __init__(self, truth_problem, expression_type, basis_generation,
                     function):
            self.V = truth_problem.V
            #
            folder_prefix = os.path.join("test_eim_approximation_11_tempdir",
                                         expression_type, basis_generation)
            assert expression_type in ("Function", "Vector", "Matrix")
            if expression_type == "Function":
                # Call Parent constructor
                EIMApproximation.__init__(
                    self, truth_problem,
                    ParametrizedExpressionFactory(truth_problem._solution),
                    folder_prefix, basis_generation)
            elif expression_type == "Vector":
                v = TestFunction(self.V)
                form = truth_problem._solution * v * dx
                # Call Parent constructor
                EIMApproximation.__init__(self, truth_problem,
                                          ParametrizedTensorFactory(form),
                                          folder_prefix, basis_generation)
            elif expression_type == "Matrix":
                u = TrialFunction(self.V)
                v = TestFunction(self.V)
                form = truth_problem._solution * u * v * dx
                # Call Parent constructor
                EIMApproximation.__init__(self, truth_problem,
                                          ParametrizedTensorFactory(form),
                                          folder_prefix, basis_generation)
            else:  # impossible to arrive here anyway thanks to the assert
                raise AssertionError("Invalid expression_type")

    # 1. Create the mesh for this test
    mesh = IntervalMesh(100, -1., 1.)

    # 2. Create Finite Element space (Lagrange P1)
    V = FunctionSpace(mesh, "Lagrange", 1)

    # 3. Create a parametrized problem
    problem = MockProblem(V)
    mu_range = [
        (1., pi),
    ]
    problem.set_mu_range(mu_range)

    # 4. Create a reduction method and run the offline phase to generate the corresponding
    #    reduced problem
    reduction_method = MockReductionMethod(problem)
    reduction_method.initialize_training_set(12,
                                             sampling=EquispacedDistribution())
    reduction_method.offline()

    # 5. Allocate an object of the ParametrizedFunctionApproximation class
    parametrized_function_approximation = ParametrizedFunctionApproximation(
        problem, expression_type, basis_generation, lambda u: exp(u))
    parametrized_function_approximation.set_mu_range(mu_range)

    # 6. Prepare reduction with EIM
    parametrized_function_reduction_method = EIMApproximationReductionMethod(
        parametrized_function_approximation)
    parametrized_function_reduction_method.set_Nmax(12)
    parametrized_function_reduction_method.set_tolerance(0.)

    # 7. Perform EIM offline phase
    parametrized_function_reduction_method.initialize_training_set(
        51, sampling=EquispacedDistribution())
    reduced_parametrized_function_approximation = parametrized_function_reduction_method.offline(
    )

    # 8. Perform EIM online solve
    online_mu = (1., )
    reduced_parametrized_function_approximation.set_mu(online_mu)
    reduced_parametrized_function_approximation.solve()

    # 9. Perform EIM error analysis
    parametrized_function_reduction_method.initialize_testing_set(100)
    parametrized_function_reduction_method.error_analysis()
def test_eim_approximation_09(expression_type, basis_generation):
    """
    This test is an extension of test 01.
    The aim of this script is to test the detection of parametrized expression defined using SymbolicParameters
    for mu and SpatialCoordinates for x.
    * EIM: test the case when the expression to be interpolated is an Operator (rather than an Expression).
    * DEIM: test interpolation of form with integrand function of type Operator (rather than Expression).
    """
    class MockProblem(ParametrizedProblem):
        def __init__(self, V, **kwargs):
            ParametrizedProblem.__init__(self, "")
            self.V = V

        def name(self):
            return "MockProblem_09_" + expression_type + "_" + basis_generation

    class ParametrizedFunctionApproximation(EIMApproximation):
        def __init__(self, mock_problem, expression_type, basis_generation):
            self.V = mock_problem.V
            # Parametrized function to be interpolated
            mu = SymbolicParameters(mock_problem, self.V, (1., ))
            x = SpatialCoordinate(self.V.mesh())
            f = (1 - x[0]) * cos(3 * pi * mu[0] * (1 + x[0])) * exp(-mu[0] *
                                                                    (1 + x[0]))
            #
            folder_prefix = os.path.join("test_eim_approximation_09_tempdir",
                                         expression_type, basis_generation)
            assert expression_type in ("Function", "Vector", "Matrix")
            if expression_type == "Function":
                # Call Parent constructor
                EIMApproximation.__init__(self, mock_problem,
                                          ParametrizedExpressionFactory(f),
                                          folder_prefix, basis_generation)
            elif expression_type == "Vector":
                v = TestFunction(self.V)
                form = f * v * dx
                # Call Parent constructor
                EIMApproximation.__init__(self, mock_problem,
                                          ParametrizedTensorFactory(form),
                                          folder_prefix, basis_generation)
            elif expression_type == "Matrix":
                u = TrialFunction(self.V)
                v = TestFunction(self.V)
                form = f * u * v * dx
                # Call Parent constructor
                EIMApproximation.__init__(self, mock_problem,
                                          ParametrizedTensorFactory(form),
                                          folder_prefix, basis_generation)
            else:  # impossible to arrive here anyway thanks to the assert
                raise AssertionError("Invalid expression_type")

    # 1. Create the mesh for this test
    mesh = IntervalMesh(100, -1., 1.)

    # 2. Create Finite Element space (Lagrange P1)
    V = FunctionSpace(mesh, "Lagrange", 1)

    # 3. Create a parametrized problem
    mock_problem = MockProblem(V)
    mu_range = [
        (1., pi),
    ]
    mock_problem.set_mu_range(mu_range)

    # 4. Allocate an object of the ParametrizedFunctionApproximation class
    parametrized_function_approximation = ParametrizedFunctionApproximation(
        mock_problem, expression_type, basis_generation)

    # 5. Prepare reduction with EIM
    parametrized_function_reduction_method = EIMApproximationReductionMethod(
        parametrized_function_approximation)
    parametrized_function_reduction_method.set_Nmax(30)
    parametrized_function_reduction_method.set_tolerance(0.)

    # 6. Perform the offline phase
    parametrized_function_reduction_method.initialize_training_set(
        51, sampling=EquispacedDistribution())
    reduced_parametrized_function_approximation = parametrized_function_reduction_method.offline(
    )

    # 7. Perform an online solve
    online_mu = (1., )
    reduced_parametrized_function_approximation.set_mu(online_mu)
    reduced_parametrized_function_approximation.solve()

    # 8. Perform an error analysis
    parametrized_function_reduction_method.initialize_testing_set(100)
    parametrized_function_reduction_method.error_analysis()
Beispiel #23
0
def test_eim_approximation_00(expression_type, basis_generation):
    """
    This test deals with the trivial case of interpolating the zero function/vector/matrix,
    as it is a corner case. Next files will deal with more interesting cases.
    """
    class MockProblem(ParametrizedProblem):
        def __init__(self, V, **kwargs):
            ParametrizedProblem.__init__(self, "")
            self.V = V

        def name(self):
            return "MockProblem_00_" + expression_type + "_" + basis_generation

    class ParametrizedFunctionApproximation(EIMApproximation):
        def __init__(self, V, expression_type, basis_generation):
            self.V = V
            # Parametrized function to be interpolated
            mock_problem = MockProblem(V)
            f = ParametrizedExpression(mock_problem,
                                       "0",
                                       mu=(1., ),
                                       element=V.ufl_element())
            #
            folder_prefix = os.path.join("test_eim_approximation_00_tempdir",
                                         expression_type, basis_generation)
            assert expression_type in ("Function", "Vector", "Matrix")
            if expression_type == "Function":
                # Call Parent constructor
                EIMApproximation.__init__(self, mock_problem,
                                          ParametrizedExpressionFactory(f),
                                          folder_prefix, basis_generation)
            elif expression_type == "Vector":
                v = TestFunction(V)
                form = f * v * dx
                # Call Parent constructor
                EIMApproximation.__init__(self, mock_problem,
                                          ParametrizedTensorFactory(form),
                                          folder_prefix, basis_generation)
            elif expression_type == "Matrix":
                u = TrialFunction(V)
                v = TestFunction(V)
                form = f * u * v * dx
                # Call Parent constructor
                EIMApproximation.__init__(self, mock_problem,
                                          ParametrizedTensorFactory(form),
                                          folder_prefix, basis_generation)
            else:  # impossible to arrive here anyway thanks to the assert
                raise AssertionError("Invalid expression_type")

    # 1. Create the mesh for this test
    mesh = IntervalMesh(10, 0., 1.)

    # 2. Create Finite Element space (Lagrange P1)
    V = FunctionSpace(mesh, "Lagrange", 1)

    # 3. Allocate an object of the ParametrizedFunctionApproximation class
    parametrized_function_approximation = ParametrizedFunctionApproximation(
        V, expression_type, basis_generation)
    mu_range = [
        (0., 1.),
    ]
    parametrized_function_approximation.set_mu_range(mu_range)

    # 4. Prepare reduction with EIM
    parametrized_function_reduction_method = EIMApproximationReductionMethod(
        parametrized_function_approximation)
    parametrized_function_reduction_method.set_Nmax(1)

    # 5. Perform the offline phase
    parametrized_function_reduction_method.initialize_training_set(
        5, sampling=EquispacedDistribution())
    reduced_parametrized_function_approximation = parametrized_function_reduction_method.offline(
    )
    assert reduced_parametrized_function_approximation.N == 1

    # 6. Perform an online solve
    online_mu = (1., )
    reduced_parametrized_function_approximation.set_mu(online_mu)
    reduced_parametrized_function_approximation.solve()

    # 7. Perform an error analysis
    parametrized_function_reduction_method.initialize_testing_set(5)
    parametrized_function_reduction_method.error_analysis()
Beispiel #24
0
    def model(self, parameters=None, logger=None):
        def format(arr):
            return np.array(arr)

        # Setup parameters, logger
        self.set_parameters(parameters)
        self.set_logger(logger)

        # Get parameters
        parameters = self.get_parameters()

        #SS#if not parameters.get('simulate'):
        #SS#	return

        # Setup data
        self.set_data(reset=True)
        self.set_observables(reset=True)

        # Show simulation settings
        self.get_logger()('\n\t'.join([
            'Simulating:', *[
                '%s : %r' % (param, parameters[param] if not isinstance(
                    parameters[param], dict) else list(parameters[param]))
                for param in
                ['fields', 'num_elem', 'N', 'dt', 'D', 'alpha', 'tol']
            ]
        ]))

        # Data mesh
        mesh = IntervalMesh(MPI.comm_world, parameters['num_elem'],
                            parameters['L_0'], parameters['L_1'])

        # Fields
        V = {}
        W = {}
        fields_n = {}
        fields = {}
        w = {}
        fields_0 = {}
        potential = {}
        potential_derivative = {}
        bcs = {}
        R = {}
        J = {}
        # v2d_vector = {}
        observables = {}
        for field in parameters['fields']:

            # Define functions
            V[field] = {}
            w[field] = {}
            for space in parameters['spaces']:
                V[field][space] = getattr(
                    dolfin, parameters['spaces'][space]['type'])(
                        mesh, parameters['spaces'][space]['family'],
                        parameters['spaces'][space]['degree'])
                w[field][space] = TestFunction(V[field][space])

            space = V[field][parameters['fields'][field]['space']]
            test = w[field][parameters['fields'][field]['space']]

            fields_n[field] = Function(space, name='%sn' % (field))
            fields[field] = Function(space, name=field)

            # Inital condition
            fields_0[field] = Expression(
                parameters['fields'][field]['initial'],
                element=space.ufl_element())
            fields_n[field] = project(fields_0[field], space)
            fields[field].assign(fields_n[field])

            # Define potential
            if parameters['potential'].get('kwargs') is None:
                parameters['potential']['kwargs'] = {}
            for k in parameters['potential']['kwargs']:
                if parameters['potential']['kwargs'][k] is None:
                    parameters['potential']['kwargs'][k] = fields[k]

            potential[field] = Expression(
                parameters['potential']['expression'],
                degree=parameters['potential']['degree'],
                **parameters['potential']['kwargs'])
            potential_derivative[field] = Expression(
                parameters['potential']['derivative'],
                degree=parameters['potential']['degree'] - 1,
                **parameters['potential']['kwargs'])

            #Subdomain for defining Positive grain
            sub_domains = MeshFunction('size_t', mesh,
                                       mesh.topology().dim(), 0)

            #BC condition
            bcs[field] = []
            if parameters['fields'][field]['bcs'] == 'dirichlet':
                BC_l = CompiledSubDomain('near(x[0], side) && on_boundary',
                                         side=parameters['L_0'])
                BC_r = CompiledSubDomain('near(x[0], side) && on_boundary',
                                         side=parameters['L_1'])
                bcl = DirichletBC(V, fields_n[field], BC_l)
                bcr = DirichletBC(V, fields_n[field], BC_r)
                bcs[field].extend([bcl, bcr])
            elif parameters['fields'][field]['bcs'] == 'neumann':
                bcs[field].extend([])

            # Residual and Jacobian
            R[field] = (
                ((fields[field] - fields_n[field]) / parameters['dt'] * test *
                 dx) +
                (inner(parameters['D'] * grad(test), grad(fields[field])) * dx)
                + (parameters['alpha'] * potential_derivative[field] * test *
                   dx))

            J[field] = derivative(R[field], fields[field])

            # Observables
            observables[field] = {}

        files = {
            'xdmf': XDMFFile(MPI.comm_world,
                             self.get_paths()['xdmf']),
            'hdf5': HDF5File(MPI.comm_world,
                             self.get_paths()['hdf5'], 'w'),
        }

        files['hdf5'].write(mesh, '/mesh')
        eps = lambda n, key, field, observables, tol: (
            n == 0) or (abs(observables[key]['total_energy'][n] - observables[
                key]['total_energy'][n - 1]) /
                        (observables[key]['total_energy'][0]) > tol)
        flag = {field: True for field in parameters['fields']}
        tol = {
            field: parameters['tol'][field] if isinstance(
                parameters['tol'], dict) else parameters['tol']
            for field in parameters['fields']
        }
        phases = {'p': 1, 'm': 2}
        n = 0
        problem = {}
        solver = {}
        while (n < parameters['N']
               and any([flag[field] for field in parameters['fields']])):

            self.get_logger()('Time: %d' % (n))

            for field in parameters['fields']:

                if not flag[field]:
                    continue

                # Solve
                problem[field] = NonlinearVariationalProblem(
                    R[field], fields[field], bcs[field], J[field])
                solver[field] = NonlinearVariationalSolver(problem[field])
                solver[field].solve()

                # Get field array
                array = assemble(
                    (1 / CellVolume(mesh)) *
                    inner(fields[field], w[field]['Z']) * dx).get_local()

                # Observables
                observables[field]['Time'] = parameters['dt'] * n

                # observables[field]['energy_density'] = format(0.5*dot(grad(fields[field]),grad(fields[field]))*dx)
                observables[field]['gradient_energy'] = format(
                    assemble(0.5 *
                             dot(grad(fields[field]), grad(fields[field])) *
                             dx(domain=mesh)))
                observables[field]['landau_energy'] = format(
                    assemble(potential[field] * dx(domain=mesh)))
                observables[field]['diffusion_energy'] = format(
                    assemble(
                        project(
                            div(project(grad(fields[field]), V[field]['W'])),
                            V[field]['Z']) * dx(domain=mesh))
                )  #Diffusion part of chemical potential
                observables[field]['spinodal_energy'] = format(
                    assemble(
                        potential_derivative[field] *
                        dx(domain=mesh)))  #Spinodal part of chemical potential

                observables[field]['total_energy'] = parameters[
                    'D'] * observables[field]['gradient_energy'] + parameters[
                        'alpha'] * observables[field]['landau_energy']
                observables[field]['chi'] = parameters['alpha'] * observables[
                    field]['diffusion_energy'] - parameters['D'] * observables[
                        field]['spinodal_energy']

                # Phase observables
                sub_domains.set_all(0)
                sub_domains.array()[:] = np.where(array > 0.0, phases['p'],
                                                  phases['m'])

                phases_dxp = Measure('dx',
                                     domain=mesh,
                                     subdomain_data=sub_domains)
                for phase in phases:
                    dxp = phases_dxp(phases[phase])

                    observables[field]['Phi_0%s' % (phase)] = format(
                        assemble(1 * dxp))
                    observables[field]['Phi_1%s' % (phase)] = format(
                        assemble(fields[field] * dxp))
                    observables[field]['Phi_2%s' % (phase)] = format(
                        assemble(fields[field] * fields[field] * dxp))
                    observables[field]['Phi_3%s' % (phase)] = format(
                        assemble(fields[field] * fields[field] *
                                 fields[field] * dxp))
                    observables[field]['Phi_4%s' % (phase)] = format(
                        assemble(fields[field] * fields[field] *
                                 fields[field] * fields[field] * dxp))
                    observables[field]['Phi_5%s' % (phase)] = format(
                        assemble(fields[field] * fields[field] *
                                 fields[field] * fields[field] *
                                 fields[field] * dxp))

                    observables[field]['gradient_energy_%s' %
                                       (phase)] = format(
                                           assemble(
                                               0.5 *
                                               dot(grad(fields[field]),
                                                   grad(fields[field])) * dxp))
                    observables[field]['landau_energy_%s' % (phase)] = format(
                        assemble(potential[field] * dxp))
                    observables[field][
                        'total_energy_%s' %
                        (phase)] = parameters['D'] * observables[field][
                            'gradient_energy_%s' %
                            (phase)] + parameters['alpha'] * observables[
                                field]['landau_energy_%s' % (phase)]

                    observables[field][
                        'diffusion_energy_%s' % (phase)] = format(
                            assemble(
                                project(
                                    div(
                                        project(grad(fields[field]),
                                                V[field]['W'])), V[field]['Z'])
                                * dxp))  #Diffusion part of chemical potential
                    observables[field][
                        'spinodal_energy_%s' % (phase)] = format(
                            assemble(
                                potential_derivative[field] *
                                dxp))  #Spinodal part of chemical potential

                    observables[field][
                        'chi_%s' %
                        (phase)] = parameters['alpha'] * observables[field][
                            'spinodal_energy_%s' %
                            (phase)] - parameters['D'] * observables[field][
                                'diffusion_energy_%s' % (phase)]

                files['hdf5'].write(fields[field], '/%s' % (field), n)
                files['xdmf'].write(fields[field], n)

                fields_n[field].assign(fields[field])

                self.set_data({field: array})
                self.set_observables({field: observables[field]})

                flag[field] = eps(n, field, fields[field],
                                  self.get_observables(), tol[field])

            n += 1

        for file in files:
            files[file].close()

        return