def solve(self, N=None, **kwargs):
     N, kwargs = self._online_size_from_kwargs(N, **kwargs)
     N += self.N_bc
     self._latest_solve_kwargs = kwargs
     self._solution = OnlineFunction(N)
     self._solution_over_time.clear()
     self._solution_dot = OnlineFunction(N)
     self._solution_dot_over_time.clear()
     if N == 0:  # trivial case
         self._solution_over_time.extend([
             self._solution
             for _ in self._solution_over_time.expected_times()
         ])
         self._solution_dot_over_time.extend([
             self._solution_dot
             for _ in self._solution_dot_over_time.expected_times()
         ])
         return self._solution_over_time
     try:
         assign(self._solution_over_time,
                self._solution_over_time_cache[self.mu, N, kwargs])
         # **kwargs is not supported by __getitem__
         assign(self._solution_dot_over_time,
                self._solution_dot_over_time_cache[self.mu, N, kwargs])
     except KeyError:
         assert not hasattr(self, "_is_solving")
         self._is_solving = True
         self._solve(N, **kwargs)
         delattr(self, "_is_solving")
     assign(self._solution, self._solution_over_time[-1])
     assign(self._solution_dot, self._solution_dot_over_time[-1])
     return self._solution_over_time
Beispiel #2
0
 def solve(self, N=None, **kwargs):
     N, kwargs = self._online_size_from_kwargs(N, **kwargs)
     N += self.N_bc
     self._solution = OnlineFunction(N)
     self._solution_dot = OnlineFunction(N)
     cache_key = self._cache_key_from_N_and_kwargs(N, **kwargs)
     assert ((cache_key in self._solution_cache) ==
             (cache_key in self._solution_dot_cache) ==
             (cache_key in self._solution_over_time_cache) ==
             (cache_key in self._solution_dot_over_time_cache))
     if "RAM" in self.cache_config and cache_key in self._solution_cache:
         log(PROGRESS, "Loading reduced solution from cache")
         assign(self._solution, self._solution_cache[cache_key])
         assign(self._solution_dot, self._solution_dot_cache[cache_key])
         assign(self._solution_over_time,
                self._solution_over_time_cache[cache_key])
         assign(self._solution_dot_over_time,
                self._solution_dot_over_time_cache[cache_key])
     else:
         log(PROGRESS, "Solving reduced problem")
         assert not hasattr(self, "_is_solving")
         self._is_solving = True
         self._solve(N, **kwargs)
         delattr(self, "_is_solving")
         if "RAM" in self.cache_config:
             self._solution_cache[cache_key] = copy(self._solution)
             self._solution_dot_cache[cache_key] = copy(
                 self._solution_dot)
             self._solution_over_time_cache[cache_key] = copy(
                 self._solution_over_time)
             self._solution_dot_over_time_cache[cache_key] = copy(
                 self._solution_dot_over_time)
     return self._solution_over_time
Beispiel #3
0
 def solve(self, mu, c, snapshot):
     print("Performing L^2 projection for mu =", mu, "and component", c)
     #quit()
     projected_snapshot_N = OnlineFunction(self.N)
     solver = OnlineLinearSolver(
         self.inner_product_N, projected_snapshot_N,
         transpose(self.basis_functions) * self.inner_product * snapshot)
     solver.solve()
     return projected_snapshot_N.vector().__array__()
Beispiel #4
0
 def ic_eval(self):
     problem = self.problem
     N = self.N
     if len(problem.components) > 1:
         all_initial_conditions = list()
         all_initial_conditions_thetas = list()
         for component in problem.components:
             if problem.initial_condition[
                     component] and not problem.initial_condition_is_homogeneous[
                         component]:
                 all_initial_conditions.extend(
                     problem.initial_condition[component][:N])
                 all_initial_conditions_thetas.extend(
                     problem.compute_theta("initial_condition_" +
                                           component))
         if len(all_initial_conditions) > 0:
             all_initial_conditions = tuple(all_initial_conditions)
             all_initial_conditions = OnlineAffineExpansionStorage(
                 all_initial_conditions)
             all_initial_conditions_thetas = tuple(
                 all_initial_conditions_thetas)
         else:
             all_initial_conditions = None
             all_initial_conditions_thetas = None
     else:
         if problem.initial_condition and not problem.initial_condition_is_homogeneous:
             all_initial_conditions = problem.initial_condition[:N]
             all_initial_conditions_thetas = problem.compute_theta(
                 "initial_condition")
         else:
             all_initial_conditions = None
             all_initial_conditions_thetas = None
     assert (all_initial_conditions is
             None) == (all_initial_conditions_thetas is None)
     if all_initial_conditions is not None:
         inner_product_N = problem._combined_projection_inner_product[:
                                                                      N, :
                                                                      N]
         projected_initial_condition = OnlineFunction(N)
         solver = OnlineLinearSolver(
             inner_product_N, projected_initial_condition,
             sum(
                 product(all_initial_conditions_thetas,
                         all_initial_conditions)))
         solver.set_parameters(problem._linear_solver_parameters)
         solver.solve()
         return projected_initial_condition
     else:
         return OnlineFunction(N)
Beispiel #5
0
 def _multiply(tensors_list: AbstractTensorsList,
               online_function: OnlineFunction.Type(),
               output: backend.Matrix.Type()):
     output.zero()
     for (i, matrix_i) in enumerate(tensors_list._list):
         online_vector_i = online_function.vector()[i]
         output += matrix_i * online_vector_i
 def solve(self, N=None, **kwargs):
     """
     Perform an online solve. self.N will be used as matrix dimension if the default value is provided for N.
     
     :param N : Dimension of the reduced problem
     :type N : integer
     :return: reduced solution
     """
     N, kwargs = self._online_size_from_kwargs(N, **kwargs)
     N += self.N_bc
     self._latest_solve_kwargs = kwargs
     self._solution = OnlineFunction(N)
     if N == 0:  # trivial case
         return self._solution
     try:
         assign(self._solution, self._solution_cache[
             self.mu, N,
             kwargs])  # **kwargs is not supported by __getitem__
     except KeyError:
         assert not hasattr(self, "_is_solving")
         self._is_solving = True
         self._solve(N, **kwargs)
         delattr(self, "_is_solving")
         self._solution_cache[self.mu, N, kwargs] = copy(self._solution)
     return self._solution
Beispiel #7
0
 def get_initial_error_estimate_squared(self):
     self._solution = self._solution_over_time[0]
     N = self._solution.N
     
     at_least_one_non_homogeneous_initial_condition = False
     
     addend_0 = 0.
     addend_1_right = OnlineFunction(N)
     
     if len(self.components) > 1:
         for component in self.components:
             if self.initial_condition[component] and not self.initial_condition_is_homogeneous[component]:
                 at_least_one_non_homogeneous_initial_condition = True
                 theta_ic_component = self.compute_theta("initial_condition_" + component)
                 addend_0 += sum(product(theta_ic_component, self.initial_condition_product[component, component], theta_ic_component))
                 addend_1_right += sum(product(theta_ic_component, self.initial_condition[:N]))
     else:
         if self.initial_condition and not self.initial_condition_is_homogeneous:
             at_least_one_non_homogeneous_initial_condition = True
             theta_ic = self.compute_theta("initial_condition")
             addend_0 += sum(product(theta_ic, self.initial_condition_product, theta_ic))
             addend_1_right += sum(product(theta_ic, self.initial_condition[:N]))
     
     if at_least_one_non_homogeneous_initial_condition:
         inner_product_N = self._combined_projection_inner_product[:N, :N]
         addend_1_left = self._solution
         addend_2 = transpose(self._solution)*inner_product_N*self._solution
         return addend_0 - 2.0*(transpose(addend_1_left)*addend_1_right) + addend_2
     else:
         return 0.
Beispiel #8
0
    def project(self, snapshot, on_dirichlet_bc=True, N=None, **kwargs):
        N, kwargs = self._online_size_from_kwargs(N, **kwargs)
        N += self.N_bc

        # Get truth and reduced inner product matrices for projection
        inner_product = self.truth_problem._combined_projection_inner_product
        inner_product_N = self._combined_projection_inner_product[:N, :N]

        # Get basis
        basis_functions = self.basis_functions[:N]

        # Define storage for projected solution
        projected_snapshot_N = OnlineFunction(N)

        # Project on reduced basis
        if on_dirichlet_bc:
            solver = OnlineLinearSolver(
                inner_product_N, projected_snapshot_N,
                transpose(basis_functions) * inner_product * snapshot)
        else:
            solver = OnlineLinearSolver(
                inner_product_N, projected_snapshot_N,
                transpose(basis_functions) * inner_product * snapshot,
                self._combined_and_homogenized_dirichlet_bc)
        solver.set_parameters(self._linear_solver_parameters)
        solver.solve()
        return projected_snapshot_N
Beispiel #9
0
    def _solve(self, rhs_, N=None):
        if N is None:
            N = self.N

        if N > 0:
            self._interpolation_coefficients = OnlineFunction(N)

            # Evaluate the parametrized expression at interpolation locations
            rhs = evaluate(rhs_, self.interpolation_locations[:N])

            (max_abs_rhs, _) = max(abs(rhs))
            if max_abs_rhs == 0.:
                # If the rhs is zero, then we are interpolating the zero function
                # and the default zero coefficients are enough.
                pass
            else:
                # Extract the interpolation matrix
                lhs = self.interpolation_matrix[0][:N, :N]

                # Solve the interpolation problem
                solver = OnlineLinearSolver(lhs,
                                            self._interpolation_coefficients,
                                            rhs)
                solver.solve()
        else:
            self._interpolation_coefficients = None  # OnlineFunction
Beispiel #10
0
 def _multiply(tensors_list: AbstractTensorsList,
               online_function: OnlineFunction.Type(),
               output: backend.Vector.Type()):
     output.zero()
     for (i, vector_i) in enumerate(tensors_list._list):
         online_vector_i = online_function.vector()[i]
         output.add_local(vector_i.get_local() * online_vector_i)
     output.apply("add")
Beispiel #11
0
 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
Beispiel #12
0
 def solve(self, N=None, **kwargs):
     N, kwargs = self.reduced_problem._online_size_from_kwargs(N, **kwargs)
     N += self.reduced_problem.N_bc
     self._eigenvector = OnlineFunction(N)
     cache_key = self._cache_key(**kwargs)
     try:
         self._eigenvalue = self._eigenvalue_cache[cache_key]
         assign(self._eigenvector, self._eigenvector_cache[cache_key])
     except KeyError:
         self._solve(N, **kwargs)
         self._eigenvalue_cache[cache_key] = self._eigenvalue
         self._eigenvector_cache[cache_key] = copy(self._eigenvector)
     return (self._eigenvalue, self._eigenvector)
def reduced_solve(mu, N):
    normalize_inputs = NormalizeInputs(mu_range)
    mu_torch = normalize_inputs(mu)

    mu_torch = mu_torch.view(mu_torch.shape[1], -1)

    reduced_solution = dict()
    for c in components:
        network = Network(len(mu), c, N)
        network.load_state_dict(
            torch.load(os.path.join("networks",
                                    "network_" + c + "_" + str(N))))

        normalize_outputs = NormalizeOutputs(
            os.path.join("networks",
                         "output_normalization_" + c + "_" + str(N)))

        reduced_solution_c = OnlineFunction(N)
        reduced_solution_c.vector()[:] = normalize_outputs.inv(
            network(mu_torch).detach().numpy()[0])
        reduced_solution[c] = reduced_solution_c
    return reduced_solution
Beispiel #14
0
 def solve_supremizer(self, solution):
     N_us = OnlineSizeDict(solution.N)  # create a copy
     del N_us["p"]
     kwargs = self._latest_solve_kwargs
     self._supremizer = OnlineFunction(N_us)
     try:
         assign(self._supremizer, self._supremizer_cache[
             self.mu, N_us,
             kwargs])  # **kwargs is not supported by __getitem__
     except KeyError:
         self._solve_supremizer(solution)
         self._supremizer_cache[self.mu, N_us,
                                kwargs] = copy(self._supremizer)
     return self._supremizer
Beispiel #15
0
 def solve_supremizer(self, solution):
     N_us = OnlineSizeDict(solution.N) # create a copy
     del N_us["p"]
     cache_key = self._supremizer_cache_key_from_N_and_kwargs(N_us)
     self._supremizer = OnlineFunction(N_us)
     if "RAM" in self.cache_config and cache_key in self._supremizer_cache:
         log(PROGRESS, "Loading reduced supremizer from cache")
         assign(self._supremizer, self._supremizer_cache[cache_key])
     else:
         log(PROGRESS, "Solving supremizer reduced problem")
         self._solve_supremizer(solution)
         if "RAM" in self.cache_config:
             self._supremizer_cache[cache_key] = copy(self._supremizer)
     return self._supremizer
Beispiel #16
0
 def _solve(self, N, **kwargs):
     EllipticCoerciveReducedProblem_DerivedClass._solve(
         self, N, **kwargs)
     if kwargs["online_rectification"]:
         q = self.online_solve_kwargs_with_rectification.index(kwargs)
         intermediate_solution = OnlineFunction(N)
         solver = LinearSolver(
             self.operator["projection_reduced_snapshots"][:N, :N][q],
             intermediate_solution, self._solution.vector())
         solver.set_parameters(self._linear_solver_parameters)
         solver.solve()
         self._solution.vector(
         )[:] = self.operator["projection_truth_snapshots"][:N, :N][
             0] * intermediate_solution
 def solve(self, N=None, **kwargs):
     N, kwargs = self._online_size_from_kwargs(N, **kwargs)
     N += self.N_bc
     self._latest_solve_kwargs = kwargs
     self._solution = OnlineFunction(N)
     self._solution_dot = OnlineFunction(N)
     if N == 0:  # trivial case
         time_interval = linspace(self.t0, self.T,
                                  (self.T - self.t0) / self.dt)
         self._solution_over_time = [
             self._solution for _ in time_interval
         ]
         self._solution_dot_over_time = [
             self._solution_dot for _ in time_interval
         ]
         return self._solution_over_time
     try:
         assign(self._solution_over_time,
                self._solution_over_time_cache[
                    self.mu, N,
                    kwargs])  # **kwargs is not supported by __getitem__
         assign(self._solution_dot_over_time,
                self._solution_dot_over_time_cache[self.mu, N, kwargs])
     except KeyError:
         assert not hasattr(self, "_is_solving")
         self._is_solving = True
         self._solve(N, **kwargs)
         delattr(self, "_is_solving")
         self._solution_over_time_cache[self.mu, N, kwargs] = copy(
             self._solution_over_time)
         self._solution_dot_over_time_cache[self.mu, N, kwargs] = copy(
             self._solution_dot_over_time)
     else:
         assign(self._solution, self._solution_over_time[-1])
         assign(self._solution_dot, self._solution_dot_over_time[-1])
     return self._solution_over_time
Beispiel #18
0
def plot(obj, *args, **kwargs):
    if isinstance(obj, OnlineFunction.Type()):
        assert "reduced_problem" in kwargs, "Please use this method as plot(reduced_solution, reduced_problem=my_reduced_problem) when plotting a reduced solution"
        N = obj.N
        reduced_problem = kwargs["reduced_problem"]
        del kwargs["reduced_problem"]
        basis_functions = reduced_problem.basis_functions[:N]
        truth_problem = reduced_problem.truth_problem
        obj = basis_functions * obj
    elif "truth_problem" in kwargs:
        truth_problem = kwargs["truth_problem"]
        del kwargs["truth_problem"]
    else:
        truth_problem = None
    if truth_problem is not None and hasattr(truth_problem, "mesh_motion"):
        truth_problem.mesh_motion.move_mesh()
    original_plot(obj, *args, **kwargs)
    if truth_problem is not None and hasattr(truth_problem, "mesh_motion"):
        truth_problem.mesh_motion.reset_reference()
 def _solve(self, N, **kwargs):
     # Temporarily change value of stabilized attribute in truth problem
     bak_stabilized = self.truth_problem.stabilized
     self.truth_problem.stabilized = kwargs["online_stabilization"]
     # Solve reduced problem
     if kwargs["online_vanishing_viscosity"]:
         assembled_operator = dict()
         assembled_operator["a"] = (
             sum(product(self.compute_theta("a"), self.operator["a"][:N, :N])) +
             self.operator["vanishing_viscosity"][:N, :N][0]
         )
         assembled_operator["f"] = sum(product(self.compute_theta("f"), self.operator["f"][:N]))
         self._solution = OnlineFunction(N)
         solver = LinearSolver(assembled_operator["a"], self._solution, assembled_operator["f"])
         solver.set_parameters(self._linear_solver_parameters)
         solver.solve()
     else:
         EllipticCoerciveReducedProblem_DerivedClass._solve(self, N, **kwargs)
     # Restore original value of stabilized attribute in truth problem
     self.truth_problem.stabilized = bak_stabilized
Beispiel #20
0
 def solve(self, N=None, **kwargs):
     """
     Perform an online solve. self.N will be used as matrix dimension if the default value is provided for N.
     
     :param N : Dimension of the reduced problem
     :type N : integer
     :return: reduced solution
     """
     N, kwargs = self._online_size_from_kwargs(N, **kwargs)
     N += self.N_bc
     cache_key = self._cache_key_from_N_and_kwargs(N, **kwargs)
     self._solution = OnlineFunction(N)
     if "RAM" in self.cache_config and cache_key in self._solution_cache:
         log(PROGRESS, "Loading reduced solution from cache")
         assign(self._solution, self._solution_cache[cache_key])
     else:
         log(PROGRESS, "Solving reduced problem")
         assert not hasattr(self, "_is_solving")
         self._is_solving = True
         self._solve(N, **kwargs)
         delattr(self, "_is_solving")
         if "RAM" in self.cache_config:
             self._solution_cache[cache_key] = copy(self._solution)
     return self._solution
Beispiel #21
0
def plot(obj, *args, **kwargs):
    if isinstance(obj, TimeSeries):
        is_time_series = True
    else:
        is_time_series = False
    if not is_time_series and isinstance(obj, OnlineFunction.Type()):
        is_truth_solution = False
    elif is_time_series and isinstance(obj[0], OnlineFunction.Type()):
        assert all(isinstance(obj_, OnlineFunction.Type()) for obj_ in obj)
        is_truth_solution = False
    else:
        is_truth_solution = True

    if is_time_series:
        if "every" in kwargs:
            obj = obj[::kwargs["every"]]
            del kwargs["every"]
        if "interval" in kwargs:
            anim_interval = kwargs["interval"]
            del kwargs["interval"]
        else:
            anim_interval = None

    if not is_truth_solution:
        assert "reduced_problem" in kwargs, (
            "Please use this method as plot(reduced_solution, reduced_problem=my_reduced_problem)"
            + " when plotting a reduced solution")
        if not is_time_series:
            N = obj.N
        else:
            N = obj[0].N
            assert all(obj_.N == N for obj_ in obj)
        reduced_problem = kwargs["reduced_problem"]
        del kwargs["reduced_problem"]
        basis_functions = reduced_problem.basis_functions[:N]
        truth_problem = reduced_problem.truth_problem
        if not is_time_series:
            obj = basis_functions * obj
        else:
            obj = [basis_functions * obj_ for obj_ in obj]
    elif "truth_problem" in kwargs:
        truth_problem = kwargs["truth_problem"]
        del kwargs["truth_problem"]
    else:
        truth_problem = None

    if "component" in kwargs:
        component = kwargs["component"]
        del kwargs["component"]
        if not is_time_series:
            obj = obj.sub(component)
        else:
            obj = [obj_.sub(component) for obj_ in obj]

    if truth_problem is not None and hasattr(truth_problem, "mesh_motion"):
        truth_problem.mesh_motion.move_mesh()

    if not is_time_series:
        output = original_plot(obj, *args, **kwargs)
    else:
        def animate(i):
            return original_plot(obj[i], *args, **kwargs).collections
        fig = plt.figure()
        output = matplotlib.animation.FuncAnimation(
            fig, animate, frames=len(obj), interval=anim_interval, repeat=False)
        try:
            from IPython.display import HTML
        except ImportError:
            pass
        else:
            output = HTML(output.to_html5_video())
            plt.close()

    if truth_problem is not None and hasattr(truth_problem, "mesh_motion"):
        truth_problem.mesh_motion.reset_reference()
    return output
Beispiel #22
0
 def assemble_operator(self, term, current_stage="online"):
     if term == "projection_truth_snapshots":
         assert current_stage in (
             "online", "offline_rectification_postprocessing")
         if current_stage == "online":  # load from file
             self.operator["projection_truth_snapshots"].load(
                 self.folder["reduced_operators"],
                 "projection_truth_snapshots")
             return self.operator["projection_truth_snapshots"]
         elif current_stage == "offline_rectification_postprocessing":
             assert len(
                 self.truth_problem.inner_product
             ) == 1  # the affine expansion storage contains only the inner product matrix
             inner_product = self.truth_problem.inner_product[0]
             for n in range(1, self.N + 1):
                 assert len(
                     self.inner_product
                 ) == 1  # the affine expansion storage contains only the inner product matrix
                 inner_product_n = self.inner_product[:n, :n][0]
                 basis_functions_n = self.basis_functions[:n]
                 projection_truth_snapshots_expansion = OnlineAffineExpansionStorage(
                     1)
                 projection_truth_snapshots = OnlineMatrix(n, n)
                 for (i, snapshot_i) in enumerate(self.snapshots[:n]):
                     projected_truth_snapshot_i = OnlineFunction(n)
                     solver = LinearSolver(
                         inner_product_n, projected_truth_snapshot_i,
                         transpose(basis_functions_n) * inner_product *
                         snapshot_i)
                     solver.set_parameters(
                         self._linear_solver_parameters)
                     solver.solve()
                     for j in range(n):
                         projection_truth_snapshots[
                             j,
                             i] = projected_truth_snapshot_i.vector()[j]
                 projection_truth_snapshots_expansion[
                     0] = projection_truth_snapshots
                 print("\tcondition number for n = " + str(n) + ": " +
                       str(cond(projection_truth_snapshots)))
                 self.operator[
                     "projection_truth_snapshots"][:n, :
                                                   n] = projection_truth_snapshots_expansion
             # Save
             self.operator["projection_truth_snapshots"].save(
                 self.folder["reduced_operators"],
                 "projection_truth_snapshots")
             return self.operator["projection_truth_snapshots"]
         else:
             raise ValueError("Invalid stage in assemble_operator().")
     elif term == "projection_reduced_snapshots":
         assert current_stage in (
             "online", "offline_rectification_postprocessing")
         if current_stage == "online":  # load from file
             self.operator["projection_reduced_snapshots"].load(
                 self.folder["reduced_operators"],
                 "projection_reduced_snapshots")
             return self.operator["projection_reduced_snapshots"]
         elif current_stage == "offline_rectification_postprocessing":
             # Backup mu
             bak_mu = self.mu
             # Prepare rectification for all possible online solve arguments
             for n in range(1, self.N + 1):
                 print("\tcondition number for n = " + str(n))
                 projection_reduced_snapshots_expansion = OnlineAffineExpansionStorage(
                     len(self.online_solve_kwargs_without_rectification)
                 )
                 for (q, online_solve_kwargs) in enumerate(
                         self.online_solve_kwargs_without_rectification
                 ):
                     projection_reduced_snapshots = OnlineMatrix(n, n)
                     for (i, mu_i) in enumerate(self.snapshots_mu[:n]):
                         self.set_mu(mu_i)
                         projected_reduced_snapshot_i = self.solve(
                             n, **online_solve_kwargs)
                         for j in range(n):
                             projection_reduced_snapshots[
                                 j,
                                 i] = projected_reduced_snapshot_i.vector(
                                 )[j]
                     projection_reduced_snapshots_expansion[
                         q] = projection_reduced_snapshots
                     print("\t\tonline solve options " + str(
                         dict(self.
                              online_solve_kwargs_with_rectification[q])
                     ) + ": " + str(cond(projection_reduced_snapshots)))
                 self.operator[
                     "projection_reduced_snapshots"][:n, :
                                                     n] = projection_reduced_snapshots_expansion
             # Save and restore previous mu
             self.set_mu(bak_mu)
             self.operator["projection_reduced_snapshots"].save(
                 self.folder["reduced_operators"],
                 "projection_reduced_snapshots")
             return self.operator["projection_reduced_snapshots"]
         else:
             raise ValueError("Invalid stage in assemble_operator().")
     else:
         return EllipticCoerciveReducedProblem_DerivedClass.assemble_operator(
             self, term, current_stage)