Пример #1
0
 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)
Пример #2
0
    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)
Пример #3
0
 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)
Пример #4
0
 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)
Пример #5
0
 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)
Пример #6
0
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('')
Пример #7
0
    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
Пример #8
0
    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)
Пример #9
0
 def has_neumann(self):
     return BoundaryType('neumann') in self.boundary_types
Пример #10
0
 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)
Пример #11
0
 def __init__(self, grid):
     self.grid = grid
     self.boundary_types = frozenset({BoundaryType('dirichlet')})
Пример #12
0
 def neumann_mask(self, codim):
     return self.mask(BoundaryType('neumann'), codim)
Пример #13
0
 def dirichlet_mask(self, codim):
     return self.mask(BoundaryType('dirichlet'), codim)
Пример #14
0
 def has_only_dirichletneumann(self):
     return self.boundary_types <= {BoundaryType('dirichlet'), BoundaryType('neumann')}
Пример #15
0
 def has_only_neumann(self):
     return self.boundary_types == {BoundaryType('neumann')}
Пример #16
0
 def has_only_dirichlet(self):
     return self.boundary_types == {BoundaryType('dirichlet')}
Пример #17
0
 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)
Пример #18
0
 def has_dirichlet(self):
     return BoundaryType('dirichlet') in self.boundary_types
Пример #19
0
 def robin_mask(self, codim):
     return self.mask(BoundaryType('robin'), codim)
Пример #20
0
 def has_robin(self):
     return BoundaryType('robin') in self.boundary_types