Beispiel #1
0
    def from_conf(conf, dpb, apb):

        opts = conf.options
        regions = dpb.domain.regions
        if opts.use_mesh_velocity:
            import tables as pt

            fd = pt.open_file(opts.mesh_velocity_filename, mode="r")
            aux = fd.get_node("/u").read()
            nu = nm.asarray(aux, dtype=nm.float64)
            fd.close()

        else:
            nu = None

        sp_boxes = ffd.read_spline_box_hdf5(opts.ffd_spline_data)
        dsg_vars = ffd.read_dsg_vars_hdf5(opts.ffd_spline_data)
        dsg_vars.renumber_by_boxes(sp_boxes)
        dsg_vars.normalize_null_space_base()
        print dsg_vars.indx.shape
        print dsg_vars.null_space_b.shape

        control_region = regions[opts.control_domain]
        design_region = regions[opts.design_domain]

        from sfepy.fem.mesh import Mesh

        cmm = Mesh.from_region(control_region, dpb.domain.mesh)
        dmm = Mesh.from_region(design_region, dpb.domain.mesh)
        cmm.write("control.mesh", io="auto")
        dmm.write("design.mesh", io="auto")

        SOFC = ShapeOptimFlowCase
        obj = SOFC(
            dpb=dpb,
            apb=apb,
            sp_boxes=sp_boxes,
            dsg_vars=dsg_vars,
            problem_type=opts.problem,
            objective_function_type=opts.objective_function,
            var_map=opts.var_map,
            nu=nu,
            use_mesh_velocity=opts.use_mesh_velocity,
            save_dir=opts.save_dir,
            save_iter_sols=opts.save_iter_sols,
            save_control_points=opts.save_control_points,
            save_dsg_vars=opts.save_dsg_vars,
            test_terms_if_test=opts.test_terms_if_test,
        )

        equations = getattr(conf, "_".join(("equations_sensitivity", opts.problem, opts.objective_function)))

        obj.obj_fun_term = equations["objective"]
        obj.sens_terms = equations["sensitivity"]

        obj.n_var = dsg_vars.val.shape[0]

        obj.create_evaluables()

        return obj
Beispiel #2
0
    def from_conf(conf, dpb, apb):

        opts = conf.options
        regions = dpb.domain.regions
        if opts.use_mesh_velocity:
            import tables as pt
            fd = pt.open_file(opts.mesh_velocity_filename, mode='r')
            aux = fd.get_node('/u').read()
            nu = nm.asarray(aux, dtype=nm.float64)
            fd.close()

        else:
            nu = None

        sp_boxes = ffd.read_spline_box_hdf5(opts.ffd_spline_data)
        dsg_vars = ffd.read_dsg_vars_hdf5(opts.ffd_spline_data)
        dsg_vars.renumber_by_boxes(sp_boxes)
        dsg_vars.normalize_null_space_base()
        print dsg_vars.indx.shape
        print dsg_vars.null_space_b.shape

        control_region = regions[opts.control_domain]
        design_region = regions[opts.design_domain]

        from sfepy.fem.mesh import Mesh
        cmm = Mesh.from_region(control_region, dpb.domain.mesh)
        dmm = Mesh.from_region(design_region, dpb.domain.mesh)
        cmm.write('control.mesh', io='auto')
        dmm.write('design.mesh', io='auto')

        SOFC = ShapeOptimFlowCase
        obj = SOFC(dpb=dpb,
                   apb=apb,
                   sp_boxes=sp_boxes,
                   dsg_vars=dsg_vars,
                   problem_type=opts.problem,
                   objective_function_type=opts.objective_function,
                   var_map=opts.var_map,
                   nu=nu,
                   use_mesh_velocity=opts.use_mesh_velocity,
                   save_dir=opts.save_dir,
                   save_iter_sols=opts.save_iter_sols,
                   save_control_points=opts.save_control_points,
                   save_dsg_vars=opts.save_dsg_vars,
                   test_terms_if_test=opts.test_terms_if_test)

        equations = getattr(
            conf, '_'.join(('equations_sensitivity', opts.problem,
                            opts.objective_function)))

        obj.obj_fun_term = equations['objective']
        obj.sens_terms = equations['sensitivity']

        obj.n_var = dsg_vars.val.shape[0]

        obj.create_evaluables()

        return obj
Beispiel #3
0
def dump_to_vtk(filename, output_filename_trunk=None, step0=0, steps=None,
                fields=None, linearization=None):
    """Dump a multi-time-step results file into a sequence of VTK files."""
    def _save_step(suffix, out, mesh):
        if linearization is not None:
            output('linearizing...')
            out = _linearize(out, fields, linearization)
            output('...done')
            for key, val in out.iteritems():
                lmesh = val.get('mesh', mesh)
                lmesh.write(output_filename_trunk + '_' + key + suffix,
                            io='auto', out={key : val})
                if hasattr(val, 'levels'):
                    output('max. refinement per group:', val.levels)

        else:
            mesh.write(output_filename_trunk + suffix, io='auto', out=out)

    output('dumping to VTK...')

    io = MeshIO.any_from_filename(filename)
    mesh = Mesh.from_file(filename, io=io)

    if output_filename_trunk is None:
        output_filename_trunk = get_trunk(filename)

    try:
        ts = TimeStepper(*io.read_time_stepper())
        times, nts, dts = extract_times(filename)

    except ValueError:
        output('no time stepping info found, assuming single step')

        out = io.read_data(0)
        if out is not None:
            _save_step('.vtk', out, mesh)

        ret = None

    else:
        ts.times = times
        ts.n_step = times.shape[0]

        if steps is None:
            iterator = ts.iter_from(step0)

        else:
            iterator = [(step, ts.times[step]) for step in steps]

        for step, time in iterator:
            output(ts.format % (step, ts.n_step - 1))
            out = io.read_data(step)
            if out is None: break

            _save_step('.' + ts.suffix % step + '.vtk', out, mesh)

        ret = ts.suffix

    output('...done')
    return ret
Beispiel #4
0
def dump_to_vtk( filename, options, steps = None ):
    output( 'dumping to VTK...' )
    
    mesh = Mesh.from_file( filename )

    io = HDF5MeshIO( filename )
    ts = TimeStepper( *io.read_time_stepper() )

    if options.output_filename_trunk:
        ofn_trunk = options.output_filename_trunk
    else:
        ofn_trunk = get_trunk( filename )

    if steps is None:
        iterator = ts.iter_from( options.step0 )
    else:
        iterator = [(step, ts.times[step]) for step in steps]

    for step, time in iterator:
        output( ts.format % (step, ts.n_step - 1) )
        out = io.read_data( step )
        if out is None: break
        mesh.write( ofn_trunk + ts.suffix % step + '.vtk',
                    io = 'auto', out = out )

    output( '...done' )
    return ts.suffix
Beispiel #5
0
def main():
    parser = OptionParser(usage=usage, version="%prog 42")
    parser.add_option("-s", "--scale", type=int, metavar='scale',
                      action="store", dest="scale",
                      default=2, help=help['scale'])
    parser.add_option("-r", "--repeat", type='str', metavar='nx,ny[,nz]',
                      action="callback", dest="repeat",
                      callback=parse_repeat, default=None, help=help['repeat'])
    parser.add_option("-e", "--eps", type=float, metavar='eps',
                      action="store", dest="eps",
                      default=1e-8, help=help['eps'])
    (options, args) = parser.parse_args()

    if (len( args ) == 2):
        filename_in = args[0]
        filename_out = args[1]
    else:
        parser.print_help()
        return

    output = Output('genPerMesh:')
    output('scale:', options.scale)
    output('repeat:', options.repeat)
    output('eps:', options.eps)

    mesh_in = Mesh.from_file(filename_in)
    mesh_out = gen_tiled_mesh(mesh_in, options.repeat, 1./options.scale,
                              options.eps)
    mesh_out.write(filename_out, io='auto')
    output('done.')
Beispiel #6
0
    def create_mesh(self, extra_nodes=True):
        """
        Create a mesh from the field region, optionally including the field
        extra nodes.
        """
        mesh = self.domain.mesh

        if self.approx_order != 0:
            conns, mat_ids, descs = [], [], []
            for ig, ap in self.aps.iteritems():
                group = self.domain.groups[ig]
                if extra_nodes:
                    conn = ap.econn
                else:
                    offset = group.shape.n_ep
                    conn = ap.econn[:,:offset]
                conns.append(conn)
                mat_ids.append(mesh.mat_ids[ig])
                descs.append(mesh.descs[ig])

            if extra_nodes:
                coors = self.coors

            else:
                coors = self.coors[:self.n_vertex_dof]

            mesh = Mesh.from_data(self.name, coors, None, conns,
                                  mat_ids, descs)

        return mesh
Beispiel #7
0
def gen_block_mesh(dims, shape, centre, mat_id=0, name='block',
                   coors=None, verbose=True):
    """
    Generate a 2D or 3D block mesh. The dimension is determined by the
    lenght of the shape argument.

    Parameters
    ----------
    dims : array of 2 or 3 floats
        Dimensions of the block.
    shape : array of 2 or 3 ints
        Shape (counts of nodes in x, y, z) of the block mesh.
    centre : array of 2 or 3 floats
        Centre of the block.
    mat_id : int, optional
        The material id of all elements.
    name : string
        Mesh name.
    verbose : bool
        If True, show progress of the mesh generation.

    Returns
    -------
    mesh : Mesh instance
    """
    dims = nm.asarray(dims, dtype=nm.float64)
    shape = nm.asarray(shape, dtype=nm.int32)
    centre = nm.asarray(centre, dtype=nm.float64)

    dim = shape.shape[0]

    centre = centre[:dim]
    dims = dims[:dim]

    n_nod = nm.prod(shape)
    output('generating %d vertices...' % n_nod, verbose=verbose)

    x0 = centre - 0.5 * dims
    dd = dims / (shape - 1)

    ngrid = nm.mgrid[[slice(ii) for ii in shape]]
    ngrid.shape = (dim, n_nod)

    coors = x0 + ngrid.T * dd
    output('...done', verbose=verbose)

    n_el = nm.prod(shape - 1)
    output('generating %d cells...' % n_el, verbose=verbose)

    mat_ids = nm.empty((n_el,), dtype=nm.int32)
    mat_ids.fill(mat_id)

    conn, desc = get_tensor_product_conn(shape)
    output('...done', verbose=verbose)

    mesh = Mesh.from_data(name, coors, None, [conn], [mat_ids], [desc])
    return mesh
Beispiel #8
0
    def test_mesh_smoothing(self):
        from sfepy.mesh.mesh_tools import smooth_mesh
        from sfepy.fem.mesh import Mesh
        from sfepy import data_dir

        mesh = Mesh.from_file(data_dir + '/meshes/3d/cylinder.vtk')
        vol0 = get_volume(mesh.conns[0], mesh.coors)
        mesh.coors = smooth_mesh(mesh, n_iter=10)
        vol1 = get_volume(mesh.conns[0], mesh.coors)
        filename = op.join(self.options.out_dir, 'smoothed_cylinder.vtk')
        mesh.write(filename)
        frac = vol1 / vol0

        if (frac < 0.967) and (frac > 0.966):
            self.report('mesh smoothed')
            return True

        else:
            self.report('mesh smoothed, volume mismatch!')
            return False
Beispiel #9
0
    def test_mesh_smoothing(self):
        from sfepy.mesh.mesh_tools import smooth_mesh
        from sfepy.fem.mesh import Mesh
        from sfepy import data_dir

        mesh = Mesh.from_file(data_dir + '/meshes/3d/cylinder.vtk')
        vol0 = get_volume(mesh.conns[0], mesh.coors)
        mesh.coors = smooth_mesh(mesh, n_iter=10)
        vol1 = get_volume(mesh.conns[0], mesh.coors)
        filename = op.join(self.options.out_dir, 'smoothed_cylinder.vtk')
        mesh.write(filename)
        frac = vol1 / vol0

        if (frac < 0.967) and (frac > 0.966):
            self.report('mesh smoothed')
            return True

        else:
            self.report('mesh smoothed, volume mismatch!')
            return False
Beispiel #10
0
def dump_to_vtk(filename, output_filename_trunk=None, step0=0, steps=None):
    """Dump a multi-time-step results file into a sequence of VTK files."""
    output('dumping to VTK...')
    
    io = MeshIO.any_from_filename(filename)
    mesh = Mesh.from_file(filename, io=io)

    if output_filename_trunk is None:
        output_filename_trunk = get_trunk(filename)

    try:
        ts = TimeStepper(*io.read_time_stepper())

    except:
        output('no time stepping info found, assuming single step')

        out = io.read_data(0)
        if out is not None:
            mesh.write(output_filename_trunk + '.vtk', io='auto', out=out)

        ret = None

    else:
        if steps is None:
            iterator = ts.iter_from(step0)

        else:
            iterator = [(step, ts.times[step]) for step in steps]

        for step, time in iterator:
            output(ts.format % (step, ts.n_step - 1))
            out = io.read_data(step)
            if out is None: break
            mesh.write('.'.join((output_filename_trunk,
                                 ts.suffix % step, 'vtk')),
                       io='auto', out=out)

        ret = ts.suffix

    output('...done')
    return ret
Beispiel #11
0
    def create_mesh_from_control_points( self ):
        offset = 0
        dim = self.spbs[0].cxyz.shape[1]
        coors = nm.empty((0, dim), dtype=nm.float64)
        conns = []
        mat_ids = []
        descs = []
        for ib, spb in enumerate( self.spbs ):
            n_nod = spb.cxyz.shape[0]
            coors = nm.concatenate( (coors, spb.cxyz), 0 )
            descs.append( '3_2' )

            conn = []
            for ij in xrange( spb.cpi.shape[1] ):
                for ik in xrange( spb.cpi.shape[2] ):
                    inx = spb.cpi[:,ij,ik]
                    row = [[p1, p2] for p1, p2 in zip( inx[:-1], inx[1:] )]
                    conn.extend( row )
            for ij in xrange( spb.cpi.shape[0] ):
                for ik in xrange( spb.cpi.shape[2] ):
                    inx = spb.cpi[ij,:,ik]
                    row = [[p1, p2] for p1, p2 in zip( inx[:-1], inx[1:] )]
                    conn.extend( row )
            for ij in xrange( spb.cpi.shape[0] ):
                for ik in xrange( spb.cpi.shape[1] ):
                    inx = spb.cpi[ij,ik,:]
                    row = [[p1, p2] for p1, p2 in zip( inx[:-1], inx[1:] )]
                    conn.extend( row )

            aux = nm.empty(len(conn), dtype=nm.int32)
            aux.fill(ib)
            mat_ids.append(aux)

            conns.append( offset + nm.array( conn, dtype = nm.int32 ) )
            offset += n_nod

        mesh = Mesh.from_data('control_points', coors, None, conns,
                              mat_ids, descs)
        return mesh
Beispiel #12
0
    def create_mesh_from_control_points( self ):
        offset = 0
        dim = self.spbs[0].cxyz.shape[1]
        coors = nm.empty((0, dim), dtype=nm.float64)
        conns = []
        mat_ids = []
        descs = []
        for ib, spb in enumerate( self.spbs ):
            n_nod = spb.cxyz.shape[0]
            coors = nm.concatenate( (coors, spb.cxyz), 0 )
            descs.append( '3_2' )

            conn = []
            for ij in xrange( spb.cpi.shape[1] ):
                for ik in xrange( spb.cpi.shape[2] ):
                    inx = spb.cpi[:,ij,ik]
                    row = [[p1, p2] for p1, p2 in zip( inx[:-1], inx[1:] )]
                    conn.extend( row )
            for ij in xrange( spb.cpi.shape[0] ):
                for ik in xrange( spb.cpi.shape[2] ):
                    inx = spb.cpi[ij,:,ik]
                    row = [[p1, p2] for p1, p2 in zip( inx[:-1], inx[1:] )]
                    conn.extend( row )
            for ij in xrange( spb.cpi.shape[0] ):
                for ik in xrange( spb.cpi.shape[1] ):
                    inx = spb.cpi[ij,ik,:]
                    row = [[p1, p2] for p1, p2 in zip( inx[:-1], inx[1:] )]
                    conn.extend( row )

            aux = nm.empty(len(conn), dtype=nm.int32)
            aux.fill(ib)
            mat_ids.append(aux)

            conns.append( offset + nm.array( conn, dtype = nm.int32 ) )
            offset += n_nod

        mesh = Mesh.from_data('control_points', coors, None, conns,
                              mat_ids, descs)
        return mesh
Beispiel #13
0
def main():
    parser = OptionParser(usage=usage, version="%prog 42")
    parser.add_option(
        "-s", "--scale", type=int, metavar="scale", action="store", dest="scale", default=2, help=help["scale"]
    )
    parser.add_option(
        "-r",
        "--repeat",
        type="str",
        metavar="nx,ny[,nz]",
        action="callback",
        dest="repeat",
        callback=parse_repeat,
        default=None,
        help=help["repeat"],
    )
    parser.add_option(
        "-e", "--eps", type=float, metavar="eps", action="store", dest="eps", default=1e-8, help=help["eps"]
    )
    parser.add_option("-n", "--no-mvd", action="store_true", dest="nomvd", default=False, help=help["nomvd"])
    (options, args) = parser.parse_args()

    if len(args) == 2:
        filename_in = args[0]
        filename_out = args[1]
    else:
        parser.print_help()
        return

    output = Output("genPerMesh:")
    output("scale:", options.scale)
    output("repeat:", options.repeat)
    output("eps:", options.eps)

    mesh_in = Mesh.from_file(filename_in)
    mesh_out = compose_periodic_mesh(mesh_in, options.scale, options.repeat, options.eps, check_mvd=not options.nomvd)
    mesh_out.write(filename_out, io="auto")
    output("done.")
Beispiel #14
0
def gen_mesh_from_poly(filename, verbose=True):
    """
    Import mesh generated by tetgen or triangle.

    Parameters
    ----------
    filename : string
        file name

    Returns
    -------
    mesh : Mesh instance
        triangular or tetrahedral mesh
    """
    def getnodes(fnods, up):
        f = file(fnods)
        l = [int(x) for x in f.readline().split()]
        npoints, dim, nattrib, nbound = l
        if verbose: up.init(npoints)
        nodes = []
        for line in f:
            if line[0] == "#": continue
            l = [float(x) for x in line.split()]
            l = l[:(dim + 1)]
            l[0] = int(l[0])
            nodes.append(tuple(l))
            assert l[0] == len(nodes)
        assert npoints == len(nodes)
        return nodes

    def getele(fele, up):
        f = file(fele)
        l = [int(x) for x in f.readline().split()]
        nele, nnod, nattrib = l
        #we have either linear or quadratic tetrahedra:
        if nnod in [4, 10]:
            elem = 'tetra'
            linear = (nnod == 4)
        if nnod in [3, 7]:
            elem = 'tri'
            linear = (nnod == 3)

        # if nattrib!=1:
        #     raise "tetgen didn't assign an entity number to each element (option -A)"
        els = []
        regions = {}
        for line in f:
            if line[0] == "#": continue
            l = [int(x) for x in line.split()]
            if elem == 'tri':
                if linear:
                    assert (len(l) - 1 - nattrib) == 3
                    els.append((l[0], l[1], l[2], l[3]))
                    regionnum = l[5]
                else:
                    assert len(l) - 2 == 10
                    els.append((l[0], 54, l[1], l[2], l[3], l[4], l[5], l[6],
                                l[7], l[8], l[9], l[10]))
                    regionnum = l[11]
            if elem == 'tetra':
                if linear:
                    assert len(l) - 2 == 4
                    els.append((l[0], 54, l[1], l[2], l[3], l[4]))
                    regionnum = l[5]
                else:
                    assert len(l) - 2 == 10
                    els.append((l[0], 54, l[1], l[2], l[3], l[4], l[5], l[6],
                                l[7], l[8], l[9], l[10]))
                    regionnum = l[11]
            if regionnum == 0:
                print "see %s, element # %d" % (fele, l[0])
                raise "there are elements not belonging to any physical entity"
            if regions.has_key(regionnum):
                regions[regionnum].append(l[0])
            else:
                regions[regionnum] = [l[0]]
            assert l[0] == len(els)
            if verbose: up.update(l[0])
        return els, regions, linear

    def getBCfaces(ffaces, up):
        f = file(ffaces)
        l = [int(x) for x in f.readline().split()]
        nfaces, nattrib = l
        if nattrib != 1:
            raise "tetgen didn't assign an entity number to each face \
(option -A)"

        if verbose: up.init(nfaces)
        faces = {}
        for line in f:
            if line[0] == "#": continue
            l = [int(x) for x in line.split()]
            assert len(l) == 5
            regionnum = l[4]
            if regionnum == 0: continue
            if faces.has_key(regionnum):
                faces[regionnum].append((l[1], l[2], l[3]))
            else:
                faces[regionnum] = [(l[1], l[2], l[3])]
            if verbose: up.update(l[0])
        return faces

    def calculatexyz(nodes, els):
        """Calculate the missing xyz values in place"""
        def avg(i, j, n4, nodes):
            a = nodes[n4[i - 1] - 1]
            b = nodes[n4[j - 1] - 1]
            return (a[1] + b[1]) / 2, (a[2] + b[2]) / 2, (a[3] + b[3]) / 2

        def getxyz(i, n4, nodes):
            if i + 5 == 5: return avg(1, 2, n4, nodes)
            if i + 5 == 6: return avg(2, 3, n4, nodes)
            if i + 5 == 7: return avg(1, 3, n4, nodes)
            if i + 5 == 8: return avg(1, 4, n4, nodes)
            if i + 5 == 9: return avg(2, 4, n4, nodes)
            if i + 5 == 10: return avg(3, 4, n4, nodes)
            raise "wrong topology"

        for e in els:
            n4 = e[2:2 + 4]
            n6 = e[2 + 4:2 + 4 + 10]
            for i, n in enumerate(n6):
                x, y, z = getxyz(i, n4, nodes)
                nodes[n - 1] = (n, x, y, z)

    if verbose: print "Reading geometry from poly file..."
    m = Mesh()
    m.nodes = getnodes(filename + ".node")
    m.elements, m.regions, lin = getele(filename + ".ele")
    if not lin:
        #tetgen doesn't compute xyz coordinates of the aditional 6 nodes
        #(only of the 4 corner nodes) in tetrahedra.
        calculatexyz(m.nodes, m.elements)
    m.faces = getBCfaces(filename + ".face")

    return m
Beispiel #15
0
def gen_block_mesh(dims, shape, centre, name='block'):
    """
    Generate a 2D or 3D block mesh. The dimension is determined by the
    lenght of the shape argument.

    Parameters
    ----------
    dims : array of 2 or 3 floats
        Dimensions of the block.
    shape : array of 2 or 3 ints
        Shape (counts of nodes in x, y, z) of the block mesh.
    centre : array of 2 or 3 floats
        Centre of the block.

    name : string
        Mesh name.

    Returns
    -------
    mesh : Mesh instance
    """
    dims = nm.asarray(dims, dtype=nm.float64)
    shape = nm.asarray(shape, dtype=nm.int32)
    centre = nm.asarray(centre, dtype=nm.float64)

    dim = shape.shape[0]

    centre = centre[:dim]
    dims = dims[:dim]

    x0 = centre - 0.5 * dims
    dd = dims / (shape - 1)

    grid = nm.zeros(shape, dtype = nm.int32)
    n_nod = nm.prod(shape)
    coors = nm.zeros((n_nod, dim), dtype = nm.float64)

    bar = MyBar("       nodes:")
    bar.init(n_nod)
    for ii, ic in enumerate(cycle(shape)):
        grid[tuple(ic)] = ii
        coors[ii] = x0 + ic * dd
        if not (ii % 100):
            bar.update(ii)
    bar.update(ii + 1)

    n_el = nm.prod(shape - 1)
    mat_id = nm.zeros((n_el,), dtype = nm.int32)

    if (dim == 2):
        conn = nm.zeros((n_el, 4), dtype = nm.int32)
        bar = MyBar("       elements:")
        bar.init(n_el)
        for ii, (ix, iy) in enumerate(cycle(shape - 1)):
            conn[ii,:] = [grid[ix  ,iy], grid[ix+1,iy  ],
                          grid[ix+1,iy+1], grid[ix  ,iy+1]]
            if not (ii % 100):
                bar.update(ii)
        bar.update(ii + 1)
        desc = '2_4'

    else:
        conn = nm.zeros((n_el, 8), dtype = nm.int32)
        bar = MyBar("       elements:")
        bar.init(n_el)
        for ii, (ix, iy, iz) in enumerate(cycle(shape - 1)):
            conn[ii,:] = [grid[ix  ,iy  ,iz  ], grid[ix+1,iy  ,iz  ],
                          grid[ix+1,iy+1,iz  ], grid[ix  ,iy+1,iz  ],
                          grid[ix  ,iy  ,iz+1], grid[ix+1,iy  ,iz+1],
                          grid[ix+1,iy+1,iz+1], grid[ix  ,iy+1,iz+1]]
            if not (ii % 100):
                bar.update(ii)
        bar.update(ii + 1)
        desc = '3_8'

    mesh = Mesh.from_data(name, coors, None, [conn], [mat_id], [desc])
    return mesh
Beispiel #16
0
def gen_cylinder_mesh(dims, shape, centre, axis='x', force_hollow=False,
                      is_open=False, open_angle=0.0, non_uniform=False,
                      name='cylinder'):
    """
    Generate a cylindrical mesh along an axis. Its cross-section can be
    ellipsoidal.

    Parameters
    ----------
    axis: one of 'x', 'y', 'z'
        The axis of the cylinder.
    dims : array of 5 floats
        Dimensions of the cylinder: inner surface semi-axes a1, b1, outer
        surface semi-axes a2, b2, length.
    shape : array of 3 ints
        Shape (counts of nodes in radial, circumferential and longitudinal
        directions) of the cylinder mesh.
    centre : array of 3 floats
        Centre of the cylinder.

    force_hollow : boolean
        Force hollow mesh even if inner radii a1 = b1 = 0.

    is_open : boolean
        Generate an open cylinder segment.
    open_angle : float
        Opening angle in radians.

    non_uniform : boolean
        If True, space the mesh nodes in radial direction so that the element
        volumes are (approximately) the same, making thus the elements towards
        the outer surface thinner.

    name : string
        Mesh name.

    Returns
    -------
    mesh : Mesh instance
    """
    dims = nm.asarray(dims, dtype=nm.float64)
    shape = nm.asarray(shape, dtype=nm.int32)
    centre = nm.asarray(centre, dtype=nm.float64)

    a1, b1, a2, b2, length = dims
    nr, nfi, nl = shape
    origin = centre - nm.array([0.5 * length, 0.0, 0.0])

    dfi = 2.0 * (nm.pi - open_angle) / nfi
    if is_open:
        nnfi = nfi + 1
    else:
        nnfi = nfi

    is_hollow = force_hollow or not (max(abs(a1), abs(b1)) < 1e-15)

    if is_hollow:
        mr = 0
    else:
        mr = (nnfi - 1) * nl

    grid = nm.zeros((nr, nnfi, nl), dtype=nm.int32)

    n_nod = nr * nnfi * nl - mr
    coors = nm.zeros((n_nod, 3), dtype=nm.float64)

    angles = nm.linspace(open_angle, open_angle+(nfi)*dfi, nfi+1)
    xs = nm.linspace(0.0, length, nl)
    if non_uniform:
        ras = nm.zeros((nr,), dtype=nm.float64)
        rbs = nm.zeros_like(ras)
        advol = (a2**2 - a1**2) / (nr - 1)
        bdvol = (b2**2 - b1**2) / (nr - 1)
        ras[0], rbs[0] = a1, b1
        for ii in range(1, nr):
            ras[ii] = nm.sqrt(advol + ras[ii-1]**2)
            rbs[ii] = nm.sqrt(bdvol + rbs[ii-1]**2)
    else:
        ras = nm.linspace(a1, a2, nr)
        rbs = nm.linspace(b1, b2, nr)

    # This is 3D only...
    bar = MyBar("       nodes:")
    bar.init(n_nod)
    ii = 0
    for ix in range(nr):
        a, b = ras[ix], rbs[ix]
        for iy, fi in enumerate(angles[:nnfi]):
            for iz, x in enumerate(xs):
                grid[ix,iy,iz] = ii
                coors[ii] = origin + [x, a * nm.cos(fi), b * nm.sin(fi)]
                if not (ii % 100):
                    bar.update(ii)
                ii += 1

                if not is_hollow and (ix == 0):
                    if iy > 0:
                        grid[ix,iy,iz] = grid[ix,0,iz]
                        ii -= 1
    print
    assert_(ii == n_nod)

    n_el = (nr - 1) * nnfi * (nl - 1)
    conn = nm.zeros((n_el, 8), dtype=nm.int32)

    bar = MyBar("       elements:")
    bar.init(n_el)
    ii = 0
    for (ix, iy, iz) in cycle([nr-1, nnfi, nl-1]):
        if iy < (nnfi - 1):
            conn[ii,:] = [grid[ix  ,iy  ,iz  ], grid[ix+1,iy  ,iz  ],
                          grid[ix+1,iy+1,iz  ], grid[ix  ,iy+1,iz  ],
                          grid[ix  ,iy  ,iz+1], grid[ix+1,iy  ,iz+1],
                          grid[ix+1,iy+1,iz+1], grid[ix  ,iy+1,iz+1]]
            ii += 1
        elif not is_open:
            conn[ii,:] = [grid[ix  ,iy  ,iz  ], grid[ix+1,iy  ,iz  ],
                          grid[ix+1,0,iz  ], grid[ix  ,0,iz  ],
                          grid[ix  ,iy  ,iz+1], grid[ix+1,iy  ,iz+1],
                          grid[ix+1,0,iz+1], grid[ix  ,0,iz+1]]
            ii += 1

        if not (ii % 100):
            bar.update(ii)
    print
    mat_id = nm.zeros((n_el,), dtype = nm.int32)
    desc = '3_8'

    assert_(n_nod == (conn.max() + 1))

    if axis == 'z':
        coors = coors[:,[1,2,0]]
    elif axis == 'y':
        coors = coors[:,[2,0,1]]

    mesh = Mesh.from_data(name, coors, None, [conn], [mat_id], [desc])
    return mesh
Beispiel #17
0
def gen_mesh_from_poly(filename, verbose=True):
    """
    Import mesh generated by tetgen or triangle.

    Parameters
    ----------
    filename : string
        file name

    Returns
    -------
    mesh : Mesh instance
        triangular or tetrahedral mesh
    """

    def getnodes(fnods,up):
        f=file(fnods)
        l=[int(x) for x in f.readline().split()]
        npoints,dim,nattrib,nbound=l
        if verbose: up.init(npoints)
        nodes=[]
        for line in f:
            if line[0]=="#": continue
            l=[float(x) for x in line.split()]
            l = l[:(dim + 1)]
            l[0]=int(l[0])
            nodes.append(tuple(l))
            assert l[0]==len(nodes)
        assert npoints==len(nodes)
        return nodes

    def getele(fele,up):
        f=file(fele)
        l=[int(x) for x in f.readline().split()]
        nele,nnod,nattrib=l
        #we have either linear or quadratic tetrahedra:
        if nnod in [4,10]:
            elem = 'tetra'
            linear = (nnod == 4)
        if nnod in [3, 7]:
            elem = 'tri'
            linear = (nnod == 3)

        # if nattrib!=1:
        #     raise "tetgen didn't assign an entity number to each element (option -A)"
        els=[]
        regions={}
        for line in f:
            if line[0]=="#": continue
            l=[int(x) for x in line.split()]
            if elem == 'tri':
                if linear:
                    assert (len(l) - 1 - nattrib) == 3
                    els.append((l[0],l[1],l[2],l[3]))
                    regionnum=l[5]
                else:
                    assert len(l)-2 == 10
                    els.append((l[0],54,l[1],l[2],l[3],l[4],
                                l[5],l[6],l[7],l[8],l[9],l[10]))
                    regionnum=l[11]
            if elem == 'tetra':
                if linear:
                    assert len(l)-2 == 4
                    els.append((l[0],54,l[1],l[2],l[3],l[4]))
                    regionnum=l[5]
                else:
                    assert len(l)-2 == 10
                    els.append((l[0],54,l[1],l[2],l[3],l[4],
                                l[5],l[6],l[7],l[8],l[9],l[10]))
                    regionnum=l[11]
            if regionnum==0:
                print "see %s, element # %d"%(fele,l[0])
                raise "there are elements not belonging to any physical entity"
            if regions.has_key(regionnum):
                regions[regionnum].append(l[0])
            else:
                regions[regionnum]=[l[0]]
            assert l[0]==len(els)
            if verbose: up.update(l[0])
        return els,regions,linear

    def getBCfaces(ffaces,up):
        f=file(ffaces)
        l=[int(x) for x in f.readline().split()]
        nfaces,nattrib=l
        if nattrib!=1:
            raise "tetgen didn't assign an entity number to each face \
(option -A)"
        if verbose: up.init(nfaces)
        faces={}
        for line in f:
            if line[0]=="#": continue
            l=[int(x) for x in line.split()]
            assert len(l)==5
            regionnum=l[4]
            if regionnum==0: continue
            if faces.has_key(regionnum):
                faces[regionnum].append((l[1],l[2],l[3]))
            else:
                faces[regionnum]=[(l[1],l[2],l[3])]
            if verbose: up.update(l[0])
        return faces

    def calculatexyz(nodes, els):
        """Calculate the missing xyz values in place"""
        def avg(i,j,n4,nodes):
            a=nodes[n4[i-1]-1]
            b=nodes[n4[j-1]-1]
            return (a[1]+b[1])/2, (a[2]+b[2])/2, (a[3]+b[3])/2
        def getxyz(i,n4,nodes):
            if i+5==5: return avg(1,2,n4,nodes)
            if i+5==6: return avg(2,3,n4,nodes)
            if i+5==7: return avg(1,3,n4,nodes)
            if i+5==8: return avg(1,4,n4,nodes)
            if i+5==9: return avg(2,4,n4,nodes)
            if i+5==10: return avg(3,4,n4,nodes)
            raise "wrong topology"
        for e in els:
            n4=e[2:2+4]
            n6=e[2+4:2+4+10]
            for i,n in enumerate(n6):
                x,y,z=getxyz(i,n4,nodes)
                nodes[n-1]=(n,x,y,z)

    if verbose: print "Reading geometry from poly file..."
    m=Mesh()
    m.nodes=getnodes(filename+".node")
    m.elements,m.regions, lin=getele(filename+".ele")
    if not lin:
        #tetgen doesn't compute xyz coordinates of the aditional 6 nodes
        #(only of the 4 corner nodes) in tetrahedra.
        calculatexyz(m.nodes,m.elements)
    m.faces=getBCfaces(filename+".face")

    return m
Beispiel #18
0
def create_expression_output(expression, name, primary_field_name,
                             fields, materials, variables,
                             functions=None, mode='eval', term_mode=None,
                             extra_args=None, verbose=True, kwargs=None,
                             min_level=0, max_level=1, eps=1e-4):
    """
    Create output mesh and data for the expression using the adaptive
    linearizer.

    Parameters
    ----------
    expression : str
        The expression to evaluate.
    name : str
        The name of the data.
    primary_field_name : str
        The name of field that defines the element groups and polynomial
        spaces.
    fields : dict
        The dictionary of fields used in `variables`.
    materials : Materials instance
        The materials used in the expression.
    variables : Variables instance
        The variables used in the expression.
    functions : Functions instance, optional
        The user functions for materials etc.
    mode : one of 'eval', 'el_avg', 'qp'
        The evaluation mode - 'qp' requests the values in quadrature points,
        'el_avg' element averages and 'eval' means integration over
        each term region.
    term_mode : str
        The term call mode - some terms support different call modes
        and depending on the call mode different values are
        returned.
    extra_args : dict, optional
        Extra arguments to be passed to terms in the expression.
    verbose : bool
        If False, reduce verbosity.
    kwargs : dict, optional
        The variables (dictionary of (variable name) : (Variable
        instance)) to be used in the expression.
    min_level : int
        The minimum required level of mesh refinement.
    max_level : int
        The maximum level of mesh refinement.
    eps : float
        The relative tolerance parameter of mesh adaptivity.

    Returns
    -------
    out : dict
        The output dictionary.
    """
    field = fields[primary_field_name]
    vertex_coors = field.coors[:field.n_vertex_dof, :]

    coors = []
    vdofs = []
    conns = []
    mat_ids = []
    levels = []
    offset = 0
    for ig, ap in field.aps.iteritems():
        ps = ap.interp.poly_spaces['v']
        gps = ap.interp.gel.interp.poly_spaces['v']
        group = field.domain.groups[ig]
        vertex_conn = ap.econn[:, :group.shape.n_ep]

        eval_dofs = get_eval_expression(expression, ig,
                                        fields, materials, variables,
                                        functions=functions,
                                        mode=mode, extra_args=extra_args,
                                        verbose=verbose, kwargs=kwargs)
        eval_coors = get_eval_coors(vertex_coors, vertex_conn, gps)

        (level, _coors, conn,
         _vdofs, _mat_ids) = create_output(eval_dofs, eval_coors,
                                           group.shape.n_el, ps,
                                           min_level=min_level,
                                           max_level=max_level, eps=eps)

        _mat_ids[:] = field.domain.mesh.mat_ids[ig][0]

        coors.append(_coors)
        vdofs.append(_vdofs)
        conns.append(conn + offset)
        mat_ids.append(_mat_ids)
        levels.append(level)

        offset += _coors.shape[0]

    coors = nm.concatenate(coors, axis=0)
    vdofs = nm.concatenate(vdofs, axis=0)
    mesh = Mesh.from_data('linearized_mesh', coors, None, conns, mat_ids,
                          field.domain.mesh.descs)

    out = {}
    out[name] = Struct(name='output_data', mode='vertex',
                       data=vdofs, var_name=name, dofs=None,
                       mesh=mesh, levels=levels)

    out = convert_complex_output(out)

    return out
Beispiel #19
0
def gen_mesh_from_goem(geo,
                       a=None,
                       quadratic=False,
                       verbose=True,
                       refine=False,
                       polyfilename='./meshgen.poly',
                       out='mesh',
                       **kwargs):
    """
    Runs mesh generator - tetgen for 3D or triangle for 2D meshes.

    Parameters
    ----------
    geo : geometry
        geometry description
    a : int, optional
        a maximum area/volume constraint
    quadratic : bool, optional
        set True for quadratic elements
    verbose : bool, optional
        detailed information
    refine : bool, optional
        refines mesh

    Returns
    -------
    mesh : Mesh instance
        triangular or tetrahedral mesh
    """

    import os.path as op
    import pexpect

    # write geometry to poly file
    geo.to_poly_file(polyfilename)

    if not refine:
        params = "-Apq"
    else:
        params = "-Arq"
    if verbose:
        params = params + " -Q"
    if a != None and not refine:
        params = params + " -a%f" % (a)
    if refine:
        params = params + " -a"
    if quadratic:
        params = params + " -o2"
    params = params + " %s" % (polyfilename)

    meshgen_call = {2: 'triangle', 3: 'tetgen'}
    cmd = "%s %s" % (meshgen_call[geo.dim], params)
    if verbose: print "Generating mesh using", cmd
    if geo.dim == 2:
        p = pexpect.run(cmd, timeout=None)
        bname, ext = op.splitext(polyfilename)
        mesh = Mesh.from_file(bname + '.1.node')
        mesh.write(bname + '.' + out)
    if geo.dim == 3:
        p = pexpect.spawn(cmd, timeout=None)
        if not refine:
            p.expect("Opening %s." % (polyfilename))
        else:
            p.expect("Opening %s.node.\r\n" % (polyfilename))
            p.expect("Opening %s.ele.\r\n" % (polyfilename))
            p.expect("Opening %s.face.\r\n" % (polyfilename))
            p.expect("Opening %s.vol." % (polyfilename))
        assert p.before == ""
        p.expect(pexpect.EOF)
        if p.before != "\r\n":
            print p.before
            raise "Error when running mesh generator (see above for output): %s" % cmd
Beispiel #20
0
def gen_block_mesh(dims, shape, centre, mat_id=0, name='block', verbose=True):
    """
    Generate a 2D or 3D block mesh. The dimension is determined by the
    lenght of the shape argument.

    Parameters
    ----------
    dims : array of 2 or 3 floats
        Dimensions of the block.
    shape : array of 2 or 3 ints
        Shape (counts of nodes in x, y, z) of the block mesh.
    centre : array of 2 or 3 floats
        Centre of the block.
    mat_id : int, optional
        The material id of all elements.
    name : string
        Mesh name.
    verbose : bool
        If True, show progress of the mesh generation.

    Returns
    -------
    mesh : Mesh instance
    """
    dims = nm.asarray(dims, dtype=nm.float64)
    shape = nm.asarray(shape, dtype=nm.int32)
    centre = nm.asarray(centre, dtype=nm.float64)

    dim = shape.shape[0]

    centre = centre[:dim]
    dims = dims[:dim]

    x0 = centre - 0.5 * dims
    dd = dims / (shape - 1)

    grid = nm.zeros(shape, dtype=nm.int32)
    n_nod = nm.prod(shape)
    coors = nm.zeros((n_nod, dim), dtype=nm.float64)

    bar = MyBar("       nodes:", verbose=verbose)
    bar.init(n_nod)
    for ii, ic in enumerate(cycle(shape)):
        grid[tuple(ic)] = ii
        coors[ii] = x0 + ic * dd
        if not (ii % 100):
            bar.update(ii)
    bar.update(ii + 1)

    n_el = nm.prod(shape - 1)
    mat_ids = nm.empty((n_el, ), dtype=nm.int32)
    mat_ids.fill(mat_id)

    if (dim == 2):
        conn = nm.zeros((n_el, 4), dtype=nm.int32)
        bar = MyBar("       elements:", verbose=verbose)
        bar.init(n_el)
        for ii, (ix, iy) in enumerate(cycle(shape - 1)):
            conn[ii, :] = [
                grid[ix, iy], grid[ix + 1, iy], grid[ix + 1, iy + 1],
                grid[ix, iy + 1]
            ]
            if not (ii % 100):
                bar.update(ii)
        bar.update(ii + 1)
        desc = '2_4'

    else:
        conn = nm.zeros((n_el, 8), dtype=nm.int32)
        bar = MyBar("       elements:", verbose=verbose)
        bar.init(n_el)
        for ii, (ix, iy, iz) in enumerate(cycle(shape - 1)):
            conn[ii, :] = [
                grid[ix, iy, iz], grid[ix + 1, iy, iz], grid[ix + 1, iy + 1,
                                                             iz],
                grid[ix, iy + 1, iz], grid[ix, iy, iz + 1], grid[ix + 1, iy,
                                                                 iz + 1],
                grid[ix + 1, iy + 1, iz + 1], grid[ix, iy + 1, iz + 1]
            ]
            if not (ii % 100):
                bar.update(ii)
        bar.update(ii + 1)
        desc = '3_8'

    mesh = Mesh.from_data(name, coors, None, [conn], [mat_ids], [desc])
    return mesh
Beispiel #21
0
def extract_time_history( filename, options ):
    output( 'extracting selected data...' )

    el = options.extract_list
    output( 'extraction list:', el )

    ##
    # Parse extractions.
    pes = OneTypeList( Struct )
    for chunk in el.split( ',' ):
        aux =  chunk.strip().split()
        pes.append( Struct( var = aux[0],
                            mode = aux[1],
                            indx = map( int, aux[2:] ),
                            igs = None ) )

    ##
    # Verify array limits, set igs for element data, shift indx.
    mesh = Mesh.from_file( filename )
    n_el, n_els, offs = mesh.n_el, mesh.n_els, mesh.el_offsets
    for pe in pes:
        if pe.mode == 'n':
            for ii in pe.indx:
                if (ii < 0) or (ii >= mesh.n_nod):
                    raise IndexError, 'node index 0 <= %d < %d'\
                          % (ii, mesh.n_nod)

        if pe.mode == 'e':
            pe.igs = []
            for ii, ie in enumerate( pe.indx[:] ):
                if (ie < 0) or (ie >= n_el):
                    raise IndexError, 'element index 0 <= %d < %d'\
                          % (ie, n_el)
                ig = (ie < n_els).argmax()
                pe.igs.append( ig )
                pe.indx[ii] = ie - offs[ig]

##     print pes

    ##
    # Extract data.
    # Assumes only one element group (ignores igs)!
    io = HDF5MeshIO( filename )
    ths = {}
    for pe in pes:
        mode, nname = io.read_data_header( pe.var )
        print mode, nname
        if ((pe.mode == 'n' and mode == 'vertex') or
            (pe.mode == 'e' and mode == 'cell')):
            th = io.read_time_history( nname, pe.indx )

        elif pe.mode == 'e' and mode == 'vertex':
            conn = mesh.conns[0]
            th = {}
            for iel in pe.indx:
                ips = conn[iel]
                th[iel] = io.read_time_history( nname, ips )
        else:
            raise RuntimeError, 'cannot extract cell data %s in nodes' % pe.var
            
        ths[pe.var] = th
    return ths
Beispiel #22
0
def main():

    parser = OptionParser( usage = usage, version = "%prog 42" )
    parser.add_option( "-s", "--scale", type = int, metavar = 'scale',
                       action = "store", dest = "scale",
                       default = 2, help = help['scale'] )
    parser.add_option( "-e", "--eps", type = float, metavar = 'eps',
                       action = "store", dest = "eps",
                       default = 1e-8, help = help['eps'] )
    parser.add_option( "-t", "--test",
                       action = "store_true", dest = "test",
                       default = False, help = help['test'] )
    parser.add_option( "-n", "--no-mvd",
                       action = "store_true", dest = "nomvd",
                       default = False, help = help['nomvd'] )
    (options, args) = parser.parse_args()

    if options.test:
        test()
        return

    if (len( args ) == 2):
        filename_in = args[0]
        filename_out = args[1]
    else:
        parser.print_help()
        return

    print 'scale:', options.scale
    print 'eps:', options.eps

    mesh_in = Mesh.from_file( filename_in )
    bbox = mesh_in.get_bounding_box()
    print 'bbox:\n', bbox
    mscale = bbox[1] - bbox[0]
    centre0 = 0.5 * (bbox[1] + bbox[0])
    print 'centre:\n', centre0

    scale = nm.array( options.scale, dtype = nm.float64 )

    # Normalize original coordinates.
    coor0 = (mesh_in.nod0[:,:-1] - centre0) / (mscale)
    dim = mesh_in.dim

    coor0, mesh_in.conns = fix_double_nodes( coor0, mesh_in.conns, options.eps )
    if not options.nomvd:
        mes0 = get_min_edge_size( coor0, mesh_in.conns )
        mvd0 = get_min_vertex_distance( coor0, mes0 )
        if mes0 > (mvd0 + options.eps):
            print '          original min. "edge" length: %.5e' % mes0
            print 'original approx. min. vertex distance: %.5e' % mvd0
            print '-> still double nodes in input mesh!'
            print 'try increasing eps...'
            raise ValueError

    for indx in cycle( [options.scale] * dim ):
        aindx = nm.array( indx, dtype = nm.float64 )
        centre = 0.5 * (2.0 * aindx - scale + 1.0)
        print indx, centre

        if aindx.sum() == 0:
            coor = coor0 + centre
            conns = mesh_in.conns
        else:
            coor1 = coor0 + centre
            conns1 = mesh_in.conns

            cmap = find_map( coor, coor1, eps = options.eps )
            if not cmap.size:
                print 'non-periodic mesh!'
#                raise ValueError
            else:
                print cmap.size / 2
            coor, conns = merge_mesh( coor, conns, coor1, conns1, cmap,
                                     eps = options.eps )

    if not options.nomvd:
        mes = get_min_edge_size( coor, conns )
        mvd = get_min_vertex_distance( coor, mes0 )

        print '          original min. "edge" length: %.5e' % mes0
        print '             final min. "edge" length: %.5e' % mes
        print 'original approx. min. vertex distance: %.5e' % mvd0
        print '   final approx. min. vertex distance: %.5e' % mvd
        if mvd < 0.99999 * mvd0:
            if mvd0 < (mes0 - options.eps):
                print '-> probably non-periodic input mesh!'
                print '   ... adjacent sides were not connected!'
                print '   try increasing eps...'
            else:
                print '-> input mesh might be periodic'
                print '   try increasing eps...'
        else:
            print '-> input mesh looks periodic'
    else:
        print 'non-periodic input mesh detection skipped!'

    print 'renormalizing...'
    coor = (coor * mscale) / scale
    print 'saving...'
    mesh_out = make_mesh( coor, conns, mesh_in )
    mesh_out.write( filename_out, io = 'auto' )
    print 'done.'
Beispiel #23
0
def extract_time_history(filename, extract, verbose=True):
    """Extract time history of a variable from a multi-time-step results file.

    Parameters
    ----------
    filename : str
        The name of file to extract from.
    extract : str
        The description of what to extract in a string of comma-separated
        description items. A description item consists of: name of the variable
        to extract, mode ('e' for elements, 'n' for nodes), ids of the nodes or
        elements (given by the mode). Example: 'u n 10 15, p e 0' means
        variable 'u' in nodes 10, 15 and variable 'p' in element 0.
    verbose : bool
        Verbosity control.

    Returns
    -------
    ths : dict
        The time histories in a dict with variable names as keys. If a
        nodal variable is requested in elements, its value is a dict of histories
        in the element nodes.
    ts : TimeStepper instance
        The time stepping information.
    """
    output('extracting selected data...', verbose=verbose)

    output('selection:', extract, verbose=verbose)

    ##
    # Parse extractions.
    pes = OneTypeList(Struct)
    for chunk in extract.split(','):
        aux = chunk.strip().split()
        pes.append(Struct(var = aux[0],
                          mode = aux[1],
                          indx = map(int, aux[2:]),
                          igs = None))

    ##
    # Verify array limits, set igs for element data, shift indx.
    mesh = Mesh.from_file(filename)
    n_el, n_els, offs = mesh.n_el, mesh.n_els, mesh.el_offsets
    for pe in pes:
        if pe.mode == 'n':
            for ii in pe.indx:
                if (ii < 0) or (ii >= mesh.n_nod):
                    raise ValueError('node index 0 <= %d < %d!'
                                     % (ii, mesh.n_nod))

        if pe.mode == 'e':
            pe.igs = []
            for ii, ie in enumerate(pe.indx[:]):
                if (ie < 0) or (ie >= n_el):
                    raise ValueError('element index 0 <= %d < %d!'
                                     % (ie, n_el))
                ig = (ie < n_els).argmax()
                pe.igs.append(ig)
                pe.indx[ii] = ie - offs[ig]

##     print pes

    ##
    # Extract data.
    # Assumes only one element group (ignores igs)!
    io = MeshIO.any_from_filename(filename)
    ths = {}
    for pe in pes:
        mode, nname = io.read_data_header(pe.var)
        output(mode, nname, verbose=verbose)

        if ((pe.mode == 'n' and mode == 'vertex') or
            (pe.mode == 'e' and mode == 'cell')):
            th = io.read_time_history(nname, pe.indx)

        elif pe.mode == 'e' and mode == 'vertex':
            conn = mesh.conns[0]
            th = {}
            for iel in pe.indx:
                ips = conn[iel]
                th[iel] = io.read_time_history(nname, ips)
        else:
            raise ValueError('cannot extract cell data %s in nodes!' % pe.var)
            
        ths[pe.var] = th

    output('...done', verbose=verbose)

    ts = TimeStepper(*io.read_time_stepper())

    return ths, ts
Beispiel #24
0
    def linearize(self, dofs, min_level=0, max_level=1, eps=1e-4):
        """
        Linearize the solution for post-processing.

        Parameters
        ----------
        dofs : array, shape (n_nod, n_component)
            The array of DOFs reshaped so that each column corresponds
            to one component.
        min_level : int
            The minimum required level of mesh refinement.
        max_level : int
            The maximum level of mesh refinement.
        eps : float
            The relative tolerance parameter of mesh adaptivity.

        Returns
        -------
        mesh : Mesh instance
            The adapted, nonconforming, mesh.
        vdofs : array
            The DOFs defined in vertices of `mesh`.
        levels : array of ints
            The refinement level used for each element group.
        """
        assert_(dofs.ndim == 2)

        n_nod, dpn = dofs.shape

        assert_(n_nod == self.n_nod)
        assert_(dpn == self.shape[0])

        vertex_coors = self.coors[:self.n_vertex_dof, :]

        coors = []
        vdofs = []
        conns = []
        mat_ids = []
        levels = []
        offset = 0
        for ig, ap in self.aps.iteritems():
            ps = ap.interp.poly_spaces['v']
            gps = ap.interp.gel.interp.poly_spaces['v']
            group = self.domain.groups[ig]
            vertex_conn = ap.econn[:, :group.shape.n_ep]

            eval_dofs = get_eval_dofs(dofs, ap.econn, ps, ori=ap.ori)
            eval_coors = get_eval_coors(vertex_coors, vertex_conn, gps)

            (level, _coors, conn,
             _vdofs, _mat_ids) = create_output(eval_dofs, eval_coors,
                                               group.shape.n_el, ps,
                                               min_level=min_level,
                                               max_level=max_level, eps=eps)

            _mat_ids[:] = self.domain.mesh.mat_ids[ig][0]

            coors.append(_coors)
            vdofs.append(_vdofs)
            conns.append(conn + offset)
            mat_ids.append(_mat_ids)
            levels.append(level)

            offset += _coors.shape[0]

        coors = nm.concatenate(coors, axis=0)
        vdofs = nm.concatenate(vdofs, axis=0)
        mesh = Mesh.from_data('linearized_mesh', coors, None, conns, mat_ids,
                              self.domain.mesh.descs)

        return mesh, vdofs, levels
Beispiel #25
0
def main():
    parser = OptionParser(usage=usage, version='%prog ' + sfepy.__version__)
    parser.add_option('-c',
                      '--conf',
                      metavar='"key : value, ..."',
                      action='store',
                      dest='conf',
                      type='string',
                      default=None,
                      help=help['conf'])
    parser.add_option('-O',
                      '--options',
                      metavar='"key : value, ..."',
                      action='store',
                      dest='app_options',
                      type='string',
                      default=None,
                      help=help['options'])
    parser.add_option('-o',
                      '',
                      metavar='filename',
                      action='store',
                      dest='output_filename_trunk',
                      default=None,
                      help=help['filename'])
    parser.add_option('--create-mesh',
                      action='store_true',
                      dest='create_mesh',
                      default=False,
                      help=help['create_mesh'])
    parser.add_option('--2d',
                      action='store_true',
                      dest='dim2',
                      default=False,
                      help=help['dim'])
    parser.add_option('-m',
                      '--mesh',
                      metavar='filename',
                      action='store',
                      dest='mesh',
                      default=None,
                      help=help['mesh'])
    parser.add_option('--mesh-dir',
                      metavar='dirname',
                      action='store',
                      dest='mesh_dir',
                      default='tmp',
                      help=help['mesh_dir'])
    parser.add_option('--oscillator',
                      action='store_true',
                      dest='oscillator',
                      default=False,
                      help=help['oscillator'])
    parser.add_option('--well',
                      action='store_true',
                      dest='well',
                      default=False,
                      help=help['well'])
    parser.add_option('--hydrogen',
                      action='store_true',
                      dest='hydrogen',
                      default=False,
                      help=help['hydrogen'])
    parser.add_option('--boron',
                      action='store_true',
                      dest='boron',
                      default=False,
                      help=help['boron'])

    options, args = parser.parse_args()

    if options.create_mesh and options.mesh:
        output('--create-mesh and --mesh options are mutually exclusive!')
        return

    if len(args) == 1:
        filename_in = args[0]
        auto_mesh_name = False

    elif len(args) == 0:
        auto_mesh_name = True

        mesh_filename = os.path.join(options.mesh_dir, 'mesh.vtk')
        ensure_path(mesh_filename)

        if options.oscillator:
            filename_in = fix_path("examples/quantum/oscillator.py")

        elif options.well:
            filename_in = fix_path("examples/quantum/well.py")

        elif options.hydrogen:
            filename_in = fix_path("examples/quantum/hydrogen.py")

        elif options.boron:
            filename_in = fix_path("examples/quantum/boron.py")

        elif options.create_mesh:
            output('generating mesh...')
            try:
                os.makedirs("tmp")
            except OSError, e:
                if e.errno != 17:  # [Errno 17] File exists
                    raise
            if options.dim2:
                output("dimension: 2")
                gp = fix_path('meshes/quantum/square.geo')
                os.system("cp %s tmp/mesh.geo" % gp)
                os.system("gmsh -2 tmp/mesh.geo -format mesh")
                mtv = fix_path('script/convert_mesh.py')
                os.system("%s tmp/mesh.mesh %s" % (mtv, mesh_filename))
            else:
                output("dimension: 3")
                import sfepy.mesh as geom
                from sfepy.fem.mesh import Mesh
                try:
                    from site_cfg import tetgen_path
                except ImportError:
                    tetgen_path = '/usr/bin/tetgen'
                gp = fix_path('meshes/quantum/box.geo')
                os.system("gmsh -0 %s -o tmp/x.geo" % gp)
                g = geom.read_gmsh("tmp/x.geo")
                g.printinfo()
                geom.write_tetgen(g, "tmp/t.poly")
                geom.runtetgen("tmp/t.poly",
                               a=0.03,
                               Q=1.0,
                               quadratic=False,
                               tetgenpath=tetgen_path)
                m = Mesh.from_file("tmp/t.1.node")
                m.write(mesh_filename, io="auto")
            output("...mesh written to %s" % mesh_filename)
            return

        else:
            parser.print_help()
            return
Beispiel #26
0
def extract_time_history(filename, extract, verbose=True):
    """Extract time history of a variable from a multi-time-step results file.

    Parameters
    ----------
    filename : str
        The name of file to extract from.
    extract : str
        The description of what to extract in a string of comma-separated
        description items. A description item consists of: name of the variable
        to extract, mode ('e' for elements, 'n' for nodes), ids of the nodes or
        elements (given by the mode). Example: 'u n 10 15, p e 0' means
        variable 'u' in nodes 10, 15 and variable 'p' in element 0.
    verbose : bool
        Verbosity control.

    Returns
    -------
    ths : dict
        The time histories in a dict with variable names as keys. If a
        nodal variable is requested in elements, its value is a dict of histories
        in the element nodes.
    ts : TimeStepper instance
        The time stepping information.
    """
    output('extracting selected data...', verbose=verbose)

    output('selection:', extract, verbose=verbose)

    ##
    # Parse extractions.
    pes = OneTypeList(Struct)
    for chunk in extract.split(','):
        aux = chunk.strip().split()
        pes.append(
            Struct(var=aux[0], mode=aux[1], indx=map(int, aux[2:]), igs=None))

    ##
    # Verify array limits, set igs for element data, shift indx.
    mesh = Mesh.from_file(filename)
    n_el, n_els, offs = mesh.n_el, mesh.n_els, mesh.el_offsets
    for pe in pes:
        if pe.mode == 'n':
            for ii in pe.indx:
                if (ii < 0) or (ii >= mesh.n_nod):
                    raise ValueError('node index 0 <= %d < %d!' %
                                     (ii, mesh.n_nod))

        if pe.mode == 'e':
            pe.igs = []
            for ii, ie in enumerate(pe.indx[:]):
                if (ie < 0) or (ie >= n_el):
                    raise ValueError('element index 0 <= %d < %d!' %
                                     (ie, n_el))
                ig = (ie < n_els).argmax()
                pe.igs.append(ig)
                pe.indx[ii] = ie - offs[ig]


##     print pes

##
# Extract data.
# Assumes only one element group (ignores igs)!
    io = MeshIO.any_from_filename(filename)
    ths = {}
    for pe in pes:
        mode, nname = io.read_data_header(pe.var)
        output(mode, nname, verbose=verbose)

        if ((pe.mode == 'n' and mode == 'vertex')
                or (pe.mode == 'e' and mode == 'cell')):
            th = io.read_time_history(nname, pe.indx)

        elif pe.mode == 'e' and mode == 'vertex':
            conn = mesh.conns[0]
            th = {}
            for iel in pe.indx:
                ips = conn[iel]
                th[iel] = io.read_time_history(nname, ips)
        else:
            raise ValueError('cannot extract cell data %s in nodes!' % pe.var)

        ths[pe.var] = th

    output('...done', verbose=verbose)

    ts = TimeStepper(*io.read_time_stepper())

    return ths, ts
Beispiel #27
0
def main():
    parser = OptionParser(usage=usage, version='%prog ' + sfepy.__version__)
    parser.add_option('-c', '--conf', metavar='"key : value, ..."',
                      action='store', dest='conf', type='string',
                      default=None, help= help['conf'])
    parser.add_option('-O', '--options', metavar='"key : value, ..."',
                      action='store', dest='app_options', type='string',
                      default=None, help=help['options'])
    parser.add_option('-o', '', metavar='filename',
                      action='store', dest='output_filename_trunk',
                      default=None, help=help['filename'])
    parser.add_option('--create-mesh',
                      action='store_true', dest='create_mesh',
                      default=False, help=help['create_mesh'])
    parser.add_option('--2d',
                      action='store_true', dest='dim2',
                      default=False, help=help['dim'])
    parser.add_option('-m', '--mesh', metavar='filename',
                      action='store', dest='mesh',
                      default=None, help=help['mesh'])
    parser.add_option('--mesh-dir', metavar='dirname',
                      action='store', dest='mesh_dir',
                      default='tmp', help=help['mesh_dir'])
    parser.add_option('--oscillator',
                      action='store_true', dest='oscillator',
                      default=False, help=help['oscillator'])
    parser.add_option('--well',
                      action='store_true', dest='well',
                      default=False, help=help['well'])
    parser.add_option('--hydrogen',
                      action='store_true', dest='hydrogen',
                      default=False, help=help['hydrogen'])
    parser.add_option('--boron',
                      action='store_true', dest='boron',
                      default=False, help=help['boron'])

    options, args = parser.parse_args()

    if options.create_mesh and options.mesh:
        output('--create-mesh and --mesh options are mutually exclusive!')
        return

    if len(args) == 1:
        filename_in = args[0];
        auto_mesh_name = False

    elif len(args) == 0:
        auto_mesh_name = True

        mesh_filename = os.path.join(options.mesh_dir, 'mesh.vtk')
        ensure_path(mesh_filename)

        if options.oscillator:
            filename_in = fix_path("examples/quantum/oscillator.py")

        elif options.well:
            filename_in = fix_path("examples/quantum/well.py")

        elif options.hydrogen:
            filename_in = fix_path("examples/quantum/hydrogen.py")

        elif options.boron:
            filename_in = fix_path("examples/quantum/boron.py")

        elif options.create_mesh:
            output('generating mesh...')
            try:
                os.makedirs("tmp")
            except OSError, e:
                if e.errno != 17: # [Errno 17] File exists
                    raise
            if options.dim2:
                output("dimension: 2")
                gp = fix_path('meshes/quantum/square.geo')
                os.system("cp %s tmp/mesh.geo" % gp)
                os.system("gmsh -2 tmp/mesh.geo -format mesh")
                mtv = fix_path('script/mesh_to_vtk.py')
                os.system("%s tmp/mesh.mesh %s" % (mtv, mesh_filename))
            else:
                output("dimension: 3")
                import sfepy.geom as geom
                from sfepy.fem.mesh import Mesh
                try:
                    from site_cfg import tetgen_path
                except ImportError:
                    tetgen_path = '/usr/bin/tetgen'
                gp = fix_path('meshes/quantum/box.geo')
                os.system("gmsh -0 %s -o tmp/x.geo" % gp)
                g = geom.read_gmsh("tmp/x.geo")
                g.printinfo()
                geom.write_tetgen(g, "tmp/t.poly")
                geom.runtetgen("tmp/t.poly", a=0.03, Q=1.0,
                               quadratic=False, tetgenpath=tetgen_path)
                m = Mesh.from_file("tmp/t.1.node")
                m.write(mesh_filename, io="auto")
            output("...mesh written to %s" % mesh_filename)
            return

        else:
            parser.print_help()
            return
Beispiel #28
0
def main():
    version = open( op.join( init_sfepy.install_dir,
                             'VERSION' ) ).readlines()[0][:-1]

    parser = OptionParser( usage = usage, version = "%prog " + version )
    parser.add_option( "--mesh",
                       action = "store_true", dest = "mesh",
                       default = False, help = help['mesh'] )
    parser.add_option( "--2d",
                       action = "store_true", dest = "dim2",
                       default = False, help = help['dim'] )
    parser.add_option( "-o", "", metavar = 'filename',
                       action = "store", dest = "output_filename_trunk",
                       default = "mesh", help = help['filename'] )
    parser.add_option( "--oscillator",
                       action = "store_true", dest = "oscillator",
                       default = False, help = help['oscillator'] )
    parser.add_option( "--well",
                       action = "store_true", dest = "well",
                       default = False, help = help['well'] )
    parser.add_option( "--hydrogen",
                       action = "store_true", dest = "hydrogen",
                       default = False, help = help['hydrogen'] )
    parser.add_option( "--boron",
                       action = "store_true", dest = "boron",
                       default = False, help = help['boron'] )
    parser.add_option( "--dft",
                       action = "store_true", dest = "dft",
                       default = False, help = help['dft'] )
    parser.add_option( "-p", "--plot",
                       action = "store_true", dest = "plot",
                       default = False, help = help['plot'] )

    options, args = parser.parse_args()

    if len( args ) == 1:
        filename_in = args[0];
    elif len( args ) == 0:
        if options.oscillator:
            dim = MeshIO.any_from_filename("tmp/mesh.vtk").read_dimension()
            if dim == 2:
                filename_in = "input/quantum/oscillator2d.py"
            else:
                assert_( dim == 3 )
                filename_in = "input/quantum/oscillator3d.py"
            options.dim = dim
            print "Dimension:", dim
        elif options.well:
            dim = MeshIO.any_from_filename("tmp/mesh.vtk").read_dimension()
            if dim == 2:
                filename_in = "input/quantum/well2d.py"
            else:
                assert_( dim == 3 )
                filename_in = "input/quantum/well3d.py"
            options.dim = dim
            print "Dimension:", dim
        elif options.hydrogen:
            dim = MeshIO.any_from_filename("tmp/mesh.vtk").read_dimension()
            if dim == 2:
                filename_in = "input/quantum/hydrogen2d.py"
            else:
                assert_( dim == 3 )
                filename_in = "input/quantum/hydrogen3d.py"
            options.dim = dim
            print "Dimension:", dim
        elif options.boron:
            dim = MeshIO.any_from_filename("tmp/mesh.vtk").read_dimension()
            if dim == 2:
                filename_in = "input/quantum/boron2d.py"
            else:
                assert_( dim == 3 )
                filename_in = "input/quantum/boron3d.py"
            options.dim = dim
            print "Dimension:", dim
        elif options.mesh:
            try:
                os.makedirs("tmp")
            except OSError, e:
                if e.errno != 17: # [Errno 17] File exists
                    raise
            if options.dim2:
                print "Dimension: 2"
                os.system("cp database/quantum/square.geo tmp/mesh.geo")
                os.system("gmsh -2 tmp/mesh.geo -format mesh")
                os.system("script/mesh_to_vtk.py tmp/mesh.mesh tmp/mesh.vtk")
            else:
                print "Dimension: 3"
                import geom
                from sfepy.fem.mesh import Mesh
                try:
                    from site_cfg import tetgen_path
                except ImportError:
                    tetgen_path = '/usr/bin/tetgen'
                os.system("gmsh -0 database/box.geo -o tmp/x.geo")
                g = geom.read_gmsh("tmp/x.geo")
                g.printinfo()
                geom.write_tetgen(g, "tmp/t.poly")
                geom.runtetgen("tmp/t.poly", a=0.03, Q=1.0, quadratic=False,
                        tetgenpath=tetgen_path)
                m = Mesh.from_file("tmp/t.1.node")
                m.write("tmp/mesh.vtk", io="auto")
            print "Mesh written to tmp/mesh.vtk"
            return
        elif options.dft:
            dim = MeshIO.any_from_filename("tmp/mesh.vtk").read_dimension()
            if dim == 2:
                filename_in = "input/quantum/dft2d.py"
            else:
                assert_( dim == 3 )
                filename_in = "input/quantum/dft3d.py"
            print "Dimension:", dim
            options.dim = dim
        else:
            parser.print_help()
            return
Beispiel #29
0
def gen_tiled_mesh(mesh, grid=None, scale=1.0, eps=1e-6, ret_ndmap=False):
    """
    Generate a new mesh by repeating a given periodic element
    along each axis.

    Parameters
    ----------
    mesh : Mesh instance
        The input periodic FE mesh.
    grid : array
        Number of repetition along each axis.
    scale : float, optional
        Scaling factor.
    eps : float, optional
        Tolerance for boundary detection.
    ret_ndmap : bool, optional
        If True, return global node map.

    Returns
    -------
    mesh_out : Mesh instance
        FE mesh.
    ndmap : array
        Maps: actual node id --> node id in the reference cell.
    """
    bbox = mesh.get_bounding_box()

    if grid is None:
        iscale = max(int(1.0 / scale), 1)
        grid = [iscale] * mesh.dim

    conns = mesh.conns[0]
    for ii in mesh.conns[1:]:
        conns = nm.vstack((conns, ii))
    mat_ids = mesh.mat_ids[0]
    for ii in mesh.mat_ids[1:]:
        mat_ids = nm.hstack((mat_ids, ii))

    coors = mesh.coors
    ngrps = mesh.ngroups
    nrep = nm.prod(grid)
    ndmap = None

    bar = MyBar("       repeating:")
    bar.init(nrep)
    nblk = 1
    for ii, gr in enumerate(grid):
        if ret_ndmap:
            (conns, coors,
             ngrps, ndmap0) = tiled_mesh1d(conns, coors, ngrps,
                                           ii, gr, bbox.transpose()[ii],
                                           eps=eps, mybar=(bar, nblk),
                                           ndmap=ndmap)
            ndmap = ndmap0

        else:
            conns, coors, ngrps = tiled_mesh1d(conns, coors, ngrps,
                                               ii, gr, bbox.transpose()[ii],
                                               eps=eps, mybar=(bar, nblk))
        nblk *= gr

    bar.update(nblk)

    mat_ids = nm.tile(mat_ids, (nrep,))
    mesh_out = Mesh.from_data('tiled mesh', coors * scale, ngrps,
                              [conns], [mat_ids], [mesh.descs[0]])

    if ret_ndmap:
        return mesh_out, ndmap
    else:
        return mesh_out
Beispiel #30
0
def gen_mesh_from_goem(geo, a=None, quadratic=False, verbose=True,
                       refine=False, polyfilename='./meshgen.poly',
                       out='mesh', **kwargs):
    """
    Runs mesh generator - tetgen for 3D or triangle for 2D meshes.

    Parameters
    ----------
    geo : geometry
        geometry description
    a : int, optional
        a maximum area/volume constraint
    quadratic : bool, optional
        set True for quadratic elements
    verbose : bool, optional
        detailed information
    refine : bool, optional
        refines mesh

    Returns
    -------
    mesh : Mesh instance
        triangular or tetrahedral mesh
    """

    import os.path as op
    import pexpect

    # write geometry to poly file
    geo.to_poly_file(polyfilename)

    if not refine:
        params = "-Apq"
    else:
        params = "-Arq"
    if verbose:
        params = params + " -Q"
    if a != None and not refine:
        params = params + " -a%f" % (a)
    if refine:
        params = params + " -a"
    if quadratic:
        params = params + " -o2"
    params = params + " %s" % (polyfilename)

    meshgen_call = {2: 'triangle', 3: 'tetgen'}
    cmd = "%s %s" % (meshgen_call[geo.dim], params)
    if verbose: print "Generating mesh using", cmd
    if geo.dim == 2:
        p=pexpect.run(cmd, timeout=None)
        bname, ext = op.splitext(polyfilename)
        mesh = Mesh.from_file(bname + '.1.node')
        mesh.write(bname + '.' + out)
    if geo.dim == 3:
        p=pexpect.spawn(cmd, timeout=None)
        if not refine:
            p.expect("Opening %s." % (polyfilename))
        else:
            p.expect("Opening %s.node.\r\n" % (polyfilename))
            p.expect("Opening %s.ele.\r\n" % (polyfilename))
            p.expect("Opening %s.face.\r\n" % (polyfilename))
            p.expect("Opening %s.vol." % (polyfilename))
        assert p.before == ""
        p.expect(pexpect.EOF)
        if p.before != "\r\n":
            print p.before
            raise "Error when running mesh generator (see above for output): %s" % cmd
Beispiel #31
0
def gen_tiled_mesh(mesh, grid=None, scale=1.0, eps=1e-6, ret_ndmap=False):
    """
    Generate a new mesh by repeating a given periodic element
    along each axis.

    Parameters
    ----------
    mesh : Mesh instance
        The input periodic FE mesh.
    grid : array
        Number of repetition along each axis.
    scale : float, optional
        Scaling factor.
    eps : float, optional
        Tolerance for boundary detection.
    ret_ndmap : bool, optional
        If True, return global node map.

    Returns
    -------
    mesh_out : Mesh instance
        FE mesh.
    ndmap : array
        Maps: actual node id --> node id in the reference cell.
    """
    bbox = mesh.get_bounding_box()

    if grid is None:
        iscale = max(int(1.0 / scale), 1)
        grid = [iscale] * mesh.dim

    conns = mesh.conns[0]
    for ii in mesh.conns[1:]:
        conns = nm.vstack((conns, ii))
    mat_ids = mesh.mat_ids[0]
    for ii in mesh.mat_ids[1:]:
        mat_ids = nm.hstack((mat_ids, ii))

    coors = mesh.coors
    ngrps = mesh.ngroups
    nrep = nm.prod(grid)
    ndmap = None

    bar = MyBar("       repeating:")
    bar.init(nrep)
    nblk = 1
    for ii, gr in enumerate(grid):
        if ret_ndmap:
            (conns, coors, ngrps, ndmap0) = tiled_mesh1d(conns,
                                                         coors,
                                                         ngrps,
                                                         ii,
                                                         gr,
                                                         bbox.transpose()[ii],
                                                         eps=eps,
                                                         mybar=(bar, nblk),
                                                         ndmap=ndmap)
            ndmap = ndmap0

        else:
            conns, coors, ngrps = tiled_mesh1d(conns,
                                               coors,
                                               ngrps,
                                               ii,
                                               gr,
                                               bbox.transpose()[ii],
                                               eps=eps,
                                               mybar=(bar, nblk))
        nblk *= gr

    bar.update(nblk)

    mat_ids = nm.tile(mat_ids, (nrep, ))
    mesh_out = Mesh.from_data('tiled mesh', coors * scale, ngrps, [conns],
                              [mat_ids], [mesh.descs[0]])

    if ret_ndmap:
        return mesh_out, ndmap
    else:
        return mesh_out
Beispiel #32
0
def gen_mesh_from_voxels(voxels, dims, etype='q'):
    """
    Generate FE mesh from voxels (volumetric data).

    Parameters
    ----------
    voxels : array
        Voxel matrix, 1=material.
    dims : array
        Size of one voxel.
    etype : integer, optional
        'q' - quadrilateral or hexahedral elements
        't' - triangular or tetrahedral elements
    Returns
    -------
    mesh : Mesh instance
        Finite element mesh.
    """

    dims = dims.squeeze()
    dim = len(dims)
    nddims = nm.array(voxels.shape) + 1

    nodemtx = nm.zeros(nddims, dtype=nm.int32)

    if dim == 2:
        #iy, ix = nm.where(voxels.transpose())
        iy, ix = nm.where(voxels)
        nel = ix.shape[0]

        if etype == 'q':
            nodemtx[ix,iy] += 1
            nodemtx[ix + 1,iy] += 1
            nodemtx[ix + 1,iy + 1] += 1
            nodemtx[ix,iy + 1] += 1

        elif etype == 't':
            nodemtx[ix,iy] += 2
            nodemtx[ix + 1,iy] += 1
            nodemtx[ix + 1,iy + 1] += 2
            nodemtx[ix,iy + 1] += 1
            nel *= 2

    elif dim == 3:
        #iy, ix, iz = nm.where(voxels.transpose(1, 0, 2))
        iy, ix, iz = nm.where(voxels)
        nel = ix.shape[0]

        if etype == 'q':
            nodemtx[ix,iy,iz] += 1
            nodemtx[ix + 1,iy,iz] += 1
            nodemtx[ix + 1,iy + 1,iz] += 1
            nodemtx[ix,iy + 1,iz] += 1
            nodemtx[ix,iy,iz + 1] += 1
            nodemtx[ix + 1,iy,iz + 1] += 1
            nodemtx[ix + 1,iy + 1,iz + 1] += 1
            nodemtx[ix,iy + 1,iz + 1] += 1

        elif etype == 't':
            nodemtx[ix,iy,iz] += 6
            nodemtx[ix + 1,iy,iz] += 2
            nodemtx[ix + 1,iy + 1,iz] += 2
            nodemtx[ix,iy + 1,iz] += 2
            nodemtx[ix,iy,iz + 1] += 2
            nodemtx[ix + 1,iy,iz + 1] += 2
            nodemtx[ix + 1,iy + 1,iz + 1] += 6
            nodemtx[ix,iy + 1,iz + 1] += 2
            nel *= 6

    else:
        msg = 'incorrect voxel dimension! (%d)' % dim
        raise ValueError(msg)

    ndidx = nm.where(nodemtx)
    coors = nm.array(ndidx).transpose() * dims
    nnod = coors.shape[0]

    nodeid = -nm.ones(nddims, dtype=nm.int32)
    nodeid[ndidx] = nm.arange(nnod)

    # generate elements
    if dim == 2:
        elems = nm.array([nodeid[ix,iy],
                          nodeid[ix + 1,iy],
                          nodeid[ix + 1,iy + 1],
                          nodeid[ix,iy + 1]]).transpose()

    elif dim == 3:
        elems = nm.array([nodeid[ix,iy,iz],
                          nodeid[ix + 1,iy,iz],
                          nodeid[ix + 1,iy + 1,iz],
                          nodeid[ix,iy + 1,iz],
                          nodeid[ix,iy,iz + 1],
                          nodeid[ix + 1,iy,iz + 1],
                          nodeid[ix + 1,iy + 1,iz + 1],
                          nodeid[ix,iy + 1,iz + 1]]).transpose()

    if etype == 't':
        elems = elems_q2t(elems)

    eid = etype + str(dim)
    eltab = {'q2': 4, 'q3': 8, 't2': 3, 't3': 4}

    mesh = Mesh.from_data('voxel_data',
                          coors, nm.ones((nnod,), dtype=nm.int32),
                          {0: nm.ascontiguousarray(elems)},
                          {0: nm.ones((nel,), dtype=nm.int32)},
                          {0: '%d_%d' % (dim, eltab[eid])})

    return mesh
Beispiel #33
0
def gen_mesh_from_voxels(voxels, dims, etype='q'):
    """
    Generate FE mesh from voxels (volumetric data).

    Parameters
    ----------
    voxels : array
        Voxel matrix, 1=material.
    dims : array
        Size of one voxel.
    etype : integer, optional
        'q' - quadrilateral or hexahedral elements
        't' - triangular or tetrahedral elements
    Returns
    -------
    mesh : Mesh instance
        Finite element mesh.
    """

    dims = dims.squeeze()
    dim = len(dims)
    nddims = nm.array(voxels.shape) + 2

    nodemtx = nm.zeros(nddims, dtype=nm.int32)

    if dim == 2:
        #iy, ix = nm.where(voxels.transpose())
        iy, ix = nm.where(voxels)
        nel = ix.shape[0]

        if etype == 'q':
            nodemtx[ix, iy] += 1
            nodemtx[ix + 1, iy] += 1
            nodemtx[ix + 1, iy + 1] += 1
            nodemtx[ix, iy + 1] += 1

        elif etype == 't':
            nodemtx[ix, iy] += 2
            nodemtx[ix + 1, iy] += 1
            nodemtx[ix + 1, iy + 1] += 2
            nodemtx[ix, iy + 1] += 1
            nel *= 2

    elif dim == 3:
        #iy, ix, iz = nm.where(voxels.transpose(1, 0, 2))
        iy, ix, iz = nm.where(voxels)
        nel = ix.shape[0]

        if etype == 'q':
            nodemtx[ix, iy, iz] += 1
            nodemtx[ix + 1, iy, iz] += 1
            nodemtx[ix + 1, iy + 1, iz] += 1
            nodemtx[ix, iy + 1, iz] += 1
            nodemtx[ix, iy, iz + 1] += 1
            nodemtx[ix + 1, iy, iz + 1] += 1
            nodemtx[ix + 1, iy + 1, iz + 1] += 1
            nodemtx[ix, iy + 1, iz + 1] += 1

        elif etype == 't':
            nodemtx[ix, iy, iz] += 6
            nodemtx[ix + 1, iy, iz] += 2
            nodemtx[ix + 1, iy + 1, iz] += 2
            nodemtx[ix, iy + 1, iz] += 2
            nodemtx[ix, iy, iz + 1] += 2
            nodemtx[ix + 1, iy, iz + 1] += 2
            nodemtx[ix + 1, iy + 1, iz + 1] += 6
            nodemtx[ix, iy + 1, iz + 1] += 2
            nel *= 6

    else:
        msg = 'incorrect voxel dimension! (%d)' % dim
        raise ValueError(msg)

    ndidx = nm.where(nodemtx)
    coors = nm.array(ndidx).transpose() * dims
    nnod = coors.shape[0]

    nodeid = -nm.ones(nddims, dtype=nm.int32)
    nodeid[ndidx] = nm.arange(nnod)

    # generate elements
    if dim == 2:
        elems = nm.array([
            nodeid[ix, iy], nodeid[ix + 1, iy], nodeid[ix + 1, iy + 1],
            nodeid[ix, iy + 1]
        ]).transpose()

    elif dim == 3:
        elems = nm.array([
            nodeid[ix, iy, iz], nodeid[ix + 1, iy, iz], nodeid[ix + 1, iy + 1,
                                                               iz],
            nodeid[ix, iy + 1, iz], nodeid[ix, iy, iz + 1], nodeid[ix + 1, iy,
                                                                   iz + 1],
            nodeid[ix + 1, iy + 1, iz + 1], nodeid[ix, iy + 1, iz + 1]
        ]).transpose()

    if etype == 't':
        elems = elems_q2t(elems)

    eid = etype + str(dim)
    eltab = {'q2': 4, 'q3': 8, 't2': 3, 't3': 4}

    mesh = Mesh.from_data('voxel_data', coors, nm.ones(
        (nnod, ), dtype=nm.int32), {0: nm.ascontiguousarray(elems)},
                          {0: nm.ones((nel, ), dtype=nm.int32)},
                          {0: '%d_%d' % (dim, eltab[eid])})

    return mesh
Beispiel #34
0
def dump_to_vtk(filename,
                output_filename_trunk=None,
                step0=0,
                steps=None,
                fields=None,
                linearization=None):
    """Dump a multi-time-step results file into a sequence of VTK files."""
    def _save_step(suffix, out, mesh):
        if linearization is not None:
            output('linearizing...')
            out = _linearize(out, fields, linearization)
            output('...done')
            for key, val in out.iteritems():
                lmesh = val.get('mesh', mesh)
                lmesh.write(output_filename_trunk + '_' + key + suffix,
                            io='auto',
                            out={key: val})
                if hasattr(val, 'levels'):
                    output('max. refinement per group:', val.levels)

        else:
            mesh.write(output_filename_trunk + suffix, io='auto', out=out)

    output('dumping to VTK...')

    io = MeshIO.any_from_filename(filename)
    mesh = Mesh.from_file(filename, io=io)

    if output_filename_trunk is None:
        output_filename_trunk = get_trunk(filename)

    try:
        ts = TimeStepper(*io.read_time_stepper())
        all_steps, times, nts, dts = extract_times(filename)

    except ValueError:
        output('no time stepping info found, assuming single step')

        out = io.read_data(0)
        if out is not None:
            _save_step('.vtk', out, mesh)

        ret = None

    else:
        ts.times = times
        ts.n_step = times.shape[0]

        if steps is None:
            ii0 = nm.searchsorted(all_steps, step0)
            iterator = ((all_steps[ii], times[ii])
                        for ii in xrange(ii0, len(times)))

        else:
            iterator = [(step, ts.times[step]) for step in steps]

        max_step = all_steps.max()
        for step, time in iterator:
            output(ts.format % (step, max_step))
            out = io.read_data(step)
            if out is None: break

            _save_step('.' + ts.suffix % step + '.vtk', out, mesh)

        ret = ts.suffix

    output('...done')
    return ret
Beispiel #35
0
def gen_cylinder_mesh(dims,
                      shape,
                      centre,
                      axis='x',
                      force_hollow=False,
                      is_open=False,
                      open_angle=0.0,
                      non_uniform=False,
                      name='cylinder',
                      verbose=True):
    """
    Generate a cylindrical mesh along an axis. Its cross-section can be
    ellipsoidal.

    Parameters
    ----------
    dims : array of 5 floats
        Dimensions of the cylinder: inner surface semi-axes a1, b1, outer
        surface semi-axes a2, b2, length.
    shape : array of 3 ints
        Shape (counts of nodes in radial, circumferential and longitudinal
        directions) of the cylinder mesh.
    centre : array of 3 floats
        Centre of the cylinder.
    axis: one of 'x', 'y', 'z'
        The axis of the cylinder.
    force_hollow : boolean
        Force hollow mesh even if inner radii a1 = b1 = 0.
    is_open : boolean
        Generate an open cylinder segment.
    open_angle : float
        Opening angle in radians.
    non_uniform : boolean
        If True, space the mesh nodes in radial direction so that the element
        volumes are (approximately) the same, making thus the elements towards
        the outer surface thinner.
    name : string
        Mesh name.
    verbose : bool
        If True, show progress of the mesh generation.

    Returns
    -------
    mesh : Mesh instance
    """
    dims = nm.asarray(dims, dtype=nm.float64)
    shape = nm.asarray(shape, dtype=nm.int32)
    centre = nm.asarray(centre, dtype=nm.float64)

    a1, b1, a2, b2, length = dims
    nr, nfi, nl = shape
    origin = centre - nm.array([0.5 * length, 0.0, 0.0])

    dfi = 2.0 * (nm.pi - open_angle) / nfi
    if is_open:
        nnfi = nfi + 1
    else:
        nnfi = nfi

    is_hollow = force_hollow or not (max(abs(a1), abs(b1)) < 1e-15)

    if is_hollow:
        mr = 0
    else:
        mr = (nnfi - 1) * nl

    grid = nm.zeros((nr, nnfi, nl), dtype=nm.int32)

    n_nod = nr * nnfi * nl - mr
    coors = nm.zeros((n_nod, 3), dtype=nm.float64)

    angles = nm.linspace(open_angle, open_angle + (nfi) * dfi, nfi + 1)
    xs = nm.linspace(0.0, length, nl)
    if non_uniform:
        ras = nm.zeros((nr, ), dtype=nm.float64)
        rbs = nm.zeros_like(ras)
        advol = (a2**2 - a1**2) / (nr - 1)
        bdvol = (b2**2 - b1**2) / (nr - 1)
        ras[0], rbs[0] = a1, b1
        for ii in range(1, nr):
            ras[ii] = nm.sqrt(advol + ras[ii - 1]**2)
            rbs[ii] = nm.sqrt(bdvol + rbs[ii - 1]**2)
    else:
        ras = nm.linspace(a1, a2, nr)
        rbs = nm.linspace(b1, b2, nr)

    # This is 3D only...
    bar = MyBar("       nodes:", verbose=verbose)
    bar.init(n_nod)
    ii = 0
    for ix in range(nr):
        a, b = ras[ix], rbs[ix]
        for iy, fi in enumerate(angles[:nnfi]):
            for iz, x in enumerate(xs):
                grid[ix, iy, iz] = ii
                coors[ii] = origin + [x, a * nm.cos(fi), b * nm.sin(fi)]
                if not (ii % 100):
                    bar.update(ii)
                ii += 1

                if not is_hollow and (ix == 0):
                    if iy > 0:
                        grid[ix, iy, iz] = grid[ix, 0, iz]
                        ii -= 1
    assert_(ii == n_nod)

    n_el = (nr - 1) * nnfi * (nl - 1)
    conn = nm.zeros((n_el, 8), dtype=nm.int32)

    bar = MyBar("       elements:", verbose=verbose)
    bar.init(n_el)
    ii = 0
    for (ix, iy, iz) in cycle([nr - 1, nnfi, nl - 1]):
        if iy < (nnfi - 1):
            conn[ii, :] = [
                grid[ix, iy, iz], grid[ix + 1, iy, iz], grid[ix + 1, iy + 1,
                                                             iz],
                grid[ix, iy + 1, iz], grid[ix, iy, iz + 1], grid[ix + 1, iy,
                                                                 iz + 1],
                grid[ix + 1, iy + 1, iz + 1], grid[ix, iy + 1, iz + 1]
            ]
            ii += 1
        elif not is_open:
            conn[ii, :] = [
                grid[ix, iy, iz], grid[ix + 1, iy, iz], grid[ix + 1, 0, iz],
                grid[ix, 0, iz], grid[ix, iy, iz + 1],
                grid[ix + 1, iy, iz + 1], grid[ix + 1, 0, iz + 1], grid[ix, 0,
                                                                        iz + 1]
            ]
            ii += 1

        if not (ii % 100):
            bar.update(ii)

    mat_id = nm.zeros((n_el, ), dtype=nm.int32)
    desc = '3_8'

    assert_(n_nod == (conn.max() + 1))

    if axis == 'z':
        coors = coors[:, [1, 2, 0]]
    elif axis == 'y':
        coors = coors[:, [2, 0, 1]]

    mesh = Mesh.from_data(name, coors, None, [conn], [mat_id], [desc])
    return mesh
Beispiel #36
0
def solve_eigen_problem1( conf, options ):


    pb = ProblemDefinition.from_conf( conf )
    dim = pb.domain.mesh.dim

    pb.time_update()

    dummy = pb.create_state_vector()

    output( 'assembling lhs...' )
    tt = time.clock()
    mtx_a = eval_term_op( dummy, conf.equations['lhs'], pb,
                       dw_mode = 'matrix', tangent_matrix = pb.mtx_a )
    output( '...done in %.2f s' % (time.clock() - tt) )

    output( 'assembling rhs...' )
    tt = time.clock()
    mtx_b = eval_term_op( dummy, conf.equations['rhs'], pb,
                       dw_mode = 'matrix', tangent_matrix = pb.mtx_a.copy() )
    output( '...done in %.2f s' % (time.clock() - tt) )

    #mtxA.save( 'tmp/a.txt', format='%d %d %.12f\n' )
    #mtxB.save( 'tmp/b.txt', format='%d %d %.12f\n' )
    try:
        n_eigs = conf.options.n_eigs
    except AttributeError:
        n_eigs = mtx_a.shape[0]

    if n_eigs is None:
        n_eigs = mtx_a.shape[0]

##     mtx_a.save( 'a.txt', format='%d %d %.12f\n' )
##     mtx_b.save( 'b.txt', format='%d %d %.12f\n' )
    print 'computing resonance frequencies...'
    eig = Solver.any_from_conf( pb.get_solver_conf( conf.options.eigen_solver ) )
    eigs, mtx_s_phi = eig( mtx_a, mtx_b, conf.options.n_eigs )
    from sfepy.fem.mesh import Mesh
    bounding_box = Mesh.from_file("tmp/mesh.vtk").get_bounding_box()
    # this assumes a box (3D), or a square (2D):
    a = bounding_box[1][0] - bounding_box[0][0]
    E_exact = None
    if options.hydrogen or options.boron:
        if options.hydrogen:
            Z = 1
        elif options.boron:
            Z = 5
        if options.dim == 2:
            E_exact = [-float(Z)**2/2/(n-0.5)**2/4 for n in [1]+[2]*3+[3]*5 +\
                    [4]*8 + [5]*15]
        elif options.dim == 3:
            E_exact = [-float(Z)**2/2/n**2 for n in [1]+[2]*2**2+[3]*3**2 ]
    if options.well:
        if options.dim == 2:
            E_exact = [pi**2/(2*a**2)*x for x in [2, 5, 5, 8, 10, 10, 13, 13,
                17, 17, 18, 20, 20 ] ]
        elif options.dim == 3:
            E_exact = [pi**2/(2*a**2)*x for x in [3, 6, 6, 6, 9, 9, 9, 11, 11,
                11, 12, 14, 14, 14, 14, 14, 14, 17, 17, 17] ]
    if options.oscillator:
        if options.dim == 2:
            E_exact = [1] + [2]*2 + [3]*3 + [4]*4 + [5]*5 + [6]*6
        elif options.dim == 3:
            E_exact = [float(1)/2+x for x in [1]+[2]*3+[3]*6+[4]*10 ]
    if E_exact is not None:
        print "a=%f" % a
        print "Energies:"
        print     "n      exact         FEM      error"

        for i, e in enumerate(eigs):
            from numpy import NaN
            if i < len(E_exact):
                exact = E_exact[i]
                err = 100*abs((exact - e)/exact)
            else:
                exact = NaN
                err = NaN
            print "%d:  %.8f   %.8f  %5.2f%%" % (i, exact, e, err)
    else:
        print eigs
##     import sfepy.base.plotutils as plu
##     plu.spy( mtx_b, eps = 1e-12 )
##     plu.pylab.show()
##     pause()
    n_eigs = eigs.shape[0]

    mtx_phi = nm.empty( (pb.variables.di.ptr[-1], mtx_s_phi.shape[1]),
                       dtype = nm.float64 )
    for ii in xrange( n_eigs ):
        mtx_phi[:,ii] = pb.variables.make_full_vec( mtx_s_phi[:,ii] )

    save = get_default_attr( conf.options, 'save_eig_vectors', None )
    out = {}
    for ii in xrange( n_eigs ):
        if save is not None:
            if (ii > save[0]) and (ii < (n_eigs - save[1])): continue
        aux = pb.state_to_output( mtx_phi[:,ii] )
        key = aux.keys()[0]
        out[key+'%03d' % ii] = aux[key]

    ofn_trunk = options.output_filename_trunk
    pb.domain.mesh.write( ofn_trunk + '.vtk', io = 'auto', out = out )

    fd = open( ofn_trunk + '_eigs.txt', 'w' )
    eigs.tofile( fd, ' ' )
    fd.close()

    return Struct( pb = pb, eigs = eigs, mtx_phi = mtx_phi )