from rbnics.backends.dolfin.matrix import Matrix from rbnics.backends.dolfin.snapshots_matrix import SnapshotsMatrix from rbnics.backends.dolfin.wrapping import get_mpi_comm from rbnics.backends.online import OnlineEigenSolver from rbnics.utils.decorators import BackendFor, ModuleWrapper def transpose(arg): from rbnics.backends.dolfin.transpose import transpose as backend_transpose # cannot import at global scope due to cyclic dependence return backend_transpose(arg) backend = ModuleWrapper(transpose) wrapping = ModuleWrapper(get_mpi_comm) online_backend = ModuleWrapper(OnlineEigenSolver=OnlineEigenSolver) online_wrapping = ModuleWrapper() ProperOrthogonalDecomposition_Base = BasicProperOrthogonalDecomposition( backend, wrapping, online_backend, online_wrapping, AbstractProperOrthogonalDecomposition, SnapshotsMatrix, FunctionsList) @BackendFor("dolfin", inputs=(FunctionSpace, (Form, Matrix.Type()), (str, None))) class ProperOrthogonalDecomposition(ProperOrthogonalDecomposition_Base): def __init__(self, V, inner_product, component=None): ProperOrthogonalDecomposition_Base.__init__(self, V, inner_product, component) def store_snapshot(self, snapshot, component=None, weight=None): self.snapshots_matrix.enrich(snapshot, component, weight)
function_extend_or_restrict, function_from_ufl_operators, function_save, get_function_subspace, to_petsc4py) from rbnics.backends.dolfin.wrapping.tensor_save import basic_tensor_save from rbnics.utils.decorators import backend_for, ModuleWrapper, overload from rbnics.utils.io import Folders backend = ModuleWrapper(Function, Matrix, Vector) wrapping_for_wrapping = ModuleWrapper(build_dof_map_writer_mapping, form_argument_space, to_petsc4py, form_name=form_name) tensor_save = basic_tensor_save(backend, wrapping_for_wrapping) wrapping = ModuleWrapper(function_extend_or_restrict, function_save, get_function_subspace, tensor_save=tensor_save) export_base = basic_export(backend, wrapping) # Export a solution to file @backend_for("dolfin", inputs=((Function.Type(), Matrix.Type(), Operator, Vector.Type()), (Folders.Folder, str), str, (int, None), (int, str, None))) def export(solution, directory, filename, suffix=None, component=None): _export(solution, directory, filename, suffix, component) @overload def _export( solution: ( Function.Type(), Matrix.Type(), Vector.Type() ), directory: ( Folders.Folder, str
# from math import fabs from ufl.core.operator import Operator from rbnics.backends.dolfin.matrix import Matrix from rbnics.backends.dolfin.vector import Vector from rbnics.backends.dolfin.function import Function from rbnics.backends.dolfin.wrapping import function_from_ufl_operators, get_global_dof_coordinates, get_global_dof_component, to_petsc4py from rbnics.utils.decorators import backend_for, overload from rbnics.utils.mpi import parallel_max # abs function to compute maximum absolute value of an expression, matrix or vector (for EIM). To be used in combination with max # even though here we actually carry out both the max and the abs! @backend_for("dolfin", inputs=((Matrix.Type(), Vector.Type(), Function.Type(), Operator), )) def abs(expression): return _abs(expression) @overload def _abs(matrix: Matrix.Type()): # Note: PETSc offers a method MatGetRowMaxAbs, but it is not wrapped in petsc4py. We do the same by hand mat = to_petsc4py(matrix) row_start, row_end = mat.getOwnershipRange() i_max, j_max = None, None value_max = None for i in range(row_start, row_end): cols, vals = mat.getRow(i) for (c, v) in zip(cols, vals):
def AdditionalIsFunction(arg): return isinstance(arg, Operator) def ConvertAdditionalFunctionTypes(arg): assert isinstance(arg, Operator) return function_from_ufl_operators(arg) backend = ModuleWrapper(BasisFunctionsMatrix, evaluate, Function, FunctionsList, Matrix, NonAffineExpansionStorage, ParametrizedTensorFactory, TensorsList, Vector) wrapping = ModuleWrapper(function_to_vector, matrix_mul_vector, vector_mul_vector, vectorized_matrix_inner_vectorized_matrix) online_backend = ModuleWrapper(OnlineMatrix=OnlineMatrix, OnlineVector=OnlineVector) online_wrapping = ModuleWrapper() transpose_base = basic_transpose(backend, wrapping, online_backend, online_wrapping, AdditionalIsFunction, ConvertAdditionalFunctionTypes) @backend_for("dolfin", inputs=((BasisFunctionsMatrix, Function.Type(), FunctionsList, Matrix.Type(), Operator, ParametrizedTensorFactory, TensorsList, Vector.Type()), )) def transpose(arg): return transpose_base(arg)
from rbnics.backends.dolfin.vector import Vector from rbnics.backends.dolfin.wrapping import (build_dof_map_reader_mapping, form_argument_space, function_extend_or_restrict, function_load, get_function_space, get_function_subspace, to_petsc4py) from rbnics.backends.dolfin.wrapping.tensor_load import basic_tensor_load from rbnics.utils.decorators import backend_for, ModuleWrapper from rbnics.utils.io import Folders backend = ModuleWrapper(Function, Matrix, Vector) wrapping_for_wrapping = ModuleWrapper(build_dof_map_reader_mapping, form_argument_space, to_petsc4py) tensor_load = basic_tensor_load(backend, wrapping_for_wrapping) wrapping = ModuleWrapper(function_extend_or_restrict, function_load, get_function_space, get_function_subspace, tensor_load=tensor_load) import_base = basic_import_(backend, wrapping) # Import a solution from file @backend_for("dolfin", inputs=((Function.Type(), Matrix.Type(), Vector.Type()), (Folders.Folder, str), str, (int, None), (int, str, None)) ) def import_(solution, directory, filename, suffix=None, component=None): import_base(solution, directory, filename, suffix, component)
# Copyright (C) 2015-2021 by the RBniCS authors # # This file is part of RBniCS. # # SPDX-License-Identifier: LGPL-3.0-or-later from rbnics.backends.basic import copy as basic_copy from rbnics.backends.dolfin.function import Function from rbnics.backends.dolfin.matrix import Matrix from rbnics.backends.dolfin.vector import Vector from rbnics.backends.dolfin.wrapping import function_copy, tensor_copy from rbnics.utils.decorators import backend_for, list_of, ModuleWrapper backend = ModuleWrapper(Function, Matrix, Vector) wrapping = ModuleWrapper(function_copy, tensor_copy) copy_base = basic_copy(backend, wrapping) @backend_for("dolfin", inputs=((Function.Type(), list_of(Function.Type()), Matrix.Type(), Vector.Type()), )) def copy(arg): return copy_base(arg)
def _evaluate(expression: (Matrix.Type(), Vector.Type(), TensorsList), at: ReducedMesh, **kwargs): assert len(kwargs) == 0 return evaluate_base(expression, at)
# along with RBniCS. If not, see <http://www.gnu.org/licenses/>. # from petsc4py import PETSc from ufl import Form from dolfin import __version__ as dolfin_version, as_backend_type, assemble, compile_cpp_code, DirichletBC, Function, FunctionSpace, PETScMatrix, PETScVector, SLEPcEigenSolver from rbnics.backends.dolfin.evaluate import evaluate from rbnics.backends.dolfin.matrix import Matrix from rbnics.backends.dolfin.parametrized_tensor_factory import ParametrizedTensorFactory from rbnics.backends.dolfin.wrapping.dirichlet_bc import ProductOutputDirichletBC from rbnics.backends.abstract import EigenSolver as AbstractEigenSolver from rbnics.utils.decorators import BackendFor, dict_of, list_of, overload @BackendFor("dolfin", inputs=(FunctionSpace, (Form, Matrix.Type(), ParametrizedTensorFactory), (Form, Matrix.Type(), ParametrizedTensorFactory, None), (list_of(DirichletBC), ProductOutputDirichletBC, dict_of(str, list_of(DirichletBC)), dict_of(str, ProductOutputDirichletBC), None))) class EigenSolver(AbstractEigenSolver): def __init__(self, V, A, B=None, bcs=None): self.V = V if bcs is not None: self._set_boundary_conditions(bcs) A = self._assemble_if_form(A) if B is not None: B = self._assemble_if_form(B) self._set_operators(A, B) if self.B is not None:
def _assemble_if_form(mat: Matrix.Type()): return mat
# GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with RBniCS. If not, see <http://www.gnu.org/licenses/>. # from ufl import Form from dolfin import assemble, DirichletBC from rbnics.backends.abstract import AffineExpansionStorage as AbstractAffineExpansionStorage from rbnics.backends.dolfin.matrix import Matrix from rbnics.backends.dolfin.vector import Vector from rbnics.backends.dolfin.function import Function from rbnics.utils.decorators import backend_for, list_of, overload, tuple_of # Generic backend @backend_for("dolfin", inputs=((tuple_of(list_of(DirichletBC)), tuple_of(Form), tuple_of(Function.Type()), tuple_of(Matrix.Type()), tuple_of(Vector.Type()), tuple_of((Form, Matrix.Type())), tuple_of((Form, Vector.Type()))), )) def AffineExpansionStorage(args): return _AffineExpansionStorage(args) # Base implementation class AffineExpansionStorage_Base(AbstractAffineExpansionStorage): def __init__(self, args): self._content = None def __getitem__(self, key): return self._content[key] def __iter__(self): return self._content.__iter__() def __len__(self):
def _export(solution: (Function.Type(), Matrix.Type(), Vector.Type()), directory: (Folders.Folder, str), filename: str, suffix: (int, None) = None, component: (int, str, None) = None): export_base(solution, directory, filename, suffix, component)
def _init_lhs(self, lhs: Matrix.Type(), bcs: None): self.lhs = lhs
# from ufl import Form from dolfin import assemble, DirichletBC, PETScLUSolver from rbnics.backends.abstract import LinearSolver as AbstractLinearSolver, LinearProblemWrapper from rbnics.backends.dolfin.evaluate import evaluate from rbnics.backends.dolfin.function import Function from rbnics.backends.dolfin.matrix import Matrix from rbnics.backends.dolfin.parametrized_tensor_factory import ParametrizedTensorFactory from rbnics.backends.dolfin.vector import Vector from rbnics.backends.dolfin.wrapping.dirichlet_bc import ProductOutputDirichletBC from rbnics.utils.decorators import BackendFor, dict_of, list_of, overload @BackendFor("dolfin", inputs=((Form, Matrix.Type(), ParametrizedTensorFactory, LinearProblemWrapper), Function.Type(), (Form, ParametrizedTensorFactory, Vector.Type(), None), (list_of(DirichletBC), ProductOutputDirichletBC, dict_of(str, list_of(DirichletBC)), dict_of(str, ProductOutputDirichletBC), None))) class LinearSolver(AbstractLinearSolver): @overload((Form, Matrix.Type(), ParametrizedTensorFactory), Function.Type(), (Form, ParametrizedTensorFactory, Vector.Type()), (list_of(DirichletBC), ProductOutputDirichletBC, dict_of(str, list_of(DirichletBC)), dict_of(str, ProductOutputDirichletBC), None)) def __init__(self, lhs, solution, rhs, bcs=None): self.solution = solution self._init_lhs(lhs, bcs)
from ufl.core.operator import Operator from rbnics.backends.basic import transpose as basic_transpose from rbnics.backends.dolfin.basis_functions_matrix import BasisFunctionsMatrix from rbnics.backends.dolfin.evaluate import evaluate from rbnics.backends.dolfin.function import Function from rbnics.backends.dolfin.functions_list import FunctionsList from rbnics.backends.dolfin.matrix import Matrix from rbnics.backends.dolfin.non_affine_expansion_storage import NonAffineExpansionStorage from rbnics.backends.dolfin.parametrized_tensor_factory import ParametrizedTensorFactory from rbnics.backends.dolfin.tensors_list import TensorsList from rbnics.backends.dolfin.vector import Vector from rbnics.backends.dolfin.wrapping import function_from_ufl_operators, function_to_vector, matrix_mul_vector, vector_mul_vector, vectorized_matrix_inner_vectorized_matrix from rbnics.backends.online import OnlineMatrix, OnlineVector from rbnics.utils.decorators import backend_for, ModuleWrapper def AdditionalIsFunction(arg): return isinstance(arg, Operator) def ConvertAdditionalFunctionTypes(arg): assert isinstance(arg, Operator) return function_from_ufl_operators(arg) backend = ModuleWrapper(BasisFunctionsMatrix, evaluate, Function, FunctionsList, Matrix, NonAffineExpansionStorage, ParametrizedTensorFactory, TensorsList, Vector) wrapping = ModuleWrapper(function_to_vector, matrix_mul_vector, vector_mul_vector, vectorized_matrix_inner_vectorized_matrix) online_backend = ModuleWrapper(OnlineMatrix=OnlineMatrix, OnlineVector=OnlineVector) online_wrapping = ModuleWrapper() transpose_base = basic_transpose(backend, wrapping, online_backend, online_wrapping, AdditionalIsFunction, ConvertAdditionalFunctionTypes) @backend_for("dolfin", inputs=((BasisFunctionsMatrix, Function.Type(), FunctionsList, Matrix.Type(), Operator, ParametrizedTensorFactory, TensorsList, Vector.Type()), )) def transpose(arg): return transpose_base(arg)
# Copyright (C) 2015-2021 by the RBniCS authors # # This file is part of RBniCS. # # SPDX-License-Identifier: LGPL-3.0-or-later from ufl.core.operator import Operator from dolfin import assign as dolfin_assign from rbnics.backends.dolfin.function import Function from rbnics.backends.dolfin.matrix import Matrix from rbnics.backends.dolfin.vector import Vector from rbnics.backends.dolfin.wrapping import function_from_ufl_operators, to_petsc4py from rbnics.utils.decorators import backend_for, list_of, overload @backend_for("dolfin", inputs=((Function.Type(), list_of(Function.Type()), Matrix.Type(), Vector.Type()), (Function.Type(), list_of(Function.Type()), Matrix.Type(), Operator, Vector.Type()))) def assign(object_to, object_from): _assign(object_to, object_from) @overload def _assign(object_to: Function.Type(), object_from: Function.Type()): if object_from is not object_to: dolfin_assign(object_to, object_from) @overload def _assign(object_to: Function.Type(), object_from: Operator): dolfin_assign(object_to, function_from_ufl_operators(object_from))
# # SPDX-License-Identifier: LGPL-3.0-or-later from ufl import Form from dolfin import assemble, DirichletBC, PETScLUSolver from rbnics.backends.abstract import LinearSolver as AbstractLinearSolver, LinearProblemWrapper from rbnics.backends.dolfin.evaluate import evaluate from rbnics.backends.dolfin.function import Function from rbnics.backends.dolfin.matrix import Matrix from rbnics.backends.dolfin.parametrized_tensor_factory import ParametrizedTensorFactory from rbnics.backends.dolfin.vector import Vector from rbnics.backends.dolfin.wrapping.dirichlet_bc import ProductOutputDirichletBC from rbnics.utils.decorators import BackendFor, dict_of, list_of, overload @BackendFor("dolfin", inputs=((Form, Matrix.Type(), ParametrizedTensorFactory, LinearProblemWrapper), Function.Type(), (Form, ParametrizedTensorFactory, Vector.Type(), None), (list_of(DirichletBC), ProductOutputDirichletBC, dict_of(str, list_of(DirichletBC)), dict_of(str, ProductOutputDirichletBC), None))) class LinearSolver(AbstractLinearSolver): @overload((Form, Matrix.Type(), ParametrizedTensorFactory), Function.Type(), (Form, ParametrizedTensorFactory, Vector.Type()), (list_of(DirichletBC), ProductOutputDirichletBC, dict_of(str, list_of(DirichletBC)), dict_of(str, ProductOutputDirichletBC), None)) def __init__(self, lhs, solution, rhs, bcs=None): self.solution = solution self._init_lhs(lhs, bcs) self._init_rhs(rhs, bcs) self._apply_bcs(bcs) self._linear_solver = "default" self.monitor = None
def _assign(object_to: Matrix.Type(), object_from: Matrix.Type()): if object_from is not object_to: to_petsc4py(object_from).copy(to_petsc4py(object_to), to_petsc4py(object_to).Structure.SAME_NONZERO_PATTERN)
class LinearSolver(AbstractLinearSolver): @overload((Form, Matrix.Type(), ParametrizedTensorFactory), Function.Type(), (Form, ParametrizedTensorFactory, Vector.Type()), (list_of(DirichletBC), ProductOutputDirichletBC, dict_of(str, list_of(DirichletBC)), dict_of(str, ProductOutputDirichletBC), None)) def __init__(self, lhs, solution, rhs, bcs=None): self.solution = solution self._init_lhs(lhs, bcs) self._init_rhs(rhs, bcs) self._apply_bcs(bcs) self._linear_solver = "default" self.monitor = None @overload(LinearProblemWrapper, Function.Type()) def __init__(self, problem_wrapper, solution): self.__init__(problem_wrapper.matrix_eval(), solution, problem_wrapper.vector_eval(), problem_wrapper.bc_eval()) self.monitor = problem_wrapper.monitor @overload(Form, (list_of(DirichletBC), ProductOutputDirichletBC, dict_of(str, list_of(DirichletBC)), dict_of(str, ProductOutputDirichletBC), None)) def _init_lhs(self, lhs, bcs): self.lhs = assemble(lhs, keep_diagonal=True) @overload(ParametrizedTensorFactory, (list_of(DirichletBC), ProductOutputDirichletBC, dict_of(str, list_of(DirichletBC)), dict_of(str, ProductOutputDirichletBC), None)) def _init_lhs(self, lhs, bcs): self.lhs = evaluate(lhs) @overload(Matrix.Type(), None) def _init_lhs(self, lhs, bcs): self.lhs = lhs @overload(Matrix.Type(), (list_of(DirichletBC), ProductOutputDirichletBC, dict_of(str, list_of(DirichletBC)), dict_of(str, ProductOutputDirichletBC))) def _init_lhs(self, lhs, bcs): # Create a copy of lhs, in order not to change # the original references when applying bcs self.lhs = lhs.copy() @overload(Form, (list_of(DirichletBC), ProductOutputDirichletBC, dict_of(str, list_of(DirichletBC)), dict_of(str, ProductOutputDirichletBC), None)) def _init_rhs(self, rhs, bcs): self.rhs = assemble(rhs) @overload(ParametrizedTensorFactory, (list_of(DirichletBC), ProductOutputDirichletBC, dict_of(str, list_of(DirichletBC)), dict_of(str, ProductOutputDirichletBC), None)) def _init_rhs(self, rhs, bcs): self.rhs = evaluate(rhs) @overload(Vector.Type(), None) def _init_rhs(self, rhs, bcs): self.rhs = rhs @overload(Vector.Type(), (list_of(DirichletBC), ProductOutputDirichletBC, dict_of(str, list_of(DirichletBC)), dict_of(str, ProductOutputDirichletBC))) def _init_rhs(self, rhs, bcs): # Create a copy of rhs, in order not to change # the original references when applying bcs self.rhs = rhs.copy() @overload(None) def _apply_bcs(self, bcs): pass @overload((list_of(DirichletBC), ProductOutputDirichletBC)) def _apply_bcs(self, bcs): for bc in bcs: bc.apply(self.lhs, self.rhs) @overload((dict_of(str, list_of(DirichletBC)), dict_of(str, ProductOutputDirichletBC))) def _apply_bcs(self, bcs): for key in bcs: for bc in bcs[key]: bc.apply(self.lhs, self.rhs) def set_parameters(self, parameters): assert len(parameters) in (0, 1) if len(parameters) == 1: assert "linear_solver" in parameters self._linear_solver = parameters.get("linear_solver", "default") def solve(self): solver = PETScLUSolver(self._linear_solver) solver.solve(self.lhs, self.solution.vector(), self.rhs) if self.monitor is not None: self.monitor(self.solution)
# Copyright (C) 2015-2021 by the RBniCS authors # # This file is part of RBniCS. # # SPDX-License-Identifier: LGPL-3.0-or-later from ufl import Form from ufl.core.operator import Operator from dolfin import FunctionSpace from rbnics.backends.basic import GramSchmidt as BasicGramSchmidt from rbnics.backends.dolfin.function import Function from rbnics.backends.dolfin.matrix import Matrix from rbnics.backends.dolfin.transpose import transpose from rbnics.backends.dolfin.wrapping import (function_extend_or_restrict, function_from_ufl_operators, get_function_subspace, gram_schmidt_projection_step) from rbnics.utils.decorators import BackendFor, dict_of, ModuleWrapper, overload backend = ModuleWrapper(Function, transpose) wrapping = ModuleWrapper(function_extend_or_restrict, get_function_subspace, gram_schmidt_projection_step) GramSchmidt_Base = BasicGramSchmidt(backend, wrapping) @BackendFor("dolfin", inputs=(FunctionSpace, (Form, Matrix.Type()), (str, None))) class GramSchmidt(GramSchmidt_Base): @overload(Operator, (None, str, dict_of(str, str))) def _extend_or_restrict_if_needed(self, function, component): function = function_from_ufl_operators(function) return GramSchmidt_Base._extend_or_restrict_if_needed(self, function, component)
# This file is part of RBniCS. # # RBniCS is free software: you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # RBniCS is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with RBniCS. If not, see <http://www.gnu.org/licenses/>. # from ufl import Form from rbnics.backends.basic import GramSchmidt as BasicGramSchmidt from rbnics.backends.dolfin.matrix import Matrix from rbnics.backends.dolfin.transpose import transpose from rbnics.backends.dolfin.wrapping import gram_schmidt_projection_step from rbnics.utils.decorators import BackendFor, ModuleWrapper backend = ModuleWrapper(transpose) wrapping = ModuleWrapper(gram_schmidt_projection_step) GramSchmidt_Base = BasicGramSchmidt(backend, wrapping) @BackendFor("dolfin", inputs=((Form, Matrix.Type()), )) class GramSchmidt(GramSchmidt_Base): pass