예제 #1
0
 def __mul__(self, function):
     log(PROGRESS, "Begin Z^T*A*v")
     output = online_backend.OnlineVector(
         self.basis_functions_matrix.
         _component_name_to_basis_component_length)
     matrix_times_function = wrapping.matrix_mul_vector(
         self.matrix, wrapping.function_to_vector(function))
     i = 0
     for component_name in self.basis_functions_matrix._components_name:
         for fun_i in self.basis_functions_matrix._components[
                 component_name]:
             output[i] = wrapping.vector_mul_vector(
                 wrapping.function_to_vector(fun_i),
                 matrix_times_function)
             i += 1
     log(PROGRESS, "End Z^T*A*v")
     # Assert consistency of private attributes storing the order of components and their basis length.
     assert output._component_name_to_basis_component_index == self._component_name_to_basis_component_index
     assert output._component_name_to_basis_component_length == self._component_name_to_basis_component_length
     # Return
     return output
예제 #2
0
 def solve(self, **kwargs):
     """
     Perform a truth solve in case no precomputed solution is imported.
     """
     (cache_key,
      cache_file) = self._cache_key_and_file_from_kwargs(**kwargs)
     if "RAM" in self.cache_config and cache_key in self._solution_cache:
         log(PROGRESS, "Loading truth solution from cache")
         assign(self._solution, self._solution_cache[cache_key])
     elif "Disk" in self.cache_config and self.import_solution(
             self.folder["cache"], cache_file):
         log(PROGRESS, "Loading truth solution from file")
         if "RAM" in self.cache_config:
             self._solution_cache[cache_key] = copy(self._solution)
     else:  # No precomputed solution available. Truth solve is performed.
         log(PROGRESS, "Solving truth problem")
         assert not hasattr(self, "_is_solving")
         self._is_solving = True
         assign(self._solution, Function(self.V))
         self._solve(**kwargs)
         delattr(self, "_is_solving")
         if "RAM" in self.cache_config:
             self._solution_cache[cache_key] = copy(self._solution)
         self.export_solution(
             self.folder["cache"], cache_file
         )  # Note that we export to file regardless of config options, because they may change across different runs
     return self._solution
 def solve_adjoint_supremizer(self, solution):
     (cache_key, cache_file) = self._supremizer_cache_key_and_file()
     if "RAM" in self.cache_config and cache_key in self._adjoint_supremizer_cache:
         log(PROGRESS, "Loading adjoint supremizer from cache")
         assign(self._adjoint_supremizer,
                self._adjoint_supremizer_cache[cache_key])
     elif "Disk" in self.cache_config and self.import_supremizer(
             self.folder["cache"],
             cache_file,
             self._adjoint_supremizer,
             component="r"):
         log(PROGRESS, "Loading adjoint supremizer from file")
         if "RAM" in self.cache_config:
             self._adjoint_supremizer_cache[cache_key] = copy(
                 self._adjoint_supremizer)
     else:  # No precomputed adjoint supremizer available. Truth adjoint supremizer solve is performed.
         log(PROGRESS, "Solving adjoint supremizer problem")
         self._solve_adjoint_supremizer(solution)
         if "RAM" in self.cache_config:
             self._adjoint_supremizer_cache[cache_key] = copy(
                 self._adjoint_supremizer)
         self.export_supremizer(
             self.folder["cache"],
             cache_file,
             self._adjoint_supremizer,
             component="r"
         )  # Note that we export to file regardless of config options, because they may change across different runs
     return self._adjoint_supremizer
예제 #4
0
 def compute_output(self):
     """
     
     :return: output evaluation.
     """
     cache_key = self._output_cache__current_cache_key
     assert (
         (cache_key in self._output_cache)
             ==
         (cache_key in self._output_over_time_cache)
     )
     if "RAM" in self.cache_config and cache_key in self._output_cache:
         log(PROGRESS, "Loading truth output from cache")
         self._output = self._output_cache[cache_key]
         self._output_over_time = self._output_over_time_cache[cache_key]
     else: # No precomputed output available. Truth output is performed.
         log(PROGRESS, "Computing truth output")
         self._compute_output()
         if "RAM" in self.cache_config:
             self._output_cache[cache_key] = self._output
             self._output_over_time_cache[cache_key] = self._output_over_time
     return self._output_over_time
예제 #5
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
예제 #6
0
 def solve(self, **kwargs):
     (cache_key, cache_file) = self._cache_key_and_file_from_kwargs(**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 truth 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])
     elif "Disk" in self.cache_config and (
         self.import_solution(self.folder["cache"], cache_file + "_solution", self._solution_over_time)
             and
         self.import_solution(self.folder["cache"], cache_file + "_solution_dot", self._solution_dot_over_time)
     ):
         log(PROGRESS, "Loading truth solution from file")
         assign(self._solution, self._solution_over_time[-1])
         assign(self._solution_dot, self._solution_dot_over_time[-1])
         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)
     else:
         log(PROGRESS, "Solving truth problem")
         assert not hasattr(self, "_is_solving")
         self._is_solving = True
         assign(self._solution, Function(self.V))
         assign(self._solution_dot, Function(self.V))
         self._solve(**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)
         # Note that we export to file regardless of config options, because they may change across different runs
         self.export_solution(self.folder["cache"], cache_file + "_solution", self._solution_over_time)
         self.export_solution(self.folder["cache"], cache_file + "_solution_dot", self._solution_dot_over_time)
     return self._solution_over_time
예제 #7
0
 def __getitem__(self, key):
     """
     Get key from either RAM or disk storage, if possible.
     """
     (args, kwargs, storage_key) = self._compute_storage_key(key)
     try:
         storage_value = self._storage[storage_key]
     except KeyError as key_error:
         if self._filename_generator is not None:
             storage_filename = self._filename_generator(*args, **kwargs)
             try:
                 self._storage[storage_key] = self._import(storage_filename)
             except OSError:
                 log(
                     PROGRESS, "Could not load key " + str(storage_key) +
                     " (corresponding to args = " + str(args) +
                     " and kwargs = " + str(kwargs) +
                     ") from cache or disk")
                 raise key_error
             else:
                 log(
                     PROGRESS, "Loaded key " + str(storage_key) +
                     " (corresponding to args = " + str(args) +
                     " and kwargs = " + str(kwargs) + ") from disk")
                 return self._storage[storage_key]
         else:
             log(
                 PROGRESS, "Could not load key " + str(storage_key) +
                 " (corresponding to args = " + str(args) +
                 " and kwargs = " + str(kwargs) + ") from cache")
             raise key_error
     else:
         log(
             PROGRESS, "Loaded key " + str(storage_key) +
             " (corresponding to args = " + str(args) + " and kwargs = " +
             str(kwargs) + ") from cache")
         return storage_value
예제 #8
0
    def get_stability_factor_upper_bound(self, N=None):
        if N is None:
            N = self.N
        (cache_key, cache_file) = self._cache_key_and_file(N)
        if "RAM" in self.cache_config and cache_key in self._alpha_UB_cache:
            log(PROGRESS, "Loading stability factor upper bound from cache")
            self._alpha_UB = self._alpha_UB_cache[cache_key]
        elif "Disk" in self.cache_config and self.import_stability_factor_upper_bound(
                self.folder["cache"], cache_file):
            log(PROGRESS, "Loading stability factor upper bound from file")
            if "RAM" in self.cache_config:
                self._alpha_UB_cache[cache_key] = self._alpha_UB
        else:
            log(PROGRESS,
                "Solving stability factor upper bound reduced problem")
            Q = self.truth_problem.Q["a"]
            UB_vectors = self.UB_vectors

            alpha_UB = None
            current_theta_a = self.truth_problem.compute_theta("a")

            for j in range(N):
                UB_vector = UB_vectors[j]

                # Compute the cost function for fixed omega
                obj = 0.
                for q in range(Q):
                    obj += UB_vector[q] * current_theta_a[q]

                if alpha_UB is None or obj < alpha_UB:
                    alpha_UB = obj

            assert alpha_UB is not None
            self._alpha_UB = alpha_UB
            if "RAM" in self.cache_config:
                self._alpha_UB_cache[cache_key] = alpha_UB
            self.export_stability_factor_upper_bound(
                self.folder["cache"], cache_file
            )  # Note that we export to file regardless of config options, because they may change across different runs
        return self._alpha_UB
 def solve(self):
     (cache_key, cache_file) = self._cache_key_and_file()
     assert (
         (cache_key in self._eigenvalue_cache)
             ==
         (cache_key in self._eigenvector_cache)
     )
     if "RAM" in self.cache_config and cache_key in self._eigenvalue_cache:
         log(PROGRESS, "Loading coercivity constant from cache")
         self._eigenvalue = self._eigenvalue_cache[cache_key]
         assign(self._eigenvector, self._eigenvector_cache[cache_key])
     elif "Disk" in self.cache_config and self.import_solution(self.folder["cache"], cache_file):
         log(PROGRESS, "Loading coercivity constant from file")
         if "RAM" in self.cache_config:
             self._eigenvalue_cache[cache_key] = self._eigenvalue
             self._eigenvector_cache[cache_key] = copy(self._eigenvector)
     else: # No precomputed solution available. Truth solve is performed.
         log(PROGRESS, "Solving coercivity constant eigenproblem")
         self._solve()
         if "RAM" in self.cache_config:
             self._eigenvalue_cache[cache_key] = self._eigenvalue
             self._eigenvector_cache[cache_key] = copy(self._eigenvector)
         self.export_solution(self.folder["cache"], cache_file) # Note that we export to file regardless of config options, because they may change across different runs
     return (self._eigenvalue, self._eigenvector)
예제 #10
0
 def _basic_expression_on_reduced_mesh(expression_wrapper, at):
     expression = expression_wrapper._expression
     expression_name = expression_wrapper.name()
     expression_problem = get_problem_from_parametrized_expression(expression_wrapper)
     reduced_space = at.get_reduced_function_space()
     reduced_mesh = at.get_reduced_mesh()
     mu = expression_problem.mu
     if hasattr(expression_problem, "set_time"):
         t = expression_problem.t
     else:
         t = None
     
     if (expression_name, reduced_mesh) not in expression_cache:
         visited = set()
         replacements = dict()
         truth_problems = list()
         truth_problem_to_components = { # outer dict index over time derivative
             0: dict(),
             1: dict()
         }
         truth_problem_to_exact_truth_problem = dict()
         truth_problem_to_reduced_mesh_solution = dict()
         truth_problem_to_reduced_mesh_solution_dot = dict()
         truth_problem_to_reduced_mesh_interpolator = { # outer dict index over time derivative
             0: dict(),
             1: dict()
         }
         reduced_problem_to_components = { # outer dict index over time derivative
             0: dict(),
             1: dict()
         }
         reduced_problem_to_reduced_mesh_solution = dict()
         reduced_problem_to_reduced_mesh_solution_dot = dict()
         reduced_problem_to_reduced_basis_functions = { # outer dict index over time derivative
             0: dict(),
             1: dict()
         }
         
         # Look for terminals on truth mesh
         for node in wrapping.expression_iterator(expression):
             if node in visited:
                 continue
             # ... problem solutions related to nonlinear terms
             elif wrapping.is_problem_solution_type(node):
                 node_is_problem_solution = wrapping.is_problem_solution(node)
                 node_is_problem_solution_dot = wrapping.is_problem_solution_dot(node)
                 if node_is_problem_solution or node_is_problem_solution_dot:
                     if node_is_problem_solution:
                         (preprocessed_node, component, truth_solution) = wrapping.solution_identify_component(node)
                         truth_problem = get_problem_from_solution(truth_solution)
                         # Time derivative key for components and interpolator dicts
                         time_derivative = 0
                     elif node_is_problem_solution_dot:
                         (preprocessed_node, component, truth_solution_dot) = wrapping.solution_dot_identify_component(node)
                         truth_problem = get_problem_from_solution_dot(truth_solution_dot)
                         # Time derivative key for components and interpolator dicts
                         time_derivative = 1
                     # Store truth problem
                     if truth_problem not in truth_problems:
                         truth_problems.append(truth_problem)
                     # Store the component
                     if truth_problem not in truth_problem_to_components[time_derivative]:
                         truth_problem_to_components[time_derivative][truth_problem] = list()
                     if component not in truth_problem_to_components[time_derivative][truth_problem]:
                         truth_problem_to_components[time_derivative][truth_problem].append(component)
                         # Get the function space corresponding to preprocessed_node on the reduced mesh
                         auxiliary_reduced_V = at.get_auxiliary_reduced_function_space(truth_problem, component)
                         # Define and store the replacement
                         assert preprocessed_node not in replacements # as it is related to a new truth solution component
                         replacements[preprocessed_node] = backend.Function(auxiliary_reduced_V)
                         if time_derivative is 0:
                             if truth_problem not in truth_problem_to_reduced_mesh_solution:
                                 truth_problem_to_reduced_mesh_solution[truth_problem] = list()
                             truth_problem_to_reduced_mesh_solution[truth_problem].append(replacements[preprocessed_node])
                         elif time_derivative is 1:
                             if truth_problem not in truth_problem_to_reduced_mesh_solution_dot:
                                 truth_problem_to_reduced_mesh_solution_dot[truth_problem] = list()
                             truth_problem_to_reduced_mesh_solution_dot[truth_problem].append(replacements[preprocessed_node])
                         # Get interpolator on reduced mesh
                         if truth_problem not in truth_problem_to_reduced_mesh_interpolator[time_derivative]:
                             truth_problem_to_reduced_mesh_interpolator[time_derivative][truth_problem] = list()
                         truth_problem_to_reduced_mesh_interpolator[time_derivative][truth_problem].append(at.get_auxiliary_function_interpolator(truth_problem, component))
                 else:
                     (preprocessed_node, component, auxiliary_problem) = wrapping.get_auxiliary_problem_for_non_parametrized_function(node)
                     if preprocessed_node not in replacements:
                         # Get interpolator on reduced mesh
                         auxiliary_truth_problem_to_reduced_mesh_interpolator = at.get_auxiliary_function_interpolator(auxiliary_problem, component)
                         # Define and store the replacement
                         replacements[preprocessed_node] = auxiliary_truth_problem_to_reduced_mesh_interpolator(preprocessed_node)
                 # Make sure to skip any parent solution related to this one
                 visited.add(node)
                 visited.add(preprocessed_node)
                 for parent_node in wrapping.solution_iterator(preprocessed_node):
                     visited.add(parent_node)
             # ... geometric quantities
             elif isinstance(node, GeometricQuantity):
                 replacements[node] = type(node)(reduced_mesh)
                 visited.add(node)
             else:
                 visited.add(node)
         # ... and replace them
         replaced_expression = wrapping.expression_replace(expression, replacements)
         
         # Cache the resulting dicts
         expression_cache[(expression_name, reduced_mesh)] = replaced_expression
         truth_problems_cache[(expression_name, reduced_mesh)] = truth_problems
         truth_problem_to_components_cache[(expression_name, reduced_mesh)] = truth_problem_to_components
         truth_problem_to_exact_truth_problem_cache[(expression_name, reduced_mesh)] = truth_problem_to_exact_truth_problem
         truth_problem_to_reduced_mesh_solution_cache[(expression_name, reduced_mesh)] = truth_problem_to_reduced_mesh_solution
         truth_problem_to_reduced_mesh_solution_dot_cache[(expression_name, reduced_mesh)] = truth_problem_to_reduced_mesh_solution_dot
         truth_problem_to_reduced_mesh_interpolator_cache[(expression_name, reduced_mesh)] = truth_problem_to_reduced_mesh_interpolator
         reduced_problem_to_components_cache[(expression_name, reduced_mesh)] = reduced_problem_to_components
         reduced_problem_to_reduced_mesh_solution_cache[(expression_name, reduced_mesh)] = reduced_problem_to_reduced_mesh_solution
         reduced_problem_to_reduced_mesh_solution_dot_cache[(expression_name, reduced_mesh)] = reduced_problem_to_reduced_mesh_solution_dot
         reduced_problem_to_reduced_basis_functions_cache[(expression_name, reduced_mesh)] = reduced_problem_to_reduced_basis_functions
         
     # Extract from cache
     replaced_expression = expression_cache[(expression_name, reduced_mesh)]
     truth_problems = truth_problems_cache[(expression_name, reduced_mesh)]
     truth_problem_to_components = truth_problem_to_components_cache[(expression_name, reduced_mesh)]
     truth_problem_to_exact_truth_problem = truth_problem_to_exact_truth_problem_cache[(expression_name, reduced_mesh)]
     truth_problem_to_reduced_mesh_solution = truth_problem_to_reduced_mesh_solution_cache[(expression_name, reduced_mesh)]
     truth_problem_to_reduced_mesh_solution_dot = truth_problem_to_reduced_mesh_solution_dot_cache[(expression_name, reduced_mesh)]
     truth_problem_to_reduced_mesh_interpolator = truth_problem_to_reduced_mesh_interpolator_cache[(expression_name, reduced_mesh)]
     reduced_problem_to_components = reduced_problem_to_components_cache[(expression_name, reduced_mesh)]
     reduced_problem_to_reduced_mesh_solution = reduced_problem_to_reduced_mesh_solution_cache[(expression_name, reduced_mesh)]
     reduced_problem_to_reduced_mesh_solution_dot = reduced_problem_to_reduced_mesh_solution_dot_cache[(expression_name, reduced_mesh)]
     reduced_problem_to_reduced_basis_functions = reduced_problem_to_reduced_basis_functions_cache[(expression_name, reduced_mesh)]
     
     # Get list of truth and reduced problems that need to be solved, possibly updating cache
     required_truth_problems = list()
     required_reduced_problems = list()
     for truth_problem in truth_problems:
         truth_problem_is_solving = hasattr(truth_problem, "_is_solving")
         if is_training_started(truth_problem):
             reduced_problem = get_reduced_problem_from_problem(truth_problem)
             reduced_problem_is_solving = hasattr(reduced_problem, "_is_solving")
         else:
             reduced_problem = None
             reduced_problem_is_solving = False
         if not truth_problem_is_solving:
             if is_training_finished(truth_problem):
                 # Store the replacement for solution
                 if (
                     reduced_problem not in reduced_problem_to_reduced_mesh_solution
                         and
                     truth_problem in truth_problem_to_reduced_mesh_solution
                 ):
                     reduced_problem_to_reduced_mesh_solution[reduced_problem] = truth_problem_to_reduced_mesh_solution[truth_problem]
                     # Store the component
                     assert reduced_problem not in reduced_problem_to_components[0]
                     assert truth_problem in truth_problem_to_components[0]
                     reduced_problem_to_components[0][reduced_problem] = truth_problem_to_components[0][truth_problem]
                     # Get reduced problem basis functions on reduced mesh
                     assert reduced_problem not in reduced_problem_to_reduced_basis_functions[0]
                     reduced_problem_to_reduced_basis_functions[0][reduced_problem] = [at.get_auxiliary_basis_functions_matrix(truth_problem, component) for component in reduced_problem_to_components[0][reduced_problem]]
                 # Store the replacement for solution_dot
                 if (
                     reduced_problem not in reduced_problem_to_reduced_mesh_solution_dot
                         and
                     truth_problem in truth_problem_to_reduced_mesh_solution_dot
                 ):
                     reduced_problem_to_reduced_mesh_solution_dot[reduced_problem] = truth_problem_to_reduced_mesh_solution_dot[truth_problem]
                     # Store the component
                     assert reduced_problem not in reduced_problem_to_components[1]
                     assert truth_problem in truth_problem_to_components[1]
                     reduced_problem_to_components[1][reduced_problem] = truth_problem_to_components[1][truth_problem]
                     # Get reduced problem basis functions on reduced mesh
                     assert reduced_problem not in reduced_problem_to_reduced_basis_functions[1]
                     reduced_problem_to_reduced_basis_functions[1][reduced_problem] = [at.get_auxiliary_basis_functions_matrix(truth_problem, component) for component in reduced_problem_to_components[1][reduced_problem]]
                 # Append to list of required reduced problems
                 required_reduced_problems.append((reduced_problem, reduced_problem_is_solving))
             else:
                 if (
                     hasattr(truth_problem, "_apply_exact_evaluation_at_stages")
                         and
                     not hasattr(truth_problem, "_apply_EIM_at_stages")
                         and
                     not hasattr(truth_problem, "_apply_DEIM_at_stages")
                 ):
                     # Init truth problem (if required), as it may not have been initialized
                     truth_problem.init()
                     # Append to list of required truth problems which are not currently solving
                     required_truth_problems.append((truth_problem, False, reduced_problem_is_solving))
                 else:
                     # Store the corresponding exact truth problem
                     if truth_problem not in truth_problem_to_exact_truth_problem:
                         exact_truth_problem = exact_problem(truth_problem)
                         truth_problem_to_exact_truth_problem[truth_problem] = exact_truth_problem
                         # Init exact truth problem (if required), as it may not have been initialized
                         exact_truth_problem.init()
                     else:
                         exact_truth_problem = truth_problem_to_exact_truth_problem[truth_problem]
                     # Store the replacement for solution
                     if (
                         exact_truth_problem not in truth_problem_to_reduced_mesh_solution
                             and
                         truth_problem in truth_problem_to_reduced_mesh_solution
                     ):
                         truth_problem_to_reduced_mesh_solution[exact_truth_problem] = truth_problem_to_reduced_mesh_solution[truth_problem]
                         # Store the component
                         assert exact_truth_problem not in truth_problem_to_components[0]
                         assert truth_problem in truth_problem_to_components[0]
                         truth_problem_to_components[0][exact_truth_problem] = truth_problem_to_components[0][truth_problem]
                         # Get interpolator on reduced mesh
                         assert exact_truth_problem not in truth_problem_to_reduced_mesh_interpolator[0]
                         assert truth_problem in truth_problem_to_reduced_mesh_interpolator[0]
                         truth_problem_to_reduced_mesh_interpolator[0][exact_truth_problem] = truth_problem_to_reduced_mesh_interpolator[0][truth_problem]
                     # Store the replacement for solution_dot
                     if (
                         exact_truth_problem not in truth_problem_to_reduced_mesh_solution_dot
                             and
                         truth_problem in truth_problem_to_reduced_mesh_solution_dot
                     ):
                         truth_problem_to_reduced_mesh_solution_dot[exact_truth_problem] = truth_problem_to_reduced_mesh_solution_dot[truth_problem]
                         # Store the component
                         assert exact_truth_problem not in truth_problem_to_components[1]
                         assert truth_problem in truth_problem_to_components[1]
                         truth_problem_to_components[1][exact_truth_problem] = truth_problem_to_components[1][truth_problem]
                         # Get interpolator on reduced mesh
                         assert exact_truth_problem not in truth_problem_to_reduced_mesh_interpolator[1]
                         assert truth_problem in truth_problem_to_reduced_mesh_interpolator[1]
                         truth_problem_to_reduced_mesh_interpolator[1][exact_truth_problem] = truth_problem_to_reduced_mesh_interpolator[1][truth_problem]
                     # Append to list of required truth problems which are not currently solving
                     required_truth_problems.append((exact_truth_problem, False, reduced_problem_is_solving))
         else:
             assert not reduced_problem_is_solving
             # Append to list of required truth problems which are currently solving
             required_truth_problems.append((truth_problem, True, False))
     
     # Solve truth problems (which have not been reduced yet) associated to nonlinear terms
     for (truth_problem, truth_problem_is_solving, reduced_problem_is_solving) in required_truth_problems:
         if not reduced_problem_is_solving:
             # Solve (if necessary)
             truth_problem.set_mu(mu)
             if not truth_problem_is_solving:
                 log(PROGRESS, "In expression_on_reduced_mesh, requiring truth problem solve for problem " + truth_problem.name())
                 truth_problem.solve()
             else:
                 log(PROGRESS, "In expression_on_reduced_mesh, loading current truth problem solution for problem " + truth_problem.name())
         else:
             reduced_problem = get_reduced_problem_from_problem(truth_problem)
             log(PROGRESS, "In expression_on_reduced_mesh, replacing current truth problem solution with reduced solution for problem " + reduced_problem.truth_problem.name())
         # Assign to reduced_mesh_solution
         if truth_problem in truth_problem_to_reduced_mesh_solution:
             for (reduced_mesh_solution, reduced_mesh_interpolator) in zip(truth_problem_to_reduced_mesh_solution[truth_problem], truth_problem_to_reduced_mesh_interpolator[0][truth_problem]):
                 solution_to = reduced_mesh_solution
                 if t is None:
                     if not reduced_problem_is_solving:
                         solution_from = reduced_mesh_interpolator(truth_problem._solution)
                     else:
                         solution_from = reduced_mesh_interpolator(reduced_problem.basis_functions[:reduced_problem._solution.N]*reduced_problem._solution)
                 else:
                     if not reduced_problem_is_solving:
                         if not truth_problem_is_solving:
                             solution_from = reduced_mesh_interpolator(truth_problem._solution_over_time.at(t))
                         else:
                             solution_from = reduced_mesh_interpolator(truth_problem._solution)
                     else:
                         solution_from = reduced_mesh_interpolator(reduced_problem.basis_functions[:reduced_problem._solution.N]*reduced_problem._solution)
                 backend.assign(solution_to, solution_from)
         # Assign to reduced_mesh_solution_dot
         if truth_problem in truth_problem_to_reduced_mesh_solution_dot:
             for (reduced_mesh_solution_dot, reduced_mesh_interpolator) in zip(truth_problem_to_reduced_mesh_solution_dot[truth_problem], truth_problem_to_reduced_mesh_interpolator[1][truth_problem]):
                 solution_dot_to = reduced_mesh_solution_dot
                 assert t is not None
                 if not reduced_problem_is_solving:
                     if not truth_problem_is_solving:
                         solution_dot_from = reduced_mesh_interpolator(truth_problem._solution_dot_over_time.at(t))
                     else:
                         solution_dot_from = reduced_mesh_interpolator(truth_problem._solution_dot)
                 else:
                     solution_dot_from = reduced_mesh_interpolator(reduced_problem.basis_functions[:reduced_problem._solution_dot.N]*reduced_problem._solution_dot)
                 backend.assign(solution_dot_to, solution_dot_from)
     
     # Solve reduced problems associated to nonlinear terms
     for (reduced_problem, is_solving) in required_reduced_problems:
         # Solve (if necessary)
         reduced_problem.set_mu(mu)
         if not is_solving:
             log(PROGRESS, "In expression_on_reduced_mesh, requiring reduced problem solve for problem " + reduced_problem.truth_problem.name())
             reduced_problem.solve()
         else:
             log(PROGRESS, "In expression_on_reduced_mesh, loading current reduced problem solution for problem " + reduced_problem.truth_problem.name())
         # Assign to reduced_mesh_solution
         if reduced_problem in reduced_problem_to_reduced_mesh_solution:
             for (reduced_mesh_solution, reduced_basis_functions) in zip(reduced_problem_to_reduced_mesh_solution[reduced_problem], reduced_problem_to_reduced_basis_functions[0][reduced_problem]):
                 solution_to = reduced_mesh_solution
                 solution_from_N = OnlineSizeDict()
                 for c, v in reduced_problem._solution.N.items():
                     if c in reduced_basis_functions._components_name:
                         solution_from_N[c] = v
                 solution_from = online_backend.OnlineFunction(solution_from_N)
                 if t is None or is_solving:
                     online_backend.online_assign(solution_from, reduced_problem._solution)
                 else:
                     online_backend.online_assign(solution_from, reduced_problem._solution_over_time.at(t))
                 solution_from = reduced_basis_functions[:solution_from_N]*solution_from
                 backend.assign(solution_to, solution_from)
         # Assign to reduced_mesh_solution_dot
         if reduced_problem in reduced_problem_to_reduced_mesh_solution_dot:
             for (reduced_mesh_solution_dot, reduced_basis_functions) in zip(reduced_problem_to_reduced_mesh_solution_dot[reduced_problem], reduced_problem_to_reduced_basis_functions[1][reduced_problem]):
                 solution_dot_to = reduced_mesh_solution_dot
                 solution_dot_from_N = OnlineSizeDict()
                 for c, v in reduced_problem._solution_dot.N.items():
                     if c in reduced_basis_functions._components_name:
                         solution_dot_from_N[c] = v
                 solution_dot_from = online_backend.OnlineFunction(solution_dot_from_N)
                 assert t is not None
                 if is_solving:
                     online_backend.online_assign(solution_dot_from, reduced_problem._solution_dot)
                 else:
                     online_backend.online_assign(solution_dot_from, reduced_problem._solution_dot_over_time.at(t))
                 solution_dot_from = reduced_basis_functions[:solution_dot_from_N]*solution_dot_from
                 backend.assign(solution_dot_to, solution_dot_from)
     
     # Evaluate and return
     reduced_function = backend.Function(reduced_space)
     wrapping.evaluate_expression(expression, reduced_function, replaced_expression)
     return reduced_function
예제 #11
0
 def __mul__(self, other_vector):
     log(PROGRESS, "Begin v^T w")
     output = wrapping.vector_mul_vector(self.vector, other_vector)
     log(PROGRESS, "End v^T w")
     return output
예제 #12
0
 def __mul__(self, function):
     log(PROGRESS, "Begin v^T w")
     output = wrapping.vector_mul_vector(
         self.vector, wrapping.function_to_vector(function))
     log(PROGRESS, "End v^T w")
     return output
예제 #13
0
    def _basic_form_on_truth_function_space(form_wrapper, tensor=None):
        form = form_wrapper._form
        form_name = form_wrapper.name()
        mu = get_problem_from_parametrized_operator(form_wrapper).mu

        if form_name not in form_on_truth_function_space__reduced_problem_to_truth_solution_cache:
            visited = set()
            truth_problems = list()
            truth_problem_to_components = dict()
            truth_problem_to_exact_truth_problem = dict()
            truth_problem_to_truth_solution = dict()
            reduced_problem_to_components = dict()
            reduced_problem_to_truth_solution = dict()

            # Look for terminals on truth mesh
            for node in wrapping.form_iterator(form):
                if node in visited:
                    continue
                # ... problem solutions related to nonlinear terms
                elif wrapping.is_problem_solution_or_problem_solution_component_type(
                        node):
                    if wrapping.is_problem_solution_or_problem_solution_component(
                            node):
                        (preprocessed_node, component, truth_solution
                         ) = wrapping.solution_identify_component(node)
                        truth_problem = get_problem_from_solution(
                            truth_solution)
                        truth_problems.append(truth_problem)
                        # Store the solution
                        truth_problem_to_truth_solution[
                            truth_problem] = truth_solution
                        # Store the component
                        if truth_problem not in truth_problem_to_components:
                            truth_problem_to_components[truth_problem] = list()
                        truth_problem_to_components[truth_problem].append(
                            component)
                    else:
                        preprocessed_node = node
                    # Make sure to skip any parent solution related to this one
                    visited.add(node)
                    visited.add(preprocessed_node)
                    for parent_node in wrapping.solution_iterator(
                            preprocessed_node):
                        visited.add(parent_node)

            # Cache the resulting dicts
            form_on_truth_function_space__truth_problems_cache[
                form_name] = truth_problems
            form_on_truth_function_space__truth_problem_to_components_cache[
                form_name] = truth_problem_to_components
            form_on_truth_function_space__truth_problem_to_exact_truth_problem_cache[
                form_name] = truth_problem_to_exact_truth_problem
            form_on_truth_function_space__truth_problem_to_truth_solution_cache[
                form_name] = truth_problem_to_truth_solution
            form_on_truth_function_space__reduced_problem_to_components_cache[
                form_name] = reduced_problem_to_components
            form_on_truth_function_space__reduced_problem_to_truth_solution_cache[
                form_name] = reduced_problem_to_truth_solution

        # Extract from cache
        truth_problems = form_on_truth_function_space__truth_problems_cache[
            form_name]
        truth_problem_to_components = form_on_truth_function_space__truth_problem_to_components_cache[
            form_name]
        truth_problem_to_exact_truth_problem = form_on_truth_function_space__truth_problem_to_exact_truth_problem_cache[
            form_name]
        truth_problem_to_truth_solution = form_on_truth_function_space__truth_problem_to_truth_solution_cache[
            form_name]
        reduced_problem_to_components = form_on_truth_function_space__reduced_problem_to_components_cache[
            form_name]
        reduced_problem_to_truth_solution = form_on_truth_function_space__reduced_problem_to_truth_solution_cache[
            form_name]

        # Get list of truth and reduced problems that need to be solved, possibly updating cache
        required_truth_problems = list()
        required_reduced_problems = list()
        for truth_problem in truth_problems:
            truth_problem_is_solving = hasattr(truth_problem, "_is_solving")
            if is_training_started(truth_problem):
                reduced_problem = get_reduced_problem_from_problem(
                    truth_problem)
                reduced_problem_is_solving = hasattr(reduced_problem,
                                                     "_is_solving")
            else:
                reduced_problem = None
                reduced_problem_is_solving = False
            if not truth_problem_is_solving:
                if is_training_finished(truth_problem):
                    # Store the component
                    if reduced_problem not in reduced_problem_to_components:
                        reduced_problem_to_components[
                            reduced_problem] = truth_problem_to_components[
                                truth_problem]
                    # Store the solution
                    if reduced_problem not in reduced_problem_to_truth_solution:
                        reduced_problem_to_truth_solution[
                            reduced_problem] = truth_problem_to_truth_solution[
                                truth_problem]
                    # Append to list of required reduced problems
                    required_reduced_problems.append(
                        (reduced_problem, reduced_problem_is_solving))
                else:
                    if (hasattr(truth_problem,
                                "_apply_exact_evaluation_at_stages") and
                            not hasattr(truth_problem, "_apply_EIM_at_stages")
                            and not hasattr(truth_problem,
                                            "_apply_DEIM_at_stages")):
                        # Init truth problem (if required), as it may not have been initialized
                        truth_problem.init()
                        # Append to list of required truth problems which are not currently solving
                        required_truth_problems.append(
                            (truth_problem, False, reduced_problem_is_solving))
                    else:
                        # Store the corresponding exact truth problem
                        if truth_problem not in truth_problem_to_exact_truth_problem:
                            exact_truth_problem = exact_problem(truth_problem)
                            truth_problem_to_exact_truth_problem[
                                truth_problem] = exact_truth_problem
                            # Init exact truth problem (if required), as it may not have been initialized
                            exact_truth_problem.init()
                        else:
                            exact_truth_problem = truth_problem_to_exact_truth_problem[
                                truth_problem]
                        # Store the component
                        if exact_truth_problem not in truth_problem_to_components:
                            truth_problem_to_components[
                                exact_truth_problem] = truth_problem_to_components[
                                    truth_problem]
                        # Store the solution
                        if exact_truth_problem not in truth_problem_to_truth_solution:
                            truth_problem_to_truth_solution[
                                exact_truth_problem] = truth_problem_to_truth_solution[
                                    truth_problem]
                        # Append to list of required truth problems which are not currently solving
                        required_truth_problems.append(
                            (exact_truth_problem, False,
                             reduced_problem_is_solving))
            else:
                assert not reduced_problem_is_solving
                # Append to list of required truth problems which are currently solving
                required_truth_problems.append((truth_problem, True, False))

        # Solve truth problems (which have not been reduced yet) associated to nonlinear terms
        truth_problem_to_truth_solution_copy = dict()
        for (truth_problem, truth_problem_is_solving,
             reduced_problem_is_solving) in required_truth_problems:
            if not reduced_problem_is_solving:
                # Solve (if necessary) ...
                truth_problem.set_mu(mu)
                if not truth_problem_is_solving:
                    log(
                        PROGRESS,
                        "In form_on_truth_function_space, requiring truth problem solve for problem "
                        + truth_problem.name())
                    truth_problem.solve()
                else:
                    log(
                        PROGRESS,
                        "In form_on_truth_function_space, loading current truth problem solution for problem "
                        + truth_problem.name())
            else:
                reduced_problem = get_reduced_problem_from_problem(
                    truth_problem)
                log(
                    PROGRESS,
                    "In form_on_truth_function_space, replacing current truth problem solution with reduced solution for problem "
                    + reduced_problem.truth_problem.name())
            # ... and assign to truth_solution
            truth_solution = truth_problem_to_truth_solution[truth_problem]
            truth_problem_to_truth_solution_copy[truth_problem] = backend.copy(
                truth_solution)
            for component in truth_problem_to_components[truth_problem]:
                solution_to = _sub_from_tuple(truth_solution, component)
                if not reduced_problem_is_solving:
                    solution_from = _sub_from_tuple(truth_problem._solution,
                                                    component)
                else:
                    solution_from = _sub_from_tuple(
                        reduced_problem.basis_functions[:reduced_problem.
                                                        _solution.N] *
                        reduced_problem._solution, component)
                backend.assign(solution_to, solution_from)

        # Solve reduced problems associated to nonlinear terms
        reduced_problem_to_truth_solution_copy = dict()
        for (reduced_problem, is_solving) in required_reduced_problems:
            # Solve (if necessary) ...
            reduced_problem.set_mu(mu)
            if not is_solving:
                log(
                    PROGRESS,
                    "In form_on_truth_function_space, requiring reduced problem solve for problem "
                    + reduced_problem.truth_problem.name())
                reduced_problem.solve()
            else:
                log(
                    PROGRESS,
                    "In form_on_truth_function_space, loading current reduced problem solution for problem "
                    + reduced_problem.truth_problem.name())
            # ... and assign to truth_solution
            truth_solution = reduced_problem_to_truth_solution[reduced_problem]
            reduced_problem_to_truth_solution_copy[
                reduced_problem] = backend.copy(truth_solution)
            for component in reduced_problem_to_components[reduced_problem]:
                solution_to = _sub_from_tuple(truth_solution, component)
                solution_from = _sub_from_tuple(
                    reduced_problem.basis_functions[:reduced_problem._solution.
                                                    N] *
                    reduced_problem._solution, component)
                backend.assign(solution_to, solution_from)

        # Assemble
        assembled_form = wrapping.assemble(form, tensor)
        assembled_form.generator = form_wrapper  # for I/O
        form_rank = assembled_form.rank()

        # Undo any side effect of truth problem solves
        for (truth_problem, _, _) in required_truth_problems:
            truth_solution = truth_problem_to_truth_solution[truth_problem]
            truth_solution_copy = truth_problem_to_truth_solution_copy[
                truth_problem]
            for component in truth_problem_to_components[truth_problem]:
                solution_to = _sub_from_tuple(truth_solution, component)
                solution_from = _sub_from_tuple(truth_solution_copy, component)
                backend.assign(solution_to, solution_from)

        # Undo any side effect of reduced problem solves
        for (reduced_problem, _) in required_reduced_problems:
            truth_solution = reduced_problem_to_truth_solution[reduced_problem]
            truth_solution_copy = reduced_problem_to_truth_solution_copy[
                reduced_problem]
            for component in reduced_problem_to_components[reduced_problem]:
                solution_to = _sub_from_tuple(truth_solution, component)
                solution_from = _sub_from_tuple(truth_solution_copy, component)
                backend.assign(solution_to, solution_from)

        # Return
        return (assembled_form, form_rank)
예제 #14
0
    def _basic_form_on_truth_function_space(form_wrapper, tensor=None):
        form = form_wrapper._form
        form_name = form_wrapper.name()
        form_problem = get_problem_from_parametrized_operator(form_wrapper)
        mu = form_problem.mu
        if hasattr(form_problem, "set_time"):
            t = form_problem.t
        else:
            t = None

        if form_name not in reduced_problem_to_truth_solution_cache:
            visited = set()
            truth_problems = list()
            truth_problem_to_components = {  # outer dict index over time derivative
                0: dict(),
                1: dict()
            }
            truth_problem_to_exact_truth_problem = dict()
            truth_problem_to_truth_solution = dict()
            truth_problem_to_truth_solution_copy = dict()
            truth_problem_to_truth_solution_dot = dict()
            truth_problem_to_truth_solution_dot_copy = dict()
            reduced_problem_to_components = {  # outer dict index over time derivative
                0: dict(),
                1: dict()
            }
            reduced_problem_to_truth_solution = dict()
            reduced_problem_to_truth_solution_copy = dict()
            reduced_problem_to_truth_solution_dot = dict()
            reduced_problem_to_truth_solution_dot_copy = dict()

            # Look for terminals on truth mesh
            for node in wrapping.form_iterator(form):
                if node in visited:
                    continue
                # ... problem solutions related to nonlinear terms
                elif wrapping.is_problem_solution_type(node):
                    node_is_problem_solution = wrapping.is_problem_solution(
                        node)
                    node_is_problem_solution_dot = wrapping.is_problem_solution_dot(
                        node)
                    if node_is_problem_solution or node_is_problem_solution_dot:
                        if node_is_problem_solution:
                            (preprocessed_node, component, truth_solution
                             ) = wrapping.solution_identify_component(node)
                            truth_problem = get_problem_from_solution(
                                truth_solution)
                            if truth_problem not in truth_problems:
                                truth_problems.append(truth_problem)
                            # Store the solution
                            if truth_problem not in truth_problem_to_truth_solution:
                                truth_problem_to_truth_solution[
                                    truth_problem] = truth_solution
                                truth_problem_to_truth_solution_copy[
                                    truth_problem] = backend.copy(
                                        truth_solution)
                            else:
                                assert truth_problem_to_truth_solution[
                                    truth_problem] is truth_solution
                                assert truth_problem in truth_problem_to_truth_solution_copy
                            # Time derivative key for components dict
                            time_derivative = 0
                        elif node_is_problem_solution_dot:
                            (preprocessed_node, component, truth_solution_dot
                             ) = wrapping.solution_dot_identify_component(node)
                            truth_problem = get_problem_from_solution_dot(
                                truth_solution_dot)
                            if truth_problem not in truth_problems:
                                truth_problems.append(truth_problem)
                            # Store the solution_dot
                            if truth_problem not in truth_problem_to_truth_solution_dot:
                                truth_problem_to_truth_solution_dot[
                                    truth_problem] = truth_solution_dot
                                truth_problem_to_truth_solution_dot_copy[
                                    truth_problem] = backend.copy(
                                        truth_solution_dot)
                            else:
                                assert truth_problem_to_truth_solution_dot[
                                    truth_problem] is truth_solution_dot
                                assert truth_problem in truth_problem_to_truth_solution_dot_copy
                            # Time derivative key for components dict
                            time_derivative = 1
                        # Store truth problem
                        if truth_problem not in truth_problems:
                            truth_problems.append(truth_problem)
                        # Store the component
                        if truth_problem not in truth_problem_to_components[
                                time_derivative]:
                            truth_problem_to_components[time_derivative][
                                truth_problem] = list()
                        if component not in truth_problem_to_components[
                                time_derivative][truth_problem]:
                            truth_problem_to_components[time_derivative][
                                truth_problem].append(component)
                    else:
                        (
                            preprocessed_node, _, _
                        ) = wrapping.get_auxiliary_problem_for_non_parametrized_function(
                            node)
                    # Make sure to skip any parent solution related to this one
                    visited.add(node)
                    visited.add(preprocessed_node)
                    for parent_node in wrapping.solution_iterator(
                            preprocessed_node):
                        visited.add(parent_node)
                else:
                    visited.add(node)

            # Cache the resulting dicts
            truth_problems_cache[form_name] = truth_problems
            truth_problem_to_components_cache[
                form_name] = truth_problem_to_components
            truth_problem_to_exact_truth_problem_cache[
                form_name] = truth_problem_to_exact_truth_problem
            truth_problem_to_truth_solution_cache[
                form_name] = truth_problem_to_truth_solution
            truth_problem_to_truth_solution_copy_cache[
                form_name] = truth_problem_to_truth_solution_copy
            truth_problem_to_truth_solution_dot_cache[
                form_name] = truth_problem_to_truth_solution_dot
            truth_problem_to_truth_solution_dot_copy_cache[
                form_name] = truth_problem_to_truth_solution_dot_copy
            reduced_problem_to_components_cache[
                form_name] = reduced_problem_to_components
            reduced_problem_to_truth_solution_cache[
                form_name] = reduced_problem_to_truth_solution
            reduced_problem_to_truth_solution_copy_cache[
                form_name] = reduced_problem_to_truth_solution_copy
            reduced_problem_to_truth_solution_dot_cache[
                form_name] = reduced_problem_to_truth_solution_dot
            reduced_problem_to_truth_solution_dot_copy_cache[
                form_name] = reduced_problem_to_truth_solution_dot_copy

        # Extract from cache
        truth_problems = truth_problems_cache[form_name]
        truth_problem_to_components = truth_problem_to_components_cache[
            form_name]
        truth_problem_to_exact_truth_problem = truth_problem_to_exact_truth_problem_cache[
            form_name]
        truth_problem_to_truth_solution = truth_problem_to_truth_solution_cache[
            form_name]
        truth_problem_to_truth_solution_copy = truth_problem_to_truth_solution_copy_cache[
            form_name]
        truth_problem_to_truth_solution_dot = truth_problem_to_truth_solution_dot_cache[
            form_name]
        truth_problem_to_truth_solution_dot_copy = truth_problem_to_truth_solution_dot_copy_cache[
            form_name]
        reduced_problem_to_components = reduced_problem_to_components_cache[
            form_name]
        reduced_problem_to_truth_solution = reduced_problem_to_truth_solution_cache[
            form_name]
        reduced_problem_to_truth_solution_copy = reduced_problem_to_truth_solution_copy_cache[
            form_name]
        reduced_problem_to_truth_solution_dot = reduced_problem_to_truth_solution_dot_cache[
            form_name]
        reduced_problem_to_truth_solution_dot_copy = reduced_problem_to_truth_solution_dot_copy_cache[
            form_name]

        # Get list of truth and reduced problems that need to be solved, possibly updating cache
        required_truth_problems = list()
        required_reduced_problems = list()
        for truth_problem in truth_problems:
            truth_problem_is_solving = hasattr(truth_problem, "_is_solving")
            if is_training_started(truth_problem):
                reduced_problem = get_reduced_problem_from_problem(
                    truth_problem)
                reduced_problem_is_solving = hasattr(reduced_problem,
                                                     "_is_solving")
            else:
                reduced_problem = None
                reduced_problem_is_solving = False
            if not truth_problem_is_solving:
                if is_training_finished(truth_problem):
                    # Store the solution
                    if (reduced_problem
                            not in reduced_problem_to_truth_solution and
                            truth_problem in truth_problem_to_truth_solution):
                        reduced_problem_to_truth_solution[
                            reduced_problem] = truth_problem_to_truth_solution[
                                truth_problem]
                        assert reduced_problem not in reduced_problem_to_truth_solution_copy
                        assert truth_problem in truth_problem_to_truth_solution_copy
                        reduced_problem_to_truth_solution_copy[
                            reduced_problem] = truth_problem_to_truth_solution_copy[
                                truth_problem]
                        # Store the component
                        assert reduced_problem not in reduced_problem_to_components
                        assert truth_problem in truth_problem_to_components[0]
                        reduced_problem_to_components[0][
                            reduced_problem] = truth_problem_to_components[0][
                                truth_problem]
                    # Store the solution_dot
                    if (reduced_problem
                            not in reduced_problem_to_truth_solution_dot
                            and truth_problem
                            in truth_problem_to_truth_solution_dot):
                        reduced_problem_to_truth_solution_dot[
                            reduced_problem] = truth_problem_to_truth_solution_dot[
                                truth_problem]
                        assert reduced_problem not in reduced_problem_to_truth_solution_dot_copy
                        assert truth_problem in truth_problem_to_truth_solution_dot_copy
                        reduced_problem_to_truth_solution_dot_copy[
                            reduced_problem] = truth_problem_to_truth_solution_dot_copy[
                                truth_problem]
                        # Store the component
                        assert reduced_problem not in reduced_problem_to_components
                        assert truth_problem in truth_problem_to_components[1]
                        reduced_problem_to_components[1][
                            reduced_problem] = truth_problem_to_components[1][
                                truth_problem]
                    # Append to list of required reduced problems
                    required_reduced_problems.append(
                        (reduced_problem, reduced_problem_is_solving))
                else:
                    if (hasattr(truth_problem,
                                "_apply_exact_evaluation_at_stages") and
                            not hasattr(truth_problem, "_apply_EIM_at_stages")
                            and not hasattr(truth_problem,
                                            "_apply_DEIM_at_stages")):
                        # Init truth problem (if required), as it may not have been initialized
                        truth_problem.init()
                        # Append to list of required truth problems which are not currently solving
                        required_truth_problems.append(
                            (truth_problem, False, reduced_problem_is_solving))
                    else:
                        # Store the corresponding exact truth problem
                        if truth_problem not in truth_problem_to_exact_truth_problem:
                            exact_truth_problem = exact_problem(truth_problem)
                            truth_problem_to_exact_truth_problem[
                                truth_problem] = exact_truth_problem
                            # Init exact truth problem (if required), as it may not have been initialized
                            exact_truth_problem.init()
                        else:
                            exact_truth_problem = truth_problem_to_exact_truth_problem[
                                truth_problem]
                        # Store the solution
                        if (exact_truth_problem
                                not in truth_problem_to_truth_solution
                                and truth_problem
                                in truth_problem_to_truth_solution):
                            truth_problem_to_truth_solution[
                                exact_truth_problem] = truth_problem_to_truth_solution[
                                    truth_problem]
                            assert exact_truth_problem not in truth_problem_to_truth_solution_copy
                            assert truth_problem in truth_problem_to_truth_solution_copy
                            truth_problem_to_truth_solution_copy[
                                exact_truth_problem] = truth_problem_to_truth_solution_copy[
                                    truth_problem]
                            # Store the component
                            assert exact_truth_problem not in truth_problem_to_components[
                                0]
                            assert truth_problem in truth_problem_to_components[
                                0]
                            truth_problem_to_components[0][
                                exact_truth_problem] = truth_problem_to_components[
                                    0][truth_problem]
                        # Store the solution_dot
                        if (exact_truth_problem
                                not in truth_problem_to_truth_solution_dot
                                and truth_problem
                                in truth_problem_to_truth_solution_dot):
                            truth_problem_to_truth_solution_dot[
                                exact_truth_problem] = truth_problem_to_truth_solution_dot[
                                    truth_problem]
                            assert exact_truth_problem not in truth_problem_to_truth_solution_dot_copy
                            assert truth_problem in truth_problem_to_truth_solution_dot_copy
                            truth_problem_to_truth_solution_dot_copy[
                                exact_truth_problem] = truth_problem_to_truth_solution_dot_copy[
                                    truth_problem]
                            # Store the component
                            assert exact_truth_problem not in truth_problem_to_components[
                                1]
                            assert truth_problem in truth_problem_to_components[
                                1]
                            truth_problem_to_components[1][
                                exact_truth_problem] = truth_problem_to_components[
                                    1][truth_problem]
                        # Append to list of required truth problems which are not currently solving
                        required_truth_problems.append(
                            (exact_truth_problem, False,
                             reduced_problem_is_solving))
            else:
                assert not reduced_problem_is_solving
                # Append to list of required truth problems which are currently solving
                required_truth_problems.append((truth_problem, True, False))

        # Solve truth problems (which have not been reduced yet) associated to nonlinear terms
        for (truth_problem, truth_problem_is_solving,
             reduced_problem_is_solving) in required_truth_problems:
            if not reduced_problem_is_solving:
                # Solve (if necessary)
                truth_problem.set_mu(mu)
                if not truth_problem_is_solving:
                    log(
                        PROGRESS,
                        "In form_on_truth_function_space, requiring truth problem solve for problem "
                        + truth_problem.name())
                    truth_problem.solve()
                else:
                    log(
                        PROGRESS,
                        "In form_on_truth_function_space, loading current truth problem solution for problem "
                        + truth_problem.name())
            else:
                reduced_problem = get_reduced_problem_from_problem(
                    truth_problem)
                log(
                    PROGRESS,
                    "In form_on_truth_function_space, replacing current truth problem solution with reduced solution for problem "
                    + reduced_problem.truth_problem.name())
            # Assign to truth_solution
            if truth_problem in truth_problem_to_truth_solution:
                truth_solution = truth_problem_to_truth_solution[truth_problem]
                backend.assign(
                    truth_problem_to_truth_solution_copy[truth_problem],
                    truth_solution)
                for component in truth_problem_to_components[0][truth_problem]:
                    solution_to = _sub_from_tuple(truth_solution, component)
                    if t is None:
                        if not reduced_problem_is_solving:
                            solution_from = _sub_from_tuple(
                                truth_problem._solution, component)
                        else:
                            solution_from = _sub_from_tuple(
                                reduced_problem.
                                basis_functions[:reduced_problem._solution.N] *
                                reduced_problem._solution, component)
                    else:
                        if not reduced_problem_is_solving:
                            if not truth_problem_is_solving:
                                solution_from = _sub_from_tuple(
                                    truth_problem._solution_over_time.at(t),
                                    component)
                            else:
                                solution_from = _sub_from_tuple(
                                    truth_problem._solution, component)
                        else:
                            solution_from = _sub_from_tuple(
                                reduced_problem.
                                basis_functions[:reduced_problem._solution.N] *
                                reduced_problem._solution, component)
                    backend.assign(solution_to, solution_from)
            # Assign to truth_solution_dot
            if truth_problem in truth_problem_to_truth_solution_dot:
                truth_solution_dot = truth_problem_to_truth_solution_dot[
                    truth_problem]
                backend.assign(
                    truth_problem_to_truth_solution_dot_copy[truth_problem],
                    truth_solution_dot)
                for component in truth_problem_to_components[1][truth_problem]:
                    solution_dot_to = _sub_from_tuple(truth_solution_dot,
                                                      component)
                    assert t is not None
                    if not reduced_problem_is_solving:
                        if not truth_problem_is_solving:
                            solution_dot_from = _sub_from_tuple(
                                truth_problem._solution_dot_over_time.at(t),
                                component)
                        else:
                            solution_dot_from = _sub_from_tuple(
                                truth_problem._solution_dot, component)
                    else:
                        solution_dot_from = _sub_from_tuple(
                            reduced_problem.basis_functions[:reduced_problem.
                                                            _solution_dot.N] *
                            reduced_problem._solution_dot, component)
                    backend.assign(solution_dot_to, solution_dot_from)

        # Solve reduced problems associated to nonlinear terms
        for (reduced_problem, is_solving) in required_reduced_problems:
            # Solve (if necessary)
            reduced_problem.set_mu(mu)
            if not is_solving:
                log(
                    PROGRESS,
                    "In form_on_truth_function_space, requiring reduced problem solve for problem "
                    + reduced_problem.truth_problem.name())
                reduced_problem.solve()
            else:
                log(
                    PROGRESS,
                    "In form_on_truth_function_space, loading current reduced problem solution for problem "
                    + reduced_problem.truth_problem.name())
            # Assign to truth_solution
            if reduced_problem in reduced_problem_to_truth_solution:
                truth_solution = reduced_problem_to_truth_solution[
                    reduced_problem]
                backend.assign(
                    reduced_problem_to_truth_solution_copy[reduced_problem],
                    truth_solution)
                for component in reduced_problem_to_components[0][
                        reduced_problem]:
                    solution_to = _sub_from_tuple(truth_solution, component)
                    if t is None or is_solving:
                        solution_from = _sub_from_tuple(
                            reduced_problem.basis_functions[:reduced_problem.
                                                            _solution.N] *
                            reduced_problem._solution, component)
                    else:
                        solution_from = _sub_from_tuple(
                            reduced_problem.basis_functions[:reduced_problem.
                                                            _solution.N] *
                            reduced_problem._solution_over_time.at(t),
                            component)
                    backend.assign(solution_to, solution_from)
            # Assign to truth_solution_dot
            if reduced_problem in reduced_problem_to_truth_solution_dot:
                truth_solution_dot = reduced_problem_to_truth_solution_dot[
                    reduced_problem]
                backend.assign(
                    reduced_problem_to_truth_solution_dot_copy[
                        reduced_problem], truth_solution_dot)
                for component in reduced_problem_to_components[1][
                        reduced_problem]:
                    solution_dot_to = _sub_from_tuple(truth_solution_dot,
                                                      component)
                    assert t is not None
                    if is_solving:
                        solution_dot_from = _sub_from_tuple(
                            reduced_problem.basis_functions[:reduced_problem.
                                                            _solution_dot.N] *
                            reduced_problem._solution_dot, component)
                    else:
                        solution_dot_from = _sub_from_tuple(
                            reduced_problem.basis_functions[:reduced_problem.
                                                            _solution_dot.N] *
                            reduced_problem._solution_dot_over_time.at(t),
                            component)
                    backend.assign(solution_dot_to, solution_dot_from)

        # Assemble
        assembled_form = wrapping.assemble(form, tensor)
        if not isinstance(assembled_form, Number):
            assembled_form.generator = form_wrapper  # for I/O
            form_rank = assembled_form.rank()
        else:
            form_rank = 0

        # Undo any side effect of truth problem solves
        for (truth_problem, _, _) in required_truth_problems:
            if truth_problem in truth_problem_to_truth_solution:
                truth_solution = truth_problem_to_truth_solution[truth_problem]
                truth_solution_copy = truth_problem_to_truth_solution_copy[
                    truth_problem]
                for component in truth_problem_to_components[0][truth_problem]:
                    solution_to = _sub_from_tuple(truth_solution, component)
                    solution_from = _sub_from_tuple(truth_solution_copy,
                                                    component)
                    backend.assign(solution_to, solution_from)
            if truth_problem in truth_problem_to_truth_solution_dot:
                truth_solution_dot = truth_problem_to_truth_solution_dot[
                    truth_problem]
                truth_solution_dot_copy = truth_problem_to_truth_solution_dot_copy[
                    truth_problem]
                for component in truth_problem_to_components[1][truth_problem]:
                    solution_dot_to = _sub_from_tuple(truth_solution_dot,
                                                      component)
                    solution_dot_from = _sub_from_tuple(
                        truth_solution_dot_copy, component)
                    backend.assign(solution_dot_to, solution_dot_from)

        # Undo any side effect of reduced problem solves
        for (reduced_problem, _) in required_reduced_problems:
            if reduced_problem in reduced_problem_to_truth_solution:
                truth_solution = reduced_problem_to_truth_solution[
                    reduced_problem]
                truth_solution_copy = reduced_problem_to_truth_solution_copy[
                    reduced_problem]
                for component in reduced_problem_to_components[0][
                        reduced_problem]:
                    solution_to = _sub_from_tuple(truth_solution, component)
                    solution_from = _sub_from_tuple(truth_solution_copy,
                                                    component)
                    backend.assign(solution_to, solution_from)
            if reduced_problem in reduced_problem_to_truth_solution_dot:
                truth_solution_dot = reduced_problem_to_truth_solution_dot[
                    reduced_problem]
                truth_solution_dot_copy = reduced_problem_to_truth_solution_dot_copy[
                    reduced_problem]
                for component in reduced_problem_to_components[1][
                        reduced_problem]:
                    solution_dot_to = _sub_from_tuple(truth_solution_dot,
                                                      component)
                    solution_dot_from = _sub_from_tuple(
                        truth_solution_dot_copy, component)
                    backend.assign(solution_dot_to, solution_dot_from)

        # Return
        return (assembled_form, form_rank)
예제 #15
0
    def _basic_form_on_reduced_function_space(form_wrapper, at):
        form = form_wrapper._form
        form_name = form_wrapper.name()
        mu = get_problem_from_parametrized_operator(form_wrapper).mu
        reduced_V = at.get_reduced_function_spaces()
        reduced_subdomain_data = at.get_reduced_subdomain_data()

        if (form_name,
                reduced_V) not in form_on_reduced_function_space__form_cache:
            visited = set()
            replacements = dict()
            truth_problems = list()
            truth_problem_to_components = dict()
            truth_problem_to_exact_truth_problem = dict()
            truth_problem_to_reduced_mesh_solution = dict()
            truth_problem_to_reduced_mesh_interpolator = dict()
            reduced_problem_to_components = dict()
            reduced_problem_to_reduced_mesh_solution = dict()
            reduced_problem_to_reduced_basis_functions = dict()

            # Look for terminals on truth mesh
            for node in wrapping.form_iterator(form, "nodes"):
                if node in visited:
                    continue
                # ... test and trial functions
                elif isinstance(node, Argument):
                    replacements[node] = wrapping.form_argument_replace(
                        node, reduced_V)
                    visited.add(node)
                # ... problem solutions related to nonlinear terms
                elif wrapping.is_problem_solution_or_problem_solution_component_type(
                        node):
                    if wrapping.is_problem_solution_or_problem_solution_component(
                            node):
                        (preprocessed_node, component, truth_solution
                         ) = wrapping.solution_identify_component(node)
                        truth_problem = get_problem_from_solution(
                            truth_solution)
                        truth_problems.append(truth_problem)
                        # Store the component
                        if truth_problem not in truth_problem_to_components:
                            truth_problem_to_components[truth_problem] = list()
                        truth_problem_to_components[truth_problem].append(
                            component)
                        # Get the function space corresponding to preprocessed_node on the reduced mesh
                        auxiliary_reduced_V = at.get_auxiliary_reduced_function_space(
                            truth_problem, component)
                        # Define and store the replacement
                        if truth_problem not in truth_problem_to_reduced_mesh_solution:
                            truth_problem_to_reduced_mesh_solution[
                                truth_problem] = list()
                        replacements[preprocessed_node] = backend.Function(
                            auxiliary_reduced_V)
                        truth_problem_to_reduced_mesh_solution[
                            truth_problem].append(
                                replacements[preprocessed_node])
                        # Get interpolator on reduced mesh
                        if truth_problem not in truth_problem_to_reduced_mesh_interpolator:
                            truth_problem_to_reduced_mesh_interpolator[
                                truth_problem] = list()
                        truth_problem_to_reduced_mesh_interpolator[
                            truth_problem].append(
                                at.get_auxiliary_function_interpolator(
                                    truth_problem, component))
                    else:
                        (
                            auxiliary_problem, component
                        ) = wrapping.get_auxiliary_problem_for_non_parametrized_function(
                            node)
                        preprocessed_node = node
                        # Get the function space corresponding to preprocessed_node on the reduced mesh
                        auxiliary_reduced_V = at.get_auxiliary_reduced_function_space(
                            auxiliary_problem, component)
                        # Get interpolator on reduced mesh
                        auxiliary_truth_problem_to_reduced_mesh_interpolator = at.get_auxiliary_function_interpolator(
                            auxiliary_problem, component)
                        # Define and store the replacement
                        replacements[
                            preprocessed_node] = auxiliary_truth_problem_to_reduced_mesh_interpolator(
                                preprocessed_node)
                    # Make sure to skip any parent solution related to this one
                    visited.add(node)
                    visited.add(preprocessed_node)
                    for parent_node in wrapping.solution_iterator(
                            preprocessed_node):
                        visited.add(parent_node)
                # ... geometric quantities
                elif isinstance(node, GeometricQuantity):
                    if len(reduced_V) == 2:
                        assert reduced_V[0].mesh().ufl_domain(
                        ) == reduced_V[1].mesh().ufl_domain()
                    replacements[node] = type(node)(reduced_V[0].mesh())
                    visited.add(node)
            # ... and replace them
            replaced_form = wrapping.form_replace(form, replacements, "nodes")

            # Look for measures ...
            if len(reduced_V) == 2:
                assert reduced_V[0].mesh().ufl_domain() == reduced_V[1].mesh(
                ).ufl_domain()
            measure_reduced_domain = reduced_V[0].mesh().ufl_domain()
            replacements_measures = dict()
            for integral in wrapping.form_iterator(replaced_form, "integrals"):
                # Prepare measure for the new form (from firedrake/mg/ufl_utils.py)
                integral_subdomain_data = integral.subdomain_data()
                if integral_subdomain_data is not None:
                    integral_reduced_subdomain_data = reduced_subdomain_data[
                        integral_subdomain_data]
                else:
                    integral_reduced_subdomain_data = None
                measure = Measure(
                    integral.integral_type(),
                    domain=measure_reduced_domain,
                    subdomain_id=integral.subdomain_id(),
                    subdomain_data=integral_reduced_subdomain_data,
                    metadata=integral.metadata())
                replacements_measures[integral.integrand(),
                                      integral.integral_type(),
                                      integral.subdomain_id()] = measure
            # ... and replace them
            replaced_form_with_replaced_measures = wrapping.form_replace(
                replaced_form, replacements_measures, "measures")

            # Cache the resulting dicts
            form_on_reduced_function_space__form_cache[(
                form_name, reduced_V)] = replaced_form_with_replaced_measures
            form_on_reduced_function_space__truth_problems_cache[(
                form_name, reduced_V)] = truth_problems
            form_on_reduced_function_space__truth_problem_to_components_cache[(
                form_name, reduced_V)] = truth_problem_to_components
            form_on_reduced_function_space__truth_problem_to_exact_truth_problem_cache[
                (form_name, reduced_V)] = truth_problem_to_exact_truth_problem
            form_on_reduced_function_space__truth_problem_to_reduced_mesh_solution_cache[
                (form_name,
                 reduced_V)] = truth_problem_to_reduced_mesh_solution
            form_on_reduced_function_space__truth_problem_to_reduced_mesh_interpolator_cache[
                (form_name,
                 reduced_V)] = truth_problem_to_reduced_mesh_interpolator
            form_on_reduced_function_space__reduced_problem_to_components_cache[
                (form_name, reduced_V)] = reduced_problem_to_components
            form_on_reduced_function_space__reduced_problem_to_reduced_mesh_solution_cache[
                (form_name,
                 reduced_V)] = reduced_problem_to_reduced_mesh_solution
            form_on_reduced_function_space__reduced_problem_to_reduced_basis_functions_cache[
                (form_name,
                 reduced_V)] = reduced_problem_to_reduced_basis_functions

        # Extract from cache
        replaced_form_with_replaced_measures = form_on_reduced_function_space__form_cache[
            (form_name, reduced_V)]
        truth_problems = form_on_reduced_function_space__truth_problems_cache[(
            form_name, reduced_V)]
        truth_problem_to_components = form_on_reduced_function_space__truth_problem_to_components_cache[
            (form_name, reduced_V)]
        truth_problem_to_exact_truth_problem = form_on_reduced_function_space__truth_problem_to_exact_truth_problem_cache[
            (form_name, reduced_V)]
        truth_problem_to_reduced_mesh_solution = form_on_reduced_function_space__truth_problem_to_reduced_mesh_solution_cache[
            (form_name, reduced_V)]
        truth_problem_to_reduced_mesh_interpolator = form_on_reduced_function_space__truth_problem_to_reduced_mesh_interpolator_cache[
            (form_name, reduced_V)]
        reduced_problem_to_components = form_on_reduced_function_space__reduced_problem_to_components_cache[
            (form_name, reduced_V)]
        reduced_problem_to_reduced_mesh_solution = form_on_reduced_function_space__reduced_problem_to_reduced_mesh_solution_cache[
            (form_name, reduced_V)]
        reduced_problem_to_reduced_basis_functions = form_on_reduced_function_space__reduced_problem_to_reduced_basis_functions_cache[
            (form_name, reduced_V)]

        # Get list of truth and reduced problems that need to be solved, possibly updating cache
        required_truth_problems = list()
        required_reduced_problems = list()
        for truth_problem in truth_problems:
            truth_problem_is_solving = hasattr(truth_problem, "_is_solving")
            if is_training_started(truth_problem):
                reduced_problem = get_reduced_problem_from_problem(
                    truth_problem)
                reduced_problem_is_solving = hasattr(reduced_problem,
                                                     "_is_solving")
            else:
                reduced_problem = None
                reduced_problem_is_solving = False
            if not truth_problem_is_solving:
                if is_training_finished(truth_problem):
                    # Store the component
                    if reduced_problem not in reduced_problem_to_components:
                        reduced_problem_to_components[
                            reduced_problem] = truth_problem_to_components[
                                truth_problem]
                    # Store the replacement
                    if reduced_problem not in reduced_problem_to_reduced_mesh_solution:
                        reduced_problem_to_reduced_mesh_solution[
                            reduced_problem] = truth_problem_to_reduced_mesh_solution[
                                truth_problem]
                    # Get reduced problem basis functions on reduced mesh
                    if reduced_problem not in reduced_problem_to_reduced_basis_functions:
                        reduced_problem_to_reduced_basis_functions[
                            reduced_problem] = list()
                        for component in reduced_problem_to_components[
                                reduced_problem]:
                            reduced_problem_to_reduced_basis_functions[
                                reduced_problem].append(
                                    at.get_auxiliary_basis_functions_matrix(
                                        truth_problem, reduced_problem,
                                        component))
                    # Append to list of required reduced problems
                    required_reduced_problems.append(
                        (reduced_problem, reduced_problem_is_solving))
                else:
                    if (hasattr(truth_problem,
                                "_apply_exact_evaluation_at_stages") and
                            not hasattr(truth_problem, "_apply_EIM_at_stages")
                            and not hasattr(truth_problem,
                                            "_apply_DEIM_at_stages")):
                        # Init truth problem (if required), as it may not have been initialized
                        truth_problem.init()
                        # Append to list of required truth problems which are not currently solving
                        required_truth_problems.append(
                            (truth_problem, False, reduced_problem_is_solving))
                    else:
                        # Store the corresponding exact truth problem
                        if truth_problem not in truth_problem_to_exact_truth_problem:
                            exact_truth_problem = exact_problem(truth_problem)
                            truth_problem_to_exact_truth_problem[
                                truth_problem] = exact_truth_problem
                            # Init exact truth problem (if required), as it may not have been initialized
                            exact_truth_problem.init()
                        else:
                            exact_truth_problem = truth_problem_to_exact_truth_problem[
                                truth_problem]
                        # Store the component
                        if exact_truth_problem not in truth_problem_to_components:
                            truth_problem_to_components[
                                exact_truth_problem] = truth_problem_to_components[
                                    truth_problem]
                        # Store the replacement
                        if exact_truth_problem not in truth_problem_to_reduced_mesh_solution:
                            truth_problem_to_reduced_mesh_solution[
                                exact_truth_problem] = truth_problem_to_reduced_mesh_solution[
                                    truth_problem]
                        # Get interpolator on reduced mesh
                        if exact_truth_problem not in truth_problem_to_reduced_mesh_interpolator:
                            truth_problem_to_reduced_mesh_interpolator[
                                exact_truth_problem] = list()
                            for component in truth_problem_to_components[
                                    exact_truth_problem]:
                                truth_problem_to_reduced_mesh_interpolator[
                                    exact_truth_problem].append(
                                        at.get_auxiliary_function_interpolator(
                                            exact_truth_problem, component))
                        # Append to list of required truth problems which are not currently solving
                        required_truth_problems.append(
                            (exact_truth_problem, False,
                             reduced_problem_is_solving))
            else:
                assert not reduced_problem_is_solving
                # Append to list of required truth problems which are currently solving
                required_truth_problems.append((truth_problem, True, False))

        # Solve truth problems (which have not been reduced yet) associated to nonlinear terms
        for (truth_problem, truth_problem_is_solving,
             reduced_problem_is_solving) in required_truth_problems:
            if not reduced_problem_is_solving:
                # Solve (if necessary) ...
                truth_problem.set_mu(mu)
                if not truth_problem_is_solving:
                    log(
                        PROGRESS,
                        "In form_on_reduced_function_space, requiring truth problem solve for problem "
                        + truth_problem.name())
                    truth_problem.solve()
                else:
                    log(
                        PROGRESS,
                        "In form_on_reduced_function_space, loading current truth problem solution for problem "
                        + truth_problem.name())
            else:
                reduced_problem = get_reduced_problem_from_problem(
                    truth_problem)
                log(
                    PROGRESS,
                    "In form_on_reduced_function_space, replacing current truth problem solution with reduced solution for problem "
                    + reduced_problem.truth_problem.name())
            # ... and assign to reduced_mesh_solution
            for (reduced_mesh_solution, reduced_mesh_interpolator) in zip(
                    truth_problem_to_reduced_mesh_solution[truth_problem],
                    truth_problem_to_reduced_mesh_interpolator[truth_problem]):
                solution_to = reduced_mesh_solution
                if not reduced_problem_is_solving:
                    solution_from = reduced_mesh_interpolator(
                        truth_problem._solution)
                else:
                    solution_from = reduced_mesh_interpolator(
                        reduced_problem.basis_functions[:reduced_problem.
                                                        _solution.N] *
                        reduced_problem._solution)
                backend.assign(solution_to, solution_from)

        # Solve reduced problems associated to nonlinear terms
        for (reduced_problem, is_solving) in required_reduced_problems:
            # Solve (if necessary) ...
            reduced_problem.set_mu(mu)
            if not is_solving:
                log(
                    PROGRESS,
                    "In form_on_reduced_function_space, requiring reduced problem solve for problem "
                    + reduced_problem.truth_problem.name())
                reduced_problem.solve()
            else:
                log(
                    PROGRESS,
                    "In form_on_reduced_function_space, loading current reduced problem solution for problem "
                    + reduced_problem.truth_problem.name())
            # ... and assign to reduced_mesh_solution
            for (reduced_mesh_solution, reduced_basis_functions) in zip(
                    reduced_problem_to_reduced_mesh_solution[reduced_problem],
                    reduced_problem_to_reduced_basis_functions[reduced_problem]
            ):
                solution_to = reduced_mesh_solution
                solution_from_N = OnlineSizeDict()
                for c, v in reduced_problem._solution.N.items():
                    if c in reduced_basis_functions._components_name:
                        solution_from_N[c] = v
                solution_from = online_backend.OnlineFunction(solution_from_N)
                online_backend.online_assign(solution_from,
                                             reduced_problem._solution)
                solution_from = reduced_basis_functions[:solution_from_N] * solution_from
                backend.assign(solution_to, solution_from)

        # Assemble and return
        assembled_replaced_form = wrapping.assemble(
            replaced_form_with_replaced_measures)
        form_rank = assembled_replaced_form.rank()
        return (assembled_replaced_form, form_rank)
예제 #16
0
 def __mul__(self, other_matrix):
     log(PROGRESS, "Begin A : B")
     output = wrapping.vectorized_matrix_inner_vectorized_matrix(
         self.matrix, other_matrix)
     log(PROGRESS, "End A : B")
     return output
예제 #17
0
    def get_stability_factor_lower_bound(self, N=None):
        if N is None:
            N = self.N
        assert N <= len(self.greedy_selected_parameters)
        (cache_key, cache_file) = self._cache_key_and_file(N)
        if "RAM" in self.cache_config and cache_key in self._alpha_LB_cache:
            log(PROGRESS, "Loading stability factor lower bound from cache")
            self._alpha_LB = self._alpha_LB_cache[cache_key]
        elif "Disk" in self.cache_config and self.import_stability_factor_lower_bound(
                self.folder["cache"], cache_file):
            log(PROGRESS, "Loading stability factor lower bound from file")
            if "RAM" in self.cache_config:
                self._alpha_LB_cache[cache_key] = self._alpha_LB
        else:
            log(PROGRESS,
                "Solving stability factor lower bound reduced problem")
            Q = self.truth_problem.Q["a"]
            M_e = min(self.M_e if self.M_e is not None else N, N,
                      len(self.greedy_selected_parameters))
            M_p = min(
                self.M_p if self.M_p is not None else N, N,
                len(self.training_set) - len(self.greedy_selected_parameters))

            # 1. Constrain the Q variables to be in the bounding box
            bounds = list()  # of Q pairs
            for q in range(Q):
                assert self.B_min[q] <= self.B_max[q]
                bounds.append((self.B_min[q], self.B_max[q]))

            # 2. Add three different sets of constraints.
            #    Our constrains are of the form
            #       a^T * x >= b
            constraints_matrix = Matrix(M_e + M_p + 1, Q)
            constraints_vector = Vector(M_e + M_p + 1)

            # 2a. Add constraints: a constraint is added for the closest samples to mu among the selected parameters
            mu_bak = self.mu
            closest_selected_parameters = self._closest_selected_parameters(
                M_e, N, self.mu)
            for (j, omega) in enumerate(closest_selected_parameters):
                # Overwrite parameter values
                self.set_mu(omega)

                # Compute theta
                current_theta_a = self.truth_problem.compute_theta("a")

                # Assemble the LHS of the constraint
                for q in range(Q):
                    constraints_matrix[j, q] = current_theta_a[q]

                # Assemble the RHS of the constraint
                (constraints_vector[j], _) = self.evaluate_stability_factor(
                )  # note that computations for this call may be already cached
            self.set_mu(mu_bak)

            # 2b. Add constraints: also constrain the closest point in the complement of selected parameters,
            #                      with RHS depending on previously computed lower bounds
            mu_bak = self.mu
            closest_selected_parameters_complement = self._closest_unselected_parameters(
                M_p, N, self.mu)
            for (j, nu) in enumerate(closest_selected_parameters_complement):
                # Overwrite parameter values
                self.set_mu(nu)

                # Compute theta
                current_theta_a = self.truth_problem.compute_theta("a")

                # Assemble the LHS of the constraint
                for q in range(Q):
                    constraints_matrix[M_e + j, q] = current_theta_a[q]

                # Assemble the RHS of the constraint
                if N > 1:
                    constraints_vector[
                        M_e + j] = self.get_stability_factor_lower_bound(
                            N - 1
                        )  # note that computations for this call may be already cached
                else:
                    constraints_vector[M_e + j] = 0.
            self.set_mu(mu_bak)

            # 2c. Add constraints: also constrain the coercivity constant for mu to be positive
            # Compute theta
            current_theta_a = self.truth_problem.compute_theta("a")

            # Assemble the LHS of the constraint
            for q in range(Q):
                constraints_matrix[M_e + M_p, q] = current_theta_a[q]

            # Assemble the RHS of the constraint
            constraints_vector[M_e + M_p] = 0.

            # 3. Add cost function coefficients
            cost = Vector(Q)
            for q in range(Q):
                cost[q] = current_theta_a[q]

            # 4. Solve the linear programming problem
            linear_program = LinearProgramSolver(cost, constraints_matrix,
                                                 constraints_vector, bounds)
            try:
                alpha_LB = linear_program.solve()
            except LinearProgramSolverError:
                print("SCM warning at mu = " + str(self.mu) +
                      ": error occured while solving linear program.")
                print(
                    "Please consider switching to a different solver. A truth eigensolve will be performed."
                )

                (alpha_LB, _) = self.evaluate_stability_factor()

            self._alpha_LB = alpha_LB
            if "RAM" in self.cache_config:
                self._alpha_LB_cache[cache_key] = alpha_LB
            self.export_stability_factor_lower_bound(
                self.folder["cache"], cache_file
            )  # Note that we export to file regardless of config options, because they may change across different runs
        return self._alpha_LB
예제 #18
0
def ReductionMethodFactory(truth_problem, category, **kwargs):

    log(
        DEBUG, "In ReductionMethodFactory with\n" + "\ttruth problem = " +
        str(type(truth_problem)) + "\n" + "\tcategory = " + str(category) +
        "\n" + "\tkwargs = " + str(kwargs))
    if hasattr(type(truth_problem), "ProblemDecorators"):
        log(
            DEBUG, "\ttruth problem decorators = " + "\n\t\t".join([
                str(Decorator)
                for Decorator in type(truth_problem).ProblemDecorators
            ]) + "\n")

    TypesList = list()

    # Generate ReductionMethod type based on Problem type
    log(DEBUG, "Generate ReductionMethod type based on Problem type")
    ReductionMethodGenerator = getattr(reduction_method_cache, category)
    TypesList.append(ReductionMethodGenerator(truth_problem))

    # Look if any customizer has been defined
    for (Problem, customizer) in customize_reduction_method_cache.items():
        if isinstance(truth_problem, Problem):
            TypesList.append(customizer)

    # Append ReductionMethodDecorator types based on Algorithm type
    if hasattr(type(truth_problem), "ProblemDecorators"):
        log(DEBUG,
            "Append ReductionMethodDecorator types based on Algorithm type")
        for Decorator in type(truth_problem).ProblemDecorators:
            ReductionMethodDecoratorGenerator = getattr(
                reduction_method_decorator_cache, Decorator.__name__)
            TypesList.append(
                ReductionMethodDecoratorGenerator(truth_problem, **kwargs))

    # Log
    log(DEBUG, "The reduction method is a composition of the following types:")
    for t in range(len(TypesList) - 1, -1, -1):
        log(DEBUG, str(TypesList[t]))
    log(DEBUG, "\n")

    # Compose all types
    assert len(TypesList) > 0
    ComposedType = TypesList[0]
    for t in range(1, len(TypesList)):
        ComposedType = TypesList[t](ComposedType)

    # Finally, return an instance of the generated class
    return ComposedType(truth_problem, **kwargs)
예제 #19
0
 def solve_and_estimate_error(mu):
     self.reduced_problem.set_mu(mu)
     self.reduced_problem.solve()
     error_estimator = self.reduced_problem.estimate_error()
     log(DEBUG, "Error estimator for mu = " + str(mu) + " is " + str(error_estimator))
     return error_estimator