def __repr__(self): top = ', top=' + repr( self.top) if self.top != BoundaryType('dirichlet') else '' bottom = ', bottom=' + repr( self.bottom) if self.bottom != BoundaryType('dirichlet') else '' return 'CylindricalDomain({}{})'.format( str(self.domain).replace('\n', ','), top + bottom)
def __init__(self, angle, radius, arc=BoundaryType('dirichlet'), radii=BoundaryType('dirichlet'), num_points=100): self.angle = angle self.radius = radius self.arc = arc self.radii = radii self.num_points = num_points assert (0 < self.angle) and (self.angle < 2 * np.pi) assert self.radius > 0 assert self.arc is None or isinstance(self.arc, BoundaryType) assert self.radii is None or isinstance(self.radii, BoundaryType) assert self.num_points > 0 points = [[0., 0.]] points.extend( [[self.radius * np.cos(t), self.radius * np.sin(t)] for t in np.linspace( start=0, stop=angle, num=self.num_points, endpoint=True)]) if self.arc == self.radii: boundary_types = {self.arc: list(range(1, len(points) + 1))} else: boundary_types = {self.arc: list(range(2, len(points)))} boundary_types.update({self.radii: [1, len(points)]}) if None in boundary_types: del boundary_types[None] super().__init__(points, boundary_types)
def __init__(self, domain=(0, 1), left=BoundaryType('dirichlet'), right=BoundaryType('dirichlet')): assert domain[0] <= domain[1] assert left is None or isinstance(left, BoundaryType) assert right is None or isinstance(right, BoundaryType) self.boundary_types = frozenset({left, right}) self.left = left self.right = right self.domain = np.array(domain)
def __repr__(self): left = ', left=' + repr( self.left) if self.left != BoundaryType('dirichlet') else '' right = ', right=' + repr( self.right) if self.right != BoundaryType('dirichlet') else '' top = ', top=' + repr( self.top) if self.top != BoundaryType('dirichlet') else '' bottom = ', bottom=' + repr( self.bottom) if self.bottom != BoundaryType('dirichlet') else '' return 'RectDomain({}{})'.format( str(self.domain).replace('\n', ','), left + right + top + bottom)
def __init__(self, domain=([0, 0], [1, 1]), top=BoundaryType('dirichlet'), bottom=BoundaryType('dirichlet')): assert domain[0][0] <= domain[1][0] assert domain[0][1] <= domain[1][1] assert top is None or isinstance(top, BoundaryType) assert bottom is None or isinstance(bottom, BoundaryType) self.boundary_types = frozenset({top, bottom}) self.top = top self.bottom = bottom self.domain = np.array(domain)
def elliptic_demo(args): args['PROBLEM-NUMBER'] = int(args['PROBLEM-NUMBER']) assert 0 <= args['PROBLEM-NUMBER'] <= 1, ValueError('Invalid problem number') args['DIRICHLET-NUMBER'] = int(args['DIRICHLET-NUMBER']) assert 0 <= args['DIRICHLET-NUMBER'] <= 2, ValueError('Invalid Dirichlet boundary number.') args['NEUMANN-NUMBER'] = int(args['NEUMANN-NUMBER']) assert 0 <= args['NEUMANN-NUMBER'] <= 2, ValueError('Invalid Neumann boundary number.') args['NEUMANN-COUNT'] = int(args['NEUMANN-COUNT']) assert 0 <= args['NEUMANN-COUNT'] <= 3, ValueError('Invalid Neumann boundary count.') rhss = [GenericFunction(lambda X: np.ones(X.shape[:-1]) * 10, 2), GenericFunction(lambda X: (X[..., 0] - 0.5) ** 2 * 1000, 2)] dirichlets = [GenericFunction(lambda X: np.zeros(X.shape[:-1]), 2), GenericFunction(lambda X: np.ones(X.shape[:-1]), 2), GenericFunction(lambda X: X[..., 0], 2)] neumanns = [None, ConstantFunction(3., dim_domain=2), GenericFunction(lambda X: 50*(0.1 <= X[..., 1]) * (X[..., 1] <= 0.2) +50*(0.8 <= X[..., 1]) * (X[..., 1] <= 0.9), 2)] domains = [RectDomain(), RectDomain(right=BoundaryType('neumann')), RectDomain(right=BoundaryType('neumann'), top=BoundaryType('neumann')), RectDomain(right=BoundaryType('neumann'), top=BoundaryType('neumann'), bottom=BoundaryType('neumann'))] rhs = rhss[args['PROBLEM-NUMBER']] dirichlet = dirichlets[args['DIRICHLET-NUMBER']] neumann = neumanns[args['NEUMANN-NUMBER']] domain = domains[args['NEUMANN-COUNT']] for n in [32, 128]: grid_name = '{1}(({0},{0}))'.format(n, 'RectGrid' if args['--rect'] else 'TriaGrid') print('Solving on {0}'.format(grid_name)) print('Setup problem ...') problem = EllipticProblem(domain=domain, rhs=rhs, dirichlet_data=dirichlet, neumann_data=neumann) print('Discretize ...') if args['--rect']: grid, bi = discretize_domain_default(problem.domain, diameter=m.sqrt(2) / n, grid_type=RectGrid) else: grid, bi = discretize_domain_default(problem.domain, diameter=1. / n, grid_type=TriaGrid) discretizer = discretize_elliptic_fv if args['--fv'] else discretize_elliptic_cg discretization, _ = discretizer(analytical_problem=problem, grid=grid, boundary_info=bi) print('Solve ...') U = discretization.solve() print('Plot ...') discretization.visualize(U, title=grid_name) print('')
def __init__(self, grid, sections): assert isinstance(grid, GmshGrid) self.grid = grid # Save |BoundaryTypes|. self.boundary_types = [ BoundaryType(pn[2]) for pn in sections['PhysicalNames'] if pn[1] == 1 ] # Compute ids, since Gmsh starts numbering with 1 instead of 0. name_ids = dict( zip([pn[0] for pn in sections['PhysicalNames']], np.arange(len(sections['PhysicalNames']), dtype=np.int32))) node_ids = dict( zip([n[0] for n in sections['Nodes']], np.arange(len(sections['Nodes']), dtype=np.int32))) if 'line' in sections['Elements']: superentities = grid.superentities(2, 1) # find the edge for given vertices. def find_edge(vertices): edge_set = set(superentities[vertices[0]]).intersection( superentities[vertices[1]]) - {-1} if len(edge_set) != 1: raise ValueError return next(iter(edge_set)) line_ids = { l[0]: find_edge([node_ids[l[2][0]], node_ids[l[2][1]]]) for l in sections['Elements']['line'] } # compute boundary masks for all |BoundaryTypes|. masks = {} for bt in self.boundary_types: masks[bt] = [ np.array([False] * grid.size(1)), np.array([False] * grid.size(2)) ] masks[bt][0][[line_ids[l[0]] for l in sections['Elements']['line']]] = \ [(bt.type == sections['PhysicalNames'][name_ids[l[1][0]]][2]) for l in sections['Elements']['line']] ind = np.array([ node_ids[n] for l in sections['Elements']['line'] for n in l[2] ]) val = masks[bt][0][[ line_ids[l[0]] for l in sections['Elements']['line'] for n in l[2] ]] masks[bt][1][ind[val]] = True self._masks = masks
def __init__(self, radius, boundary=BoundaryType('dirichlet'), num_points=100): self.radius = radius self.boundary = boundary self.num_points = num_points assert self.radius > 0 assert self.boundary is None or isinstance(self.boundary, BoundaryType) assert self.num_points > 0 points = [[self.radius * np.cos(t), self.radius * np.sin(t)] for t in np.linspace( start=0, stop=2 * np.pi, num=num_points, endpoint=False)] boundary_types = {} if self.boundary is None else { boundary: list(range(1, len(points) + 1)) } super().__init__(points, boundary_types)
def has_neumann(self): return BoundaryType('neumann') in self.boundary_types
def mask(self, boundary_type, codim): assert boundary_type == BoundaryType('dirichlet'), 'Has no boundary_type "{}"'.format(boundary_type) assert 1 <= codim <= self.grid.dim return np.ones(self.grid.size(codim), dtype='bool') * self.grid.boundary_mask(codim)
def __init__(self, grid): self.grid = grid self.boundary_types = frozenset({BoundaryType('dirichlet')})
def neumann_mask(self, codim): return self.mask(BoundaryType('neumann'), codim)
def dirichlet_mask(self, codim): return self.mask(BoundaryType('dirichlet'), codim)
def has_only_dirichletneumann(self): return self.boundary_types <= {BoundaryType('dirichlet'), BoundaryType('neumann')}
def has_only_neumann(self): return self.boundary_types == {BoundaryType('neumann')}
def has_only_dirichlet(self): return self.boundary_types == {BoundaryType('dirichlet')}
def __repr__(self): left = ', left=' + repr(self.left) if self.left != BoundaryType('dirichlet') else '' right = ', right=' + repr(self.right) if self.right != BoundaryType('dirichlet') else '' return 'LineDomain({}{})'.format(self.domain, left + right)
def has_dirichlet(self): return BoundaryType('dirichlet') in self.boundary_types
def robin_mask(self, codim): return self.mask(BoundaryType('robin'), codim)
def has_robin(self): return BoundaryType('robin') in self.boundary_types