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
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()
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)
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)
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)
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()
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()
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()
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)
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()
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()
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)
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()
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()
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