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