Пример #1
0
    def __init__(self, name, nurbs, bmesh, regions=None, **kwargs):
        """
        Create an IGA domain.

        Parameters
        ----------
        name : str
            The domain name.
        """
        Domain.__init__(self,
                        name,
                        nurbs=nurbs,
                        bmesh=bmesh,
                        regions=regions,
                        **kwargs)
        from sfepy.discrete.fem.geometry_element import create_geometry_elements
        from sfepy.discrete.fem import Mesh
        from sfepy.discrete.fem.utils import prepare_remap

        tconn = iga.get_bezier_topology(bmesh.conn, nurbs.degrees)
        itc = nm.unique(tconn)

        remap = prepare_remap(itc, bmesh.conn.max() + 1)

        ltcoors = bmesh.cps[itc]
        ltconn = remap[tconn]

        n_nod, dim = ltcoors.shape
        n_el = ltconn.shape[0]
        self.shape = Struct(n_nod=n_nod, dim=dim, tdim=0, n_el=n_el)

        desc = '%d_%d' % (dim, bmesh.conn.shape[1])
        mat_id = nm.zeros(bmesh.conn.shape[0], dtype=nm.int32)
        eval_mesh = Mesh.from_data(self.name + '_eval', nurbs.cps, None,
                                   [nurbs.conn], [mat_id], [desc])
        self.eval_mesh = eval_mesh

        desc = '%d_%d' % (dim, 2**dim)
        mat_id = nm.zeros(ltconn.shape[0], dtype=nm.int32)
        self.mesh = Mesh.from_data(self.name + '_topo', ltcoors, None,
                                   [ltconn], [mat_id], [desc])

        self.cmesh = self.mesh.cmesh
        gels = create_geometry_elements()
        self.cmesh.set_local_entities(gels)
        self.cmesh.setup_entities()

        self.shape.tdim = self.cmesh.tdim

        self.gel = gels[desc]

        if regions is not None:
            self.vertex_set_bcs = {}
            for key, val in six.iteritems(self.regions):
                self.vertex_set_bcs[key] = remap[val]

        self.reset_regions()
Пример #2
0
    def __init__(self, name, nurbs, bmesh, regions=None, **kwargs):
        """
        Create an IGA domain.

        Parameters
        ----------
        name : str
            The domain name.
        """
        Domain.__init__(self, name, nurbs=nurbs, bmesh=bmesh, regions=regions,
                        **kwargs)
        from sfepy.discrete.fem.geometry_element import create_geometry_elements
        from sfepy.discrete.fem import Mesh
        from sfepy.discrete.fem.utils import prepare_remap

        tconn = iga.get_bezier_topology(bmesh.conn, nurbs.degrees)
        itc = nm.unique(tconn)

        remap = prepare_remap(itc, bmesh.conn.max() + 1)

        ltcoors = bmesh.cps[itc]
        ltconn = remap[tconn]

        n_nod, dim = ltcoors.shape
        n_el = ltconn.shape[0]
        self.shape = Struct(n_nod=n_nod, dim=dim, tdim=0, n_el=n_el)

        desc = '%d_%d' % (dim, bmesh.conn.shape[1])
        mat_id = nm.zeros(bmesh.conn.shape[0], dtype=nm.int32)
        eval_mesh = Mesh.from_data(self.name + '_eval', nurbs.cps, None,
                                   [nurbs.conn], [mat_id], [desc])
        self.eval_mesh = eval_mesh

        desc = '%d_%d' % (dim, 2**dim)
        mat_id = nm.zeros(ltconn.shape[0], dtype=nm.int32)
        self.mesh = Mesh.from_data(self.name + '_topo', ltcoors, None, [ltconn],
                                   [mat_id], [desc])

        self.cmesh = self.mesh.cmesh
        gels = create_geometry_elements()
        self.cmesh.set_local_entities(gels)
        self.cmesh.setup_entities()

        self.shape.tdim = self.cmesh.tdim

        self.gel = gels[desc]

        if regions is not None:
            self.vertex_set_bcs = {}
            for key, val in self.regions.iteritems():
                self.vertex_set_bcs[key] = remap[val]

        self.reset_regions()
Пример #3
0
def _get_bqp(geometry, order):
    from sfepy.discrete import Integral
    from sfepy.discrete.fem.geometry_element import GeometryElement
    from sfepy.discrete.fem import Mesh, FEDomain, Field

    gel = GeometryElement(geometry)

    mesh = Mesh.from_data('aux', gel.coors, None, [gel.conn[None, :]], [[0]],
                          [geometry])
    domain = FEDomain('domain', mesh)
    omega = domain.create_region('Omega', 'all')
    surf = domain.create_region('Surf', 'vertices of surface', 'facet')
    field = Field.from_args('f',
                            nm.float64,
                            shape=1,
                            region=omega,
                            approx_order=1)
    field.setup_surface_data(surf)

    integral = Integral('aux', order=order)
    field.create_bqp('Surf', integral)

    sd = field.surface_data['Surf']
    qp = field.qp_coors[(integral.order, sd.bkey)]

    output('geometry:', geometry, 'order:', order, 'num. points:',
           qp.vals.shape[1], 'true_order:',
           integral.qps[gel.surface_facet_name].order)
    output('min. weight:', qp.weights.min())
    output('max. weight:', qp.weights.max())

    return (gel, qp.vals.reshape(
        (-1, mesh.dim)), nm.tile(qp.weights, qp.vals.shape[0]))
Пример #4
0
def triangulate(mesh, verbose=False):
    """
    Triangulate a 2D or 3D tensor product mesh: quadrilaterals->triangles,
    hexahedrons->tetrahedrons.

    Parameters
    ----------
    mesh : Mesh
        The input mesh.

    Returns
    -------
    mesh : Mesh
        The triangulated mesh.
    """
    conns = None
    for k, new_desc in [('3_8', '3_4'), ('2_4', '2_3')]:
        if k in mesh.descs:
            conns = mesh.get_conn(k)
            break

    if conns is not None:
        nelo = conns.shape[0]
        output('initial mesh: %d elements' % nelo, verbose=verbose)

        new_conns = elems_q2t(conns)
        nn = new_conns.shape[0] // nelo
        new_cgroups = nm.repeat(mesh.cmesh.cell_groups, nn)

        output('new mesh: %d elements' % new_conns.shape[0], verbose=verbose)
        mesh = Mesh.from_data(mesh.name, mesh.coors,
                              mesh.cmesh.vertex_groups,
                              [new_conns], [new_cgroups], [new_desc])

    return mesh
def gen_two_bodies(dims0, shape0, centre0, dims1, shape1, centre1, shift1):
    from sfepy.discrete.fem import Mesh
    from sfepy.mesh.mesh_generators import gen_block_mesh

    m0 = gen_block_mesh(dims0, shape0, centre0)
    m1 = gen_block_mesh(dims1, shape1, centre1)

    coors = nm.concatenate((m0.coors, m1.coors + shift1), axis=0)

    desc = m0.descs[0]
    c0 = m0.get_conn(desc)
    c1 = m1.get_conn(desc)
    conn = nm.concatenate((c0, c1 + m0.n_nod), axis=0)

    ngroups = nm.zeros(coors.shape[0], dtype=nm.int32)
    ngroups[m0.n_nod:] = 1

    mat_id = nm.zeros(conn.shape[0], dtype=nm.int32)
    mat_id[m0.n_el:] = 1

    name = 'two_bodies.mesh'

    mesh = Mesh.from_data(name, coors, ngroups, [conn], [mat_id], m0.descs)

    mesh.write(name, io='auto')

    return mesh
Пример #6
0
def save_basis(nurbs, pars):
    """
    Save a NURBS object basis on a FE mesh corresponding to the given
    parametrization in VTK files.

    Parameters
    ----------
    nurbs : igakit.nurbs.NURBS instance
        The NURBS object.
    pars : sequence of array, optional
        The values of parameters in each parametric dimension.
    """
    coors, conn, desc = create_linear_fe_mesh(nurbs, pars)
    mat_id = nm.zeros(conn.shape[0], dtype=nm.int32)
    mesh = Mesh.from_data('nurbs', coors, None, [conn], [mat_id], [desc])

    n_dof = nurbs.weights.ravel().shape[0]
    variable = nm.zeros(n_dof, dtype=nm.float64)
    field = variable.reshape(nurbs.weights.shape)
    for ic in xrange(n_dof):
        variable[ic - 1] = 0.0
        variable[ic] = 1.0

        vals = nurbs.evaluate(field, *pars).reshape((-1))
        out = {}
        out['bf'] = Struct(name='output_data', mode='vertex',
                           data=vals[:, None])
        mesh.write('iga_basis_%03d.vtk' % ic, io='auto', out=out)
Пример #7
0
def triangulate(mesh, verbose=False):
    """
    Triangulate a 2D or 3D tensor product mesh: quadrilaterals->triangles,
    hexahedrons->tetrahedrons.

    Parameters
    ----------
    mesh : Mesh
        The input mesh.

    Returns
    -------
    mesh : Mesh
        The triangulated mesh.
    """
    conns = None
    for k, new_desc in [('3_8', '3_4'), ('2_4', '2_3')]:
        if k in mesh.descs:
            conns = mesh.get_conn(k)
            break

    if conns is not None:
        nelo = conns.shape[0]
        output('initial mesh: %d elements' % nelo, verbose=verbose)

        new_conns = elems_q2t(conns)
        nn = new_conns.shape[0] // nelo
        new_cgroups = nm.repeat(mesh.cmesh.cell_groups, nn)

        output('new mesh: %d elements' % new_conns.shape[0], verbose=verbose)
        mesh = Mesh.from_data(mesh.name, mesh.coors, mesh.cmesh.vertex_groups,
                              [new_conns], [new_cgroups], [new_desc])

    return mesh
Пример #8
0
def save_basis(nurbs, pars):
    """
    Save a NURBS object basis on a FE mesh corresponding to the given
    parametrization in VTK files.

    Parameters
    ----------
    nurbs : igakit.nurbs.NURBS instance
        The NURBS object.
    pars : sequence of array, optional
        The values of parameters in each parametric dimension.
    """
    coors, conn, desc = create_linear_fe_mesh(nurbs, pars)
    mat_id = nm.zeros(conn.shape[0], dtype=nm.int32)
    mesh = Mesh.from_data('nurbs', coors, None, [conn], [mat_id], [desc])

    n_dof = nurbs.weights.ravel().shape[0]
    variable = nm.zeros(n_dof, dtype=nm.float64)
    field = variable.reshape(nurbs.weights.shape)
    for ic in xrange(n_dof):
        variable[ic - 1] = 0.0
        variable[ic] = 1.0

        vals = nurbs.evaluate(field, *pars).reshape((-1))
        out = {}
        out['bf'] = Struct(name='output_data',
                           mode='vertex',
                           data=vals[:, None])
        mesh.write('iga_basis_%03d.vtk' % ic, io='auto', out=out)
Пример #9
0
def refine_3_8(mesh_in, cmesh):
    """
    Refines hexahedral mesh by cutting cutting each edge in half and
    making 8 new finer hexahedrons out of one coarser one.
    """
    # Unique edge centres.
    e_centres = cmesh.get_centroids(cmesh.dim - 2)

    # Unique face centres.
    f_centres = cmesh.get_centroids(cmesh.dim - 1)

    # Unique element centres.
    coors = mesh_in.get_element_coors()
    centres = 0.125 * nm.sum(coors, axis=1)

    # New coordinates after the original ones.
    coors = nm.r_[mesh_in.coors, e_centres, f_centres, centres]

    o1 = mesh_in.n_nod
    o2 = o1 + e_centres.shape[0]
    o3 = o2 + f_centres.shape[0]

    ecc = cmesh.get_conn(cmesh.dim, cmesh.dim - 2)
    eoffs = ecc.offsets

    fcc = cmesh.get_conn(cmesh.dim, cmesh.dim - 1)
    foffs = fcc.offsets

    st = nm.vstack

    conns = []
    mat_ids = []
    for ig, conn in enumerate(mesh_in.conns):
        off0, off1 = mesh_in.el_offsets[ig : ig + 2]
        n_el  = conn.shape[0]

        e_nodes = ecc.indices[eoffs[off0]:eoffs[off1]].reshape((n_el, 12)) + o1
        f_nodes = fcc.indices[foffs[off0]:foffs[off1]].reshape((n_el, 6)) + o2
        nodes = nm.arange(n_el) + off0 + o3

        c = nm.c_[conn, e_nodes, f_nodes, nodes].T

        new_conn = st([c[0], c[8], c[20], c[11], c[16], c[22], c[26], c[21],
                       c[1], c[9], c[20], c[8], c[17], c[24], c[26], c[22],
                       c[2], c[10], c[20], c[9], c[18], c[25], c[26], c[24],
                       c[3], c[11], c[20], c[10], c[19], c[21], c[26], c[25],
                       c[4], c[15], c[23], c[12], c[16], c[21], c[26], c[22],
                       c[5], c[12], c[23], c[13], c[17], c[22], c[26], c[24],
                       c[6], c[13], c[23], c[14], c[18], c[24], c[26], c[25],
                       c[7], c[14], c[23], c[15], c[19], c[25], c[26], c[21]]).T
        new_conn = new_conn.reshape((8 * n_el, 8))
        conns.append(new_conn)

        new_mat_id = mesh_in.mat_ids[ig].repeat(8)
        mat_ids.append(new_mat_id)

    mesh = Mesh.from_data(mesh_in.name + '_r', coors, None, conns,
                          mat_ids, mesh_in.descs )

    return mesh
Пример #10
0
def refine_2_3(mesh_in):
    """
    Refines mesh out of triangles by cutting cutting each edge in half
    and making 4 new finer triangles out of one coarser one.
    """
    cmesh = mesh_in.cmesh

    # Unique edge centres.
    e_centres = cmesh.get_centroids(cmesh.dim - 1)

    # New coordinates after the original ones.
    coors = nm.r_[mesh_in.coors, e_centres]

    o1 = mesh_in.n_nod

    cc = cmesh.get_conn(cmesh.dim, cmesh.dim - 1)

    conn = mesh_in.get_conn('2_3')
    n_el = conn.shape[0]

    e_nodes = cc.indices.reshape((n_el, 3)) + o1

    c = nm.c_[conn, e_nodes].T

    new_conn = nm.vstack([
        c[0], c[3], c[5], c[3], c[4], c[5], c[1], c[4], c[3], c[2], c[5], c[4]
    ]).T
    new_conn = new_conn.reshape((4 * n_el, 3))

    new_mat_id = cmesh.cell_groups.repeat(4)

    mesh = Mesh.from_data(mesh_in.name + '_r', coors, None, [new_conn],
                          [new_mat_id], mesh_in.descs)

    return mesh
Пример #11
0
def _get_bqp(geometry, order):
    from sfepy.discrete import Integral
    from sfepy.discrete.fem.geometry_element import GeometryElement
    from sfepy.discrete.fem import Mesh, FEDomain, Field

    gel = GeometryElement(geometry)

    mesh = Mesh.from_data('aux', gel.coors, None,
                          [gel.conn[None, :]], [[0]], [geometry])
    domain = FEDomain('domain', mesh)
    omega = domain.create_region('Omega', 'all')
    surf =  domain.create_region('Surf', 'vertices of surface', 'facet')
    field = Field.from_args('f', nm.float64, shape=1,
                            region=omega, approx_order=1)
    field.setup_surface_data(surf)

    integral = Integral('aux', order=order)
    field.create_bqp('Surf', integral)

    sd = field.surface_data['Surf']
    qp = field.qp_coors[(integral.order, sd.bkey)]

    output('geometry:', geometry, 'order:', order, 'num. points:',
           qp.vals.shape[1], 'true_order:',
           integral.qps[gel.surface_facet_name].order)
    output('min. weight:', qp.weights.min())
    output('max. weight:', qp.weights.max())

    return (gel, qp.vals.reshape((-1, mesh.dim)),
            nm.tile(qp.weights, qp.vals.shape[0]))
Пример #12
0
def refine_3_4(mesh_in, cmesh):
    """
    Refines tetrahedra by cutting each edge in half and making 8 new
    finer tetrahedra out of one coarser one. Old nodal coordinates come
    first in `coors`, then the new ones. The new tetrahedra are similar
    to the old one, no degeneration is supposed to occur as at most 3
    congruence classes of tetrahedra appear, even when re-applied
    iteratively (provided that `conns` are not modified between two
    applications - ordering of vertices in tetrahedra matters not only
    for positivity of volumes).

    References:

    - Juergen Bey: Simplicial grid refinement: on Freudenthal s algorithm and 
      the optimal number of congruence classes, Numer.Math. 85 (2000), 
      no. 1, 1--29, or
    - Juergen Bey: Tetrahedral grid refinement, Computing 55 (1995), 
      no. 4, 355--378, or
      http://citeseer.ist.psu.edu/bey95tetrahedral.html
    """
    # Unique edge centres.
    e_centres = cmesh.get_centroids(cmesh.dim - 2)

    # New coordinates after the original ones.
    coors = nm.r_[mesh_in.coors, e_centres]

    o1 = mesh_in.n_nod

    cc = cmesh.get_conn(cmesh.dim, cmesh.dim - 2)
    offs = cc.offsets

    conns = []
    mat_ids = []
    for ig, conn in enumerate(mesh_in.conns):
        off0, off1 = mesh_in.el_offsets[ig : ig + 2]
        n_el  = conn.shape[0]

        e_nodes = cc.indices[offs[off0]:offs[off1]].reshape((n_el, 6)) + o1

        c = nm.c_[conn, e_nodes].T

        new_conn = nm.vstack([c[0], c[4], c[6], c[7],
                              c[4], c[1], c[5], c[8],
                              c[6], c[5], c[2], c[9],
                              c[7], c[8], c[9], c[3],
                              c[4], c[6], c[7], c[8],
                              c[4], c[6], c[8], c[5],
                              c[6], c[7], c[8], c[9],
                              c[6], c[5], c[9], c[8]]).T
        new_conn = new_conn.reshape((8 * n_el, 4))
        conns.append(new_conn)

        new_mat_id = mesh_in.mat_ids[ig].repeat(8)
        mat_ids.append(new_mat_id)

    mesh = Mesh.from_data(mesh_in.name + '_r', coors, None, conns,
                          mat_ids, mesh_in.descs )

    return mesh
Пример #13
0
    def __init__(self, name, nurbs, bmesh, regions=None, **kwargs):
        """
        Create an IGA domain.

        Parameters
        ----------
        name : str
            The domain name.
        """
        Domain.__init__(self, name, nurbs=nurbs, bmesh=bmesh, regions=regions,
                        **kwargs)
        from sfepy.discrete.fem.geometry_element import create_geometry_elements
        from sfepy.discrete.fem import Mesh
        from sfepy.discrete.fem.extmods.cmesh import CMesh
        from sfepy.discrete.fem.utils import prepare_remap

        ac = nm.ascontiguousarray
        self.nurbs.cs = [ac(nm.array(cc, dtype=nm.float64)[:, None, ...])
                         for cc in self.nurbs.cs]

        self.nurbs.degrees = self.nurbs.degrees.astype(nm.int32)

        self.facets = iga.get_bezier_element_entities(nurbs.degrees)

        tconn = iga.get_bezier_topology(bmesh.conn, nurbs.degrees)
        itc = nm.unique(tconn)

        remap = prepare_remap(itc, bmesh.conn.max() + 1)

        ltcoors = bmesh.cps[itc]
        ltconn = remap[tconn]

        n_nod, dim = ltcoors.shape
        n_el = ltconn.shape[0]
        self.shape = Struct(n_nod=n_nod, dim=dim, tdim=0, n_el=n_el, n_gr=1)

        desc = '%d_%d' % (dim, 2**dim)
        mat_id = nm.zeros(ltconn.shape[0], dtype=nm.int32)
        self.mesh = Mesh.from_data(self.name + '_topo', ltcoors, None, [ltconn],
                                   [mat_id], [desc])

        self.cmesh = CMesh.from_mesh(self.mesh)
        gels = create_geometry_elements()
        self.cmesh.set_local_entities(gels)
        self.cmesh.setup_entities()

        self.shape.tdim = self.cmesh.tdim

        self.gel = gels[desc]

        if regions is not None:
            self.vertex_set_bcs = {}
            for key, val in self.regions.iteritems():
                self.vertex_set_bcs[key] = remap[val]

        self.cell_offsets = {0 : 0}

        self.reset_regions()
Пример #14
0
def refine_region(domain0, region0, region1):
    """
    Coarse cell sub_cells[ii, 0] in mesh0 is split into sub_cells[ii, 1:] in
    mesh1.

    The new fine cells are interleaved among the original coarse cells so that
    the indices of the coarse cells do not change.

    The cell groups are preserved. The vertex groups are preserved only in the
    coarse (non-refined) cells.
    """
    if region1 is None:
        return domain0, None

    mesh0 = domain0.mesh
    mesh1 = Mesh.from_region(region1, mesh0)
    domain1 = FEDomain('d', mesh1)
    domain1r = domain1.refine()
    mesh1r = domain1r.mesh

    n_cell = region1.shape.n_cell
    n_sub = 4 if mesh0.cmesh.tdim == 2 else 8

    sub_cells = nm.empty((n_cell, n_sub + 1), dtype=nm.uint32)
    sub_cells[:, 0] = region1.cells
    sub_cells[:, 1] = region1.cells
    aux = nm.arange((n_sub - 1) * n_cell, dtype=nm.uint32)
    sub_cells[:, 2:] = mesh0.n_el + aux.reshape((n_cell, -1))

    coors0, vgs0, conns0, mat_ids0, descs0 = mesh0._get_io_data()
    coors, vgs, _conns, _mat_ids, descs = mesh1r._get_io_data()

    # Preserve vertex groups of non-refined cells.
    vgs[:len(vgs0)] = vgs0

    def _interleave_refined(c0, c1):
        if c1.ndim == 1:
            c0 = c0[:, None]
            c1 = c1[:, None]

        n_row, n_col = c1.shape
        n_new = region0.shape.n_cell + n_row

        out = nm.empty((n_new, n_col), dtype=c0.dtype)
        out[region0.cells] = c0[region0.cells]
        out[region1.cells] = c1[::n_sub]
        aux = c1.reshape((-1, n_col * n_sub))
        out[mesh0.n_el:] = aux[:, n_col:].reshape((-1, n_col))

        return out

    conn = _interleave_refined(conns0[0], _conns[0])
    mat_id = _interleave_refined(mat_ids0[0], _mat_ids[0]).squeeze()

    mesh = Mesh.from_data('a', coors, vgs, [conn], [mat_id], descs)
    domain = FEDomain('d', mesh)

    return domain, sub_cells
Пример #15
0
def refine_region(domain0, region0, region1):
    """
    Coarse cell sub_cells[ii, 0] in mesh0 is split into sub_cells[ii, 1:] in
    mesh1.

    The new fine cells are interleaved among the original coarse cells so that
    the indices of the coarse cells do not change.

    The cell groups are preserved. The vertex groups are preserved only in the
    coarse (non-refined) cells.
    """
    if region1 is None:
        return domain0, None

    mesh0 = domain0.mesh
    mesh1 = Mesh.from_region(region1, mesh0)
    domain1 = FEDomain('d', mesh1)
    domain1r = domain1.refine()
    mesh1r = domain1r.mesh

    n_cell = region1.shape.n_cell
    n_sub = 4 if mesh0.cmesh.tdim == 2 else 8

    sub_cells = nm.empty((n_cell, n_sub + 1), dtype=nm.uint32)
    sub_cells[:, 0] = region1.cells
    sub_cells[:, 1] = region1.cells
    aux = nm.arange((n_sub - 1) * n_cell, dtype=nm.uint32)
    sub_cells[:, 2:] = mesh0.n_el + aux.reshape((n_cell, -1))

    coors0, vgs0, conns0, mat_ids0, descs0 = mesh0._get_io_data()
    coors, vgs, _conns, _mat_ids, descs = mesh1r._get_io_data()

    # Preserve vertex groups of non-refined cells.
    vgs[:len(vgs0)] = vgs0

    def _interleave_refined(c0, c1):
        if c1.ndim == 1:
            c0 = c0[:, None]
            c1 = c1[:, None]

        n_row, n_col = c1.shape
        n_new = region0.shape.n_cell + n_row

        out = nm.empty((n_new, n_col), dtype=c0.dtype)
        out[region0.cells] = c0[region0.cells]
        out[region1.cells] = c1[::n_sub]
        aux = c1.reshape((-1, n_col * n_sub))
        out[mesh0.n_el:] = aux[:, n_col:].reshape((-1, n_col))

        return out

    conn = _interleave_refined(conns0[0], _conns[0])
    mat_id = _interleave_refined(mat_ids0[0], _mat_ids[0]).squeeze()

    mesh = Mesh.from_data('a', coors, vgs, [conn], [mat_id], descs)
    domain = FEDomain('d', mesh)

    return domain, sub_cells
Пример #16
0
def refine_3_4(mesh_in, cmesh):
    """
    Refines tetrahedra by cutting each edge in half and making 8 new
    finer tetrahedra out of one coarser one. Old nodal coordinates come
    first in `coors`, then the new ones. The new tetrahedra are similar
    to the old one, no degeneration is supposed to occur as at most 3
    congruence classes of tetrahedra appear, even when re-applied
    iteratively (provided that `conns` are not modified between two
    applications - ordering of vertices in tetrahedra matters not only
    for positivity of volumes).

    References:

    - Juergen Bey: Simplicial grid refinement: on Freudenthal s algorithm and 
      the optimal number of congruence classes, Numer.Math. 85 (2000), 
      no. 1, 1--29, or
    - Juergen Bey: Tetrahedral grid refinement, Computing 55 (1995), 
      no. 4, 355--378, or
      http://citeseer.ist.psu.edu/bey95tetrahedral.html
    """
    # Unique edge centres.
    e_centres = cmesh.get_centroids(cmesh.dim - 2)

    # New coordinates after the original ones.
    coors = nm.r_[mesh_in.coors, e_centres]

    o1 = mesh_in.n_nod

    cc = cmesh.get_conn(cmesh.dim, cmesh.dim - 2)
    offs = cc.offsets

    conns = []
    mat_ids = []
    for ig, conn in enumerate(mesh_in.conns):
        off0, off1 = mesh_in.el_offsets[ig:ig + 2]
        n_el = conn.shape[0]

        e_nodes = cc.indices[offs[off0]:offs[off1]].reshape((n_el, 6)) + o1

        c = nm.c_[conn, e_nodes].T

        new_conn = nm.vstack([
            c[0], c[4], c[6], c[7], c[4], c[1], c[5], c[8], c[6], c[5], c[2],
            c[9], c[7], c[8], c[9], c[3], c[4], c[6], c[7], c[8], c[4], c[6],
            c[8], c[5], c[6], c[7], c[8], c[9], c[6], c[5], c[9], c[8]
        ]).T
        new_conn = new_conn.reshape((8 * n_el, 4))
        conns.append(new_conn)

        new_mat_id = mesh_in.mat_ids[ig].repeat(8)
        mat_ids.append(new_mat_id)

    mesh = Mesh.from_data(mesh_in.name + '_r', coors, None, conns, mat_ids,
                          mesh_in.descs)

    return mesh
Пример #17
0
def refine_3_8(mesh_in):
    """
    Refines hexahedral mesh by cutting cutting each edge in half and
    making 8 new finer hexahedrons out of one coarser one.
    """
    cmesh = mesh_in.cmesh

    # Unique edge centres.
    e_centres = cmesh.get_centroids(cmesh.dim - 2)

    # Unique face centres.
    f_centres = cmesh.get_centroids(cmesh.dim - 1)

    # Unique element centres.
    centres = cmesh.get_centroids(cmesh.dim)

    # New coordinates after the original ones.
    coors = nm.r_[mesh_in.coors, e_centres, f_centres, centres]

    o1 = mesh_in.n_nod
    o2 = o1 + e_centres.shape[0]
    o3 = o2 + f_centres.shape[0]

    ecc = cmesh.get_conn(cmesh.dim, cmesh.dim - 2)
    fcc = cmesh.get_conn(cmesh.dim, cmesh.dim - 1)

    conn = mesh_in.get_conn('3_8')
    n_el = conn.shape[0]

    st = nm.vstack

    e_nodes = ecc.indices.reshape((n_el, 12)) + o1
    f_nodes = fcc.indices.reshape((n_el, 6)) + o2
    nodes = nm.arange(n_el) + o3

    c = nm.c_[conn, e_nodes, f_nodes, nodes].T

    new_conn = st([
        c[0], c[8], c[20], c[11], c[16], c[22], c[26], c[21], c[1], c[9],
        c[20], c[8], c[17], c[24], c[26], c[22], c[2], c[10], c[20], c[9],
        c[18], c[25], c[26], c[24], c[3], c[11], c[20], c[10], c[19], c[21],
        c[26], c[25], c[4], c[15], c[23], c[12], c[16], c[21], c[26], c[22],
        c[5], c[12], c[23], c[13], c[17], c[22], c[26], c[24], c[6], c[13],
        c[23], c[14], c[18], c[24], c[26], c[25], c[7], c[14], c[23], c[15],
        c[19], c[25], c[26], c[21]
    ]).T
    new_conn = new_conn.reshape((8 * n_el, 8))

    new_mat_id = cmesh.cell_groups.repeat(8)

    mesh = Mesh.from_data(mesh_in.name + '_r', coors, None, [new_conn],
                          [new_mat_id], mesh_in.descs)

    return mesh
Пример #18
0
def refine_3_8(mesh_in):
    """
    Refines hexahedral mesh by cutting cutting each edge in half and
    making 8 new finer hexahedrons out of one coarser one.
    """
    cmesh = mesh_in.cmesh

    # Unique edge centres.
    e_centres = cmesh.get_centroids(cmesh.dim - 2)

    # Unique face centres.
    f_centres = cmesh.get_centroids(cmesh.dim - 1)

    # Unique element centres.
    centres = cmesh.get_centroids(cmesh.dim)

    # New coordinates after the original ones.
    coors = nm.r_[mesh_in.coors, e_centres, f_centres, centres]

    o1 = mesh_in.n_nod
    o2 = o1 + e_centres.shape[0]
    o3 = o2 + f_centres.shape[0]

    ecc = cmesh.get_conn(cmesh.dim, cmesh.dim - 2)
    fcc = cmesh.get_conn(cmesh.dim, cmesh.dim - 1)

    conn = mesh_in.get_conn('3_8')
    n_el = conn.shape[0]

    st = nm.vstack

    e_nodes = ecc.indices.reshape((n_el, 12)) + o1
    f_nodes = fcc.indices.reshape((n_el, 6)) + o2
    nodes = nm.arange(n_el) + o3

    c = nm.c_[conn, e_nodes, f_nodes, nodes].T

    new_conn = st([c[0], c[8], c[20], c[11], c[16], c[22], c[26], c[21],
                   c[1], c[9], c[20], c[8], c[17], c[24], c[26], c[22],
                   c[2], c[10], c[20], c[9], c[18], c[25], c[26], c[24],
                   c[3], c[11], c[20], c[10], c[19], c[21], c[26], c[25],
                   c[4], c[15], c[23], c[12], c[16], c[21], c[26], c[22],
                   c[5], c[12], c[23], c[13], c[17], c[22], c[26], c[24],
                   c[6], c[13], c[23], c[14], c[18], c[24], c[26], c[25],
                   c[7], c[14], c[23], c[15], c[19], c[25], c[26], c[21]]).T
    new_conn = new_conn.reshape((8 * n_el, 8))

    new_mat_id = cmesh.cell_groups.repeat(8)

    mesh = Mesh.from_data(mesh_in.name + '_r', coors, None, [new_conn],
                          [new_mat_id], mesh_in.descs )

    return mesh
Пример #19
0
def create_mesh_and_output(nurbs, pars=None, **kwargs):
    """
    Create a nD-linear tensor product FE mesh using
    :func:`create_linear_fe_mesh()`, evaluate field variables given as keyword
    arguments in the mesh vertices and create a dictionary of output data
    usable by Mesh.write().

    Parameters
    ----------
    nurbs : igakit.nurbs.NURBS instance
        The NURBS object.
    pars : sequence of array, optional
        The values of parameters in each parametric dimension. If not given,
        the values are set so that the resulting mesh has the same number of
        vertices as the number of control points/basis functions of the NURBS
        object.
    **kwargs : kwargs
        The field variables as keyword arguments. Their names serve as keys in
        the output dictionary.

    Returns
    -------
    mesh : Mesh instance
        The finite element mesh.
    out : dict
        The output dictionary.
    """
    coors, conn, desc = create_linear_fe_mesh(nurbs, pars)
    mat_id = nm.zeros(conn.shape[0], dtype=nm.int32)
    mesh = Mesh.from_data('nurbs', coors, None, [conn], [mat_id], [desc])

    out = {}
    for key, variable in kwargs.iteritems():
        if variable.ndim == 2:
            nc = variable.shape[1]
            field = variable.reshape(nurbs.weights.shape + (nc, ))

        else:
            field = variable.reshape(nurbs.weights.shape)
            nc = 1

        vals = nurbs.evaluate(field, *pars)
        out[key] = Struct(name='output_data',
                          mode='vertex',
                          data=vals.reshape((-1, nc)))

    return mesh, out
Пример #20
0
def create_mesh_and_output(nurbs, pars=None, **kwargs):
    """
    Create a nD-linear tensor product FE mesh using
    :func:`create_linear_fe_mesh()`, evaluate field variables given as keyword
    arguments in the mesh vertices and create a dictionary of output data
    usable by Mesh.write().

    Parameters
    ----------
    nurbs : igakit.nurbs.NURBS instance
        The NURBS object.
    pars : sequence of array, optional
        The values of parameters in each parametric dimension. If not given,
        the values are set so that the resulting mesh has the same number of
        vertices as the number of control points/basis functions of the NURBS
        object.
    **kwargs : kwargs
        The field variables as keyword arguments. Their names serve as keys in
        the output dictionary.

    Returns
    -------
    mesh : Mesh instance
        The finite element mesh.
    out : dict
        The output dictionary.
    """
    coors, conn, desc = create_linear_fe_mesh(nurbs, pars)
    mat_id = nm.zeros(conn.shape[0], dtype=nm.int32)
    mesh = Mesh.from_data('nurbs', coors, None, [conn], [mat_id], [desc])

    out = {}
    for key, variable in kwargs.iteritems():
        if variable.ndim == 2:
            nc = variable.shape[1]
            field = variable.reshape(nurbs.weights.shape + (nc,))

        else:
            field = variable.reshape(nurbs.weights.shape)
            nc = 1

        vals = nurbs.evaluate(field, *pars)
        out[key] = Struct(name='output_data', mode='vertex',
                          data=vals.reshape((-1, nc)))

    return mesh, out
Пример #21
0
def refine_2_4(mesh_in, cmesh):
    """
    Refines mesh out of quadrilaterals by cutting cutting each edge in
    half and making 4 new finer quadrilaterals out of one coarser one.
    """
    # Unique edge centres.
    e_centres = cmesh.get_centroids(cmesh.dim - 1)

    # Unique element centres.
    centres = cmesh.get_centroids(cmesh.dim)

    # New coordinates after the original ones.
    coors = nm.r_[mesh_in.coors, e_centres, centres]

    o1 = mesh_in.n_nod
    o2 = o1 + e_centres.shape[0]

    cc = cmesh.get_conn(cmesh.dim, cmesh.dim - 1)
    offs = cc.offsets

    conns = []
    mat_ids = []
    for ig, conn in enumerate(mesh_in.conns):
        off0, off1 = mesh_in.el_offsets[ig:ig + 2]
        n_el = conn.shape[0]

        e_nodes = cc.indices[offs[off0]:offs[off1]].reshape((n_el, 4)) + o1
        nodes = nm.arange(n_el) + off0 + o2

        c = nm.c_[conn, e_nodes, nodes].T

        new_conn = nm.vstack([
            c[0], c[4], c[8], c[7], c[1], c[5], c[8], c[4], c[2], c[6], c[8],
            c[5], c[3], c[7], c[8], c[6]
        ]).T
        new_conn = new_conn.reshape((4 * n_el, 4))
        conns.append(new_conn)

        new_mat_id = mesh_in.mat_ids[ig].repeat(4)
        mat_ids.append(new_mat_id)

    mesh = Mesh.from_data(mesh_in.name + '_r', coors, None, conns, mat_ids,
                          mesh_in.descs)

    return mesh
Пример #22
0
def refine_2_4(mesh_in, cmesh):
    """
    Refines mesh out of quadrilaterals by cutting cutting each edge in
    half and making 4 new finer quadrilaterals out of one coarser one.
    """
    # Unique edge centres.
    e_centres = cmesh.get_centroids(cmesh.dim - 1)

    # Unique element centres.
    centres = cmesh.get_centroids(cmesh.dim)

    # New coordinates after the original ones.
    coors = nm.r_[mesh_in.coors, e_centres, centres]

    o1 = mesh_in.n_nod
    o2 = o1 + e_centres.shape[0]

    cc = cmesh.get_conn(cmesh.dim, cmesh.dim - 1)
    offs = cc.offsets

    conns = []
    mat_ids = []
    for ig, conn in enumerate(mesh_in.conns):
        off0, off1 = mesh_in.el_offsets[ig : ig + 2]
        n_el  = conn.shape[0]

        e_nodes = cc.indices[offs[off0]:offs[off1]].reshape((n_el, 4)) + o1
        nodes = nm.arange(n_el) + off0 + o2

        c = nm.c_[conn, e_nodes, nodes].T

        new_conn = nm.vstack([c[0], c[4], c[8], c[7],
                              c[1], c[5], c[8], c[4],
                              c[2], c[6], c[8], c[5],
                              c[3], c[7], c[8], c[6]]).T
        new_conn = new_conn.reshape((4 * n_el, 4))
        conns.append(new_conn)

        new_mat_id = mesh_in.mat_ids[ig].repeat(4)
        mat_ids.append(new_mat_id)

    mesh = Mesh.from_data(mesh_in.name + '_r', coors, None, conns,
                          mat_ids, mesh_in.descs )

    return mesh
Пример #23
0
    def mesh_hook(mesh, mode):
        """
        Generate the 1D mesh.
        """
        if mode == 'read':

            coors = nm.linspace(XS, XE, n_nod).reshape((n_nod, 1))
            conn = nm.arange(n_nod, dtype=nm.int32) \
                       .repeat(2)[1:-1].reshape((-1, 2))
            mat_ids = nm.zeros(n_nod - 1, dtype=nm.int32)
            descs = ['1_2']

            mesh = Mesh.from_data('uniform_1D{}'.format(n_nod), coors, None,
                                  [conn], [mat_ids], descs)
            return mesh

        elif mode == 'write':
            pass
Пример #24
0
def mesh_hook(mesh, mode):
    """
    Generate the 1D mesh.
    """
    if mode == 'read':
        n_nod = 101

        coors = nm.linspace(0.0, 1.0, n_nod).reshape((n_nod, 1))
        conn = nm.arange(n_nod, dtype=nm.int32).repeat(2)[1:-1].reshape((-1, 2))
        mat_ids = nm.zeros(n_nod - 1, dtype=nm.int32)
        descs = ['1_2']

        mesh = Mesh.from_data('laplace_1d', coors, None,
                              [conn], [mat_ids], descs)
        return mesh

    elif mode == 'write':
        pass
Пример #25
0
def refine_2_4(mesh_in):
    """
    Refines mesh out of quadrilaterals by cutting cutting each edge in
    half and making 4 new finer quadrilaterals out of one coarser one.
    """
    cmesh = mesh_in.cmesh

    # Unique edge centres.
    e_centres = cmesh.get_centroids(cmesh.dim - 1)

    # Unique element centres.
    centres = cmesh.get_centroids(cmesh.dim)

    # New coordinates after the original ones.
    coors = nm.r_[mesh_in.coors, e_centres, centres]

    o1 = mesh_in.n_nod
    o2 = o1 + e_centres.shape[0]

    cc = cmesh.get_conn(cmesh.dim, cmesh.dim - 1)

    conn = mesh_in.get_conn('2_4')
    n_el = conn.shape[0]

    e_nodes = cc.indices.reshape((n_el, 4)) + o1
    nodes = nm.arange(n_el) + o2

    c = nm.c_[conn, e_nodes, nodes].T

    new_conn = nm.vstack([c[0], c[4], c[8], c[7],
                          c[1], c[5], c[8], c[4],
                          c[2], c[6], c[8], c[5],
                          c[3], c[7], c[8], c[6]]).T
    new_conn = new_conn.reshape((4 * n_el, 4))

    new_mat_id = cmesh.cell_groups.repeat(4)

    mesh = Mesh.from_data(mesh_in.name + '_r', coors, None, [new_conn],
                          [new_mat_id], mesh_in.descs )

    return mesh
def make_mesh(dims, shape, transform=None):
    """
    Generate a 2D rectangle mesh in 3D space, and optionally apply a coordinate
    transform.
    """
    _mesh = gen_block_mesh(dims, shape, [0, 0], name='shell10x', verbose=False)

    coors = nm.c_[_mesh.coors, nm.zeros(_mesh.n_nod, dtype=nm.float64)]
    coors = nm.ascontiguousarray(coors)

    conns = [_mesh.get_conn(_mesh.descs[0])]

    mesh = Mesh.from_data(_mesh.name, coors, _mesh.cmesh.vertex_groups, conns,
                          [_mesh.cmesh.cell_groups], _mesh.descs)

    if transform == 'bend':
        bbox = mesh.get_bounding_box()
        x0, x1 = bbox[:, 0]

        angles = 0.5 *  nm.pi * (coors[:, 0] - x0) / (x1 - x0)
        mtx = make_axis_rotation_matrix([0, -1, 0], angles[:, None, None])

        coors = mesh.coors.copy()
        coors[:, 0] = 0
        coors[:, 2] = (x1 - x0)

        mesh.coors[:] = transform_data(coors, mtx=mtx)
        mesh.coors[:, 0] -= 0.5 * (x1 - x0)

    elif transform == 'twist':
        bbox = mesh.get_bounding_box()
        x0, x1 = bbox[:, 0]

        angles = 0.5 *  nm.pi * (coors[:, 0] - x0) / (x1 - x0)
        mtx = make_axis_rotation_matrix([-1, 0, 0], angles[:, None, None])

        mesh.coors[:] = transform_data(mesh.coors, mtx=mtx)

    return mesh
Пример #27
0
def make_mesh(dims, shape, transform=None):
    """
    Generate a 2D rectangle mesh in 3D space, and optionally apply a coordinate
    transform.
    """
    _mesh = gen_block_mesh(dims, shape, [0, 0], name='shell10x', verbose=False)

    coors = nm.c_[_mesh.coors, nm.zeros(_mesh.n_nod, dtype=nm.float64)]
    coors = nm.ascontiguousarray(coors)

    conns = [_mesh.get_conn(_mesh.descs[0])]

    mesh = Mesh.from_data(_mesh.name, coors, _mesh.cmesh.vertex_groups, conns,
                          [_mesh.cmesh.cell_groups], _mesh.descs)

    if transform == 'bend':
        bbox = mesh.get_bounding_box()
        x0, x1 = bbox[:, 0]

        angles = 0.5 *  nm.pi * (coors[:, 0] - x0) / (x1 - x0)
        mtx = make_axis_rotation_matrix([0, -1, 0], angles[:, None, None])

        coors = mesh.coors.copy()
        coors[:, 0] = 0
        coors[:, 2] = (x1 - x0)

        mesh.coors[:] = transform_data(coors, mtx=mtx)
        mesh.coors[:, 0] -= 0.5 * (x1 - x0)

    elif transform == 'twist':
        bbox = mesh.get_bounding_box()
        x0, x1 = bbox[:, 0]

        angles = 0.5 *  nm.pi * (coors[:, 0] - x0) / (x1 - x0)
        mtx = make_axis_rotation_matrix([-1, 0, 0], angles[:, None, None])

        mesh.coors[:] = transform_data(mesh.coors, mtx=mtx)

    return mesh
Пример #28
0
def _permute_quad_face(mesh0):
    from sfepy.discrete.fem import Mesh

    coors0, ngroups0, conns0, mat_ids0, desc0 = mesh0._get_io_data()
    im = nm.arange(4, 8)
    cperms = [[0, 1, 2, 3],
              [0, 2, 1, 3],
              [0, 1, 3, 2]]
    meshes = []
    for ip, cperm in enumerate(cperms):
        tr = nm.arange(12)
        tr[im] = tr[im[cperm]]

        coors = coors0.copy()
        coors[im] = coors0[im[cperm]]
        conn = conns0[0].copy()
        conn = tr[conn]

        mesh = Mesh.from_data(mesh0.name + str(ip), coors, ngroups0,
                              [conn], mat_ids0, desc0)
        meshes.append(mesh)

    return meshes
Пример #29
0
def refine_1_2(mesh_in):
    """
    Refines 1D mesh by cutting each element in half
    """

    if not nm.all(mesh_in.coors[:-1] <= mesh_in.coors[1:]):
        raise ValueError("1D Mesh for refinement must have sorted coors array")

    cmesh = mesh_in.cmesh
    c_centres = cmesh.get_centroids(cmesh.dim)
    new_coors = nm.zeros((2*mesh_in.n_nod - 1, 1))
    new_coors[0::2] = mesh_in.coors
    new_coors[1::2] = c_centres

    n_nod = len(new_coors)

    new_conn = nm.arange(n_nod, dtype=nm.int32).repeat(2)[1:-1].reshape((-1, 2))

    new_mat_id = cmesh.cell_groups.repeat(2)

    mesh = Mesh.from_data(mesh_in.name + '_r', new_coors, None, [new_conn],
                          [new_mat_id], mesh_in.descs)
    return mesh
Пример #30
0
def expand2d(mesh2d, dist, rep):
    """
    Expand 2D planar mesh into 3D volume,
    convert triangular/quad mesh to tetrahedrons/hexahedrons.

    Parameters
    ----------
    mesh2d : Mesh
        The 2D mesh.
    dist : float
        The elements size in the 3rd direction.
    rep : int
        The number of elements in the 3rd direction.

    Returns
    -------
    mesh3d : Mesh
        The 3D mesh.
    """
    if len(mesh2d.descs) > 1:
        raise ValueError('More than one cell type (%s). Not supported!' %
                         ', '.join(mesh2d.descs))

    nel = mesh2d.n_el
    nnd = mesh2d.n_nod
    et = mesh2d.descs[0]
    coors = mesh2d.coors
    conn = mesh2d.get_conn(et)

    zcoor = nm.arange(rep + 1) * dist
    coors3d = nm.hstack([
        nm.tile(coors, (rep + 1, 1)),
        nm.tile(zcoor, (nnd, 1)).T.flatten()[:, nm.newaxis]
    ])
    ngroups = nm.tile(mesh2d.cmesh.vertex_groups, (rep + 1, ))

    if et == '2_4':
        descs3d = '3_8'
        conn3d = nm.zeros((nel * rep, 8), dtype=nm.int32)
        mats3d = nm.tile(mesh2d.cmesh.cell_groups, (1, rep)).squeeze()

    elif et == '2_3':
        descs3d = '3_4'
        conn3d = nm.zeros((3 * nel * rep, 4), dtype=nm.int32)
        mats3d = nm.tile(mesh2d.cmesh.cell_groups, (1, 3 * rep)).squeeze()

    for ii in range(rep):
        bgn0 = nnd * ii
        bgn1 = bgn0 + nnd
        if et == '2_4':
            bge0 = nel * ii
            bge1 = bge0 + nel
            conn3d[bge0:bge1, :4] = conn + bgn0
            conn3d[bge0:bge1, 4:] = conn + bgn1

        elif et == '2_3':
            # 0 1 2 5
            bge0 = 3 * nel * ii
            bge1 = bge0 + nel
            conn3d[bge0:bge1, :] = nm.array([
                conn[:, 0] + bgn0, conn[:, 1] + bgn0, conn[:, 2] + bgn0,
                conn[:, 2] + bgn1
            ]).T
            # 0 1 5 4
            bge0 += nel
            bge1 += nel
            conn3d[bge0:bge1, :] = nm.array([
                conn[:, 0] + bgn0, conn[:, 1] + bgn0, conn[:, 2] + bgn1,
                conn[:, 1] + bgn1
            ]).T
            # 0 4 5 3
            bge0 += nel
            bge1 += nel
            conn3d[bge0:bge1, :] = nm.array([
                conn[:, 0] + bgn0, conn[:, 1] + bgn1, conn[:, 2] + bgn1,
                conn[:, 0] + bgn1
            ]).T

    mesh3d = Mesh.from_data('mesh', coors3d, ngroups, [conn3d], [mats3d],
                            [descs3d])

    return mesh3d
Пример #31
0
def main():
    parser = ArgumentParser(description=__doc__,
                            formatter_class=RawDescriptionHelpFormatter)
    parser.add_argument('-s', '--scale', metavar='scale',
                        action='store', dest='scale',
                        default=None, help=helps['scale'])
    parser.add_argument('-c', '--center', metavar='center',
                        action='store', dest='center',
                        default=None, help=helps['center'])
    parser.add_argument('-r', '--refine', metavar='level',
                        action='store', type=int, dest='refine',
                        default=0, help=helps['refine'])
    parser.add_argument('-f', '--format', metavar='format',
                        action='store', type=str, dest='format',
                        default=None, help=helps['format'])
    parser.add_argument('-l', '--list', action='store_true',
                        dest='list', help=helps['list'])
    parser.add_argument('-m', '--merge', action='store_true',
                        dest='merge', help=helps['merge'])
    parser.add_argument('-t', '--tri-tetra', action='store_true',
                        dest='tri_tetra', help=helps['tri-tetra'])
    parser.add_argument('filename_in')
    parser.add_argument('filename_out')
    options = parser.parse_args()

    if options.list:
        output('Supported readable mesh formats:')
        output('--------------------------------')
        output_mesh_formats('r')
        output('')
        output('Supported writable mesh formats:')
        output('--------------------------------')
        output_mesh_formats('w')
        sys.exit(0)

    scale = _parse_val_or_vec(options.scale, 'scale', parser)
    center = _parse_val_or_vec(options.center, 'center', parser)

    filename_in = options.filename_in
    filename_out = options.filename_out

    mesh = Mesh.from_file(filename_in)

    if scale is not None:
        if len(scale) == 1:
            tr = nm.eye(mesh.dim, dtype=nm.float64) * scale
        elif len(scale) == mesh.dim:
            tr = nm.diag(scale)
        else:
            raise ValueError('bad scale! (%s)' % scale)
        mesh.transform_coors(tr)

    if center is not None:
        cc = 0.5 * mesh.get_bounding_box().sum(0)
        shift = center - cc
        tr = nm.c_[nm.eye(mesh.dim, dtype=nm.float64), shift[:, None]]
        mesh.transform_coors(tr)

    if options.refine > 0:
        domain = FEDomain(mesh.name, mesh)
        output('initial mesh: %d nodes %d elements'
               % (domain.shape.n_nod, domain.shape.n_el))

        for ii in range(options.refine):
            output('refine %d...' % ii)
            domain = domain.refine()
            output('... %d nodes %d elements'
                   % (domain.shape.n_nod, domain.shape.n_el))

        mesh = domain.mesh

    if options.tri_tetra > 0:
        conns = None
        for k, new_desc in [('3_8', '3_4'), ('2_4', '2_3')]:
            if k in mesh.descs:
                conns = mesh.get_conn(k)
                break

        if conns is not None:
            nelo = conns.shape[0]
            output('initial mesh: %d elements' % nelo)

            new_conns = elems_q2t(conns)
            nn = new_conns.shape[0] // nelo
            new_cgroups = nm.repeat(mesh.cmesh.cell_groups, nn)

            output('new mesh: %d elements' % new_conns.shape[0])
            mesh = Mesh.from_data(mesh.name, mesh.coors,
                                  mesh.cmesh.vertex_groups,
                                  [new_conns], [new_cgroups], [new_desc])

    if options.merge:
        desc = mesh.descs[0]
        coor, ngroups, conns = fix_double_nodes(mesh.coors,
                                                mesh.cmesh.vertex_groups,
                                                mesh.get_conn(desc), 1e-9)
        mesh = Mesh.from_data(mesh.name + '_merged',
                              coor, ngroups,
                              [conns], [mesh.cmesh.cell_groups], [desc])

    io = MeshIO.for_format(filename_out, format=options.format,
                           writable=True)

    cell_types = ', '.join(supported_cell_types[io.format])
    output('writing [%s] %s...' % (cell_types, filename_out))
    mesh.write(filename_out, io=io)
    output('...done')
Пример #32
0
def refine_reference(geometry, level):
    """
    Refine reference element given by `geometry`.

    Notes
    -----
    The error edges must be generated in the order of the connectivity
    of the previous (lower) level.
    """
    from sfepy.discrete.fem import Domain
    from sfepy.discrete.fem.geometry_element import geometry_data

    gcoors, gconn = geometry.coors, geometry.conn
    if level == 0:
        return gcoors, gconn

    gd = geometry_data[geometry.name]
    conn = nm.array([gd.conn], dtype=nm.int32)
    mat_id = conn[:, 0].copy()
    mat_id[:] = 0

    mesh = Mesh.from_data('aux', gd.coors, None, [conn],
                          [mat_id], [geometry.name])
    domain = Domain('aux', mesh)

    for ii in range(level):
        domain = domain.refine()

    coors = domain.mesh.coors
    conn = domain.mesh.conns[0]

    n_el = conn.shape[0]

    if geometry.name == '2_3':
        aux_conn = conn.reshape((n_el / 4, 4, 3))

        ir = [[0, 1, 2], [2, 2, 3], [3, 3, 0]]
        ic = [[0, 0, 0], [0, 1, 0], [0, 1, 0]]

    elif geometry.name == '2_4':
        aux_conn = conn.reshape((n_el / 4, 4, 4))

        ir = [[0, 0, 1], [1, 1, 2], [2, 2, 3], [3, 3, 0], [0, 0, 2], [3, 3, 1]]
        ic = [[0, 1, 0], [0, 1, 0], [0, 1, 0], [0, 1, 0], [1, 2, 1], [1, 2, 1]]

    elif geometry.name == '3_4':
        aux_conn = conn.reshape((n_el / 8, 8, 4))

        ir = [[0, 0, 1], [1, 1, 2], [2, 0, 0], [3, 1, 1], [3, 2, 2], [3, 0, 0]]
        ic = [[0, 1, 1], [1, 2, 2], [2, 2, 0], [3, 3, 1], [3, 3, 2], [3, 3, 0]]

    elif geometry.name == '3_8':
        aux_conn = conn.reshape((n_el / 8, 8, 8))

        ir = [[0, 0, 1], [1, 1, 2], [2, 2, 3], [3, 0, 0], [0, 0, 2], [0, 0, 1],
              [0, 0, 1], [1, 1, 2], [2, 2, 3], [3, 0, 0], [0, 0, 2], [0, 0, 1],
              [4, 4, 5], [5, 5, 6], [6, 6, 7], [7, 4, 4], [4, 4, 6], [4, 4, 5],
              [0, 0, 4], [1, 1, 5], [2, 2, 6], [3, 3, 7],
              [0, 0, 4], [1, 1, 5], [2, 2, 6], [0, 0, 4],
              [0, 0, 4]]
        ic = [[0, 1, 0], [0, 1, 0], [0, 1, 0], [0, 3, 0], [1, 2, 1], [3, 2, 1],
              [4, 5, 4], [4, 5, 4], [4, 5, 4], [4, 7, 4], [5, 6, 5], [7, 6, 5],
              [0, 3, 0], [0, 3, 0], [0, 3, 0], [0, 1, 0], [3, 2, 3], [1, 2, 3],
              [0, 4, 0], [0, 4, 0], [0, 4, 0], [0, 4, 0],
              [1, 5, 3], [1, 5, 3], [1, 5, 3], [3, 7, 1],
              [2, 6, 2]]

    else:
        raise ValueError('unsupported geometry! (%s)' % geometry.name)

    conn = nm.array(conn, dtype=nm.int32)
    error_edges = aux_conn[:, ir, ic]

    return coors, conn, error_edges
Пример #33
0
def expand2d(mesh2d, dist, rep):
    """
    Expand 2D planar mesh into 3D volume,
    convert triangular/quad mesh to tetrahedrons/hexahedrons.

    Parameters
    ----------
    mesh2d : Mesh
        The 2D mesh.
    dist : float
        The elements size in the 3rd direction.
    rep : int
        The number of elements in the 3rd direction.

    Returns
    -------
    mesh3d : Mesh
        The 3D mesh.
    """
    if len(mesh2d.descs) > 1:
        raise ValueError('More than one cell type (%s). Not supported!'
                         % ', '.join(mesh2d.descs))

    nel = mesh2d.n_el
    nnd = mesh2d.n_nod
    et = mesh2d.descs[0]
    coors = mesh2d.coors
    conn = mesh2d.get_conn(et)

    zcoor = nm.arange(rep + 1) * dist
    coors3d = nm.hstack([nm.tile(coors, (rep + 1, 1)),
                         nm.tile(zcoor, (nnd,1)).T.flatten()[:,nm.newaxis]])
    ngroups = nm.tile(mesh2d.cmesh.vertex_groups, (rep + 1,))

    if et == '2_4':
        descs3d = '3_8'
        conn3d = nm.zeros((nel * rep, 8), dtype=nm.int32)
        mats3d = nm.tile(mesh2d.cmesh.cell_groups, (1, rep)).squeeze()

    elif et == '2_3':
        descs3d = '3_4'
        conn3d = nm.zeros((3 * nel * rep, 4), dtype=nm.int32)
        mats3d = nm.tile(mesh2d.cmesh.cell_groups, (1, 3 * rep)).squeeze()

    for ii in range(rep):
        bgn0 = nnd * ii
        bgn1 = bgn0 + nnd
        if et == '2_4':
            bge0 = nel * ii
            bge1 = bge0 + nel
            conn3d[bge0:bge1,:4] = conn + bgn0
            conn3d[bge0:bge1,4:] = conn + bgn1

        elif et == '2_3':
            # 0 1 2 5
            bge0 = 3 * nel * ii
            bge1 = bge0 + nel
            conn3d[bge0:bge1,:] = nm.array([conn[:,0] + bgn0,
                                            conn[:,1] + bgn0,
                                            conn[:,2] + bgn0,
                                            conn[:,2] + bgn1]).T
            # 0 1 5 4
            bge0 += nel
            bge1 += nel
            conn3d[bge0:bge1,:] = nm.array([conn[:,0] + bgn0,
                                            conn[:,1] + bgn0,
                                            conn[:,2] + bgn1,
                                            conn[:,1] + bgn1]).T
            # 0 4 5 3
            bge0 += nel
            bge1 += nel
            conn3d[bge0:bge1,:] = nm.array([conn[:,0] + bgn0,
                                            conn[:,1] + bgn1,
                                            conn[:,2] + bgn1,
                                            conn[:,0] + bgn1]).T

    mesh3d = Mesh.from_data('mesh', coors3d, ngroups, [conn3d],
                            [mats3d], [descs3d])

    return mesh3d
Пример #34
0
def main():
    parser = ArgumentParser(description=__doc__,
                            formatter_class=RawDescriptionHelpFormatter)
    parser.add_argument('-s',
                        '--scale',
                        metavar='scale',
                        action='store',
                        dest='scale',
                        default=None,
                        help=helps['scale'])
    parser.add_argument('-c',
                        '--center',
                        metavar='center',
                        action='store',
                        dest='center',
                        default=None,
                        help=helps['center'])
    parser.add_argument('-r',
                        '--refine',
                        metavar='level',
                        action='store',
                        type=int,
                        dest='refine',
                        default=0,
                        help=helps['refine'])
    parser.add_argument('-f',
                        '--format',
                        metavar='format',
                        action='store',
                        type=str,
                        dest='format',
                        default=None,
                        help=helps['format'])
    parser.add_argument('-l',
                        '--list',
                        action='store_true',
                        dest='list',
                        help=helps['list'])
    parser.add_argument('-m',
                        '--merge',
                        action='store_true',
                        dest='merge',
                        help=helps['merge'])
    parser.add_argument('-t',
                        '--tri-tetra',
                        action='store_true',
                        dest='tri_tetra',
                        help=helps['tri-tetra'])
    parser.add_argument('-2',
                        '--2d',
                        action='store_true',
                        dest='force_2d',
                        help=helps['2d'])
    parser.add_argument('--save-per-mat',
                        action='store_true',
                        dest='save_per_mat',
                        help=helps['save-per-mat'])
    parser.add_argument('--remesh',
                        metavar='options',
                        action='store',
                        dest='remesh',
                        default=None,
                        help=helps['remesh'])
    parser.add_argument('filename_in')
    parser.add_argument('filename_out')
    options = parser.parse_args()

    if options.list:
        output('Supported readable mesh formats:')
        output('--------------------------------')
        output_mesh_formats('r')
        output('')
        output('Supported writable mesh formats:')
        output('--------------------------------')
        output_mesh_formats('w')
        sys.exit(0)

    scale = _parse_val_or_vec(options.scale, 'scale', parser)
    center = _parse_val_or_vec(options.center, 'center', parser)

    filename_in = options.filename_in
    filename_out = options.filename_out

    if options.remesh:
        import tempfile
        import shlex
        import subprocess

        dirname = tempfile.mkdtemp()

        is_surface = options.remesh.startswith('q')
        if is_surface:
            mesh = Mesh.from_file(filename_in)
            domain = FEDomain(mesh.name, mesh)
            region = domain.create_region('surf', 'vertices of surface',
                                          'facet')
            surf_mesh = Mesh.from_region(region,
                                         mesh,
                                         localize=True,
                                         is_surface=True)

            filename = op.join(dirname, 'surf.mesh')
            surf_mesh.write(filename, io='auto')

        else:
            import shutil

            shutil.copy(filename_in, dirname)
            filename = op.join(dirname, op.basename(filename_in))

        qopts = ''.join(options.remesh.split())  # Remove spaces.
        command = 'tetgen -BFENkACp%s %s' % (qopts, filename)
        args = shlex.split(command)
        subprocess.call(args)

        root, ext = op.splitext(filename)
        mesh = Mesh.from_file(root + '.1.vtk')

        remove_files(dirname)

    else:
        mesh = Mesh.from_file(filename_in)

    if options.force_2d:
        data = list(mesh._get_io_data())
        data[0] = data[0][:, :2]
        mesh = Mesh.from_data(mesh.name, *data)

    if scale is not None:
        if len(scale) == 1:
            tr = nm.eye(mesh.dim, dtype=nm.float64) * scale
        elif len(scale) == mesh.dim:
            tr = nm.diag(scale)
        else:
            raise ValueError('bad scale! (%s)' % scale)
        mesh.transform_coors(tr)

    if center is not None:
        cc = 0.5 * mesh.get_bounding_box().sum(0)
        shift = center - cc
        tr = nm.c_[nm.eye(mesh.dim, dtype=nm.float64), shift[:, None]]
        mesh.transform_coors(tr)

    if options.refine > 0:
        domain = FEDomain(mesh.name, mesh)
        output('initial mesh: %d nodes %d elements' %
               (domain.shape.n_nod, domain.shape.n_el))

        for ii in range(options.refine):
            output('refine %d...' % ii)
            domain = domain.refine()
            output('... %d nodes %d elements' %
                   (domain.shape.n_nod, domain.shape.n_el))

        mesh = domain.mesh

    if options.tri_tetra > 0:
        mesh = triangulate(mesh, verbose=True)

    if options.merge:
        desc = mesh.descs[0]
        coor, ngroups, conns = fix_double_nodes(mesh.coors,
                                                mesh.cmesh.vertex_groups,
                                                mesh.get_conn(desc))
        mesh = Mesh.from_data(mesh.name + '_merged', coor, ngroups, [conns],
                              [mesh.cmesh.cell_groups], [desc])

    if options.save_per_mat:
        desc = mesh.descs[0]
        conns, cgroups = mesh.get_conn(desc), mesh.cmesh.cell_groups
        coors, ngroups = mesh.coors, mesh.cmesh.vertex_groups
        mat_ids = nm.unique(cgroups)

        for mat_id in mat_ids:
            idxs = nm.where(cgroups == mat_id)[0]
            imesh = Mesh.from_data(mesh.name + '_matid_%d' % mat_id, coors,
                                   ngroups, [conns[idxs]], [cgroups[idxs]],
                                   [desc])

            fbase, fext = op.splitext(filename_out)
            ifilename_out = '%s_matid_%d%s' % (fbase, mat_id, fext)
            io = MeshIO.for_format(ifilename_out,
                                   format=options.format,
                                   writable=True)
            output('writing %s...' % ifilename_out)
            imesh.write(ifilename_out, io=io)
            output('...done')

    io = MeshIO.for_format(filename_out, format=options.format, writable=True)

    cell_types = ', '.join(supported_cell_types[io.format])
    output('writing [%s] %s...' % (cell_types, filename_out))
    mesh.write(filename_out, io=io)
    output('...done')
Пример #35
0
def refine_reference(geometry, level):
    """
    Refine reference element given by `geometry`.

    Notes
    -----
    The error edges must be generated in the order of the connectivity
    of the previous (lower) level.
    """
    from sfepy.discrete.fem import FEDomain
    from sfepy.discrete.fem.geometry_element import geometry_data

    gcoors, gconn = geometry.coors, geometry.conn
    if level == 0:
        return gcoors, gconn, None

    gd = geometry_data[geometry.name]
    conn = nm.array([gd.conn], dtype=nm.int32)
    mat_id = conn[:, 0].copy()
    mat_id[:] = 0

    mesh = Mesh.from_data('aux', gd.coors, None, [conn], [mat_id],
                          [geometry.name])
    domain = FEDomain('aux', mesh)

    for ii in range(level):
        domain = domain.refine()

    coors = domain.mesh.coors
    conn = domain.get_conn()

    n_el = conn.shape[0]

    if geometry.name == '2_3':
        aux_conn = conn.reshape((n_el / 4, 4, 3))

        ir = [[0, 1, 2], [2, 2, 3], [3, 3, 0]]
        ic = [[0, 0, 0], [0, 1, 0], [0, 1, 0]]

    elif geometry.name == '2_4':
        aux_conn = conn.reshape((n_el / 4, 4, 4))

        ir = [[0, 0, 1], [1, 1, 2], [2, 2, 3], [3, 3, 0], [0, 0, 2], [3, 3, 1]]
        ic = [[0, 1, 0], [0, 1, 0], [0, 1, 0], [0, 1, 0], [1, 2, 1], [1, 2, 1]]

    elif geometry.name == '3_4':
        aux_conn = conn.reshape((n_el / 8, 8, 4))

        ir = [[0, 0, 1], [1, 1, 2], [2, 0, 0], [3, 1, 1], [3, 2, 2], [3, 0, 0]]
        ic = [[0, 1, 1], [1, 2, 2], [2, 2, 0], [3, 3, 1], [3, 3, 2], [3, 3, 0]]

    elif geometry.name == '3_8':
        aux_conn = conn.reshape((n_el / 8, 8, 8))

        ir = [[0, 0, 1], [1, 1, 2], [2, 2, 3], [3, 0, 0], [0, 0, 2], [0, 0, 1],
              [0, 0, 1], [1, 1, 2], [2, 2, 3], [3, 0, 0], [0, 0, 2], [0, 0, 1],
              [4, 4, 5], [5, 5, 6], [6, 6, 7], [7, 4, 4], [4, 4, 6], [4, 4, 5],
              [0, 0, 4], [1, 1, 5], [2, 2, 6], [3, 3, 7], [0, 0, 4], [1, 1, 5],
              [2, 2, 6], [0, 0, 4], [0, 0, 4]]
        ic = [[0, 1, 0], [0, 1, 0], [0, 1, 0], [0, 3, 0], [1, 2, 1], [3, 2, 1],
              [4, 5, 4], [4, 5, 4], [4, 5, 4], [4, 7, 4], [5, 6, 5], [7, 6, 5],
              [0, 3, 0], [0, 3, 0], [0, 3, 0], [0, 1, 0], [3, 2, 3], [1, 2, 3],
              [0, 4, 0], [0, 4, 0], [0, 4, 0], [0, 4, 0], [1, 5, 3], [1, 5, 3],
              [1, 5, 3], [3, 7, 1], [2, 6, 2]]

    else:
        raise ValueError('unsupported geometry! (%s)' % geometry.name)

    conn = nm.array(conn, dtype=nm.int32)
    error_edges = aux_conn[:, ir, ic]

    return coors, conn, error_edges
Пример #36
0
def recover_micro_hook_eps(micro_filename, region,
                           eval_var, nodal_values, const_values, eps0,
                           recovery_file_tag='',
                           define_args=None, verbose=False):
    # Create a micro-problem instance.
    required, other = get_standard_keywords()
    required.remove('equations')
    conf = ProblemConf.from_file(micro_filename, required, other,
                                 verbose=False, define_args=define_args)

    coefs_filename = conf.options.get('coefs_filename', 'coefs')
    output_dir = conf.options.get('output_dir', '.')
    coefs_filename = op.join(output_dir, coefs_filename) + '.h5'

    # Coefficients and correctors
    coefs = Coefficients.from_file_hdf5(coefs_filename)
    corrs = get_correctors_from_file(dump_names=coefs.dump_names)

    recovery_hook = conf.options.get('recovery_hook', None)

    if recovery_hook is not None:
        recovery_hook = conf.get_function(recovery_hook)
        pb = Problem.from_conf(conf, init_equations=False, init_solvers=False)

        # Get tiling of a given region
        rcoors = region.domain.mesh.coors[region.get_entities(0), :]
        rcmin = nm.min(rcoors, axis=0)
        rcmax = nm.max(rcoors, axis=0)
        nn = nm.round((rcmax - rcmin) / eps0)
        if nm.prod(nn) == 0:
            output('inconsistency in recovery region and microstructure size!')
            return

        cs = []
        for ii, n in enumerate(nn):
            cs.append(nm.arange(n) * eps0 + rcmin[ii])

        x0 = nm.empty((int(nm.prod(nn)), nn.shape[0]), dtype=nm.float64)
        for ii, icoor in enumerate(nm.meshgrid(*cs, indexing='ij')):
            x0[:, ii] = icoor.flatten()

        mesh = pb.domain.mesh
        coors, conn, outs, ndoffset = [], [], [], 0
        # Recover region
        mic_coors = (mesh.coors - mesh.get_bounding_box()[0, :]) * eps0
        evfield = eval_var.field

        output('recovering microsctructures...')
        tt = time.clock()
        output_fun = output.output_function
        output_level = output.level

        for ii, c0 in enumerate(x0):
            local_macro = {'eps0': eps0}
            local_coors = mic_coors + c0
            # Inside recovery region?
            v = nm.ones((evfield.region.entities[0].shape[0], 1))
            v[evfield.vertex_remap[region.entities[0]]] = 0
            no = nm.sum(v)
            aux = evfield.evaluate_at(local_coors, v)
            if (nm.sum(aux) / no) > 1e-3:
                continue

            output.level = output_level
            output('micro: %d' % ii)

            for k, v in six.iteritems(nodal_values):
                local_macro[k] = evfield.evaluate_at(local_coors, v)
            for k, v in six.iteritems(const_values):
                local_macro[k] = v

            output.set_output(quiet=not(verbose))
            outs.append(recovery_hook(pb, corrs, local_macro))
            output.output_function = output_fun
            coors.append(local_coors)
            conn.append(mesh.get_conn(mesh.descs[0]) + ndoffset)
            ndoffset += mesh.n_nod

    output('...done in %.2f s' % (time.clock() - tt))

    # Collect output variables
    outvars = {}
    for k, v in six.iteritems(outs[0]):
        if v.var_name in outvars:
            outvars[v.var_name].append(k)
        else:
            outvars[v.var_name] = [k]

    # Split output by variables/regions
    pvs = pb.create_variables(outvars.keys())
    outregs = {k: pvs[k].field.region.get_entities(-1) for k in outvars.keys()}
    nrve = len(coors)
    coors = nm.vstack(coors)
    ngroups = nm.tile(mesh.cmesh.vertex_groups.squeeze(), (nrve,))
    conn = nm.vstack(conn)
    cgroups = nm.tile(mesh.cmesh.cell_groups.squeeze(), (nrve,))

    # Get region mesh and data
    for k, cidxs in six.iteritems(outregs):
        gcidxs = nm.hstack([cidxs + mesh.n_el * ii for ii in range(nrve)])
        rconn = conn[gcidxs]
        remap = -nm.ones((coors.shape[0],), dtype=nm.int32)
        remap[rconn] = 1
        vidxs = nm.where(remap > 0)[0]
        remap[vidxs] = nm.arange(len(vidxs))
        rconn = remap[rconn]
        rcoors = coors[vidxs, :]

        out = {}
        for ifield in outvars[k]:
            data = [outs[ii][ifield].data for ii in range(nrve)]
            out[ifield] = Struct(name='output_data',
                                 mode=outs[0][ifield].mode,
                                 dofs=None,
                                 var_name=k,
                                 data=nm.vstack(data))

        micro_name = pb.get_output_name(extra='recovered%s_%s'
                                        % (recovery_file_tag, k))
        filename = op.join(output_dir, op.basename(micro_name))
        mesh_out = Mesh.from_data('recovery_%s' % k, rcoors, ngroups[vidxs],
                                  [rconn], [cgroups[gcidxs]], [mesh.descs[0]])
        mesh_out.write(filename, io='auto', out=out)
Пример #37
0
def refine_3_8(mesh_in, cmesh):
    """
    Refines hexahedral mesh by cutting cutting each edge in half and
    making 8 new finer hexahedrons out of one coarser one.
    """
    # Unique edge centres.
    e_centres = cmesh.get_centroids(cmesh.dim - 2)

    # Unique face centres.
    f_centres = cmesh.get_centroids(cmesh.dim - 1)

    # Unique element centres.
    coors = mesh_in.get_element_coors()
    centres = 0.125 * nm.sum(coors, axis=1)

    # New coordinates after the original ones.
    coors = nm.r_[mesh_in.coors, e_centres, f_centres, centres]

    o1 = mesh_in.n_nod
    o2 = o1 + e_centres.shape[0]
    o3 = o2 + f_centres.shape[0]

    ecc = cmesh.get_conn(cmesh.dim, cmesh.dim - 2)
    eoffs = ecc.offsets

    fcc = cmesh.get_conn(cmesh.dim, cmesh.dim - 1)
    foffs = fcc.offsets

    st = nm.vstack

    conns = []
    mat_ids = []
    for ig, conn in enumerate(mesh_in.conns):
        off0, off1 = mesh_in.el_offsets[ig:ig + 2]
        n_el = conn.shape[0]

        e_nodes = ecc.indices[eoffs[off0]:eoffs[off1]].reshape((n_el, 12)) + o1
        f_nodes = fcc.indices[foffs[off0]:foffs[off1]].reshape((n_el, 6)) + o2
        nodes = nm.arange(n_el) + off0 + o3

        c = nm.c_[conn, e_nodes, f_nodes, nodes].T

        new_conn = st([
            c[0], c[8], c[20], c[11], c[16], c[22], c[26], c[21], c[1], c[9],
            c[20], c[8], c[17], c[24], c[26], c[22], c[2], c[10], c[20], c[9],
            c[18], c[25], c[26], c[24], c[3], c[11], c[20], c[10], c[19],
            c[21], c[26], c[25], c[4], c[15], c[23], c[12], c[16], c[21],
            c[26], c[22], c[5], c[12], c[23], c[13], c[17], c[22], c[26],
            c[24], c[6], c[13], c[23], c[14], c[18], c[24], c[26], c[25], c[7],
            c[14], c[23], c[15], c[19], c[25], c[26], c[21]
        ]).T
        new_conn = new_conn.reshape((8 * n_el, 8))
        conns.append(new_conn)

        new_mat_id = mesh_in.mat_ids[ig].repeat(8)
        mat_ids.append(new_mat_id)

    mesh = Mesh.from_data(mesh_in.name + '_r', coors, None, conns, mat_ids,
                          mesh_in.descs)

    return mesh
Пример #38
0
    def _eval_basis_transform(self, subs):
        """
        """
        from sfepy.discrete import Integral
        from sfepy.discrete.fem import Mesh, FEDomain, Field

        transform = nm.tile(nm.eye(self.econn.shape[1]),
                            (self.econn.shape[0], 1, 1))
        if subs is None:
            return transform

        gel = self.gel
        ao = self.approx_order

        conn = [gel.conn]
        mesh = Mesh.from_data('a', gel.coors, None, [conn], [nm.array([0])],
                              [gel.name])
        cdomain = FEDomain('d', mesh)
        comega = cdomain.create_region('Omega', 'all')
        rcfield = Field.from_args('rc', self.dtype, 1, comega, approx_order=ao)

        fdomain = cdomain.refine()
        fomega = fdomain.create_region('Omega', 'all')
        rffield = Field.from_args('rf', self.dtype, 1, fomega, approx_order=ao)

        def assign_transform(transform, bf, subs, ef):
            if not len(subs): return

            n_sub = (subs.shape[1] - 2) // 2

            for ii, sub in enumerate(subs):
                for ij in range(n_sub):
                    ik = 2 * (ij + 1)

                    fface = ef[sub[ik + 1]]

                    mtx = transform[sub[ik]]
                    ix, iy = nm.meshgrid(fface, fface)

                    cbf = bf[iy, 0, ix]

                    mtx[ix, iy] = cbf

        fcoors = rffield.get_coor()

        coors = fcoors[rffield.econn[0]]
        integral = Integral('i',
                            coors=coors,
                            weights=nm.ones_like(coors[:, 0]))

        rcfield.clear_qp_base()
        bf = rcfield.get_base('v', False, integral)

        if gel.name == '2_4':
            fsubs = subs
            esubs = None

            assign_transform(transform, bf, fsubs, rffield.efaces)

        else:
            fsubs = subs[0]
            esubs = subs[1]

            assign_transform(transform, bf, fsubs, rffield.efaces)
            if esubs is not None:
                assign_transform(transform, bf, esubs, rffield.eedges)

        assert_((nm.abs(transform.sum(1) - 1.0) < 1e-15).all())

        return transform
Пример #39
0
def recover_micro_hook_eps(micro_filename, region,
                           eval_var, nodal_values, const_values, eps0,
                           recovery_file_tag='',
                           define_args=None):
    # Create a micro-problem instance.
    required, other = get_standard_keywords()
    required.remove('equations')
    conf = ProblemConf.from_file(micro_filename, required, other,
                                 verbose=False, define_args=define_args)

    coefs_filename = conf.options.get('coefs_filename', 'coefs')
    output_dir = conf.options.get('output_dir', '.')
    coefs_filename = op.join(output_dir, coefs_filename) + '.h5'

    # Coefficients and correctors
    coefs = Coefficients.from_file_hdf5(coefs_filename)
    corrs = get_correctors_from_file(dump_names=coefs.dump_names)

    recovery_hook = conf.options.get('recovery_hook', None)

    if recovery_hook is not None:
        recovery_hook = conf.get_function(recovery_hook)
        pb = Problem.from_conf(conf, init_equations=False, init_solvers=False)

        # Get tiling of a given region
        rcoors = region.domain.mesh.coors[region.get_entities(0), :]
        rcmin = nm.min(rcoors, axis=0)
        rcmax = nm.max(rcoors, axis=0)
        nn = nm.round((rcmax - rcmin) / eps0)
        if nm.prod(nn) == 0:
            output('inconsistency in recovery region and microstructure size!')
            return

        cs = []
        for ii, n in enumerate(nn):
            cs.append(nm.arange(n) * eps0 + rcmin[ii])

        x0 = nm.empty((int(nm.prod(nn)), nn.shape[0]), dtype=nm.float64)
        for ii, icoor in enumerate(nm.meshgrid(*cs, indexing='ij')):
            x0[:, ii] = icoor.flatten()

        mesh = pb.domain.mesh
        coors, conn, outs, ndoffset = [], [], [], 0
        # Recover region
        for ii, c0 in enumerate(x0):
            local_macro = {'eps0': eps0}
            local_coors = pb.domain.mesh.coors * eps0 + c0
            # Inside recovery region?
            v = nm.ones((eval_var.field.region.entities[0].shape[0], 1))
            v[region.entities[0]] = 0
            no = nm.sum(v)
            aux = eval_var.field.evaluate_at(local_coors, v)
            if (nm.sum(aux) / no) > 1e-3:
                continue

            output('ii: %d' % ii)

            for k, v in six.iteritems(nodal_values):
                local_macro[k] = eval_var.field.evaluate_at(local_coors, v)
            for k, v in six.iteritems(const_values):
                local_macro[k] = v

            outs.append(recovery_hook(pb, corrs, local_macro))
            coors.append(local_coors)
            conn.append(mesh.get_conn(mesh.descs[0]) + ndoffset)
            ndoffset += mesh.n_nod

    # Collect output variables
    outvars = {}
    for k, v in six.iteritems(outs[0]):
        if v.var_name in outvars:
            outvars[v.var_name].append(k)
        else:
            outvars[v.var_name] = [k]

    # Split output by variables/regions
    pvs = pb.create_variables(outvars.keys())
    outregs = {k: pvs[k].field.region.get_entities(-1) for k in outvars.keys()}
    nrve = len(coors)
    coors = nm.vstack(coors)
    ngroups = nm.tile(mesh.cmesh.vertex_groups.squeeze(), (nrve,))
    conn = nm.vstack(conn)
    cgroups = nm.tile(mesh.cmesh.cell_groups.squeeze(), (nrve,))

    # Get region mesh and data
    for k, cidxs in six.iteritems(outregs):
        gcidxs = nm.hstack([cidxs + mesh.n_el * ii for ii in range(nrve)])
        rconn = conn[gcidxs]
        remap = -nm.ones((coors.shape[0],), dtype=nm.int32)
        remap[rconn] = 1
        vidxs = nm.where(remap > 0)[0]
        remap[vidxs] = nm.arange(len(vidxs))
        rconn = remap[rconn]
        rcoors = coors[vidxs, :]

        out = {}
        for ifield in outvars[k]:
            data = [outs[ii][ifield].data for ii in range(nrve)]
            out[ifield] = Struct(name='output_data',
                                 mode=outs[0][ifield].mode,
                                 dofs=None,
                                 var_name=k,
                                 data=nm.vstack(data))

        micro_name = pb.get_output_name(extra='recovered%s_%s'
                                        % (recovery_file_tag, k))
        filename = op.join(output_dir, op.basename(micro_name))
        mesh_out = Mesh.from_data('recovery_%s' % k, rcoors, ngroups[vidxs],
                                  [rconn], [cgroups[gcidxs]], [mesh.descs[0]])
        mesh_out.write(filename, io='auto', out=out)
Пример #40
0
def main():
    parser = ArgumentParser(description=__doc__,
                            formatter_class=RawDescriptionHelpFormatter)
    parser.add_argument('-s',
                        '--scale',
                        metavar='scale',
                        action='store',
                        dest='scale',
                        default=None,
                        help=helps['scale'])
    parser.add_argument('-c',
                        '--center',
                        metavar='center',
                        action='store',
                        dest='center',
                        default=None,
                        help=helps['center'])
    parser.add_argument('-r',
                        '--refine',
                        metavar='level',
                        action='store',
                        type=int,
                        dest='refine',
                        default=0,
                        help=helps['refine'])
    parser.add_argument('-f',
                        '--format',
                        metavar='format',
                        action='store',
                        type=str,
                        dest='format',
                        default=None,
                        help=helps['format'])
    parser.add_argument('-l',
                        '--list',
                        action='store_true',
                        dest='list',
                        help=helps['list'])
    parser.add_argument('-m',
                        '--merge',
                        action='store_true',
                        dest='merge',
                        help=helps['merge'])
    parser.add_argument('-t',
                        '--tri-tetra',
                        action='store_true',
                        dest='tri_tetra',
                        help=helps['tri-tetra'])
    parser.add_argument('filename_in')
    parser.add_argument('filename_out')
    options = parser.parse_args()

    if options.list:
        output('Supported readable mesh formats:')
        output('--------------------------------')
        output_mesh_formats('r')
        output('')
        output('Supported writable mesh formats:')
        output('--------------------------------')
        output_mesh_formats('w')
        sys.exit(0)

    scale = _parse_val_or_vec(options.scale, 'scale', parser)
    center = _parse_val_or_vec(options.center, 'center', parser)

    filename_in = options.filename_in
    filename_out = options.filename_out

    mesh = Mesh.from_file(filename_in)

    if scale is not None:
        if len(scale) == 1:
            tr = nm.eye(mesh.dim, dtype=nm.float64) * scale
        elif len(scale) == mesh.dim:
            tr = nm.diag(scale)
        else:
            raise ValueError('bad scale! (%s)' % scale)
        mesh.transform_coors(tr)

    if center is not None:
        cc = 0.5 * mesh.get_bounding_box().sum(0)
        shift = center - cc
        tr = nm.c_[nm.eye(mesh.dim, dtype=nm.float64), shift[:, None]]
        mesh.transform_coors(tr)

    if options.refine > 0:
        domain = FEDomain(mesh.name, mesh)
        output('initial mesh: %d nodes %d elements' %
               (domain.shape.n_nod, domain.shape.n_el))

        for ii in range(options.refine):
            output('refine %d...' % ii)
            domain = domain.refine()
            output('... %d nodes %d elements' %
                   (domain.shape.n_nod, domain.shape.n_el))

        mesh = domain.mesh

    if options.tri_tetra > 0:
        conns = None
        for k, new_desc in [('3_8', '3_4'), ('2_4', '2_3')]:
            if k in mesh.descs:
                conns = mesh.get_conn(k)
                break

        if conns is not None:
            nelo = conns.shape[0]
            output('initial mesh: %d elements' % nelo)

            new_conns = elems_q2t(conns)
            nn = new_conns.shape[0] // nelo
            new_cgroups = nm.repeat(mesh.cmesh.cell_groups, nn)

            output('new mesh: %d elements' % new_conns.shape[0])
            mesh = Mesh.from_data(mesh.name, mesh.coors,
                                  mesh.cmesh.vertex_groups, [new_conns],
                                  [new_cgroups], [new_desc])

    if options.merge:
        desc = mesh.descs[0]
        coor, ngroups, conns = fix_double_nodes(mesh.coors,
                                                mesh.cmesh.vertex_groups,
                                                mesh.get_conn(desc), 1e-9)
        mesh = Mesh.from_data(mesh.name + '_merged', coor, ngroups, [conns],
                              [mesh.cmesh.cell_groups], [desc])

    io = MeshIO.for_format(filename_out, format=options.format, writable=True)

    cell_types = ', '.join(supported_cell_types[io.format])
    output('writing [%s] %s...' % (cell_types, filename_out))
    mesh.write(filename_out, io=io)
    output('...done')
Пример #41
0
    'output_log_name':
    pjoin(output_folder, f"last_run_{problem_name}_{approx_order}.txt")
})

# ------------
# | Get mesh |
# ------------
X1 = 0.
XN = 1.
n_nod = 100
n_el = n_nod - 1
coors = nm.linspace(X1, XN, n_nod).reshape((n_nod, 1))
conn = nm.arange(n_nod, dtype=nm.int32).repeat(2)[1:-1].reshape((-1, 2))
mat_ids = nm.zeros(n_nod - 1, dtype=nm.int32)
descs = ['1_2']
mesh = Mesh.from_data('uniform_1D{}'.format(n_nod), coors, None, [conn],
                      [mat_ids], descs)

# -----------------------------
# | Create problem components |
# -----------------------------

integral = Integral('i', order=approx_order * 2)
domain = FEDomain(domain_name, mesh)
omega = domain.create_region('Omega', 'all')
left = domain.create_region('Gamma1', 'vertices in x == %.10f' % X1, 'vertex')
right = domain.create_region('Gamma2', 'vertices in x == %.10f' % XN, 'vertex')
field = DGField('dgfu', nm.float64, 'scalar', omega, approx_order=approx_order)

u = FieldVariable('u', 'unknown', field, history=1)
v = FieldVariable('v', 'test', field, primary_var_name='u')
Пример #42
0
# lcar3 = .055

# Assign a mesh size to all the points:
gmsh.model.mesh.setSize(gmsh.model.getEntities(0), lcar1)

# Override this constraint on the points of the five spheres:
# gmsh.model.mesh.setSize(gmsh.model.getBoundary(holes, False, False, True),
#                         lcar3)

# Select the corner point by searching for it geometrically:
# eps = 1e-3
# ov = gmsh.model.getEntitiesInBoundingBox(0.5 - eps, 0.5 - eps, 0.5 - eps,
#                                          0.5 + eps, 0.5 + eps, 0.5 + eps, 0)
# gmsh.model.mesh.setSize(ov, lcar2)

gmsh.model.mesh.generate(3)

gmsh.write("meshes/%s.msh" % mesh_name)
gmsh.write("meshes/%s.vtk" % mesh_name)

# Launch the GUI to see the results:
if '-nopopup' not in sys.argv:
    gmsh.fltk.run()

gmsh.finalize()

raw_mesh = Mesh.from_file("meshes/%s.msh" % mesh_name)  # load the gmesh file
data = list(raw_mesh._get_io_data(cell_dim_only=[3]))  # strip non-3d elements
mesh = Mesh.from_data(raw_mesh.name, *data)
mesh.write("meshes/%s.vtk" % mesh_name)
Пример #43
0
def main():
    parser = ArgumentParser(description=__doc__,
                            formatter_class=RawDescriptionHelpFormatter)
    parser.add_argument('-s', '--scale', metavar='scale',
                        action='store', dest='scale',
                        default=None, help=helps['scale'])
    parser.add_argument('-c', '--center', metavar='center',
                        action='store', dest='center',
                        default=None, help=helps['center'])
    parser.add_argument('-r', '--refine', metavar='level',
                        action='store', type=int, dest='refine',
                        default=0, help=helps['refine'])
    parser.add_argument('-f', '--format', metavar='format',
                        action='store', type=str, dest='format',
                        default=None, help=helps['format'])
    parser.add_argument('-l', '--list', action='store_true',
                        dest='list', help=helps['list'])
    parser.add_argument('-m', '--merge', action='store_true',
                        dest='merge', help=helps['merge'])
    parser.add_argument('-t', '--tri-tetra', action='store_true',
                        dest='tri_tetra', help=helps['tri-tetra'])
    parser.add_argument('-2', '--2d', action='store_true',
                        dest='force_2d', help=helps['2d'])
    parser.add_argument('--save-per-mat', action='store_true',
                        dest='save_per_mat', help=helps['save-per-mat'])
    parser.add_argument('--remesh', metavar='options',
                        action='store', dest='remesh',
                        default=None, help=helps['remesh'])
    parser.add_argument('filename_in')
    parser.add_argument('filename_out')
    options = parser.parse_args()

    if options.list:
        output('Supported readable mesh formats:')
        output('--------------------------------')
        output_mesh_formats('r')
        output('')
        output('Supported writable mesh formats:')
        output('--------------------------------')
        output_mesh_formats('w')
        sys.exit(0)

    scale = _parse_val_or_vec(options.scale, 'scale', parser)
    center = _parse_val_or_vec(options.center, 'center', parser)

    filename_in = options.filename_in
    filename_out = options.filename_out

    if options.remesh:
        import tempfile
        import shlex
        import subprocess

        dirname = tempfile.mkdtemp()

        is_surface = options.remesh.startswith('q')
        if is_surface:
            mesh = Mesh.from_file(filename_in)
            domain = FEDomain(mesh.name, mesh)
            region = domain.create_region('surf', 'vertices of surface',
                                          'facet')
            surf_mesh = Mesh.from_region(region, mesh,
                                         localize=True, is_surface=True)

            filename = op.join(dirname, 'surf.mesh')
            surf_mesh.write(filename, io='auto')

        else:
            import shutil

            shutil.copy(filename_in, dirname)
            filename = op.join(dirname, op.basename(filename_in))

        qopts = ''.join(options.remesh.split()) # Remove spaces.
        command = 'tetgen -BFENkACp%s %s' % (qopts, filename)
        args = shlex.split(command)
        subprocess.call(args)

        root, ext = op.splitext(filename)
        mesh = Mesh.from_file(root + '.1.vtk')

        remove_files(dirname)

    else:
        mesh = Mesh.from_file(filename_in)

    if options.force_2d:
        data = list(mesh._get_io_data())
        data[0] = data[0][:, :2]
        mesh = Mesh.from_data(mesh.name, *data)

    if scale is not None:
        if len(scale) == 1:
            tr = nm.eye(mesh.dim, dtype=nm.float64) * scale
        elif len(scale) == mesh.dim:
            tr = nm.diag(scale)
        else:
            raise ValueError('bad scale! (%s)' % scale)
        mesh.transform_coors(tr)

    if center is not None:
        cc = 0.5 * mesh.get_bounding_box().sum(0)
        shift = center - cc
        tr = nm.c_[nm.eye(mesh.dim, dtype=nm.float64), shift[:, None]]
        mesh.transform_coors(tr)

    if options.refine > 0:
        domain = FEDomain(mesh.name, mesh)
        output('initial mesh: %d nodes %d elements'
               % (domain.shape.n_nod, domain.shape.n_el))

        for ii in range(options.refine):
            output('refine %d...' % ii)
            domain = domain.refine()
            output('... %d nodes %d elements'
                   % (domain.shape.n_nod, domain.shape.n_el))

        mesh = domain.mesh

    if options.tri_tetra > 0:
        conns = None
        for k, new_desc in [('3_8', '3_4'), ('2_4', '2_3')]:
            if k in mesh.descs:
                conns = mesh.get_conn(k)
                break

        if conns is not None:
            nelo = conns.shape[0]
            output('initial mesh: %d elements' % nelo)

            new_conns = elems_q2t(conns)
            nn = new_conns.shape[0] // nelo
            new_cgroups = nm.repeat(mesh.cmesh.cell_groups, nn)

            output('new mesh: %d elements' % new_conns.shape[0])
            mesh = Mesh.from_data(mesh.name, mesh.coors,
                                  mesh.cmesh.vertex_groups,
                                  [new_conns], [new_cgroups], [new_desc])

    if options.merge:
        desc = mesh.descs[0]
        coor, ngroups, conns = fix_double_nodes(mesh.coors,
                                                mesh.cmesh.vertex_groups,
                                                mesh.get_conn(desc), 1e-9)
        mesh = Mesh.from_data(mesh.name + '_merged',
                              coor, ngroups,
                              [conns], [mesh.cmesh.cell_groups], [desc])

    if options.save_per_mat:
        desc = mesh.descs[0]
        conns, cgroups = mesh.get_conn(desc), mesh.cmesh.cell_groups
        coors, ngroups = mesh.coors, mesh.cmesh.vertex_groups
        mat_ids = nm.unique(cgroups)

        for mat_id in mat_ids:
            idxs = nm.where(cgroups == mat_id)[0]
            imesh = Mesh.from_data(mesh.name + '_matid_%d' % mat_id,
                                   coors, ngroups,
                                   [conns[idxs]], [cgroups[idxs]], [desc])

            fbase, fext = op.splitext(filename_out)
            ifilename_out = '%s_matid_%d%s' % (fbase, mat_id, fext)
            io = MeshIO.for_format(ifilename_out, format=options.format,
                                   writable=True)
            output('writing %s...' % ifilename_out)
            imesh.write(ifilename_out, io=io)
            output('...done')

    io = MeshIO.for_format(filename_out, format=options.format,
                           writable=True)

    cell_types = ', '.join(supported_cell_types[io.format])
    output('writing [%s] %s...' % (cell_types, filename_out))
    mesh.write(filename_out, io=io)
    output('...done')
def post_process_hook(pb,
                      nd_data,
                      qp_data,
                      ccoor,
                      vol,
                      im,
                      tstep,
                      eps0,
                      recovery_file_tag=''):
    from sfepy.discrete.fem import Mesh

    elavg_data = {}
    elvol = nm.sum(vol, axis=1)
    sh0 = vol.shape[:2]
    for k in qp_data.keys():
        print(k, qp_data[k].shape, vol.shape, elvol.shape)
        sh1 = qp_data[k].shape[1:]
        val = qp_data[k].reshape(sh0 + sh1)
        elavg_data[k] = (nm.sum(val * vol, axis=1) / elvol)[:, None, ...]

    output_dir = pb.conf.options.get('output_dir', '.')
    suffix = '%03d.%03d' % (im, tstep)
    coors = pb.get_mesh_coors(actual=True)
    coors = (coors - 0.5*(nm.max(coors, axis=0)\
        - nm.min(coors, axis=0))) * eps0 + ccoor

    # Y
    out = {}
    out['displacement'] = Struct(name='output_data',
                                 mode='vertex',
                                 data=nd_data['u'] * eps0,
                                 variable='u')
    out['green_strain'] = Struct(name='output_data',
                                 mode='cell',
                                 data=elavg_data['E'])

    mesh = Mesh.from_region(pb.domain.regions['Y'], pb.domain.mesh)
    mesh.coors[:] = coors

    micro_name = pb.get_output_name(extra='recovered_Y_' + recovery_file_tag +
                                    suffix)
    filename = osp.join(output_dir, osp.basename(micro_name))

    output('  %s' % filename)
    mesh.write(filename, io='auto', out=out)

    p_tab = {'Ym': 'p', 'Yc1': 'p1', 'Yc2': 'p2'}
    mesh0 = pb.domain.mesh
    for rname in ['Ym'] + ['Yc%d' % ch for ch in pb.conf.chs]:
        reg = pb.domain.regions[rname]
        cells = reg.get_cells()

        out = {}
        out['cauchy_stress'] = Struct(name='output_data',
                                      mode='cell',
                                      data=elavg_data['S'][cells])
        out['velocity'] = Struct(name='output_data',
                                 mode='cell',
                                 data=elavg_data['w'][cells])
        out['pressure'] = Struct(name='output_data',
                                 mode='vertex',
                                 data=nd_data[p_tab[rname]][:, None])

        ac = nm.ascontiguousarray
        conn = mesh0.cmesh.get_cell_conn()
        cells = reg.entities[-1]
        verts = reg.entities[0]
        aux = nm.diff(conn.offsets)
        assert nm.sum(nm.diff(aux)) == 0
        conn = ac(conn.indices.reshape((mesh0.n_el, aux[0]))[cells])
        remap = -nm.ones(mesh0.n_nod)
        remap[verts] = nm.arange(verts.shape[0])
        conn = remap[conn]

        mesh = Mesh.from_data('region_%s' % rname, ac(coors[verts]),
                              ac(mesh0.cmesh.vertex_groups[verts]), [conn],
                              [ac(mesh0.cmesh.cell_groups[cells])],
                              [mesh0.descs[0]])

        micro_name = pb.get_output_name(extra='recovered_%s_' % rname +
                                        recovery_file_tag + suffix)
        filename = osp.join(output_dir, osp.basename(micro_name))

        output('  %s' % filename)
        mesh.write(filename, io='auto', out=out)
Пример #45
0
def main():
    parser = OptionParser(usage=usage, version='%prog')
    parser.add_option('-b', '--basis', metavar='name',
                      action='store', dest='basis',
                      default='lagrange', help=help['basis'])
    parser.add_option('-d', '--derivative', metavar='d', type=int,
                      action='store', dest='derivative',
                      default=0, help=help['derivative'])
    parser.add_option('-n', '--max-order', metavar='order', type=int,
                      action='store', dest='max_order',
                      default=2, help=help['max_order'])
    parser.add_option('-g', '--geometry', metavar='name',
                      action='store', dest='geometry',
                      default='2_4', help=help['geometry'])
    parser.add_option('-m', '--mesh', metavar='mesh',
                      action='store', dest='mesh',
                      default=None, help=help['mesh'])
    parser.add_option('', '--permutations', metavar='permutations',
                      action='store', dest='permutations',
                      default=None, help=help['permutations'])
    parser.add_option('', '--dofs', metavar='dofs',
                      action='store', dest='dofs',
                      default=None, help=help['dofs'])
    parser.add_option('-l', '--lin-options', metavar='options',
                      action='store', dest='lin_options',
                      default='min_level=2,max_level=5,eps=1e-3',
                      help=help['lin_options'])
    parser.add_option('', '--plot-dofs',
                      action='store_true', dest='plot_dofs',
                      default=False, help=help['plot_dofs'])
    options, args = parser.parse_args()

    if len(args) == 1:
        output_dir = args[0]
    else:
        parser.print_help(),
        return

    output('polynomial space:', options.basis)
    output('max. order:', options.max_order)

    lin = Struct(kind='adaptive', min_level=2, max_level=5, eps=1e-3)
    for opt in options.lin_options.split(','):
        key, val = opt.split('=')
        setattr(lin, key, eval(val))

    if options.mesh is None:
        dim, n_ep = int(options.geometry[0]), int(options.geometry[2])
        output('reference element geometry:')
        output('  dimension: %d, vertices: %d' % (dim, n_ep))

        gel = GeometryElement(options.geometry)
        gps = PolySpace.any_from_args(None, gel, 1,
                                      base=options.basis)
        ps = PolySpace.any_from_args(None, gel, options.max_order,
                                     base=options.basis)

        n_digit, _format = get_print_info(ps.n_nod, fill='0')
        name_template = os.path.join(output_dir, 'bf_%s.vtk' % _format)
        for ip in get_dofs(options.dofs, ps.n_nod):
            output('shape function %d...' % ip)

            def eval_dofs(iels, rx):
                if options.derivative == 0:
                    bf = ps.eval_base(rx).squeeze()
                    rvals = bf[None, :, ip:ip+1]

                else:
                    bfg = ps.eval_base(rx, diff=True)
                    rvals = bfg[None, ..., ip]

                return rvals

            def eval_coors(iels, rx):
                bf = gps.eval_base(rx).squeeze()
                coors = nm.dot(bf, gel.coors)[None, ...]
                return coors

            (level, coors, conn,
             vdofs, mat_ids) = create_output(eval_dofs, eval_coors, 1,
                                             ps, min_level=lin.min_level,
                                             max_level=lin.max_level,
                                             eps=lin.eps)
            out = {
                'bf' : Struct(name='output_data',
                              mode='vertex', data=vdofs,
                              var_name='bf', dofs=None)
            }

            mesh = Mesh.from_data('bf_mesh', coors, None, [conn], [mat_ids],
                                  [options.geometry])

            name = name_template % ip
            ensure_path(name)
            mesh.write(name, out=out)

            output('...done (%s)' % name)

    else:
        mesh = Mesh.from_file(options.mesh)
        output('mesh geometry:')
        output('  dimension: %d, vertices: %d, elements: %d'
               % (mesh.dim, mesh.n_nod, mesh.n_el))

        if options.permutations:
            if options.permutations == 'all':
                from sfepy.linalg import cycle
                gel = GeometryElement(mesh.descs[0])
                n_perms = gel.get_conn_permutations().shape[0]
                all_permutations = [ii for ii in cycle(mesh.n_el * [n_perms])]

            else:
                all_permutations = [int(ii)
                                    for ii in options.permutations.split(',')]
                all_permutations = nm.array(all_permutations)
                np = len(all_permutations)
                all_permutations.shape = (np / mesh.n_el, mesh.n_el)

            output('using connectivity permutations:\n', all_permutations)

        else:
            all_permutations = [None]

        for ip, permutations in enumerate(all_permutations):
            if permutations is None:
                suffix = ''

            else:
                suffix = '_' + '_'.join('%d' % ii for ii in permutations)

            save_basis_on_mesh(mesh, options, output_dir, lin, permutations,
                               suffix)
Пример #46
0
    def _eval_basis_transform(self, subs):
        """
        """
        from sfepy.discrete import Integral
        from sfepy.discrete.fem import Mesh, FEDomain, Field

        transform = nm.tile(nm.eye(self.econn.shape[1]),
                            (self.econn.shape[0], 1, 1))
        if subs is None:
            return transform

        gel = self.gel
        ao = self.approx_order

        conn = [gel.conn]
        mesh = Mesh.from_data('a', gel.coors, None, [conn], [nm.array([0])],
                              [gel.name])
        cdomain = FEDomain('d', mesh)
        comega = cdomain.create_region('Omega', 'all')
        rcfield = Field.from_args('rc', self.dtype, 1, comega, approx_order=ao)

        fdomain = cdomain.refine()
        fomega = fdomain.create_region('Omega', 'all')
        rffield = Field.from_args('rf', self.dtype, 1, fomega, approx_order=ao)

        def assign_transform(transform, bf, subs, ef):
            if not len(subs): return

            n_sub = (subs.shape[1] - 2) // 2

            for ii, sub in enumerate(subs):
                for ij in range(n_sub):
                    ik = 2 * (ij + 1)

                    fface = ef[sub[ik+1]]

                    mtx = transform[sub[ik]]
                    ix, iy = nm.meshgrid(fface, fface)

                    cbf = bf[iy, 0, ix]

                    mtx[ix, iy] = cbf

        fcoors = rffield.get_coor()

        coors = fcoors[rffield.econn[0]]
        integral = Integral('i', coors=coors, weights=nm.ones_like(coors[:, 0]))

        rcfield.clear_qp_base()
        bf = rcfield.get_base('v', False, integral)

        if gel.name == '2_4':
            fsubs = subs
            esubs = None

            assign_transform(transform, bf, fsubs, rffield.efaces)

        else:
            fsubs = subs[0]
            esubs = subs[1]

            assign_transform(transform, bf, fsubs, rffield.efaces)
            if esubs is not None:
                assign_transform(transform, bf, esubs, rffield.eedges)

        assert_((nm.abs(transform.sum(1) - 1.0) < 1e-15).all())

        return transform