def __init__(self, operators, functionals, vector_operators, products=None, estimator=None, visualizer=None, cache_region=None, name=None): self.operators = FrozenDict(operators) self.functionals = FrozenDict(functionals) self.vector_operators = FrozenDict(vector_operators) self.linear = all( op is None or op.linear for op in chain(operators.values(), functionals.values())) self.products = products self.estimator = estimator self.visualizer = visualizer self.enable_caching(cache_region) self.name = name if products: for k, v in products.items(): setattr(self, '{}_product'.format(k), v) setattr(self, '{}_norm'.format(k), induced_norm(v))
def __init__(self, d): self._impl = d lhs_op = BlockOperator([[wrapper[d.get_local_operator(ss)] if ss == nn else wrapper[d.get_coupling_operator(ss, nn)] if nn in list(d.neighbouring_subdomains(ss)) else None for nn in np.arange(d.num_subdomains())] for ss in np.arange(d.num_subdomains())]) rhs_op = BlockOperator.hstack([wrapper[d.get_local_functional(ss)] for ss in np.arange(d.num_subdomains())]) operators = {'operator': lhs_op} functionals = {'rhs': rhs_op} vector_operators = {} self.operators = FrozenDict(operators) self.functionals = FrozenDict(functionals) self.vector_operators = FrozenDict(vector_operators) self.operator = operators['operator'] self.solution_space = self.operator.source self.rhs = functionals['rhs'] self.products = {k: BlockDiagonalOperator([wrapper[d.get_local_product(ss, k)] for ss in np.arange(d.num_subdomains())]) for k in list(d.available_products())} if self.products: for k, v in self.products.iteritems(): setattr(self, '{}_product'.format(k), v) setattr(self, '{}_norm'.format(k), induced_norm(v)) self.linear = all(op.linear for op in operators.itervalues()) self.num_subdomains = self._impl.num_subdomains() self.neighboring_subdomains = [self._impl.neighbouring_subdomains(ss) for ss in np.arange(self.num_subdomains)] self.build_parameter_type(inherits=operators.values()) assert self.parameter_type == self._wrapper[d.parameter_type()]
def __init__(self, d): def wrap_op(op, name=None): if not op.parametric() and op.num_components() == 0 and op.has_affine_part(): wrapped_op = self._wrapper[op.affine_part()] else: wrapped_op = self._wrapper[op] return wrapped_op.with_(name=name) if name else wrapped_op self._impl = d operators = {'operator': wrap_op(d.get_operator())} functionals = {'rhs': self._wrapper[d.get_rhs()]} vector_operators = FrozenDict({k: VectorOperator(make_listvectorarray(self._wrapper[d.get_vector(k)])) for k in list(d.available_vectors())}) self.operators = FrozenDict(operators) self.functionals = FrozenDict(functionals) self.vector_operators = FrozenDict(vector_operators) self.operator = operators['operator'] self.rhs = functionals['rhs'] self.products = FrozenDict({k: wrap_op(d.get_product(k), k) for k in list(d.available_products())}) if self.products: for k, v in self.products.iteritems(): setattr(self, '{}_product'.format(k), v) setattr(self, '{}_norm'.format(k), induced_norm(v)) self.linear = all(op.linear for op in operators.itervalues()) self.solution_space = self.operator.source self.build_parameter_type(inherits=operators.values() + functionals.values()) assert self.parameter_type == self._wrapper[d.parameter_type()] self.solver_options = self._impl.solver_options()
def __init__( self, operators, functionals, vector_operators, products=None, estimator=None, visualizer=None, cache_region=None, name=None, ): self.operators = FrozenDict(operators) self.functionals = FrozenDict(functionals) self.vector_operators = FrozenDict(vector_operators) self.linear = all(op is None or op.linear for op in chain(operators.itervalues(), functionals.itervalues())) self.products = products self.estimator = estimator self.visualizer = visualizer self.enable_caching(cache_region) self.name = name if products: for k, v in products.iteritems(): setattr(self, "{}_product".format(k), v) setattr(self, "{}_norm".format(k), induced_norm(v))
def test_induced(): grid = TriaGrid(num_intervals=(10, 10)) boundary_info = AllDirichletBoundaryInfo(grid) product = L2ProductP1(grid, boundary_info) zero = product.source.zeros() norm = induced_norm(product) value = norm(zero) np.testing.assert_almost_equal(value, 0.0)
def test_induced(): grid = TriaGrid(num_intervals=(10, 10)) boundary_info = AllDirichletBoundaryInfo(grid) product = L2ProductP1(grid, boundary_info) zero = NumpyVectorArray(np.zeros(grid.size(2))) norm = induced_norm(product) value = norm(zero) np.testing.assert_almost_equal(value, 0.0)
def almost_equal(U, V, U_ind=None, V_ind=None, product=None, norm=None, rtol=1e-14, atol=1e-14): """Compare U and V for almost equality. The vectors of `U` and `V` are compared in pairs for almost equality. Two vectors `u` and `v` are considered almost equal iff ||u - v|| <= atol + ||v|| * rtol. The norm to be used can be specified via the `norm` or `product` parameter. If the length of `U` (`U_ind`) resp. `V` (`V_ind`) is 1, the single specified vector is compared to all vectors of the other array. Otherwise, the lengths of both indexed arrays have to agree. Parameters ---------- U, V |VectorArrays| to be compared. U_ind, V_ind Indices of the vectors that are to be compared (see |VectorArray|). product If specified, use this inner product |Operator| to compute the norm. `product` and `norm` are mutually exclusive. norm If specified, must be a callable, which is used to compute the norm or, alternatively, one of the string 'l1', 'l2', 'sup', in which case the respective |VectorArray| norm methods are used. `product` and `norm` are mutually exclusive. If neither is specified, `norm='l2'` is assumed. rtol The relative tolerance. atol The absolute tolerance. """ assert product is None or norm is None assert not isinstance(norm, str) or norm in ('l1', 'l2', 'sup') norm = induced_norm(product) if product is not None else norm if norm is None: norm = 'l2' if isinstance(norm, str): norm_str = norm norm = lambda U: getattr(U, norm_str + '_norm')() X = V.copy(V_ind) V_norm = norm(X) # broadcast if necessary if len(X) == 1: len_U = U.len_ind(U_ind) if len_U > 1: X.append(X, o_ind=np.zeros(len_U - 1, dtype=np.int)) X.axpy(-1, U, x_ind=U_ind) ERR_norm = norm(X) return ERR_norm <= atol + V_norm * rtol
def reconstruct(self, u): """Reconstruct high-dimensional residual vector from reduced vector `u`.""" if self.residual_range is False: if self.product: norm = induced_norm(self.product) return u * (u.l2_norm() / norm(u))[0] else: return u else: return self.residual_range[:u.dim].lincomb(u.to_numpy())
def almost_equal(U, V, product=None, norm=None, rtol=1e-14, atol=1e-14): """Compare U and V for almost equality. The vectors of `U` and `V` are compared in pairs for almost equality. Two vectors `u` and `v` are considered almost equal iff ||u - v|| <= atol + ||v|| * rtol. The norm to be used can be specified via the `norm` or `product` parameter. If the length of `U` resp. `V` is 1, the single specified vector is compared to all vectors of the other array. Otherwise, the lengths of both indexed arrays have to agree. Parameters ---------- U, V |VectorArrays| to be compared. product If specified, use this inner product |Operator| to compute the norm. `product` and `norm` are mutually exclusive. norm If specified, must be a callable, which is used to compute the norm or, alternatively, one of the string 'l1', 'l2', 'sup', in which case the respective |VectorArray| norm methods are used. `product` and `norm` are mutually exclusive. If neither is specified, `norm='l2'` is assumed. rtol The relative tolerance. atol The absolute tolerance. """ assert product is None or norm is None assert not isinstance(norm, str) or norm in ('l1', 'l2', 'sup') norm = induced_norm(product) if product is not None else norm if norm is None: norm = 'l2' if isinstance(norm, str): norm_str = norm norm = lambda U: getattr(U, norm_str + '_norm')() X = V.copy() V_norm = norm(X) # broadcast if necessary if len(X) == 1: if len(U) > 1: X.append(X[np.zeros(len(U) - 1, dtype=np.int)]) X -= U ERR_norm = norm(X) return ERR_norm <= atol + V_norm * rtol
def __init__(self, products=None, estimator=None, visualizer=None, name=None, **kwargs): products = FrozenDict(products or {}) if products: for k, v in products.items(): setattr(self, f'{k}_product', v) setattr(self, f'{k}_norm', induced_norm(v)) self.__auto_init(locals())
def __init__(self, products=None, estimator=None, visualizer=None, cache_region=None, name=None, **kwargs): self.products = FrozenDict(products or {}) self.estimator = estimator self.visualizer = visualizer self.enable_caching(cache_region) self.name = name if products: for k, v in products.items(): setattr(self, f'{k}_product', v) setattr(self, f'{k}_norm', induced_norm(v))
def test_almost_equal_self_product(operator_with_arrays_and_products): _, _, v, _, product, _ = operator_with_arrays_and_products norm = induced_norm(product) for ind in valid_inds(v): for rtol, atol in ((1e-5, 1e-8), (1e-10, 1e-12), (0., 1e-8), (1e-5, 1e-8), (1e-12, 0.)): r = almost_equal(v[ind], v[ind], norm=norm) assert isinstance(r, np.ndarray) assert r.shape == (v.len_ind(ind),) assert np.all(r) if v.len_ind(ind) == 0 or np.max(v[ind].sup_norm() == 0): continue r = almost_equal(v[ind], v[ind], product=product) assert isinstance(r, np.ndarray) assert r.shape == (v.len_ind(ind),) assert np.all(r) if v.len_ind(ind) == 0 or np.max(v[ind].sup_norm() == 0): continue c = v.copy() c.scal(atol * (1 - 1e-10) / (np.max(norm(v[ind])))) assert np.all(almost_equal(c[ind], c.zeros(v.len_ind(ind)), atol=atol, rtol=rtol, norm=norm)) assert np.all(almost_equal(c[ind], c.zeros(v.len_ind(ind)), atol=atol, rtol=rtol, product=product)) if atol > 0: c = v.copy() c.scal(2. * atol / (np.max(norm(v[ind])))) assert not np.all(almost_equal(c[ind], c.zeros(v.len_ind(ind)), atol=atol, rtol=rtol, norm=norm)) assert not np.all(almost_equal(c[ind], c.zeros(v.len_ind(ind)), atol=atol, rtol=rtol, product=product)) c = v.copy() c.scal(1. + rtol * 0.9) assert np.all(almost_equal(c[ind], v[ind], atol=atol, rtol=rtol, norm=norm)) assert np.all(almost_equal(c[ind], v[ind], atol=atol, rtol=rtol, product=product)) if rtol > 0: c = v.copy() c.scal(2. + rtol * 1.1) assert not np.all(almost_equal(c[ind], v[ind], atol=atol, rtol=rtol, norm=norm)) assert not np.all(almost_equal(c[ind], v[ind], atol=atol, rtol=rtol, product=product)) c = v.copy() c.scal(1. + atol * 0.9 / np.max(np.max(norm(v[ind])))) assert np.all(almost_equal(c[ind], v[ind], atol=atol, rtol=rtol, norm=norm)) assert np.all(almost_equal(c[ind], v[ind], atol=atol, rtol=rtol, product=product)) if atol > 0 or rtol > 0: c = v.copy() c.scal(1 + rtol * 1.1 + atol * 1.1 / np.max(np.max(norm(v[ind])))) assert not np.all(almost_equal(c[ind], v[ind], atol=atol, rtol=rtol, norm=norm)) assert not np.all(almost_equal(c[ind], v[ind], atol=atol, rtol=rtol, product=product))
def __init__(self, operators=None, products=None, estimator=None, visualizer=None, cache_region=None, name=None, **kwargs): operators = {} if operators is None else dict(operators) # handle special operators for on in self.special_operators: # special operators must be provided as keyword argument to __init__ assert on in kwargs # special operators may not already exist as attributes assert not hasattr(self, on) # special operators may not be contained in operators dict assert on not in operators op = kwargs[on] # operators either have to be None or an Operator assert op is None \ or isinstance(op, OperatorInterface) \ or all(isinstance(o, OperatorInterface) for o in op) # set special operator as an attribute setattr(self, on, op) # add special operator to the operators dict operators[on] = op self.operators = FrozenDict(operators) self.linear = all(op is None or op.linear for op in operators.values()) self.products = FrozenDict(products or {}) self.estimator = estimator self.visualizer = visualizer self.enable_caching(cache_region) self.name = name if products: for k, v in products.items(): setattr(self, '{}_product'.format(k), v) setattr(self, '{}_norm'.format(k), induced_norm(v)) self.build_parameter_type(*operators.values())
def calculate_csis(gq, lq): spaces = gq["spaces"] for space in spaces: ldict = lq[space] T = ldict["solution_matrix_robin"] u_s = ldict["local_sol2"] product = ldict["omega_star_product"] norm = induced_norm(product) if norm(u_s).real < 1e-14: result = 1 else: x = np.linalg.lstsq(T, u_s.data.T, rcond=None)[0] y = T.dot(x) y_p = NumpyVectorSpace.make_array(y.T) y_p = y_p.lincomb(1 / norm(y_p).real) result = np.sqrt( norm(u_s).real[0]**2 / (norm(u_s).real[0]**2 - product.apply2(u_s, y_p).real[0][0]**2)) ldict["csi"] = result print("calculated csis")
def test_almost_equal_product(operator_with_arrays_and_products): _, _, v1, _, product, _ = operator_with_arrays_and_products if len(v1) < 2: return v2 = v1.empty() v2.append(v1[:len(v1) // 2]) for ind1, ind2 in valid_inds_of_same_length(v1, v2): for rtol, atol in ((1e-5, 1e-8), (1e-10, 1e-12), (0., 1e-8), (1e-5, 1e-8)): norm = induced_norm(product) r = almost_equal(v1[ind1], v2[ind2], norm=norm) assert isinstance(r, np.ndarray) assert r.shape == (v1.len_ind(ind1),) assert np.all(r == (norm(v1[ind1] - v2[ind2]) <= atol + rtol * norm(v2[ind2]))) r = almost_equal(v1[ind1], v2[ind2], product=product) assert isinstance(r, np.ndarray) assert r.shape == (v1.len_ind(ind1),) assert np.all(r == (norm(v1[ind1] - v2[ind2]) <= atol + rtol * norm(v2[ind2])))
def prepare(cfg): logger = getLogger('.OS2015_SISC__6_2.prepare') logger.setLevel('INFO') reference_needed = ( (cfg['greedy_use_estimator'] or cfg['estimate_some_errors']) and ('discretization_error' in cfg['estimator_compute'] or 'full_error' in cfg['estimator_compute'] or 'model_reduction_error' in cfg['estimator_compute']) or cfg['local_indicators'] == 'model_reduction_error') logger.info('Initializing DUNE module ({}):'.format(cfg['dune_example'])) Example = dune_module.__dict__[cfg['dune_example']] example = Example(partitioning=cfg['dune_partitioning'], num_refinements=cfg['dune_num_refinements'], oversampling_layers=cfg['dune_oversampling_layers'], products=cfg['dune_products'], with_reference=reference_needed, info_log_levels=cfg['dune_log_info_level'], debug_log_levels=cfg['dune_log_debug_level'], enable_warnings=cfg['dune_log_enable_warnings'], enable_colors=True, info_color='blue') _, wrapper = wrap_module(dune_module) discretization = wrapper[example.discretization()] logger.info(' grid has {} subdomain{}'.format( discretization.num_subdomains, '' if discretization.num_subdomains == 1 else 's')) logger.info(' discretization has {} DoFs'.format( discretization.solution_space.dim)) discretization = discretization.with_(parameter_space=CubicParameterSpace( discretization.parameter_type, cfg['parameter_range'][0], cfg['parameter_range'][1])) logger.info(' parameter type is {}'.format(discretization.parameter_type)) example.visualize(cfg['dune_example']) def create_product(products, product_type): if product_type is None: return None, 'None' if not isinstance(product_type, tuple): return products[product_type], product_type else: prods = [products[tt] for tt in product_type] product_name = product_type[0] for ii in np.arange(1, len(product_type)): product_name += '_plus_' + product_type[ii] return LincombOperator(operators=prods, coefficients=[1 for pp in prods ]), product_name logger.info('Preparing products and norms ...') mu_hat_dune = wrapper.DuneParameter('mu', cfg['mu_hat_value']) mu_bar_dune = wrapper.DuneParameter('mu', cfg['mu_bar_value']) all_global_products = {} all_local_products = [{} for ss in np.arange(discretization.num_subdomains)] # get all products from the discretization and assemble the parametric ones for nm, pr in discretization.products.items(): if not pr.parametric: all_global_products[nm] = pr else: all_global_products[nm] = pr.assemble(mu=wrapper[mu_bar_dune]) for ss in np.arange(discretization.num_subdomains): pr = discretization.local_product(ss, nm) if pr.parametric: all_local_products[ss][nm] = pr.assemble( mu=wrapper[mu_bar_dune]) else: all_local_products[ss][nm] = pr # combine products (if necessarry) global_product, _ = create_product(all_global_products, cfg['extension_product']) local_products, _ = map( list, zip(*[ create_product(all_local_pr, cfg['extension_product']) for all_local_pr in all_local_products ])) # assert all(nm == local_products_name[0] for nm in local_products_name) # local_products_name = local_products_name[0] norm, _ = create_product(all_global_products, cfg['greedy_error_norm']) norm = induced_norm(norm) if norm is not None else None return { 'example': example, 'discretization': discretization, 'local_products': local_products, 'norm': norm, 'mu_bar_dune': mu_bar_dune, 'mu_hat_dune': mu_hat_dune, 'wrapper': wrapper }
def prepare(cfg): logger = getLogger('.OS2015_SISC__6_2.prepare') logger.setLevel('INFO') reference_needed = ((cfg['greedy_use_estimator'] or cfg['estimate_some_errors']) and ('discretization_error' in cfg['estimator_compute'] or 'full_error' in cfg['estimator_compute'] or 'model_reduction_error' in cfg['estimator_compute']) or cfg['local_indicators'] == 'model_reduction_error') logger.info('Initializing DUNE module ({}):'.format(cfg['dune_example'])) Example = dune_module.__dict__[cfg['dune_example']] example = Example(partitioning=cfg['dune_partitioning'], num_refinements=cfg['dune_num_refinements'], oversampling_layers=cfg['dune_oversampling_layers'], products=cfg['dune_products'], with_reference=reference_needed, info_log_levels=cfg['dune_log_info_level'], debug_log_levels=cfg['dune_log_debug_level'], enable_warnings=cfg['dune_log_enable_warnings'], enable_colors=True, info_color='blue') _, wrapper = wrap_module(dune_module) discretization = wrapper[example.discretization()] logger.info(' grid has {} subdomain{}'.format(discretization.num_subdomains, '' if discretization.num_subdomains == 1 else 's')) logger.info(' discretization has {} DoFs'.format(discretization.solution_space.dim)) discretization = discretization.with_( parameter_space=CubicParameterSpace(discretization.parameter_type, cfg['parameter_range'][0], cfg['parameter_range'][1])) logger.info(' parameter type is {}'.format(discretization.parameter_type)) example.visualize(cfg['dune_example']) def create_product(products, product_type): if product_type is None: return None, 'None' if not isinstance(product_type, tuple): return products[product_type], product_type else: prods = [products[tt] for tt in product_type] product_name = product_type[0] for ii in np.arange(1, len(product_type)): product_name += '_plus_' + product_type[ii] return LincombOperator(operators=prods, coefficients=[1 for pp in prods]), product_name logger.info('Preparing products and norms ...') mu_hat_dune = wrapper.DuneParameter('mu', cfg['mu_hat_value']) mu_bar_dune = wrapper.DuneParameter('mu', cfg['mu_bar_value']) all_global_products = {} all_local_products = [{} for ss in np.arange(discretization.num_subdomains)] # get all products from the discretization and assemble the parametric ones for nm, pr in discretization.products.items(): if not pr.parametric: all_global_products[nm] = pr else: all_global_products[nm] = pr.assemble(mu=wrapper[mu_bar_dune]) for ss in np.arange(discretization.num_subdomains): pr = discretization.local_product(ss, nm) if pr.parametric: all_local_products[ss][nm] = pr.assemble(mu=wrapper[mu_bar_dune]) else: all_local_products[ss][nm] = pr # combine products (if necessarry) global_product, _ = create_product(all_global_products, cfg['extension_product']) local_products, _ = map(list, zip(*[create_product(all_local_pr, cfg['extension_product']) for all_local_pr in all_local_products])) # assert all(nm == local_products_name[0] for nm in local_products_name) # local_products_name = local_products_name[0] norm, _ = create_product(all_global_products, cfg['greedy_error_norm']) norm = induced_norm(norm) if norm is not None else None return {'example': example, 'discretization': discretization, 'local_products': local_products, 'norm': norm, 'mu_bar_dune': mu_bar_dune, 'mu_hat_dune': mu_hat_dune, 'wrapper': wrapper}
def __init__(self, estimator_matrix, coercivity_estimator): self.__auto_init(locals()) self.norm = induced_norm(estimator_matrix)
def __init__(self, estimator_matrix, coercivity_estimator): self.estimator_matrix = estimator_matrix self.coercivity_estimator = coercivity_estimator self.norm = induced_norm(estimator_matrix)
def localize_problem(p, coarse_grid_resolution, fine_grid_resolution, mus=None, calT=False, calTd=False, calQ=False, dof_codim=2, localization_codim=2, discretizer=None, m=1): assert coarse_grid_resolution > (m + 1) * 2 assert fine_grid_resolution % coarse_grid_resolution == 0 print("localizing problem") global_quantities = {} global_quantities["coarse_grid_resolution"] = coarse_grid_resolution local_quantities = {} # Diskretisierung auf dem feinen Gitter: diameter = 1. / fine_grid_resolution global_quantities["diameter"] = diameter if discretizer is None: discretizer = discretize_stationary_cg d, data = discretizer(p, diameter=diameter) grid = data["grid"] global_quantities["d"] = d global_quantities["data"] = data global_operator = d.operator.assemble(mus) global_quantities["op"] = global_operator global_quantities["op_not_assembled"] = d.operator global_rhs = d.rhs.assemble(mus) global_quantities["rhs"] = global_rhs op_fixed = copy.deepcopy(d.operator) # Skalierung der Dirichlet-Freiheitsgrade: try: dirichlet_dofs = data['boundary_info'].dirichlet_boundaries(dof_codim) for op in op_fixed.operators: op.assemble(mus).matrix[dirichlet_dofs, dirichlet_dofs] *= 1e5 # d.rhs.assemble(mus)._matrix[:, dirichlet_dofs] *= 1e5 except KeyError: pass global_operator_fixed = op_fixed.assemble(mus) global_quantities["op_fixed"] = global_operator_fixed global_quantities["op_fixed_not_assembled"] = op_fixed global_quantities["p"] = p try: dmask = data['boundary_info'].dirichlet_mask(dof_codim) except KeyError: dmask = None # Konstruktion der Teilraeume: subspaces, subspaces_per_codim = build_subspaces( *partition_any_grid(grid, num_intervals=(coarse_grid_resolution, coarse_grid_resolution), dmask=dmask, codim=dof_codim)) global_quantities["subspaces"] = subspaces global_quantities["subspaces_per_codim"] = subspaces_per_codim localizer = NumpyLocalizer(d.solution_space, subspaces['dofs']) global_quantities["localizer"] = localizer def create_m_patch(xspace, m): for i in range(m): space = xspace cspace = tuple( set(i for k in space if subspaces[k]['codim'] == 0 for i in subspaces[k]['cpatch'] if i not in space)) xspace = tuple( set(i for k in cspace if subspaces[k]['codim'] == 1 for i in subspaces[k]['env']) | set(space)) cxspace = tuple( set(i for k in xspace if subspaces[k]['codim'] == 0 for i in subspaces[k]['cpatch'] if i not in xspace)) return xspace, cxspace pou = localized_pou(subspaces, subspaces_per_codim, localizer, coarse_grid_resolution, grid, localization_codim, dof_codim) global_quantities["pou"] = pou spaces = [subspaces[s_id]["env"] for s_id in subspaces_per_codim[2]] global_quantities["spaces"] = spaces full_l2_product = d.products["l2"].assemble() full_h1_semi_product = d.products["h1_semi"].assemble() k_product = LincombOperator((full_h1_semi_product, full_l2_product), (1, mus["k"]**2)).assemble() global_quantities["full_norm"] = induced_norm(k_product) global_quantities["k_product"] = k_product for xpos in range(coarse_grid_resolution - 1): for ypos in range(coarse_grid_resolution - 1): # print "localizing..." s_id = subspaces_per_codim[localization_codim][ ypos + xpos * (coarse_grid_resolution - 1)] space = subspaces[s_id]["env"] ldict = {} local_quantities[space] = ldict ldict["pos"] = (xpos, ypos) # Konstruktion der lokalen Raeume: range_space = subspaces[s_id]["env"] ldict["range_space"] = range_space omega_space = tuple( sorted( set(subspaces[s_id]['env']) | set(subspaces[s_id]['cenv']))) ldict["omega_space"] = omega_space training_space, source_space = create_m_patch(range_space, m) # source_space = subspaces[s_id]["cxenv"] ldict["source_space"] = source_space # training_space = subspaces[s_id]["xenv"] ldict["training_space"] = training_space omega_star_space = tuple( sorted(set(training_space) | set(source_space))) ldict["omega_star_space"] = omega_star_space # lokale Shift-Loesung mit f(Dirichlet) local_op = localizer.localize_operator(global_operator, training_space, training_space) local_rhs = localizer.localize_operator(global_rhs, None, training_space) local_solution = local_op.apply_inverse(local_rhs.as_range_array()) local_solution = localizer.to_space(local_solution, training_space, range_space) local_solution = pou[range_space](local_solution) ldict["local_solution_dirichlet"] = local_solution # Dirichlet Transferoperator: rhsop = localizer.localize_operator(global_operator, training_space, source_space) transop_dirichlet = create_dirichlet_transfer( localizer, local_op, rhsop, source_space, training_space, range_space, pou) ldict["dirichlet_transfer"] = transop_dirichlet # subgrid xmin = max(0, xpos - m) xsize = min(xpos + 2 + m, coarse_grid_resolution) - xmin ymin = max(0, ypos - m) ysize = min(ypos + 2 + m, coarse_grid_resolution) - ymin ldict["posext"] = [(xmin / coarse_grid_resolution, ymin / coarse_grid_resolution), ((xmin + xsize) / coarse_grid_resolution, (ymin + ysize) / coarse_grid_resolution)] mysubgrid = getsubgrid(grid, xmin, ymin, coarse_grid_resolution, xsize=xsize, ysize=ysize) mysubbi = SubGridBoundaryInfo(mysubgrid, grid, data['boundary_info'], 'robin') ld, ldata = discretizer(p, grid=mysubgrid, boundary_info=mysubbi) lop = ld.operator.assemble(mus) # index conversion ndofsext = len(ldata['grid'].parent_indices(dof_codim)) global_dofnrsext = -100000000 * np.ones( shape=(d.solution_space.dim, )) global_dofnrsext[ldata['grid'].parent_indices( dof_codim)] = np.array(range(ndofsext)) lvecext = localizer.localize_vector_array( NumpyVectorSpace.make_array(global_dofnrsext), omega_star_space).data[0] # Robin Transferoperator: bilifo = NumpyMatrixOperator(lop.matrix[:, lvecext][lvecext, :]) transop_robin = create_robin_transfer(localizer, bilifo, source_space, omega_star_space, range_space, pou) ldict["robin_transfer"] = transop_robin # lokale Shift-Loesung mit f(Robin) lrhs = ld.rhs.assemble(mus) llrhs = NumpyMatrixOperator(lrhs.matrix[lvecext.astype(int)]) local_solution = bilifo.apply_inverse(llrhs.as_range_array()) ldict["local_sol2"] = local_solution local_solution = localizer.to_space(local_solution, omega_star_space, range_space) local_solution_pou = pou[range_space](local_solution) ldict["local_solution_robin"] = local_solution_pou if calT: # Transfer-Matrix: ldict["transfer_matrix_robin"] = transop_robin.as_range_array( ).data.T if calTd: # Transfer-Matrix: ldict[ "transfer_matrix_dirichlet"] = transop_dirichlet.as_range_array( ).data.T # Konstruktion der Produkte: range_k = localizer.localize_operator(k_product, range_space, range_space) omstar_k = LincombOperator((NumpyMatrixOperator( ld.products["h1_semi"].assemble().matrix[:, lvecext][lvecext, :]), NumpyMatrixOperator( ld.products["l2"].assemble( ).matrix[:, lvecext][lvecext, :])), (1, mus["k"]**2)).assemble() ldict["omega_star_product"] = omstar_k ldict["range_product"] = range_k if calQ: # Loesungs-Matrix: solution_op_robin = create_robin_solop(localizer, bilifo, source_space, omega_star_space) Q_r = solution_op_robin.as_range_array() ldict["solution_matrix_robin"] = Q_r.data.T source_Q_r_product = NumpyMatrixOperator( omstar_k.apply(Q_r).data.T) ldict["source_product"] = source_Q_r_product lproduct = localizer.localize_operator(full_l2_product, source_space, source_space) lmat = lproduct.matrix.tocoo() lmat.data = np.array([ 4. / 6. * diameter if (row == col) else diameter / 6. for row, col in zip(lmat.row, lmat.col) ]) ldict["source_product"] = NumpyMatrixOperator(lmat.tocsc().astype( np.cfloat)) return global_quantities, local_quantities
def __init__(self, product): self.norm = induced_norm(product) if product else None
def online_phase(cfg, detailed_data, offline_data): logger = getLogger('.OS2015_SISC__6_2.online_phase') logger.setLevel('INFO') def doerfler_marking(indicators, theta): assert 0.0 < theta <= 1.0 indices = list(range(len(indicators))) indicators = [ii**2 for ii in indicators] indicators, indices = [list(x) for x in zip(*sorted(zip(indicators, indices), key=lambda pair: pair[0], reverse=True))] total = np.sum(indicators) sums = np.array([np.sum(indicators[:ii+1]) for ii in np.arange(len(indicators))]) where = sums > theta*total if np.any(where): return indices[:np.argmax(where)+1] else: return indices discretization = detailed_data['discretization'] example = detailed_data['example'] local_products = detailed_data['local_products'] mu_bar_dune = detailed_data['mu_bar_dune'] mu_hat_dune = detailed_data['mu_hat_dune'] norm = detailed_data['norm'] wrapper = detailed_data['wrapper'] basis = offline_data['basis'] basis_mus = offline_data['basis_mus'] rd = offline_data['rd'] rc = offline_data['rc'] reduced_estimator = ReducedEstimator(discretization, example, wrapper, mu_hat_dune, mu_bar_dune, norm, cfg['estimator_compute'], cfg['estimator_return']) reduced_estimator.extension_step += 1 reduced_estimator.rc = rc num_test_samples = cfg['num_test_samples'] target_error = cfg['online_target_error'] logger.info('Started online phase for {} samples'.format(num_test_samples)) test_samples = list(discretization.parameter_space.sample_randomly(num_test_samples)) if cfg['estimate_some_errors'] and len(test_samples) > 0: logger.info('Estimating discretization errors:') detailed_estimator = DetailedEstimator(example, wrapper, mu_hat_dune, mu_bar_dune) estimates = [detailed_estimator.estimate( discretization.globalize_vectors(discretization.solve(mu))._list[0]._impl, wrapper.dune_parameter(mu)) for mu in test_samples] max_error = np.amax(estimates) logger.info(' range: [{}, {}]'.format(np.amin(estimates), max_error)) logger.info(' mean: {}'.format(np.mean(estimates))) add_values(estimates=estimates) if max_error > cfg['online_target_error']: logger.warn('Given target error of {} is below the worst discretization error {}!'.format( cfg['online_target_error'], max_error)) print('') failures = 0 successes = 0 for mu in test_samples: mu_dune = wrapper.dune_parameter(mu) mu_in_basis = mu in basis_mus age = np.ones(discretization.num_subdomains) logger.info('Solving for {} ...'.format(mu)) U_red = rd.solve(mu) logger.info('Estimating (mu is {}in the basis) ...'.format('already ' if mu_in_basis else 'not ')) error = reduced_estimator.estimate(U_red, mu, discretization) if error > target_error: if mu_in_basis: logger.error(('The error ({}) is larger than the target_error ({}), ' + 'but {} is already in the basis: aborting!').format( error, target_error, mu)) logger.error('This usually means that the tolerances are poorly chosen!') failures += 1 print('') else: try: logger.info('The error ({}) is too large, starting local enrichment phase:'.format(error)) num_extensions = 0 intermediate_basis = [bb.copy() for bb in basis] if cfg['local_indicators'] == 'model_reduction_error': U_h = discretization.solve(mu) assert len(U_h) == 1 while error > target_error and num_extensions < cfg['online_max_extensions']: U_red_h = rc.reconstruct(U_red) assert len(U_red_h) == 1 U_red_global = discretization.globalize_vectors(U_red_h) U_red_dune = U_red_global._list[0]._impl if (cfg['uniform_enrichment_factor'] > 0 and error/target_error > cfg['uniform_enrichment_factor']): logger.info('- Enriching on all subdomains, since error/target_error = {}'.format( error/target_error)) marked_subdomains = range(discretization.num_subdomains) if 'age' in cfg['marking_strategy']: age = np.ones(discretization.num_subdomains) else: logger.info('- Estimating local error contributions ...') # compute local error indicators if cfg['local_indicators'] == 'model_reduction_error': difference = U_h - U_red_h local_indicators = [induced_norm(local_products[ss])(difference._blocks[ss]) for ss in np.arange(discretization.num_subdomains)] elif cfg['local_indicators'] == 'eta_red': local_indicators = list(example.estimate_local(U_red_dune, 'eta_OS2014_*', mu_hat_dune, mu_bar_dune, mu_dune)) else: raise ConfigurationError('Unknown local_indicators given: {}'.format( cfg['local_indicators'])) # mark subdomains if 'doerfler' in cfg['marking_strategy']: marked_subdomains = set(doerfler_marking(local_indicators, cfg['doerfler_marking_theta'])) else: raise ConfigurationError('Unknown marking_strategy given: {}'.format( cfg['local_indicators'])) if 'neighbours' in cfg['marking_strategy']: for ss in list(marked_subdomains): neighbours = (list(discretization._impl.neighbouring_subdomains(ss))) for nn in neighbours: marked_subdomains.append(nn) marked_subdomains = set(marked_subdomains) if 'age' in cfg['marking_strategy']: only_marked = len(marked_subdomains) too_old = np.where(age > cfg['marking_max_age'])[0] for ss in too_old: marked_subdomains.add(ss) logger.info((' {} subdomains marked ({} bc. of age), ' + 'computing local solutions ...').format( len(marked_subdomains), len(marked_subdomains) - only_marked)) else: logger.info(' {} subdomains marked, computing local solutions ...'.format( len(marked_subdomains))) for ss in np.arange(discretization.num_subdomains): if ss in marked_subdomains: age[ss] = 1 else: age[ss] += 1 # compute updated local solution local_solutions = [None for ss in np.arange(discretization.num_subdomains)] for subdomain in marked_subdomains: local_boundary_values = cfg['local_boundary_values'] if not (local_boundary_values == 'dirichlet' or local_boundary_values == 'neumann'): raise ConfigurationError('Unknown local_boundary_values given: {}'.format( local_boundary_values)) oversampled_discretization = discretization.get_oversampled_discretization( subdomain, local_boundary_values) local_discretization = discretization.get_local_discretization(subdomain) U_red_oversampled_dune = example.project_global_to_oversampled(U_red_dune, subdomain) U_h_improved_oversampled_dune = example.solve_oversampled( subdomain, local_boundary_values, U_red_oversampled_dune, mu_dune) U_h_improved_local_dune = example.project_oversampled_to_local( U_h_improved_oversampled_dune, subdomain) U_h_improved_local = make_listvectorarray(wrapper[U_h_improved_local_dune]) local_solutions[subdomain] = U_h_improved_local # extend local bases logger.info(' Extending bases on {} subdomain{}...'.format( len(marked_subdomains), '' if len(marked_subdomains) == 1 else 's')) old_basis_size = sum([len(bb) for bb in intermediate_basis]) extended_bases, _ = gram_schmidt_block_basis_extension( [intermediate_basis[ss] for ss in marked_subdomains], [local_solutions[ss] for ss in marked_subdomains], product=[local_products[ss] for ss in marked_subdomains]) assert len(extended_bases) == len(marked_subdomains) for ii, subdomain in enumerate(marked_subdomains): intermediate_basis[subdomain] = extended_bases[ii] new_basis_size = sum([len(bb) for bb in intermediate_basis]) num_extensions += 1 logger.info(' Reducing ...') rd, _, _ = reduce_generic_rb(discretization, intermediate_basis) rc = GenericBlockRBReconstructor(intermediate_basis) reduced_estimator.rc = rc reduced_estimator.extension_step += 1 U_red = rd.solve(mu) logger.info(' Estimating (total basis size: {})'.format( sum(len(bb) for bb in intermediate_basis))) new_error = reduced_estimator.estimate(U_red, mu, discretization) order = np.log(new_error/error)/np.log(old_basis_size/new_basis_size) logger.info(' {} (relative improvement: {})'.format(new_error, order)) if new_error > error: logger.warn('The error has increased (from {} to {}) after enrichment!'.format(error, new_error)) elif order < 1: logger.warn(('The error has decreased only slightly ' + '(from {} to {}) after enrichment!').format(error, new_error)) if num_extensions >= cfg['online_max_extensions'] and new_error > cfg['online_target_error']: basis = intermediate_basis raise EnrichmentError('Reached maximum number of {} extensions!'.format( cfg['online_max_extensions'])) error = new_error logger.info(' The error ({}) is below the target error, continuing ...'.format(error)) successes += 1 basis = intermediate_basis logger.info('Basis sizes range from {} to {}.'.format(np.min([len(bb) for bb in basis]), np.max([len(bb) for bb in basis]))) except EnrichmentError, ee: logger.critical('Enrichment stopped because: {}'.format(ee)) logger.info('Basis sizes range from {} to {}.'.format(np.min([len(bb) for bb in basis]), np.max([len(bb) for bb in basis]))) logger.info('Continuing with the next parameter ...') failures += 1 print('') else: logger.info('The error ({}) is below the target error, continuing ...'.format(error)) successes += 1 print('')