def transfer_manager(self): """This allows the transfer manager to be set from options, e.g. solver_parameters = {"ksp_type": "cg", "pc_type": "mg", "mg_transfer_manager": __name__ + ".manager"} The value for "mg_transfer_manager" can either be a specific instantiated object, or a function or class name. In the latter case it will be invoked with no arguments to instantiate the object. If "snes_type": "fas" is used, the relevant option is "fas_transfer_manager", with the same semantics. """ if self._transfer_manager is None: opts = PETSc.Options() prefix = self.options_prefix or "" if opts.hasName(prefix + "mg_transfer_manager"): managername = opts[prefix + "mg_transfer_manager"] elif opts.hasName(prefix + "fas_transfer_manager"): managername = opts[prefix + "fas_transfer_manager"] else: managername = None if managername is None: from firedrake import TransferManager transfer = TransferManager(use_averaging=True) else: (modname, objname) = managername.rsplit(".", 1) mod = __import__(modname) obj = getattr(mod, objname) if isinstance(obj, type): transfer = obj() else: transfer = obj self._transfer_manager = transfer return self._transfer_manager
def indicate_errors(self, enrichment_kwargs={}, adj_kwargs={}): """ Compute goal-oriented error indicators for each subinterval based on solving the adjoint problem in a globally enriched space. :kwarg enrichment_kwargs: keyword arguments to pass to the global enrichment method :kwarg adj_kwargs: keyword arguments to pass to the adjoint solver """ mesh_seq_e = self.get_enriched_mesh_seq(**enrichment_kwargs) sols = self.solve_adjoint(**adj_kwargs) sols_e = mesh_seq_e.solve_adjoint(**adj_kwargs) tm = TransferManager() indicators = [] for i, mesh in enumerate(self): P0 = FunctionSpace(self[i], "DG", 0) indicator = [] # Get Functions u, u_, u_star, u_star_next, u_star_e = {}, {}, {}, {}, {} solutions = {} enriched_spaces = { f: mesh_seq_e.function_spaces[f][i] for f in self.fields } mapping = {} for f, fs_e in enriched_spaces.items(): u[f] = Function(fs_e) u_[f] = Function(fs_e) mapping[f] = (u[f], u_[f]) u_star[f] = Function(fs_e) u_star_next[f] = Function(fs_e) u_star_e[f] = Function(fs_e) solutions[f] = [ sols[f]["forward"][i], sols[f]["forward_old"][i], sols[f]["adjoint"][i], sols[f]["adjoint_next"][i], sols_e[f]["adjoint"][i], sols_e[f]["adjoint_next"][i], ] # Get form in enriched space F = mesh_seq_e.form(i, mapping) for j in range(len(sols[self.fields[0]]["forward"][i])): for f in self.fields: # Update fields tm.prolong(sols[f]["forward"][i][j], u[f]) tm.prolong(sols[f]["forward_old"][i][j], u_[f]) tm.prolong(sols[f]["adjoint"][i][j], u_star[f]) tm.prolong(sols[f]["adjoint_next"][i][j], u_star_next[f]) # Combine adjoint solutions as appropriate u_star[f].assign(0.5 * (u_star[f] + u_star_next[f])) u_star_e[f].assign(0.5 * (sols_e[f]["adjoint"][i][j] + sols_e[f]["adjoint_next"][i][j])) u_star_e[f] -= u_star[f] # Evaluate error indicator indi_e = get_dwr_indicator(F, u_star_e, enriched_spaces) # Project back to the base space indi = project(indi_e, P0) indi.interpolate(abs(indi)) indicator.append(indi) indicators.append(indicator) return sols, indicators
def transfer_manager(self): if self._transfer_manager is None: from firedrake import TransferManager self._transfer_manager = TransferManager(use_averaging=True) return self._transfer_manager