def _offline(self): # Change default online solve arguments during offline stage to not use rectification # (which will be prepared in a postprocessing stage) self.reduced_problem._online_solve_default_kwargs[ "online_rectification"] = False self.reduced_problem.OnlineSolveKwargs = OnlineSolveKwargsGenerator( **self.reduced_problem._online_solve_default_kwargs) # Call standard offline phase EllipticCoerciveReductionMethod_DerivedClass._offline(self) print( "==============================================================" ) print("=" + "{:^60}".format( self.label + " offline rectification postprocessing phase begins") + "=") print( "==============================================================" ) print("") # Compute projection of truth and reduced snapshots self.reduced_problem.init("offline_rectification_postprocessing") self.reduced_problem.build_reduced_operators( "offline_rectification_postprocessing") # Carry out a consistency verification of the rectified solution for n in range(1, self.reduced_problem.N + 1): print( "consistency verification of rectified solutions for n =", n) for online_solve_kwargs in self.reduced_problem.online_solve_kwargs_with_rectification: print("\tonline solve options:", dict(online_solve_kwargs)) for mu_i in self.reduced_problem.snapshots_mu[:n]: self.reduced_problem.set_mu(mu_i) self.reduced_problem.solve(n, **online_solve_kwargs) error = self.reduced_problem.compute_error( **online_solve_kwargs) print("\t\tmu = " + str(mu_i) + ", absolute error = " + str(error)) print( "==============================================================" ) print("=" + "{:^60}".format( self.label + " offline rectification postprocessing phase ends") + "=") print( "==============================================================" ) print("") # Restore default online solve arguments for online stage self.reduced_problem._online_solve_default_kwargs[ "online_rectification"] = True self.reduced_problem.OnlineSolveKwargs = OnlineSolveKwargsGenerator( **self.reduced_problem._online_solve_default_kwargs)
def __init__(self, truth_problem, **kwargs): # Call to parent EllipticCoerciveReducedProblem_DerivedClass.__init__( self, truth_problem, **kwargs) # Store vanishing viscosity data self._viscosity = truth_problem._viscosity self._N_threshold_min = truth_problem._N_threshold_min self._N_threshold_max = truth_problem._N_threshold_max # Temporary storage for vanishing viscosity eigenvalues self.vanishing_viscosity_eigenvalues = list() # Default values for keyword arguments in solve self._online_solve_default_kwargs = OrderedDict() self._online_solve_default_kwargs["online_stabilization"] = False self._online_solve_default_kwargs[ "online_vanishing_viscosity"] = True self.OnlineSolveKwargs = OnlineSolveKwargsGenerator( **self._online_solve_default_kwargs) # Flag to disable inner product combination after vanishing viscosity operator has been setup self._disable_inner_product_combination = False # Flag to disable error estimation after vanishing viscosity operator has been setup self._disable_error_estimation = False
def __init__(self, truth_problem, **kwargs): # Call to parent EllipticCoerciveReducedProblem_DerivedClass.__init__( self, truth_problem, **kwargs) # Copy of greedy snapshots self.snapshots_mu = GreedySelectedParametersList( ) # the difference between this list and greedy_selected_parameters in the reduction method is that this one also stores the initial parameter self.snapshots = SnapshotsMatrix(truth_problem.V) # Extend allowed keywords argument in solve self._online_solve_default_kwargs["online_rectification"] = True self.OnlineSolveKwargs = OnlineSolveKwargsGenerator( **self._online_solve_default_kwargs) # Generate all combinations of allowed keyword arguments in solve online_solve_kwargs_with_rectification = list() online_solve_kwargs_without_rectification = list() for other_args in cartesian_product( (True, False), repeat=len(self._online_solve_default_kwargs) - 1): args_with_rectification = self.OnlineSolveKwargs(*(other_args + (True, ))) args_without_rectification = self.OnlineSolveKwargs( *(other_args + (False, ))) online_solve_kwargs_with_rectification.append( args_with_rectification) online_solve_kwargs_without_rectification.append( args_without_rectification) self.online_solve_kwargs_with_rectification = online_solve_kwargs_with_rectification self.online_solve_kwargs_without_rectification = online_solve_kwargs_without_rectification # Flag to disable error estimation after rectification has been setup self._disable_error_estimation = False
def __init__(self, truth_problem, **kwargs): # Call to parent EllipticCoerciveReducedProblem_DerivedClass.__init__( self, truth_problem, **kwargs) # Default values for keyword arguments in solve self._online_solve_default_kwargs = OrderedDict() self._online_solve_default_kwargs["online_stabilization"] = True self.OnlineSolveKwargs = OnlineSolveKwargsGenerator( **self._online_solve_default_kwargs)
def _offline(self): # Change default online solve arguments during offline stage to use online stabilization # instead of vanishing viscosity one (which will be prepared in a postprocessing stage) self.reduced_problem._online_solve_default_kwargs[ "online_stabilization"] = True self.reduced_problem._online_solve_default_kwargs[ "online_vanishing_viscosity"] = False self.reduced_problem.OnlineSolveKwargs = OnlineSolveKwargsGenerator( **self.reduced_problem._online_solve_default_kwargs) # Call standard offline phase EllipticCoerciveReductionMethod_DerivedClass._offline(self) # Start vanishing viscosity postprocessing print( TextBox( self.truth_problem.name() + " " + self.label + " offline vanishing viscosity postprocessing phase begins", fill="=")) print("") # Prepare storage for copy of lifting basis functions matrix lifting_basis_functions = BasisFunctionsMatrix( self.truth_problem.V) lifting_basis_functions.init(self.truth_problem.components) # Copy current lifting basis functions to lifting_basis_functions N_bc = self.reduced_problem.N_bc for i in range(N_bc): lifting_basis_functions.enrich( self.reduced_problem.basis_functions[i]) # Prepare storage for unrotated basis functions matrix, without lifting unrotated_basis_functions = BasisFunctionsMatrix( self.truth_problem.V) unrotated_basis_functions.init(self.truth_problem.components) # Copy current basis functions (except lifting) to unrotated_basis_functions N = self.reduced_problem.N for i in range(N_bc, N): unrotated_basis_functions.enrich( self.reduced_problem.basis_functions[i]) # Prepare new storage for non-hierarchical basis functions matrix and # corresponding affine expansions self.reduced_problem.init( "offline_vanishing_viscosity_postprocessing") # Rotated basis functions matrix are not hierarchical, i.e. a different # rotation will be applied for each basis size n. for n in range(1, N + 1): # Prepare storage for rotated basis functions matrix rotated_basis_functions = BasisFunctionsMatrix( self.truth_problem.V) rotated_basis_functions.init(self.truth_problem.components) # Rotate basis print("rotate basis functions matrix for n =", n) truth_operator_k = self.truth_problem.operator["k"] truth_operator_m = self.truth_problem.operator["m"] assert len(truth_operator_k) == 1 assert len(truth_operator_m) == 1 reduced_operator_k = ( transpose(unrotated_basis_functions[:n]) * truth_operator_k[0] * unrotated_basis_functions[:n]) reduced_operator_m = ( transpose(unrotated_basis_functions[:n]) * truth_operator_m[0] * unrotated_basis_functions[:n]) rotation_eigensolver = OnlineEigenSolver( unrotated_basis_functions[:n], reduced_operator_k, reduced_operator_m) parameters = { "problem_type": "hermitian", "spectrum": "smallest real" } rotation_eigensolver.set_parameters(parameters) rotation_eigensolver.solve() # Store and save rotated basis rotation_eigenvalues = ExportableList("text") rotation_eigenvalues.extend([ rotation_eigensolver.get_eigenvalue(i)[0] for i in range(n) ]) for i in range(0, n): print("lambda_" + str(i) + " = " + str(rotation_eigenvalues[i])) rotation_eigenvalues.save(self.folder["post_processing"], "rotation_eigs_n=" + str(n)) for i in range(N_bc): rotated_basis_functions.enrich(lifting_basis_functions[i]) for i in range(0, n): (eigenvector_i, _) = rotation_eigensolver.get_eigenvector(i) rotated_basis_functions.enrich( unrotated_basis_functions[:n] * eigenvector_i) self.reduced_problem.basis_functions[: n] = rotated_basis_functions # Attach eigenvalues to the vanishing viscosity reduced operator self.reduced_problem.vanishing_viscosity_eigenvalues.append( rotation_eigenvalues) # Save basis functions self.reduced_problem.basis_functions.save( self.reduced_problem.folder["basis"], "basis") # Re-compute all reduced operators, since the basis functions have changed print("build reduced operators") self.reduced_problem.build_reduced_operators( "offline_vanishing_viscosity_postprocessing") # Clean up reduced solution and output cache, since the basis has changed self.reduced_problem._solution_cache.clear() self.reduced_problem._output_cache.clear() print( TextBox( self.truth_problem.name() + " " + self.label + " offline vanishing viscosity postprocessing phase ends", fill="=")) print("") # Restore default online solve arguments for online stage self.reduced_problem._online_solve_default_kwargs[ "online_stabilization"] = False self.reduced_problem._online_solve_default_kwargs[ "online_vanishing_viscosity"] = True self.reduced_problem.OnlineSolveKwargs = OnlineSolveKwargsGenerator( **self.reduced_problem._online_solve_default_kwargs)