def _prepare_solution_fcns(self): # Extract parameters needed to create finite elements N = self.parameters["N"] gdim = self._mesh.geometry().dim() # Group elements for phi, chi, v elements_ch = (N - 1) * [ self._FE["phi"], ] + (N - 1) * [ self._FE["chi"], ] elements_ns = [ VectorElement(self._FE["v"], dim=gdim), ] # Append elements for p and th elements_ns.append(self._FE["p"]) if self._FE["th"] is not None: elements_ns.append(self._FE["th"]) # Build function spaces W_ch = FunctionSpace(self._mesh, MixedElement(elements_ch), constrained_domain=self._constrained_domain) W_ns = FunctionSpace(self._mesh, MixedElement(elements_ns), constrained_domain=self._constrained_domain) self._ndofs["CH"] = W_ch.dim() self._ndofs["NS"] = W_ns.dim() self._ndofs["total"] = W_ch.dim() + W_ns.dim() self._subspace["phi"] = [W_ch.sub(i) for i in range(N - 1)] self._subspace["chi"] = [ W_ch.sub(i) for i in range(N - 1, 2 * (N - 1)) ] self._ndofs["phi"] = W_ch.sub(0).dim() self._ndofs["chi"] = W_ch.sub(N - 1).dim() if gdim == 1: self._subspace["v"] = [ W_ns.sub(0), ] self._ndofs["v"] = W_ns.sub(0).dim() else: self._subspace["v"] = [W_ns.sub(0).sub(i) for i in range(gdim)] self._ndofs["v"] = W_ns.sub(0).sub(0).dim() self._subspace["p"] = W_ns.sub(1) self._ndofs["p"] = W_ns.sub(1).dim() self._ndofs["th"] = 0 if W_ns.num_sub_spaces() == 3: self._subspace["th"] = W_ns.sub(2) self._ndofs["th"] = W_ns.sub(2).dim() # ndofs = ( # (N-1)*(self._ndofs["phi"] + self._ndofs["chi"]) # + gdim*self._ndofs["v"] # + self._ndofs["p"] # + self._ndofs["th"] # ) # assert self._ndofs["total"] == ndofs # Create solution variables at ctl w_ctl = (Function(W_ch), Function(W_ns)) w_ctl[0].rename("semi_ctl_ch", "solution_semi_ch_ctl") w_ctl[1].rename("semi_ctl_ns", "solution_semi_ns_ctl") # Create solution variables at ptl w_ptl = [(Function(W_ch), Function(W_ns)) \ for i in range(self.parameters["PTL"])] for i, f in enumerate(w_ptl): f[0].rename("semi_ptl%i_ch" % i, "solution_semi_ch_ptl%i" % i) f[1].rename("semi_ptl%i_ns" % i, "solution_semi_ns_ptl%i" % i) return (w_ctl, w_ptl)
def _setup_dg2_projection_2D(self, w, incompressibility_flux_type, D12, use_bcs): """ Implement the projection where the result is BDM embeded in a DG2 function """ sim = self.simulation k = 2 gdim = 2 mesh = w[0].function_space().mesh() V = VectorFunctionSpace(mesh, 'DG', k) n = FacetNormal(mesh) # The mixed function space of the projection test functions e1 = FiniteElement('DGT', mesh.ufl_cell(), k) e2 = VectorElement('DG', mesh.ufl_cell(), k - 2) e3 = FiniteElement('Bubble', mesh.ufl_cell(), 3) em = MixedElement([e1, e2, e3]) W = FunctionSpace(mesh, em) v1, v2, v3b = TestFunctions(W) u = TrialFunction(V) # The same fluxes that are used in the incompressibility equation if incompressibility_flux_type == 'central': u_hat_dS = dolfin.avg(w) elif incompressibility_flux_type == 'upwind': w_nU = (dot(w, n) + abs(dot(w, n))) / 2.0 switch = dolfin.conditional(dolfin.gt(w_nU('+'), 0.0), 1.0, 0.0) u_hat_dS = switch * w('+') + (1 - switch) * w('-') if D12 is not None: u_hat_dS += dolfin.Constant([D12, D12]) * dolfin.jump(w, n) # Equation 1 - flux through the sides a = L = 0 for R in '+-': a += dot(u(R), n(R)) * v1(R) * dS L += dot(u_hat_dS, n(R)) * v1(R) * dS # Eq. 1 cont. - flux through external boundaries a += dot(u, n) * v1 * ds if use_bcs: for d in range(gdim): dirichlet_bcs = sim.data['dirichlet_bcs']['u%d' % d] neumann_bcs = sim.data['neumann_bcs'].get('u%d' % d, []) robin_bcs = sim.data['robin_bcs'].get('u%d' % d, []) outlet_bcs = sim.data['outlet_bcs'] for dbc in dirichlet_bcs: u_bc = dbc.func() L += u_bc * n[d] * v1 * dbc.ds() for nbc in neumann_bcs + robin_bcs + outlet_bcs: if nbc.enforce_zero_flux: pass # L += 0 else: L += w[d] * n[d] * v1 * nbc.ds() for sbc in sim.data['slip_bcs'].get('u', []): pass # L += 0 else: L += dot(w, n) * v1 * ds # Equation 2 - internal shape a += dot(u, v2) * dx L += dot(w, v2) * dx # Equation 3 - BDM Phi v3 = as_vector([v3b.dx(1), -v3b.dx(0)]) # Curl of [0, 0, v3b] a += dot(u, v3) * dx L += dot(w, v3) * dx return a, L, V
def _prepare_solution_fcns(self): # Extract parameters needed to create finite elements N = self.parameters["N"] gdim = self._mesh.geometry().dim() # Group elements for phi, chi, v elements_ch = (N - 1) * [ self._FE["phi"], ] + (N - 1) * [ self._FE["chi"], ] # NOTE: Elements for phi and chi are grouped together to avoid special # treatment of the case with N = 2. For example, if N == 2 and # phi would be represented as a vector with a single component # then a special treatment is needed to plot this single # component (UFL/DOLFIN ban to plot 1D function on a 2D mesh). elements = [] elements.append(MixedElement(elements_ch)) elements.append(VectorElement(self._FE["v"], dim=gdim)) # Append elements for p and th elements.append(self._FE["p"]) if self._FE["th"] is not None: elements.append(self._FE["th"]) # Build function spaces W = FunctionSpace(self._mesh, MixedElement(elements), constrained_domain=self._constrained_domain) self._ndofs["total"] = W.dim() self._subspace["phi"] = [W.sub(0).sub(i) for i in range(N - 1)] self._subspace["chi"] = [ W.sub(0).sub(i) for i in range(N - 1, 2 * (N - 1)) ] self._ndofs["phi"] = W.sub(0).sub(0).dim() self._ndofs["chi"] = W.sub(0).sub(N - 1).dim() if gdim == 1: self._subspace["v"] = [ W.sub(1), ] self._ndofs["v"] = W.sub(1).dim() else: self._subspace["v"] = [W.sub(1).sub(i) for i in range(gdim)] self._ndofs["v"] = W.sub(1).sub(0).dim() self._subspace["p"] = W.sub(2) self._ndofs["p"] = W.sub(2).dim() self._ndofs["th"] = 0 if W.num_sub_spaces() == 4: self._subspace["th"] = W.sub(3) self._ndofs["th"] = W.sub(3).dim() self._ndofs["CH"] = W.sub(0).dim() self._ndofs["NS"] = (gdim * self._ndofs["v"] + self._ndofs["p"] + self._ndofs["th"]) assert self._ndofs["total"] == self._ndofs["CH"] + self._ndofs["NS"] # Create solution variable at ctl w_ctl = (Function(W), ) w_ctl[0].rename("mono_ctl", "solution_mono_ctl") # Create solution variables at ptl w_ptl = [(Function(W), ) for i in range(self.parameters["PTL"])] for (i, f) in enumerate(w_ptl): f[0].rename("mono_ptl%i" % i, "solution_mono_ptl%i" % i) return (w_ctl, w_ptl)
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 solve(mesh, W_element, P_element, Q_element, u0, p0, theta0, kappa, rho, mu, cp, g, extra_force, heat_source, u_bcs, p_bcs, theta_dirichlet_bcs, theta_neumann_bcs, dx_submesh, ds_submesh): # First do a fixed_point iteration. This is usually quite robust and leads # to a point from where Newton can converge reliably. u0, p0, theta0 = solve_fixed_point(mesh, W_element, P_element, Q_element, theta0, kappa, rho, mu, cp, g, extra_force, heat_source, u_bcs, p_bcs, theta_dirichlet_bcs, theta_neumann_bcs, my_dx=dx_submesh, my_ds=ds_submesh, max_iter=100, tol=1.0e-8) WPQ = FunctionSpace(mesh, MixedElement([W_element, P_element, Q_element])) uptheta0 = Function(WPQ) # Initial guess assign(uptheta0.sub(0), u0) assign(uptheta0.sub(1), p0) assign(uptheta0.sub(2), theta0) rho_const = rho(_average(theta0)) stokes_heat_problem = StokesHeat(WPQ, kappa, rho, rho_const, mu, cp, g, extra_force, heat_source, u_bcs, p_bcs, theta_dirichlet_bcs=theta_dirichlet_bcs, theta_neumann_bcs=theta_neumann_bcs, my_dx=dx_submesh, my_ds=ds_submesh) # solver = FixedPointSolver() from dolfin import PETScSNESSolver solver = PETScSNESSolver() # http://www.mcs.anl.gov/petsc/petsc-current/docs/manualpages/SNES/SNESType.html solver.parameters['method'] = 'newtonls' # The Jacobian system for Stokes (+heat) are hard to solve. # Use LU for now. solver.parameters['linear_solver'] = 'lu' solver.parameters['maximum_iterations'] = 100 # TODO tighten tolerance. might not always work though... solver.parameters['absolute_tolerance'] = 1.0e-3 solver.parameters['relative_tolerance'] = 0.0 solver.parameters['report'] = True solver.solve(stokes_heat_problem, uptheta0.vector()) # u0, p0, theta0 = split(uptheta0) # Create a *deep* copy of u0, p0, theta0 to be able to deal with them # as actually separate entities vectors. u0, p0, theta0 = uptheta0.split(deepcopy=True) return u0, p0, theta0
def generate_mixed_linear_form_space(mesh): element_0 = VectorElement("Lagrange", mesh.ufl_cell(), 2) element_1 = FiniteElement("Lagrange", mesh.ufl_cell(), 1) element = MixedElement(element_0, element_1) return (FunctionSpace(mesh, element), )
def StokesElement(family, cell, degree): V_element = VectorElement(family, cell, degree + 1) Q_element = FiniteElement(family, cell, degree) return MixedElement(V_element, Q_element)
def run_with_params(Tb, mu_value, k_s, path): run_time_init = clock() mesh = BoxMesh(Point(0.0, 0.0, 0.0), Point(mesh_width, mesh_width, mesh_height), nx, ny, nz) pbc = PeriodicBoundary() WE = VectorElement('CG', mesh.ufl_cell(), 2) SE = FiniteElement('CG', mesh.ufl_cell(), 1) WSSS = FunctionSpace(mesh, MixedElement(WE, SE, SE, SE), constrained_domain=pbc) # W = FunctionSpace(mesh, WE, constrained_domain=pbc) # S = FunctionSpace(mesh, SE, constrained_domain=pbc) W = WSSS.sub(0).collapse() S = WSSS.sub(1).collapse() temperature_vals = [27.0 + 273, Tb + 273, 1300.0 + 273, 1305.0 + 273] temp_prof = TemperatureProfile(temperature_vals, element=S.ufl_element()) mu_a = mu_value # this was taken from the Blankenbach paper, can change Ep = b / temp_prof.delta mu_bot = exp(-Ep * (temp_prof.bottom * temp_prof.delta - 1573.0) + cc) * mu_a # TODO: verify exponentiation Ra = rho_0 * alpha * g * temp_prof.delta * h**3 / (kappa_0 * mu_a) w0 = rho_0 * alpha * g * temp_prof.delta * h**2 / mu_a tau = h / w0 p0 = mu_a * w0 / h log(mu_a, mu_bot, Ra, w0, p0) slip_vx = 1.6E-09 / w0 # Non-dimensional slip_velocity = Constant((slip_vx, 0.0, 0.0)) zero_slip = Constant((0.0, 0.0, 0.0)) time_step = 3.0E11 / tau * 2 dt = Constant(time_step) t_end = 3.0E15 / tau / 5.0 # Non-dimensional times u = Function(WSSS) # Instead of TrialFunctions, we use split(u) for our non-linear problem v, p, T, Tf = split(u) v_t, p_t, T_t, Tf_t = TestFunctions(WSSS) T0 = interpolate(temp_prof, S) mu_exp = Expression( 'exp(-Ep * (T_val * dTemp - 1573.0) + cc * x[2] / mesh_height)', Ep=Ep, dTemp=temp_prof.delta, cc=cc, mesh_height=mesh_height, T_val=T0, element=S.ufl_element()) Tf0 = interpolate(temp_prof, S) mu = Function(S) v0 = Function(W) v_theta = (1.0 - theta) * v0 + theta * v T_theta = (1.0 - theta) * T0 + theta * T Tf_theta = (1.0 - theta) * Tf0 + theta * Tf # TODO: Verify forms r_v = (inner(sym(grad(v_t)), 2.0 * mu * sym(grad(v))) - div(v_t) * p - T * v_t[2]) * dx r_p = p_t * div(v) * dx heat_transfer = Constant(k_s) * (Tf_theta - T_theta) * dt r_T = ( T_t * ((T - T0) + dt * inner(v_theta, grad(T_theta))) # TODO: Inner vs dot + (dt / Ra) * inner(grad(T_t), grad(T_theta)) - T_t * heat_transfer) * dx v_melt = Function(W) z_hat = Constant((0.0, 0.0, 1.0)) # TODO: inner -> dot, take out Tf_t r_Tf = (Tf_t * ((Tf - Tf0) + dt * inner(v_melt, grad(Tf_theta))) + Tf_t * heat_transfer) * dx r = r_v + r_p + r_T + r_Tf bcv0 = DirichletBC(WSSS.sub(0), zero_slip, top) bcv1 = DirichletBC(WSSS.sub(0), slip_velocity, bottom) bcv2 = DirichletBC(WSSS.sub(0).sub(1), Constant(0.0), back) bcv3 = DirichletBC(WSSS.sub(0).sub(1), Constant(0.0), front) bcp0 = DirichletBC(WSSS.sub(1), Constant(0.0), bottom) bct0 = DirichletBC(WSSS.sub(2), Constant(temp_prof.surface), top) bct1 = DirichletBC(WSSS.sub(2), Constant(temp_prof.bottom), bottom) bctf1 = DirichletBC(WSSS.sub(3), Constant(temp_prof.bottom), bottom) bcs = [bcv0, bcv1, bcv2, bcv3, bcp0, bct0, bct1, bctf1] t = 0 count = 0 files = DefaultDictByKey(partial(create_xdmf, path)) while t < t_end: mu.interpolate(mu_exp) rhosolid = rho_0 * (1.0 - alpha * (T0 * temp_prof.delta - 1573.0)) deltarho = rhosolid - rho_melt # TODO: project (accuracy) vs interpolate assign( v_melt, project( v0 - darcy * (grad(p) * p0 / h - deltarho * z_hat * g) / w0, W)) # TODO: Written out one step later? # v_melt.assign(v0 - darcy * (grad(p) * p0 / h - deltarho * yvec * g) / w0) # TODO: use nP after to avoid projection? solve(r == 0, u, bcs) nV, nP, nT, nTf = u.split() # TODO: write with Tf, ... etc if count % output_every == 0: time_left(count, t_end / time_step, run_time_init) # TODO: timestep vs dt # TODO: Make sure all writes are to the same function for each time step files['T_fluid'].write(nTf, t) files['p'].write(nP, t) files['v_solid'].write(nV, t) files['T_solid'].write(nT, t) files['mu'].write(mu, t) files['v_melt'].write(v_melt, t) files['gradp'].write(project(grad(nP), W), t) files['rho'].write(project(rhosolid, S), t) files['Tf_grad'].write(project(grad(Tf), W), t) files['advect'].write(project(dt * dot(v_melt, grad(nTf))), t) files['ht'].write(project(heat_transfer, S), t) assign(T0, nT) assign(v0, nV) assign(Tf0, nTf) t += time_step count += 1 log('Case mu={}, Tb={}, k={} complete. Run time = {:.2f} minutes'.format( mu_a, Tb, k_s, (clock() - run_time_init) / 60.0))
ny = 80 mesh = RectangleMesh(Point(- 0.5 * Lx - Lpml, 0.0), Point(0.5 * Lx + Lpml, - Ly - Lpml), nx, ny, "crossed") # Markers for Dirichlet bc ff = MeshFunction("size_t", mesh, mesh.geometry().dim() - 1) Dirichlet().mark(ff, 1) # Markers for disk source mf = MeshFunction("size_t", mesh, mesh.geometry().dim()) circle().mark(mf, 1) # Create function spaces VE = VectorElement("CG", mesh.ufl_cell(), 1, dim=2) TE = TensorElement("DG", mesh.ufl_cell(), 0, shape=(2, 2), symmetry=True) W = FunctionSpace(mesh, MixedElement([VE, TE])) F = FunctionSpace(mesh, "CG", 2) V = W.sub(0).collapse() M = W.sub(1).collapse() # Time stepping Parameters omega_p = 8*DOLFIN_PI dt = 0.0025 t = 0.0 t_end = 1 gamma = 0.50 beta = 0.25 # Circle CI test if "CI" in os.environ.keys():
def test_unsteady_stokes(): nx, ny = 15, 15 k = 1 nu = Constant(1.E-0) dt = Constant(2.5e-2) num_steps = 20 theta0 = 1.0 # Initial theta value theta1 = 0.5 # Theta after 1 step theta = Constant(theta0) mesh = UnitSquareMesh(nx, ny) # The 'unsteady version' of the benchmark in the 2012 paper by Labeur&Wells u_exact = Expression(("sin(t) * x[0]*x[0]*(1.0 - x[0])*(1.0 - x[0])*(2.0*x[1] \ -6.0*x[1]*x[1] + 4.0*x[1]*x[1]*x[1])", "-sin(t)* x[1]*x[1]*(1.0 - x[1])*(1.0 - x[1])*(2.0*x[0] \ - 6.0*x[0]*x[0] + 4.0*x[0]*x[0]*x[0])"), t=0, degree=7, domain=mesh) p_exact = Expression("sin(t) * x[0]*(1.0 - x[0])", t=0, degree=7, domain=mesh) du_exact = Expression(("cos(t) * x[0]*x[0]*(1.0 - x[0])*(1.0 - x[0])*(2.0*x[1] \ - 6.0*x[1]*x[1] + 4.0*x[1]*x[1]*x[1])", "-cos(t)* x[1]*x[1]*(1.0 - x[1])*(1.0 - x[1])*(2.0*x[0] \ -6.0*x[0]*x[0] + 4.0*x[0]*x[0]*x[0])"), t=0, degree=7, domain=mesh) ux_exact = Expression(("x[0]*x[0]*(1.0 - x[0])*(1.0 - x[0])*(2.0*x[1] \ - 6.0*x[1]*x[1] + 4.0*x[1]*x[1]*x[1])", "-x[1]*x[1]*(1.0 - x[1])*(1.0 - x[1])*(2.0*x[0] \ - 6.0*x[0]*x[0] + 4.0*x[0]*x[0]*x[0])"), degree=7, domain=mesh) px_exact = Expression("x[0]*(1.0 - x[0])", degree=7, domain=mesh) sin_ext = Expression("sin(t)", t=0, degree=7, domain=mesh) f = du_exact + sin_ext * div(px_exact*Identity(2) - 2*sym(grad(ux_exact))) Vhigh = VectorFunctionSpace(mesh, "DG", 7) Phigh = FunctionSpace(mesh, "DG", 7) # New syntax: V = VectorElement("DG", mesh.ufl_cell(), k) Q = FiniteElement("DG", mesh.ufl_cell(), k-1) Vbar = VectorElement("DGT", mesh.ufl_cell(), k) Qbar = FiniteElement("DGT", mesh.ufl_cell(), k) mixedL = FunctionSpace(mesh, MixedElement([V, Q])) mixedG = FunctionSpace(mesh, MixedElement([Vbar, Qbar])) V2 = FunctionSpace(mesh, V) Uh = Function(mixedL) Uhbar = Function(mixedG) U0 = Function(mixedL) Uhbar0 = Function(mixedG) u0, p0 = split(U0) ubar0, pbar0 = split(Uhbar0) ustar = Function(V2) # Then the boundary conditions bc0 = DirichletBC(mixedG.sub(0), Constant((0, 0)), Gamma) bc1 = DirichletBC(mixedG.sub(1), Constant(0), Corner, "pointwise") bcs = [bc0, bc1] alpha = Constant(6*k*k) forms_stokes = FormsStokes(mesh, mixedL, mixedG, alpha).forms_unsteady(ustar, dt, nu, f) ssc = StokesStaticCondensation(mesh, forms_stokes['A_S'], forms_stokes['G_S'], forms_stokes['G_ST'], forms_stokes['B_S'], forms_stokes['Q_S'], forms_stokes['S_S']) t = 0. step = 0 for step in range(num_steps): step += 1 t += float(dt) if comm.Get_rank() == 0: print("Step "+str(step)+" Time "+str(t)) # Set time level in exact solution u_exact.t = t p_exact.t = t du_exact.t = t - (1-float(theta))*float(dt) sin_ext.t = t - (1-float(theta))*float(dt) ssc.assemble_global_lhs() ssc.assemble_global_rhs() for bc in bcs: ssc.apply_boundary(bc) ssc.solve_problem(Uhbar, Uh, 'none', 'default') assign(U0, Uh) assign(ustar, U0.sub(0)) assign(Uhbar0, Uhbar) if step == 1: theta.assign(theta1) udiv_e = sqrt(assemble(div(Uh.sub(0)) * div(Uh.sub(0))*dx)) u_ex_h = interpolate(u_exact, Vhigh) p_ex_h = interpolate(p_exact, Phigh) u_error = sqrt(assemble(dot(Uh.sub(0) - u_ex_h, Uh.sub(0) - u_ex_h)*dx)) p_error = sqrt(assemble(dot(Uh.sub(1) - p_ex_h, Uh.sub(1) - p_ex_h)*dx)) assert udiv_e < 1e-12 assert u_error < 1.5e-4 assert p_error < 1e-2
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 @StoreMapFromProblemToReductionMethod @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() self.update_basis_matrix((index, 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, index_and_snapshot): (index, snapshot) = index_and_snapshot component = "u" if index % 2 == 0 else "s" self.reduced_problem.basis_functions.enrich(snapshot, component) self.GS.apply(self.reduced_problem.basis_functions[component], 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_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()
T_E_2 = VectorElement("DG", mesh.ufl_cell(), 0) Wbar_E_2 = VectorElement("DGT", mesh.ufl_cell(), kbar) Wbar_E_2_H12 = VectorElement("CG", mesh.ufl_cell(), kbar)["facet"] Q_E = FiniteElement("DG", mesh.ufl_cell(), k - 1) Qbar_E = FiniteElement("DGT", mesh.ufl_cell(), k) # Function spaces for projection W_2 = FunctionSpace(mesh, W_E_2) T_2 = FunctionSpace(mesh, T_E_2) Wbar_2 = FunctionSpace(mesh, Wbar_E_2, constrained_domain=pbc) Wbar_2_H12 = FunctionSpace(mesh, Wbar_E_2_H12, constrained_domain=pbc) # Function spaces for Stokes mixedL = FunctionSpace(mesh, MixedElement([W_E_2, Q_E]), constrained_domain=pbc) mixedG = FunctionSpace(mesh, MixedElement([Wbar_E_2_H12, Qbar_E]), constrained_domain=pbc) # Define functions u0_a, ustar = Function(W_2), Function(W_2) duh0, duh00 = Function(W_2), Function(W_2) ubar0_a = Function(Wbar_2_H12) ubar_a = Function(Wbar_2) Udiv = Function(W_2) U0, Uh = Function(mixedL), Function(mixedL) Uhbar = Function(mixedG)
def forward(mu_expression, lmbda_expression, rho, Lx=10, Ly=10, t_end=1, omega_p=5, amplitude=5000, center=0, target=False): Lpml = Lx / 10 #c_p = cp(mu.vector(), lmbda.vector(), rho) max_velocity = 200 #c_p.max() stable_hx = stable_dx(max_velocity, omega_p) nx = int(Lx / stable_hx) + 1 #nx = max(nx, 60) ny = int(Ly * nx / Lx) + 1 mesh = mesh_generator(Lx, Ly, Lpml, nx, ny) used_hx = Lx / nx dt = stable_dt(used_hx, max_velocity) cfl_ct = cfl_constant(max_velocity, dt, used_hx) print(used_hx, stable_hx) print(cfl_ct) #time.sleep(10) PE = FunctionSpace(mesh, "DG", 0) mu = interpolate(mu_expression, PE) lmbda = interpolate(lmbda_expression, PE) m = 2 R = 10e-8 t = 0.0 gamma = 0.50 beta = 0.25 ff = MeshFunction("size_t", mesh, mesh.geometry().dim() - 1) Dirichlet(Lx, Ly, Lpml).mark(ff, 1) # Create function spaces VE = VectorElement("CG", mesh.ufl_cell(), 1, dim=2) TE = TensorElement("DG", mesh.ufl_cell(), 0, shape=(2, 2), symmetry=True) W = FunctionSpace(mesh, MixedElement([VE, TE])) F = FunctionSpace(mesh, "CG", 2) V = W.sub(0).collapse() M = W.sub(1).collapse() alpha_0 = Alpha_0(m, stable_hx, R, Lpml) alpha_1 = Alpha_1(alpha_0, Lx, Lpml, degree=2) alpha_2 = Alpha_2(alpha_0, Ly, Lpml, degree=2) beta_0 = Beta_0(m, max_velocity, R, Lpml) beta_1 = Beta_1(beta_0, Lx, Lpml, degree=2) beta_2 = Beta_2(beta_0, Ly, Lpml, degree=2) alpha_1 = interpolate(alpha_1, F) alpha_2 = interpolate(alpha_2, F) beta_1 = interpolate(beta_1, F) beta_2 = interpolate(beta_2, F) a_ = alpha_1 * alpha_2 b_ = alpha_1 * beta_2 + alpha_2 * beta_1 c_ = beta_1 * beta_2 Lambda_e = as_tensor([[alpha_2, 0], [0, alpha_1]]) Lambda_p = as_tensor([[beta_2, 0], [0, beta_1]]) a_ = alpha_1 * alpha_2 b_ = alpha_1 * beta_2 + alpha_2 * beta_1 c_ = beta_1 * beta_2 Lambda_e = as_tensor([[alpha_2, 0], [0, alpha_1]]) Lambda_p = as_tensor([[beta_2, 0], [0, beta_1]]) # Set up boundary condition bc = DirichletBC(W.sub(0), Constant(("0.0", "0.0")), ff, 1) # Create measure for the source term dx = Measure("dx", domain=mesh) ds = Measure("ds", domain=mesh, subdomain_data=ff) # Set up initial values u0 = Function(V) u0.set_allow_extrapolation(True) v0 = Function(V) a0 = Function(V) U0 = Function(M) V0 = Function(M) A0 = Function(M) # Test and trial functions (u, S) = TrialFunctions(W) (w, T) = TestFunctions(W) g = ModifiedRickerPulse(0, omega_p, amplitude, center) F = rho * inner(a_ * N_ddot(u, u0, a0, v0, dt, beta) \ + b_ * N_dot(u, u0, v0, a0, dt, beta, gamma) + c_ * u, w) * dx \ + inner(N_dot(S, U0, V0, A0, dt, beta, gamma).T * Lambda_e + S.T * Lambda_p, grad(w)) * dx \ - inner(g, w) * ds \ + inner(compliance(a_ * N_ddot(S, U0, A0, V0, dt, beta) + b_ * N_dot(S, U0, V0, A0, dt, beta, gamma) + c_ * S, u, mu, lmbda), T) * dx \ - 0.5 * inner(grad(u) * Lambda_p + Lambda_p * grad(u).T + grad(N_dot(u, u0, v0, a0, dt, beta, gamma)) * Lambda_e \ + Lambda_e * grad(N_dot(u, u0, v0, a0, dt, beta, gamma)).T, T) * dx \ a, L = lhs(F), rhs(F) # Assemble rhs (once) A = assemble(a) # Create GMRES Krylov solver solver = KrylovSolver(A, "gmres") # Create solution function S = Function(W) if target: xdmffile_u = XDMFFile("inversion_temporal_file/target/u.xdmf") pvd = File("inversion_temporal_file/target/u.pvd") xdmffile_u.write(u0, t) timeseries_u = TimeSeries( "inversion_temporal_file/target/u_timeseries") else: xdmffile_u = XDMFFile("inversion_temporal_file/obs/u.xdmf") xdmffile_u.write(u0, t) timeseries_u = TimeSeries("inversion_temporal_file/obs/u_timeseries") rec_counter = 0 while t < t_end - 0.5 * dt: t += float(dt) if rec_counter % 10 == 0: print( '\n\rtime: {:.3f} (Progress: {:.2f}%)'.format( t, 100 * t / t_end), ) g.t = t # Assemble rhs and apply boundary condition b = assemble(L) bc.apply(A, b) # Compute solution solver.solve(S.vector(), b) (u, U) = S.split(True) # Update previous time step update(u, u0, v0, a0, beta, gamma, dt) update(U, U0, V0, A0, beta, gamma, dt) xdmffile_u.write(u, t) pvd << (u, t) timeseries_u.store(u.vector(), t) energy = inner(u, u) * dx E = assemble(energy) print("E = ", E) print(u.vector().max())
def _setup_projection_nedelec(self, w, incompressibility_flux_type, D12, use_bcs, pdeg, gdim): """ Implement the BDM-like projection using Nedelec elements in the test function """ sim = self.simulation k = pdeg mesh = w[0].function_space().mesh() V = VectorFunctionSpace(mesh, 'DG', k) n = FacetNormal(mesh) # The mixed function space of the projection test functions e1 = FiniteElement('DGT', mesh.ufl_cell(), k) e2 = FiniteElement('N1curl', mesh.ufl_cell(), k - 1) em = MixedElement([e1, e2]) W = FunctionSpace(mesh, em) v1, v2 = TestFunctions(W) u = TrialFunction(V) # The same fluxes that are used in the incompressibility equation if incompressibility_flux_type == 'central': u_hat_dS = dolfin.avg(w) elif incompressibility_flux_type == 'upwind': w_nU = (dot(w, n) + abs(dot(w, n))) / 2.0 switch = dolfin.conditional(dolfin.gt(w_nU('+'), 0.0), 1.0, 0.0) u_hat_dS = switch * w('+') + (1 - switch) * w('-') if D12 is not None: u_hat_dS += dolfin.Constant([D12] * gdim) * dolfin.jump(w, n) # Equation 1 - flux through the sides a = L = 0 for R in '+-': a += dot(u(R), n(R)) * v1(R) * dS L += dot(u_hat_dS, n(R)) * v1(R) * dS # Eq. 1 cont. - flux through external boundaries a += dot(u, n) * v1 * ds if use_bcs: for d in range(gdim): dirichlet_bcs = sim.data['dirichlet_bcs'].get('u%d' % d, []) neumann_bcs = sim.data['neumann_bcs'].get('u%d' % d, []) robin_bcs = sim.data['robin_bcs'].get('u%d' % d, []) outlet_bcs = sim.data['outlet_bcs'] for dbc in dirichlet_bcs: u_bc = dbc.func() L += u_bc * n[d] * v1 * dbc.ds() for nbc in neumann_bcs + robin_bcs + outlet_bcs: if nbc.enforce_zero_flux: pass # L += 0 else: L += w[d] * n[d] * v1 * nbc.ds() for sbc in sim.data['slip_bcs'].get('u', []): pass # L += 0 else: L += dot(w, n) * v1 * ds # Equation 2 - internal shape using 'Nedelec 1st kind H(curl)' elements a += dot(u, v2) * dx L += dot(w, v2) * dx return a, L, V
def test_eim_approximation_08(expression_type, basis_generation): """ The aim of this script is to test that DEIM correctly handles collapsed subspaces. This is a prototype of the restricted operators required by the right-hand side of a supremizer solve. * EIM: not applicable. * DEIM: define a test function on a collapsed subspace (while, in case of rank 2 forms, the trial is defined on the full space), and integrate. """ class MockProblem(ParametrizedProblem): def __init__(self, V, **kwargs): ParametrizedProblem.__init__(self, "") self.V = V def name(self): return "MockProblem_08_" + 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) f1 = ParametrizedExpression(mock_problem, "1/sqrt(pow(x[0]-mu[0], 2) + pow(x[1]-mu[1], 2) + 0.01)", mu=(-1., -1.), element=V.sub(1).ufl_element()) # folder_prefix = os.path.join("test_eim_approximation_08_tempdir", expression_type, basis_generation) assert expression_type in ("Vector", "Matrix") if expression_type == "Vector": q = TestFunction(V.sub(1).collapse()) form = f1*q*dx # Call Parent constructor EIMApproximation.__init__(self, mock_problem, ParametrizedTensorFactory(form), folder_prefix, basis_generation) elif expression_type == "Matrix": up = TrialFunction(V) q = TestFunction(V.sub(1).collapse()) (u, p) = split(up) form = f1*q*div(u)*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 = RectangleMesh(Point(0.1, 0.1), Point(0.9, 0.9), 20, 20) # 2. Create Finite Element space (Lagrange P1) element_0 = VectorElement("Lagrange", mesh.ufl_cell(), 2) element_1 = FiniteElement("Lagrange", mesh.ufl_cell(), 1) element = MixedElement(element_0, element_1) V = FunctionSpace(mesh, element) # 3. Allocate an object of the ParametrizedFunctionApproximation class parametrized_function_approximation = ParametrizedFunctionApproximation(V, expression_type, basis_generation) mu_range = [(-1., -0.01), (-1., -0.01)] 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(20) parametrized_function_reduction_method.set_tolerance(0.) # 5. Perform the offline phase parametrized_function_reduction_method.initialize_training_set(100, sampling=EquispacedDistribution()) reduced_parametrized_function_approximation = parametrized_function_reduction_method.offline() # 6. Perform an online solve online_mu = (-1., -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_eim_approximation_05(expression_type, basis_generation): """ This test is combination of tests 01-03. The aim of this script is to test that integration correctly handles several parametrized expressions. * EIM: not applicable. * DEIM: several parametrized expressions are combined when defining forms. """ class MockProblem(ParametrizedProblem): def __init__(self, V, **kwargs): ParametrizedProblem.__init__(self, "") self.V = V def name(self): return "MockProblem_05_" + 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) f1 = ParametrizedExpression( mock_problem, "1/sqrt(pow(x[0]-mu[0], 2) + pow(x[1]-mu[1], 2) + 0.01)", mu=(-1., -1.), element=V.sub(1).ufl_element()) f2 = ParametrizedExpression( mock_problem, "exp( - 2*pow(x[0]-mu[0], 2) - 2*pow(x[1]-mu[1], 2) )", mu=(-1., -1.), element=V.sub(1).ufl_element()) f3 = ParametrizedExpression( mock_problem, "(1-x[0])*cos(3*pi*(pi+mu[1])*(1+x[1]))*exp(-(pi+mu[0])*(1+x[0]))", mu=(-1., -1.), element=V.sub(1).ufl_element()) # folder_prefix = os.path.join("test_eim_approximation_05_tempdir", expression_type, basis_generation) assert expression_type in ("Vector", "Matrix") if expression_type == "Vector": vq = TestFunction(V) (v, q) = split(vq) form = f1 * v[0] * dx + f2 * v[1] * dx + f3 * q * dx # Call Parent constructor EIMApproximation.__init__( self, mock_problem, ParametrizedTensorFactory(form), folder_prefix, basis_generation) elif expression_type == "Matrix": up = TrialFunction(V) vq = TestFunction(V) (u, p) = split(up) (v, q) = split(vq) form = f1 * inner(grad(u), grad(v)) * dx + f2 * p * div(v) * dx + f3 * q * div(u) * 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 = RectangleMesh(Point(0.1, 0.1), Point(0.9, 0.9), 20, 20) # 2. Create Finite Element space (Lagrange P1) element_0 = VectorElement("Lagrange", mesh.ufl_cell(), 2) element_1 = FiniteElement("Lagrange", mesh.ufl_cell(), 1) element = MixedElement(element_0, element_1) V = FunctionSpace(mesh, element) # 3. Allocate an object of the ParametrizedFunctionApproximation class parametrized_function_approximation = ParametrizedFunctionApproximation(V, expression_type, basis_generation) mu_range = [(-1., -0.01), (-1., -0.01)] 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(20) parametrized_function_reduction_method.set_tolerance(0.) # 5. Perform the offline phase parametrized_function_reduction_method.initialize_training_set(100, sampling=EquispacedDistribution()) reduced_parametrized_function_approximation = parametrized_function_reduction_method.offline() # 6. Perform an online solve online_mu = (-1., -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()
# Function Spaces density tracking/pressure T_1 = FunctionSpace(mesh, 'DG', 0) Q_E_Rho = FiniteElement("DG", mesh.ufl_cell(), k) # Vector valued function spaces for specific momentum tracking W_E_2 = VectorElement("DG", mesh.ufl_cell(), k) T_E_2 = VectorElement("DG", mesh.ufl_cell(), 0) Wbar_E_2 = VectorElement("DGT", mesh.ufl_cell(), kbar) Wbar_E_2_H12 = VectorElement("CG", mesh.ufl_cell(), kbar)["facet"] # Function spaces for Stokes Q_E = FiniteElement("DG", mesh.ufl_cell(), 0) Qbar_E = FiniteElement("DGT", mesh.ufl_cell(), k) # For Stokes mixedL = FunctionSpace(mesh, MixedElement([W_E_2, Q_E])) mixedG = FunctionSpace(mesh, MixedElement([Wbar_E_2_H12, Qbar_E])) W_2 = FunctionSpace(mesh, W_E_2) T_2 = FunctionSpace(mesh, T_E_2) Wbar_2 = FunctionSpace(mesh, Wbar_E_2) Wbar_2_H12 = FunctionSpace(mesh, Wbar_E_2_H12) Q_Rho = FunctionSpace(mesh, Q_E_Rho) Qbar = FunctionSpace(mesh, Qbar_E) # Define some functions rho, rho0, rho00 = Function(Q_Rho), Function(Q_Rho), Function(Q_Rho) rhobar = Function(Qbar) u0, ustar = Function(W_2), Function(W_2) ustar_bar = Function(Wbar_2) duh0, duh00 = Function(W_2), Function(W_2)
def right_boundary(x, on_boundary): return on_boundary and near(x[0], 15.0E-3) def bottom_boundary(x, on_boundary): return on_boundary and near(x[1], 0.0) def top_boundary(x, on_boundary): return on_boundary and near(x[1], 15.0E-3) ################################### FE part ################################### P1 = FiniteElement('P', 'triangle', 2) element = MixedElement([P1, P1, P1]) ME = FunctionSpace(mesh, element) subdomain = CompiledSubDomain( '(pow((x[0] - 7.5E-3), 2) + pow((x[1] - 7.5E-3), 2)) <= pow(2.5E-3, 2)') subdomains = MeshFunction("size_t", mesh, 2) subdomains.set_all(0) subdomain.mark(subdomains, 1) fc = Constant(2.0) # FCD V0_r = FunctionSpace(mesh, 'DG', 0) fc_function = Function(V0_r) fc_val = [0.0, fc] help = np.asarray(subdomains.array(), dtype=np.int32) fc_function.vector()[:] = np.choose(help, fc_val)
def test_steady_stokes(k): # Polynomial order and mesh resolution nx_list = [4, 8, 16] nu = Constant(1) if comm.Get_rank() == 0: print('{:=^72}'.format('Computing for polynomial order ' + str(k))) # Error listst error_u, error_p, error_div = [], [], [] for nx in nx_list: if comm.Get_rank() == 0: print('# Resolution ' + str(nx)) mesh = UnitSquareMesh(nx, nx) # Get forcing from exact solutions u_exact, p_exact = exact_solution(mesh) f = div(p_exact * Identity(2) - 2 * nu * sym(grad(u_exact))) # Define FunctionSpaces and functions V = VectorElement("DG", mesh.ufl_cell(), k) Q = FiniteElement("DG", mesh.ufl_cell(), k - 1) Vbar = VectorElement("DGT", mesh.ufl_cell(), k) Qbar = FiniteElement("DGT", mesh.ufl_cell(), k) mixedL = FunctionSpace(mesh, MixedElement([V, Q])) mixedG = FunctionSpace(mesh, MixedElement([Vbar, Qbar])) Uh = Function(mixedL) Uhbar = Function(mixedG) # Set forms alpha = Constant(6 * k * k) forms_stokes = FormsStokes(mesh, mixedL, mixedG, alpha).forms_steady(nu, f) # No-slip boundary conditions, set pressure in one of the corners bc0 = DirichletBC(mixedG.sub(0), Constant((0, 0)), Gamma) bc1 = DirichletBC(mixedG.sub(1), Constant(0), Corner, "pointwise") bcs = [bc0, bc1] # Initialize static condensation class ssc = StokesStaticCondensation(mesh, forms_stokes['A_S'], forms_stokes['G_S'], forms_stokes['B_S'], forms_stokes['Q_S'], forms_stokes['S_S'], bcs) # Assemble global system and incorporates bcs ssc.assemble_global_system(True) # Solve using mumps ssc.solve_problem(Uhbar, Uh, "mumps", "default") # Compute velocity/pressure/local div error uh, ph = Uh.split() e_u = np.sqrt(np.abs(assemble(dot(uh - u_exact, uh - u_exact) * dx))) e_p = np.sqrt(np.abs(assemble((ph - p_exact) * (ph - p_exact) * dx))) e_d = np.sqrt(np.abs(assemble(div(uh) * div(uh) * dx))) if comm.rank == 0: error_u.append(e_u) error_p.append(e_p) error_div.append(e_d) print('Error in velocity ' + str(error_u[-1])) print('Error in pressure ' + str(error_p[-1])) print('Local mass error ' + str(error_div[-1])) if comm.rank == 0: iterator_list = [1. / float(nx) for nx in nx_list] conv_u = compute_convergence(iterator_list, error_u) conv_p = compute_convergence(iterator_list, error_p) assert any(conv > k + 0.75 for conv in conv_u) assert any(conv > (k - 1) + 0.75 for conv in conv_p)
def xtest_mg_solver_stokes(): mesh0 = UnitCubeMesh(2, 2, 2) mesh1 = UnitCubeMesh(4, 4, 4) mesh2 = UnitCubeMesh(8, 8, 8) Ve = VectorElement("CG", mesh0.ufl_cell(), 2) Qe = FiniteElement("CG", mesh0.ufl_cell(), 1) Ze = MixedElement([Ve, Qe]) Z0 = FunctionSpace(mesh0, Ze) Z1 = FunctionSpace(mesh1, Ze) Z2 = FunctionSpace(mesh2, Ze) W = Z2 # Boundaries def right(x, on_boundary): return x[0] > (1.0 - DOLFIN_EPS) def left(x, on_boundary): return x[0] < DOLFIN_EPS def top_bottom(x, on_boundary): return x[1] > 1.0 - DOLFIN_EPS or x[1] < DOLFIN_EPS # No-slip boundary condition for velocity noslip = Constant((0.0, 0.0, 0.0)) bc0 = DirichletBC(W.sub(0), noslip, top_bottom) # Inflow boundary condition for velocity inflow = Expression(("-sin(x[1]*pi)", "0.0", "0.0"), degree=2) bc1 = DirichletBC(W.sub(0), inflow, right) # Collect boundary conditions bcs = [bc0, bc1] # Define variational problem (u, p) = TrialFunctions(W) (v, q) = TestFunctions(W) f = Constant((0.0, 0.0, 0.0)) a = inner(grad(u), grad(v)) * dx + div(v) * p * dx + q * div(u) * dx L = inner(f, v) * dx # Form for use in constructing preconditioner matrix b = inner(grad(u), grad(v)) * dx + p * q * dx # Assemble system A, bb = assemble_system(a, L, bcs) # Assemble preconditioner system P, btmp = assemble_system(b, L, bcs) spaces = [Z0, Z1, Z2] dm_collection = PETScDMCollection(spaces) solver = PETScKrylovSolver() solver.set_operators(A, P) PETScOptions.set("ksp_type", "gcr") PETScOptions.set("pc_type", "mg") PETScOptions.set("pc_mg_levels", 3) PETScOptions.set("pc_mg_galerkin") PETScOptions.set("ksp_monitor_true_residual") PETScOptions.set("ksp_atol", 1.0e-10) PETScOptions.set("ksp_rtol", 1.0e-10) solver.set_from_options() from petsc4py import PETSc ksp = solver.ksp() ksp.setDM(dm_collection.dm()) ksp.setDMActive(False) x = PETScVector() solver.solve(x, bb) # Check multigrid solution against LU solver solver = LUSolver(A) # noqa x_lu = PETScVector() solver.solve(x_lu, bb) assert round((x - x_lu).norm("l2"), 10) == 0 # Clear all PETSc options opts = PETSc.Options() for key in opts.getAll(): opts.delValue(key)
def FunctionAndRealElement(family, cell, degree): V_element = FiniteElement(family, cell, degree) R_element = FiniteElement("Real", cell, 0) return MixedElement(V_element, R_element)
def MixedSpace(mesh): element_0 = VectorElement("Lagrange", mesh.ufl_cell(), 2) element_1 = FiniteElement("Lagrange", mesh.ufl_cell(), 1) element = MixedElement(element_0, element_1) return FunctionSpace(mesh, element)
def solve_fixed_point(mesh, W_element, P_element, Q_element, u0, p0, theta0, kappa, rho, mu, cp, g, extra_force, heat_source, u_bcs, p_bcs, theta_dirichlet_bcs, theta_neumann_bcs, my_dx, my_ds, max_iter, tol): # Solve the coupled heat-Stokes equation approximately. Do this # iteratively by solving the heat equation, then solving Stokes with the # updated heat, the heat equation with the updated velocity and so forth # until the change is 'small'. WP = FunctionSpace(mesh, MixedElement([W_element, P_element])) Q = FunctionSpace(mesh, Q_element) # Initialize functions. up0 = Function(WP) u0, p0 = up0.split() theta1 = Function(Q) for _ in range(max_iter): heat_problem = heat.Heat(Q, kappa=kappa, rho=rho(theta0), cp=cp, convection=u0, source=heat_source, dirichlet_bcs=theta_dirichlet_bcs, neumann_bcs=theta_neumann_bcs, my_dx=my_dx, my_ds=my_ds) theta1.assign(heat_problem.solve_stationary()) # Solve problem for velocity, pressure. f = rho(theta0) * g # coupling if extra_force: f += as_vector((extra_force[0], extra_force[1], 0.0)) # up1 = up0.copy() stokes.stokes_solve(up0, mu, u_bcs, p_bcs, f, my_dx=my_dx, tol=1.0e-10, verbose=False, maxiter=1000) # from dolfin import plot # plot(u0) # plot(theta0) theta_diff = errornorm(theta0, theta1) info('||theta - theta0|| = {:e}'.format(theta_diff)) # info('||u - u0|| = {:e}'.format(u_diff)) # info('||p - p0|| = {:e}'.format(p_diff)) # diff = theta_diff + u_diff + p_diff diff = theta_diff info('sum = {:e}'.format(diff)) # # Show the iterates. # plot(theta0, title='theta0') # plot(u0, title='u0') # interactive() # #exit() if diff < tol: break theta0.assign(theta1) # Create a *deep* copy of u0, p0, to be able to deal with them as # actually separate entities. u0, p0 = up0.split(deepcopy=True) return u0, p0, theta0
def test_eim_approximation_18(expression_type, basis_generation): """ This test is the version of test 17 where high fidelity solution is used in place of 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_18_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., -1.)) self.f00 = 1. / sqrt( pow(x[0] - mu[0], 2) + pow(x[1] - mu[1], 2) + 0.01) self.f01 = 1. / sqrt( pow(x[0] - mu[0], 4) + pow(x[1] - mu[1], 4) + 0.01) # 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_18_" + 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_18_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.V # folder_prefix = os.path.join("test_eim_approximation_18_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 = inner(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 = inner(truth_problem._solution, u) * v[0] * 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 = RectangleMesh(Point(0.1, 0.1), Point(0.9, 0.9), 20, 20) # 2. Create Finite Element space (Lagrange P1) element_0 = VectorElement("Lagrange", mesh.ufl_cell(), 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., -0.01), (-1., -0.01)] 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(16) parametrized_function_reduction_method.set_tolerance(0.) # 7. Perform EIM offline phase parametrized_function_reduction_method.initialize_training_set( 64, sampling=EquispacedDistribution()) reduced_parametrized_function_approximation = parametrized_function_reduction_method.offline( ) # 8. Perform EIM online solve online_mu = (-1., -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_15(expression_type, basis_generation): """ This test is similar to test 13. * EIM: not applicable, no relevant difference with respect to test 13. * DEIM: the solution component is not further split between x and y. This results in a single coefficient of type ListTensor (rather than two coefficients 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_15_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., -1.)) self.f00 = 1. / sqrt( pow(x[0] - mu[0], 2) + pow(x[1] - mu[1], 2) + 0.01) self.f01 = 1. / sqrt( pow(x[0] - mu[0], 4) + pow(x[1] - mu[1], 4) + 0.01) # 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_15_" + 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 @StoreMapFromProblemToReductionMethod @UpdateMapFromProblemToTrainingStatus class MockReductionMethod(ReductionMethod): def __init__(self, truth_problem, **kwargs): # Call parent ReductionMethod.__init__( self, os.path.join("test_eim_approximation_15_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.V, 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() self.update_basis_matrix((index, 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, index_and_snapshot): (index, snapshot) = index_and_snapshot component = "u" if index % 2 == 0 else "s" new_basis_function = self.GS.apply( snapshot, self.reduced_problem.basis_functions[component], component=component) self.reduced_problem.basis_functions.enrich( new_basis_function, component) 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_15_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_15_tempdir", expression_type, basis_generation) assert expression_type in ("Vector", "Matrix") if expression_type == "Vector": v = TestFunction(self.V) form = inner(f0, grad(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 = inner(f0, grad(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 = RectangleMesh(Point(0.1, 0.1), Point(0.9, 0.9), 20, 20) # 2. Create Finite Element space (Lagrange P1) element_0 = VectorElement("Lagrange", mesh.ufl_cell(), 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., -0.01), (-1., -0.01)] 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(16, 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(16) parametrized_function_reduction_method.set_tolerance(0.) # 7. Perform EIM offline phase parametrized_function_reduction_method.initialize_training_set( 64, sampling=EquispacedDistribution()) reduced_parametrized_function_approximation = parametrized_function_reduction_method.offline( ) # 8. Perform EIM online solve online_mu = (-1., -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()
W_E_2 = VectorElement("DG", mesh.ufl_cell(), k) T_E_2 = VectorElement("DG", mesh.ufl_cell(), 0) Wbar_E_2 = VectorElement("DGT", mesh.ufl_cell(), kbar) Wbar_E_2_H12 = VectorElement("CG", mesh.ufl_cell(), kbar)["facet"] Q_E = FiniteElement("DG", mesh.ufl_cell(), k-1) Qbar_E = FiniteElement("DGT", mesh.ufl_cell(), k) # Function spaces for projection W_2 = FunctionSpace(mesh, W_E_2) T_2 = FunctionSpace(mesh, T_E_2) Wbar_2 = FunctionSpace(mesh, Wbar_E_2, constrained_domain=pbc) Wbar_2_H12 = FunctionSpace(mesh, Wbar_E_2_H12, constrained_domain=pbc) # Function spaces for Stokes mixedL = FunctionSpace(mesh, MixedElement([W_E_2, Q_E])) mixedG = FunctionSpace(mesh, MixedElement([Wbar_E_2_H12, Qbar_E]), constrained_domain=pbc) # Define functions u0_a, ustar = Function(W_2), Function(W_2) duh0, duh00 = Function(W_2), Function(W_2) ubar0_a = Function(Wbar_2_H12) ubar_a = Function(Wbar_2) Udiv = Function(W_2) Uh = Function(mixedL) Uhbar = Function(mixedG) U0 = Function(mixedL) Uhbar0 = Function(mixedG) lamb = Function(T_2)