def load(self, directory, filename): # Get full directory name full_directory = Folders.Folder(os.path.join(str(directory), filename)) # Load problem corresponding to self._lhs, and update self._lhs accordingly assert self._lhs is None assert LHSIO.exists_file(full_directory, "lhs_problem_name") lhs_problem_name = LHSIO.load_file(full_directory, "lhs_problem_name") lhs_problem = get_problem_from_problem_name(lhs_problem_name) lhs_reduced_problem = get_reduced_problem_from_problem(lhs_problem) self._lhs = lhs_reduced_problem._riesz_solve_inner_product # Load problem corresponding to self._solution, and update self._solution accordingly assert self._solution is None assert SolutionIO.exists_file(full_directory, "solution_problem_name") solution_problem_name = SolutionIO.load_file(full_directory, "solution_problem_name") solution_problem = get_problem_from_problem_name(solution_problem_name) solution_reduced_problem = get_reduced_problem_from_problem( solution_problem) self._solution = solution_reduced_problem._riesz_solve_storage # Load problem and operator corresponding to self._rhs, and update self._solution accordingly assert self._rhs is None assert RHSIO.exists_file(full_directory, "rhs_type") rhs_type = RHSIO.load_file(full_directory, "rhs_type") assert rhs_type in ("ParametrizedTensorFactory", "DelayedProduct") if rhs_type == "ParametrizedTensorFactory": assert RHSIO.exists_file(full_directory, "rhs_arg_0") (rhs_problem_name_0, rhs_term_0, rhs_index_0) = RHSIO.load_file(full_directory, "rhs_arg_0") rhs_problem_0 = get_problem_from_problem_name(rhs_problem_name_0) rhs_arg_0 = rhs_problem_0.operator[rhs_term_0][rhs_index_0] assert isinstance(rhs_arg_0, AbstractParametrizedTensorFactory) self._rhs = rhs_arg_0 elif rhs_type == "DelayedProduct": assert RHSIO.exists_file(full_directory, "rhs_arg_0") rhs_arg_0 = RHSIO.load_file(full_directory, "rhs_arg_0") assert rhs_arg_0 == -1.0 assert RHSIO.exists_file(full_directory, "rhs_arg_1") (rhs_problem_name_1, rhs_term_1, rhs_index_1) = RHSIO.load_file(full_directory, "rhs_arg_1") rhs_problem_1 = get_problem_from_problem_name(rhs_problem_name_1) rhs_arg_1 = rhs_problem_1.operator[rhs_term_1][rhs_index_1] assert isinstance(rhs_arg_1, AbstractParametrizedTensorFactory) assert RHSIO.exists_file(full_directory, "rhs_arg_2") (rhs_problem_name_2, rhs_component_2, rhs_index_2) = RHSIO.load_file(full_directory, "rhs_arg_2") rhs_problem_2 = get_problem_from_problem_name(rhs_problem_name_2) rhs_reduced_problem_2 = get_reduced_problem_from_problem( rhs_problem_2) if rhs_component_2 is not None: rhs_arg_2 = rhs_reduced_problem_2.basis_functions[ rhs_component_2][rhs_index_2] else: rhs_arg_2 = rhs_reduced_problem_2.basis_functions[rhs_index_2] rhs = DelayedProduct(rhs_arg_0) rhs *= rhs_arg_1 rhs *= rhs_arg_2 self._rhs = rhs else: raise TypeError("Invalid rhs") # Load problem corresponding to self._bcs, and update self._bcs accordingly assert self._bcs is None assert BCsIO.exists_file(full_directory, "bcs_problem_name") bcs_problem_name = BCsIO.load_file(full_directory, "bcs_problem_name") bcs_problem = get_problem_from_problem_name(bcs_problem_name) bcs_reduced_problem = get_reduced_problem_from_problem(bcs_problem) self._bcs = bcs_reduced_problem._riesz_solve_homogeneous_dirichlet_bc # Load parameters assert len(self._parameters) is 0 assert ParametersIO.exists_file(full_directory, "parameters") self._parameters = ParametersIO.load_file(full_directory, "parameters") # Return return True
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_reduced_mesh(expression_wrapper, at): expression = expression_wrapper._expression expression_name = expression_wrapper.name() reduced_space = at.get_reduced_function_space() mu = get_problem_from_parametrized_expression(expression_wrapper).mu reduced_mesh = at.get_reduced_mesh() if (expression_name, reduced_mesh ) not in expression_on_reduced_mesh__expression_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.expression_iterator(expression): 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 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): replacements[node] = type(node)(reduced_mesh) visited.add(node) # ... and replace them replaced_expression = wrapping.expression_replace( expression, replacements) # Cache the resulting dicts expression_on_reduced_mesh__expression_cache[( expression_name, reduced_mesh)] = replaced_expression expression_on_reduced_mesh__truth_problems_cache[( expression_name, reduced_mesh)] = truth_problems expression_on_reduced_mesh__truth_problem_to_components_cache[( expression_name, reduced_mesh)] = truth_problem_to_components expression_on_reduced_mesh__truth_problem_to_exact_truth_problem_cache[ (expression_name, reduced_mesh)] = truth_problem_to_exact_truth_problem expression_on_reduced_mesh__truth_problem_to_reduced_mesh_solution_cache[ (expression_name, reduced_mesh)] = truth_problem_to_reduced_mesh_solution expression_on_reduced_mesh__truth_problem_to_reduced_mesh_interpolator_cache[ (expression_name, reduced_mesh)] = truth_problem_to_reduced_mesh_interpolator expression_on_reduced_mesh__reduced_problem_to_components_cache[( expression_name, reduced_mesh)] = reduced_problem_to_components expression_on_reduced_mesh__reduced_problem_to_reduced_mesh_solution_cache[ (expression_name, reduced_mesh)] = reduced_problem_to_reduced_mesh_solution expression_on_reduced_mesh__reduced_problem_to_reduced_basis_functions_cache[ (expression_name, reduced_mesh)] = reduced_problem_to_reduced_basis_functions # Extract from cache replaced_expression = expression_on_reduced_mesh__expression_cache[( expression_name, reduced_mesh)] truth_problems = expression_on_reduced_mesh__truth_problems_cache[( expression_name, reduced_mesh)] truth_problem_to_components = expression_on_reduced_mesh__truth_problem_to_components_cache[ (expression_name, reduced_mesh)] truth_problem_to_exact_truth_problem = expression_on_reduced_mesh__truth_problem_to_exact_truth_problem_cache[ (expression_name, reduced_mesh)] truth_problem_to_reduced_mesh_solution = expression_on_reduced_mesh__truth_problem_to_reduced_mesh_solution_cache[ (expression_name, reduced_mesh)] truth_problem_to_reduced_mesh_interpolator = expression_on_reduced_mesh__truth_problem_to_reduced_mesh_interpolator_cache[ (expression_name, reduced_mesh)] reduced_problem_to_components = expression_on_reduced_mesh__reduced_problem_to_components_cache[ (expression_name, reduced_mesh)] reduced_problem_to_reduced_mesh_solution = expression_on_reduced_mesh__reduced_problem_to_reduced_mesh_solution_cache[ (expression_name, reduced_mesh)] reduced_problem_to_reduced_basis_functions = expression_on_reduced_mesh__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 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 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()) # ... 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 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()) # ... 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) # Evaluate and return reduced_function = backend.Function(reduced_space) wrapping.evaluate_expression(expression, reduced_function, replaced_expression) return reduced_function
def load(self, directory, filename): from rbnics.backends import BasisFunctionsMatrix if self._type != "empty": # avoid loading multiple times if self._type in ("basis_functions_matrix", "functions_list"): delayed_functions = self._content[self._type] it = NonAffineExpansionStorageContent_Iterator( delayed_functions, flags=["c_index", "multi_index", "refs_ok"], op_flags=["readonly"]) while not it.finished: if isinstance(delayed_functions[it.multi_index], DelayedFunctionsList): assert self._type == "functions_list" if len( delayed_functions[it.multi_index] ) > 0: # ... unless it is an empty FunctionsList return False elif isinstance(delayed_functions[it.multi_index], DelayedBasisFunctionsMatrix): assert self._type == "basis_functions_matrix" if sum( delayed_functions[it.multi_index]. _component_name_to_basis_component_length. values() ) > 0: # ... unless it is an empty BasisFunctionsMatrix return False else: raise TypeError("Invalid delayed functions") it.iternext() else: return False # Get full directory name full_directory = Folders.Folder(os.path.join(str(directory), filename)) # Detect trivial case assert TypeIO.exists_file(full_directory, "type") imported_type = TypeIO.load_file(full_directory, "type") self._type = imported_type assert self._type in ("basis_functions_matrix", "empty", "error_estimation_operators_11", "error_estimation_operators_21", "error_estimation_operators_22", "functions_list", "operators") if self._type in ("basis_functions_matrix", "functions_list"): # Load delayed functions assert self._type in self._content delayed_functions = self._content[self._type] it = NonAffineExpansionStorageContent_Iterator( delayed_functions, flags=["c_index", "multi_index", "refs_ok"]) while not it.finished: delayed_function = delayed_functions[it.multi_index] delayed_function.load(full_directory, "delayed_functions_" + str(it.index)) it.iternext() elif self._type == "empty": pass elif self._type in ("error_estimation_operators_11", "error_estimation_operators_21", "error_estimation_operators_22"): # Load delayed functions assert "delayed_functions" not in self._content self._content["delayed_functions"] = [ NonAffineExpansionStorageContent_Base(self._shape[0], dtype=object), NonAffineExpansionStorageContent_Base(self._shape[1], dtype=object) ] for (index, delayed_functions) in enumerate( self._content["delayed_functions"]): it = NonAffineExpansionStorageContent_Iterator( delayed_functions, flags=["c_index", "refs_ok"]) while not it.finished: assert DelayedFunctionsTypeIO.exists_file( full_directory, "delayed_functions_" + str(index) + "_" + str(it.index) + "_type") delayed_function_type = DelayedFunctionsTypeIO.load_file( full_directory, "delayed_functions_" + str(index) + "_" + str(it.index) + "_type") assert DelayedFunctionsProblemNameIO.exists_file( full_directory, "delayed_functions_" + str(index) + "_" + str(it.index) + "_problem_name") delayed_function_problem_name = DelayedFunctionsProblemNameIO.load_file( full_directory, "delayed_functions_" + str(index) + "_" + str(it.index) + "_problem_name") delayed_function_problem = get_problem_from_problem_name( delayed_function_problem_name) assert delayed_function_type in ( "DelayedBasisFunctionsMatrix", "DelayedLinearSolver") if delayed_function_type == "DelayedBasisFunctionsMatrix": delayed_function = DelayedBasisFunctionsMatrix( delayed_function_problem.V) delayed_function.init( delayed_function_problem.components) elif delayed_function_type == "DelayedLinearSolver": delayed_function = DelayedLinearSolver() else: raise ValueError("Invalid delayed function") delayed_function.load( full_directory, "delayed_functions_" + str(index) + "_" + str(it.index) + "_content") delayed_functions[it.index] = delayed_function it.iternext() # Load inner product assert ErrorEstimationInnerProductIO.exists_file( full_directory, "inner_product_matrix_problem_name") inner_product_matrix_problem_name = ErrorEstimationInnerProductIO.load_file( full_directory, "inner_product_matrix_problem_name") inner_product_matrix_problem = get_problem_from_problem_name( inner_product_matrix_problem_name) inner_product_matrix_reduced_problem = get_reduced_problem_from_problem( inner_product_matrix_problem) self._content[ "inner_product_matrix"] = inner_product_matrix_reduced_problem._error_estimation_inner_product # Recompute shape assert "delayed_functions_shape" not in self._content self._content["delayed_functions_shape"] = DelayedTransposeShape( (self._content["delayed_functions"][0][0], self._content["delayed_functions"][1][0])) # Prepare precomputed slices self._precomputed_slices = dict() self._prepare_trivial_precomputed_slice() elif self._type == "empty": pass elif self._type == "operators": # Load truth content assert "truth_operators" not in self._content self._content[ "truth_operators"] = NonAffineExpansionStorageContent_Base( self._shape, dtype=object) it = NonAffineExpansionStorageContent_Iterator( self._content["truth_operators"], flags=["c_index", "multi_index", "refs_ok"]) while not it.finished: assert TruthContentItemIO.exists_file( full_directory, "truth_operator_" + str(it.index) + "_type") operator_type = TruthContentItemIO.load_file( full_directory, "truth_operator_" + str(it.index) + "_type") assert operator_type in ("NumericForm", "ParametrizedTensorFactory") if operator_type == "NumericForm": assert TruthContentItemIO.exists_file( full_directory, "truth_operator_" + str(it.index)) value = TruthContentItemIO.load_file( full_directory, "truth_operator_" + str(it.index)) self._content["truth_operators"][ it.multi_index] = NumericForm(value) elif operator_type == "ParametrizedTensorFactory": assert TruthContentItemIO.exists_file( full_directory, "truth_operator_" + str(it.index)) (problem_name, term, index) = TruthContentItemIO.load_file( full_directory, "truth_operator_" + str(it.index)) truth_problem = get_problem_from_problem_name(problem_name) self._content["truth_operators"][ it.multi_index] = truth_problem.operator[term][index] else: raise ValueError("Invalid operator type") it.iternext() assert "truth_operators_as_expansion_storage" not in self._content self._prepare_truth_operators_as_expansion_storage() # Load basis functions content assert BasisFunctionsContentLengthIO.exists_file( full_directory, "basis_functions_length") basis_functions_length = BasisFunctionsContentLengthIO.load_file( full_directory, "basis_functions_length") assert basis_functions_length in (0, 1, 2) assert "basis_functions" not in self._content self._content["basis_functions"] = list() for index in range(basis_functions_length): assert BasisFunctionsProblemNameIO.exists_file( full_directory, "basis_functions_" + str(index) + "_problem_name") basis_functions_problem_name = BasisFunctionsProblemNameIO.load_file( full_directory, "basis_functions_" + str(index) + "_problem_name") assert BasisFunctionsProblemNameIO.exists_file( full_directory, "basis_functions_" + str(index) + "_components_name") basis_functions_components_name = BasisFunctionsProblemNameIO.load_file( full_directory, "basis_functions_" + str(index) + "_components_name") basis_functions_problem = get_problem_from_problem_name( basis_functions_problem_name) basis_functions_reduced_problem = get_reduced_problem_from_problem( basis_functions_problem) basis_functions = BasisFunctionsMatrix( basis_functions_reduced_problem.basis_functions.space, basis_functions_components_name if basis_functions_components_name != basis_functions_problem.components else None) basis_functions.init(basis_functions_components_name) basis_functions_loaded = basis_functions.load( full_directory, "basis_functions_" + str(index) + "_content") assert basis_functions_loaded self._content["basis_functions"].append(basis_functions) # Recompute shape self._content["basis_functions_shape"] = DelayedTransposeShape( self._content["basis_functions"]) # Reset precomputed slices self._precomputed_slices = dict() self._prepare_trivial_precomputed_slice() else: raise ValueError("Invalid type") return True
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)