예제 #1
0
def get_bc(max_x_func, domain, dim, bc_dict_func):
    """Get the periodic boundary condition

    Args:
      max_x_func: function for finding the maximum value of x
      domain: the Sfepy domain
      dim: the x, y or z direction
      bc_dict_func: function to generate the bc dict

    Returns:
      the boundary condition and the sfepy function
    """
    dim_dict = lambda x: [
        ("x", per.match_x_plane),
        ("y", per.match_y_plane),
        ("z", per.match_z_plane),
    ][dim][x]
    return pipe(
        domain.get_mesh_bounding_box(),
        lambda x: PeriodicBC(
            "periodic_{0}".format(dim_dict(0)),
            list(
                map_(
                    get_region_func(max_x_func(x), dim_dict(0), domain),
                    zip(("plus", "minus"), x[:, dim][::-1]),
                )
            ),
            bc_dict_func(x),
            match="match_{0}_plane".format(dim_dict(0)),
        ),
        lambda x: (x, Function("match_{0}_plane".format(dim_dict(0)), dim_dict(1))),
    )
예제 #2
0
    def _get_periodicBC_X(self, domain, dim):
        dim_dict = {1: ('y', per.match_y_plane),
                    2: ('z', per.match_z_plane)}
        dim_string = dim_dict[dim][0]
        match_plane = dim_dict[dim][1]
        min_, max_ = domain.get_mesh_bounding_box()[:, dim]
        min_x, max_x = domain.get_mesh_bounding_box()[:, 0]
        plus_ = self._subdomain_func(max_x=max_x, **{dim_string: (max_,)})
        minus_ = self._subdomain_func(max_x=max_x, **{dim_string: (min_,)})
        plus_string = dim_string + 'plus'
        minus_string = dim_string + 'minus'
        plus = Function(plus_string, plus_)
        minus = Function(minus_string, minus_)
        region_plus = domain.create_region(
            'region_{0}_plus'.format(dim_string),
            'vertices by {0}'.format(
                plus_string),
            'facet',
            functions=Functions([plus]))
        region_minus = domain.create_region(
            'region_{0}_minus'.format(dim_string),
            'vertices by {0}'.format(
                minus_string),
            'facet',
            functions=Functions([minus]))
        match_plane = Function(
            'match_{0}_plane'.format(dim_string), match_plane)

        bc_dict = {'u.0': 'u.0'}

        bc = PeriodicBC('periodic_{0}'.format(dim_string),
                        [region_plus, region_minus],
                        bc_dict,
                        match='match_{0}_plane'.format(dim_string))
        return bc, match_plane
예제 #3
0
    def test_epbcs(self):
        from sfepy.discrete import Function, Functions
        from sfepy.discrete.conditions import Conditions, PeriodicBC
        from sfepy.discrete.common.dof_info import expand_nodes_to_equations
        from sfepy.discrete.fem.periodic import match_y_line

        variables = self.variables
        regions = self.problem.domain.regions

        match_y_line = Function('match_y_line', match_y_line)
        pbc = PeriodicBC('pbc', [regions['LeftStrip'], regions['RightStrip']],
                         {'u.[1,0]': 'u.[0,1]'},
                         match='match_y_line')

        functions = Functions([match_y_line])

        epbcs = Conditions([pbc])
        variables.equation_mapping(ebcs=None,
                                   epbcs=epbcs,
                                   ts=None,
                                   functions=functions)

        vec = init_vec(variables)
        variables.apply_ebc(vec)

        var = variables['u']
        var_bcs = epbcs.group_by_variables()['u']
        bc = var_bcs['pbc']
        bc.canonize_dof_names(var.dofs)

        nods0 = var.field.get_dofs_in_region(bc.regions[0])
        nods1 = var.field.get_dofs_in_region(bc.regions[1])

        coors0 = var.field.get_coor(nods0)
        coors1 = var.field.get_coor(nods1)
        i0, i1 = match_y_line(coors0, coors1)

        eq0 = expand_nodes_to_equations(nods0[i0], bc.dofs[0], var.dofs)
        eq1 = expand_nodes_to_equations(nods1[i1], bc.dofs[1], var.dofs)

        ok = True

        _ok = len(nm.setdiff1d(eq0, var.eq_map.master)) == 0
        if not _ok:
            self.report('master equations mismatch! (set(%s) == set(%s))' %
                        (eq0, var.eq_map.master))
        ok = ok and _ok

        _ok = len(nm.setdiff1d(eq1, var.eq_map.slave)) == 0
        if not _ok:
            self.report('slave equations mismatch! (set(%s) == set(%s))' %
                        (eq1, var.eq_map.slave))
        ok = ok and _ok

        off = variables.di.indx['u'].start
        _ok = nm.allclose(vec[off + eq0], vec[off + eq1], atol=1e-14, rtol=0.0)
        if not _ok:
            self.report('periodicity test failed! (%s == %s)' %
                        (vec[off + eq0], vec[off + eq0]))
        ok = ok and _ok

        return ok