예제 #1
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
예제 #2
0
    def _get_shift_displacementsBCs(self, domain):
        """
        Fix the right top and bottom points in x, y and z

        Args:
          domain: an Sfepy domain

        Returns:
          the Sfepy boundary conditions

        """
        min_xyz = domain.get_mesh_bounding_box()[0]
        max_xyz = domain.get_mesh_bounding_box()[1]
        kwargs = {}
        if len(min_xyz) == 3:
            kwargs = {'z': (max_xyz[2], min_xyz[2])}

        displacement = self.macro_strain * (max_xyz[0] - min_xyz[0])
        shift_points_dict = {'u.0': displacement}

        shift_x_points_ = self._subdomain_func(x=(max_xyz[0],),
                                               y=(max_xyz[1], min_xyz[1]),
                                               **kwargs)

        shift_x_points = Function('shift_x_points', shift_x_points_)
        region_shift_points = domain.create_region(
            'region_shift_points',
            'vertices by shift_x_points',
            'vertex',
            functions=Functions([shift_x_points]))
        return EssentialBC('shift_points_BC',
                           region_shift_points, shift_points_dict)
예제 #3
0
    def _get_fixed_displacementsBCs(self, domain):
        """
        Fix the left top and bottom points in x, y and z

        Args:
          domain: an Sfepy domain

        Returns:
          the Sfepy boundary conditions

        """
        min_xyz = domain.get_mesh_bounding_box()[0]
        max_xyz = domain.get_mesh_bounding_box()[1]

        kwargs = {}
        fix_points_dict = {'u.0': 0.0, 'u.1': 0.0}
        if len(min_xyz) == 3:
            kwargs = {'z': (max_xyz[2], min_xyz[2])}
            fix_points_dict['u.2'] = 0.0
        fix_x_points_ = self._subdomain_func(x=(min_xyz[0],),
                                             y=(max_xyz[1], min_xyz[1]),
                                             **kwargs)

        fix_x_points = Function('fix_x_points', fix_x_points_)
        region_fix_points = domain.create_region(
            'region_fix_points',
            'vertices by fix_x_points',
            'vertex',
            functions=Functions([fix_x_points]))
        return EssentialBC('fix_points_BC', region_fix_points, fix_points_dict)
예제 #4
0
    def _get_periodicBCs(self, domain):
        dims = domain.get_mesh_bounding_box().shape[1]

        bc_list_YZ, func_list_YZ = list(
            zip(*[self._get_periodicBC_YZ(domain, i) for i in range(0, dims)]))
        bc_list_X, func_list_X = list(
            zip(*[self._get_periodicBC_X(domain, i) for i in range(1, dims)]))
        return Conditions(
            bc_list_YZ + bc_list_X), Functions(func_list_YZ + func_list_X)
예제 #5
0
    def _get_linear_combinationBCs(self, domain):
        """
        The right nodes are periodic with the left nodes but also displaced.

        Args:
          domain: an Sfepy domain

        Returns:
          the Sfepy boundary conditions

        """
        min_xyz = domain.get_mesh_bounding_box()[0]
        max_xyz = domain.get_mesh_bounding_box()[1]
        xplus_ = self._subdomain_func(x=(max_xyz[0], ))
        xminus_ = self._subdomain_func(x=(min_xyz[0], ))

        xplus = Function('xplus', xplus_)
        xminus = Function('xminus', xminus_)
        region_x_plus = domain.create_region('region_x_plus',
                                             'vertices by xplus',
                                             'facet',
                                             functions=Functions([xplus]))
        region_x_minus = domain.create_region('region_x_minus',
                                              'vertices by xminus',
                                              'facet',
                                              functions=Functions([xminus]))
        match_x_plane = Function('match_x_plane', per.match_x_plane)

        def shift_(ts, coors, region):
            return np.ones_like(
                coors[:, 0]) * self.macro_strain * (max_xyz[0] - min_xyz[0])

        shift = Function('shift', shift_)
        lcbc = LinearCombinationBC('lcbc', [region_x_plus, region_x_minus],
                                   {'u.0': 'u.0'},
                                   match_x_plane,
                                   'shifted_periodic',
                                   arguments=(shift, ))

        return Conditions([lcbc])
예제 #6
0
    def from_conf(conf, options):
        from sfepy import data_dir
        from sfepy.discrete.fem import Mesh, FEDomain
        from sfepy.discrete import Functions

        mesh = Mesh("test mesh", data_dir + "/meshes/various_formats/abaqus_tet.inp")
        mesh.nodal_bcs["set0"] = [0, 7]
        domain = FEDomain("test domain", mesh)

        conf_functions = {"get_vertices": (get_vertices,), "get_cells": (get_cells,)}
        functions = Functions.from_conf(transform_functions(conf_functions))

        test = Test(conf=conf, options=options, domain=domain, functions=functions)
        return test
예제 #7
0
 def func(min_xyz, max_xyz):
     return pipe(
         dict(z_points=(max_xyz[2], min_xyz[2])) if len(min_xyz) == 3 else dict(),
         lambda x: subdomain_func(
             x_points=x_points_f(min_xyz, max_xyz),
             y_points=(max_xyz[1], min_xyz[1]),
             **x,
         ),
         lambda x: Function(f"{name}_x_points", x),
         lambda x: domain.create_region(
             f"region_{name}_points",
             f"vertices by {name}_x_points",
             "vertex",
             functions=Functions([x]),
         ),
         lambda x: EssentialBC(
             f"{name}_points_BC", x, points_dict_f(min_xyz, max_xyz)
         ),
     )
예제 #8
0
    def from_conf( conf, options ):
        from sfepy import data_dir
        from sfepy.discrete.fem import Mesh, FEDomain
        from sfepy.discrete import Functions

        mesh = Mesh.from_file(data_dir
                              + '/meshes/various_formats/abaqus_tet.inp')
        mesh.nodal_bcs['set0'] = [0, 7]
        domain = FEDomain('test domain', mesh)

        conf_functions = {
            'get_vertices' : (get_vertices,),
            'get_cells' : (get_cells,),
        }
        functions = Functions.from_conf(transform_functions(conf_functions))

        test = Test(conf=conf, options=options,
                    domain=domain, functions=functions)
        return test
예제 #9
0
def get_periodic_bcs(domain):
    """Get the periodic boundary conditions

    Args:
      domain: the Sfepy domain

    Returns:
      the boundary conditions and sfepy functions
    """
    zipped = lambda x, f: pipe(
        range(x, domain.get_mesh_bounding_box().shape[1]),
        map_(f(domain)),
        lambda x: zip(*x),
        list,
    )

    return pipe(
        (zipped(0, get_periodic_bc_yz), zipped(1, get_periodic_bc_x)),
        lambda x: (Conditions(x[0][0] + x[1][0]), Functions(x[0][1] + x[1][1])),
    )
예제 #10
0
def get_region_func(max_x, dim_string, domain, name_minmax):
    """Generate the Sfepy region

    Args:
      max_x: max value in the x direction
      dim_string: either "x", "y", or "z"
      domain: the Sfepy domain
      name_minmax: tuple of name and min / max

    Returns:
      the Sfepy region
    """
    return pipe(
        subdomain_func(max_x=max_x, **{dim_string + "_points": (name_minmax[1],)}),
        lambda x: Function(dim_string + name_minmax[0], x),
        lambda x: domain.create_region(
            "region_{0}_{1}".format(dim_string, name_minmax[0]),
            "vertices by {0}".format(x.name),
            "facet",
            functions=Functions([x]),
        ),
    )
예제 #11
0
def get_bc(domain, delta_x, index, cond):
    """Make a displacement boundary condition

    Args:
      domain: the Sfepy domain
      delta_x: the mesh spacing
      index: the index (either 0 or 1) depends on direction of axes
      cond: the BC dictionary

    Returns:
      the Sfepy boundary condition
    """
    return pipe(
        Function("fix_points", subdomain(index, domain, delta_x * 1e-3)),
        lambda x: domain.create_region(
            "region_fix_points",
            "vertices by fix_points",
            "vertex",
            functions=Functions([x]),
        ),
        lambda x: EssentialBC("fix_points_BC", x, cond),
    )
예제 #12
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
예제 #13
0
def find_level_interface(domain, refine_flag):
    """
    Find facets of the coarse mesh that are on the coarse-refined cell
    boundary.

    ids w.r.t. current mesh:
    - facets: global, local w.r.t. cells[:, 0], local w.r.t. cells[:, 1]

    - interface cells:
      - cells[:, 0] - cells to refine
      - cells[:, 1] - their facet sharing neighbors (w.r.t. both meshes)
      - cells[:, 2] - facet kind: 0 = face, 1 = edge
    """
    if not refine_flag.any():
        facets = nm.zeros((0, 3), dtype=nm.uint32)
        cells = nm.zeros((0, 3), dtype=nm.uint32)
        return facets, cells, 0, None, None

    def _get_refine(coors, domain=None):
        return nm.nonzero(refine_flag)[0]

    def _get_coarse(coors, domain=None):
        return nm.nonzero(1 - refine_flag)[0]

    get_refine = Function('get_refine', _get_refine)
    get_coarse = Function('get_coarse', _get_coarse)
    functions = Functions([get_refine, get_coarse])
    region0 = domain.create_region('coarse',
                                   'cells by get_coarse',
                                   functions=functions,
                                   add_to_regions=False,
                                   allow_empty=True)
    region1 = domain.create_region('refine',
                                   'cells by get_refine',
                                   functions=functions,
                                   add_to_regions=False)

    cmesh = domain.mesh.cmesh
    dim = cmesh.dim

    if dim == 2:
        oe = 0

        facets = nm.intersect1d(region0.facets, region1.facets)

        cmesh.setup_connectivity(dim - 1, dim)
        cells, offs = cmesh.get_incident(dim,
                                         facets,
                                         dim - 1,
                                         ret_offsets=True)
        assert_((nm.diff(offs) == 2).all())

        ii = cmesh.get_local_ids(facets, dim - 1, cells, offs, dim)

        ii = ii.reshape((-1, 2))
        cells = cells.reshape((-1, 2))

        ii = nm.where(refine_flag[cells], ii[:, :1], ii[:, 1:])
        cells = nm.where(refine_flag[cells], cells[:, :1], cells[:, 1:])

        facets = nm.c_[facets, ii]

        cells = nm.c_[cells, nm.zeros_like(cells[:, 1])]

    else:  # if dim == 3:
        gel = domain.geom_els['3_8']
        epf = gel.get_edges_per_face()

        cmesh.setup_connectivity(dim, dim)
        fc, coffs = cmesh.get_incident(dim,
                                       region1.cells,
                                       dim,
                                       ret_offsets=True)
        cc = nm.repeat(region1.cells, nm.diff(coffs))
        aux = nm.c_[cc, fc]
        """
        nnn[:, 0] cells to refine, nnn[:, 1] non-refined neighbours, nnn[:, 2]
        neighbour kind : 0 face, 1 edge.
        """
        nn = aux[refine_flag[fc] == 0]

        cf = nn[:, 0].copy().astype(nm.uint32)
        cc = nn[:, 1].copy().astype(nm.uint32)

        vc, vco = cmesh.get_incident(0, cc, dim, ret_offsets=True)
        vf, vfo = cmesh.get_incident(0, cf, dim, ret_offsets=True)
        vc = vc.reshape((-1, 8))
        vf = vf.reshape((-1, 8))

        nnn = []
        oe = 0
        ov = nn.shape[0]
        for ii in range(vc.shape[0]):
            aux = set(vc[ii]).intersection(vf[ii])
            nc = len(aux)
            if nc == 1:
                nnn.append((0, 0, 2))
                ov -= 1

            elif nc == 4:
                nnn.append((nn[ii, 0], nn[ii, 1], 0))
                oe += 1

            else:
                nnn.append((nn[ii, 0], nn[ii, 1], 1))
        nnn = nm.array(nnn)

        if nnn.shape[0] == 0:
            facets = nm.zeros((0, 3), dtype=nm.uint32)
            cells = nm.zeros((0, 4), dtype=nm.uint32)

            return facets, cells, 0, region0, region1

        # Sort by neighbour kind, skip vertex-only neighbours.
        ii = nm.argsort(nnn[:, 2])
        nnn = nnn[ii][:ov]
        cf = cf[ii][:ov]
        cc = cc[ii][:ov]

        ec, eco = cmesh.get_incident(1, cc, dim, ret_offsets=True)
        ef, efo = cmesh.get_incident(1, cf, dim, ret_offsets=True)
        ec = ec.reshape((-1, 12))
        ef = ef.reshape((-1, 12))

        fc, fco = cmesh.get_incident(2, cc, dim, ret_offsets=True)
        ff, ffo = cmesh.get_incident(2, cf, dim, ret_offsets=True)
        fc = fc.reshape((-1, 6))
        ff = ff.reshape((-1, 6))

        emask = nm.zeros((domain.shape.n_el, 12), dtype=nm.bool)

        ffs = []
        for ii in range(oe):
            facet = nm.intersect1d(fc[ii], ff[ii])[0]
            i1 = nm.where(ff[ii] == facet)[0][0]
            i0 = nm.where(fc[ii] == facet)[0][0]
            ffs.append((facet, i1, i0))

            emask[nnn[ii, 0], epf[i1]] = True

        for ii in range(oe, nnn.shape[0]):
            facet = nm.intersect1d(ec[ii], ef[ii])[0]
            i1 = nm.where(ef[ii] == facet)[0][0]
            i0 = nm.where(ec[ii] == facet)[0][0]
            ffs.append((facet, i1, i0))

        ffs = nm.array(ffs)

        ie = nm.where(nnn[:, 2] == 1)[0]
        ennn = nnn[ie]
        effs = ffs[ie]
        omit = ie[emask[ennn[:, 0], effs[:, 1]]]

        valid = nm.ones(nnn.shape[0], dtype=nm.bool)
        valid[omit] = False

        cells = nnn[valid]
        facets = ffs[valid]

    return facets, cells, oe, region0, region1