def get_auxiliary_reduced_function_space(self, auxiliary_problem, component, index=None): assert isinstance(component, tuple) assert len(component) > 0 index = self._get_dict_index(index) auxiliary_V = _sub_from_tuple(auxiliary_problem.V, component) key = (auxiliary_problem, component, index) if key not in self._auxiliary_reduced_function_space: auxiliary_reduced_V = wrapping.convert_functionspace_to_submesh(auxiliary_V, self.reduced_mesh[index], self._get_auxiliary_reduced_function_space_type(auxiliary_V)) self._auxiliary_reduced_function_space[key] = auxiliary_reduced_V if not self._load_auxiliary_reduced_function_space(key): # Get the map between DOFs on auxiliary_V and auxiliary_reduced_V (auxiliary_dofs_to_reduced_dofs, _) = wrapping.map_functionspaces_between_mesh_and_submesh(auxiliary_V, self.mesh, auxiliary_reduced_V, self.reduced_mesh[index]) log(DEBUG, "Auxiliary DOFs to reduced DOFs is " + str(auxiliary_dofs_to_reduced_dofs)) self._auxiliary_dofs_to_reduced_dofs[key] = auxiliary_dofs_to_reduced_dofs # Save to file self._save_auxiliary_reduced_function_space(key) else: assert key in self._auxiliary_dofs_to_reduced_dofs return self._auxiliary_reduced_function_space[key]
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_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_expression_on_truth_mesh(expression_wrapper, function=None): expression = expression_wrapper._expression expression_name = expression_wrapper.name() expression_problem = get_problem_from_parametrized_expression(expression_wrapper) space = expression_wrapper._space mu = expression_problem.mu if hasattr(expression_problem, "set_time"): t = expression_problem.t else: t = None if expression_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 logger.log(DEBUG, "Traversing terminals of expression " + expression_name) 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) logger.log(DEBUG, "\tFound problem solution of truth problem " + truth_problem.name() + " (exact problem decorator: " + str(hasattr(truth_problem, "__is_exact__")) + ", component: " + str(component) + ")") # 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) logger.log(DEBUG, "\tFound problem solution dot of truth problem " + truth_problem.name() + " (exact problem decorator: " + str(hasattr(truth_problem, "__is_exact__")) + ", component: " + str(component) + ")") # 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, component, auxiliary_problem) = wrapping.get_auxiliary_problem_for_non_parametrized_function(node) logger.log(DEBUG, "\tFound non parametrized function " + str(preprocessed_node) + " associated to auxiliary problem " + str(auxiliary_problem.name()) + ", component: " + str(component)) # 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[expression_name] = truth_problems truth_problem_to_components_cache[expression_name] = truth_problem_to_components truth_problem_to_exact_truth_problem_cache[expression_name] = truth_problem_to_exact_truth_problem truth_problem_to_truth_solution_cache[expression_name] = truth_problem_to_truth_solution truth_problem_to_truth_solution_copy_cache[expression_name] = truth_problem_to_truth_solution_copy truth_problem_to_truth_solution_dot_cache[expression_name] = truth_problem_to_truth_solution_dot truth_problem_to_truth_solution_dot_copy_cache[expression_name] = truth_problem_to_truth_solution_dot_copy reduced_problem_to_components_cache[expression_name] = reduced_problem_to_components reduced_problem_to_truth_solution_cache[expression_name] = reduced_problem_to_truth_solution reduced_problem_to_truth_solution_copy_cache[expression_name] = reduced_problem_to_truth_solution_copy reduced_problem_to_truth_solution_dot_cache[expression_name] = reduced_problem_to_truth_solution_dot reduced_problem_to_truth_solution_dot_copy_cache[ expression_name] = reduced_problem_to_truth_solution_dot_copy # Extract from cache truth_problems = truth_problems_cache[expression_name] truth_problem_to_components = truth_problem_to_components_cache[expression_name] truth_problem_to_exact_truth_problem = truth_problem_to_exact_truth_problem_cache[expression_name] truth_problem_to_truth_solution = truth_problem_to_truth_solution_cache[expression_name] truth_problem_to_truth_solution_copy = truth_problem_to_truth_solution_copy_cache[expression_name] truth_problem_to_truth_solution_dot = truth_problem_to_truth_solution_dot_cache[expression_name] truth_problem_to_truth_solution_dot_copy = truth_problem_to_truth_solution_dot_copy_cache[expression_name] reduced_problem_to_components = reduced_problem_to_components_cache[expression_name] reduced_problem_to_truth_solution = reduced_problem_to_truth_solution_cache[expression_name] reduced_problem_to_truth_solution_copy = reduced_problem_to_truth_solution_copy_cache[expression_name] reduced_problem_to_truth_solution_dot = reduced_problem_to_truth_solution_dot_cache[expression_name] reduced_problem_to_truth_solution_dot_copy = reduced_problem_to_truth_solution_dot_cache[expression_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): logger.log(DEBUG, "Truth problem " + truth_problem.name() + " (exact problem decorator: " + str(hasattr(truth_problem, "__is_exact__")) + ") is not currently solving, and its offline stage has finished:" + " truth problem will be replaced by reduced 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[0] 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[1] 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")): logger.log(DEBUG, "Truth problem " + truth_problem.name() + " (exact problem decorator: " + str(hasattr(truth_problem, "__is_exact__")) + ") is not currently solving, its offline stage has not finished," + " and only @ExactParametrizedFunctions has been used:" + " truth solve of this truth problem instance will be called") # 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: logger.log(DEBUG, "Truth problem " + truth_problem.name() + " (exact problem decorator: " + str(hasattr(truth_problem, "__is_exact__")) + ") is not currently solving, its offline stage has not finished," + " and either @ExactParametrizedFunctions has not been used" + " or it has been used in combination with @DEIM or @EIM:" + " truth solve on an auxiliary instance (with exact problem decorator)" + " will be called, to prevent early initialization of DEIM/EIM data structures") # 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: logger.log(DEBUG, "Truth problem " + truth_problem.name() + " (exact problem decorator: " + str(hasattr(truth_problem, "__is_exact__")) + ") is currently solving: current truth solution will be loaded") 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: logger.log(DEBUG, "Requiring truth problem solve for problem " + truth_problem.name() + " (exact problem decorator: " + str(hasattr(truth_problem, "__is_exact__")) + ")") truth_problem.solve() else: logger.log(DEBUG, "Loading current truth problem solution for problem " + truth_problem.name() + " (exact problem decorator: " + str(hasattr(truth_problem, "__is_exact__")) + ")") else: reduced_problem = get_reduced_problem_from_problem(truth_problem) logger.log(DEBUG, "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: logger.log(DEBUG, "Requiring reduced problem solve for problem " + reduced_problem.truth_problem.name()) reduced_problem.solve() else: logger.log(DEBUG, "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) # Evaluate if function is None: function = backend.Function(space) wrapping.evaluate_expression(expression, function) # 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 function