Exemple #1
0
def fix_double_nodes( coor, conns, eps ):
    n_nod, dim = coor.shape
    cmap = find_map( coor, nm.zeros( (0,dim) ), eps = eps, allow_double = True )
    if cmap.size:
        print 'double nodes in input mesh!'
        print 'trying to fix...'

        while cmap.size:
            print cmap.size

            # Just like in Variable.equation_mapping()...
            ii = nm.argsort( cmap[:,1] )
            scmap = cmap[ii]

            eq = nm.arange( n_nod )
            eq[scmap[:,1]] = -1
            eqi = eq[eq >= 0]
            eq[eqi] = nm.arange( eqi.shape[0] )
            remap = eq.copy()
            remap[scmap[:,1]] = eq[scmap[:,0]]
            print coor.shape
            coor = coor[eqi]
            print coor.shape
            ccs = []
            for conn in conns:
                ccs.append( remap[conn] )
            conns = ccs
            cmap = find_map( coor, nm.zeros( (0,dim) ), eps = eps,
                            allow_double = True )
        print '...done'
    return coor, conns
Exemple #2
0
def match_grid_plane( coor1, coor2, which ):
    """
    Match coordinates `coor1` with `coor2` along the plane with normal axis
    `which`.
    """
    from sfepy.fem.mesh import find_map
    
    if coor1.shape != coor2.shape:
        raise ValueError, 'incompatible shapes: %s == %s'\
              % ( coor1.shape, coor2.shape)

    offset = coor1[0,which] - coor2[0,which]
    aux = coor2.copy()
    aux[:,which] += offset
    i1, i2 = find_map( coor1, aux, join = False )

    if i1.shape[0] != coor1.shape[0]:
        print coor1[i1]
        print coor2[i2]
        print nm.abs(coor1[i1] - coor2[i2]).max(0)
        ii = nm.setdiff1d(nm.arange(coor1.shape[0]), i1)
        print coor1[ii]
        print coor2[ii]
        raise ValueError('cannot match nodes!')

    return i1, i2
Exemple #3
0
def test():
    x1 = nm.fix( nm.random.rand( 5, 3 ) * 5 ) / 10
    x2 = nm.fix( nm.random.rand( 10, 3 ) * 5 ) / 10
    cmap = find_map( x1, x2 )
    conn1 = nm.array( [[range( 5 )], [range( 5 )]] ).squeeze()
    conn2 = nm.array( [[range( 10 )], [range( 10 )]] ).squeeze()
    conn2.shape = (4, 5)

    print x1
    print conn1
    print x2
    print conn2
    print cmap
    xx, conns = merge_mesh( x1, [conn1], x2, [conn2], cmap )
    print xx
    print conns
Exemple #4
0
def match_grid_plane(coor1, coor2, which):
    from sfepy.fem.mesh import find_map

    if coor1.shape != coor2.shape:
        raise ValueError, "incompatible shapes: %s == %s" % (coor1.shape, coor2.shape)

    offset = coor1[0, which] - coor2[0, which]
    aux = coor2.copy()
    aux[:, which] += offset
    i1, i2 = find_map(coor1, aux, join=False)

    if i1.shape[0] != coor1.shape[0]:
        print "cannot match nodes\n(%s,\n %s)" % (coor1[i1], coor2[i2])
        print i1
        print coor1
        print i2
        print coor2
        raise ValueError

    return i1, i2
Exemple #5
0
def match_coors(coors1, coors2):
    """
    Match coordinates `coors1` with `coors2`.
    """
    if coors1.shape != coors2.shape:
        raise ValueError('incompatible shapes: %s == %s' %
                         (coors1.shape, coors2.shape))

    i1, i2 = find_map(coors1, coors2, join=False)

    if i1.shape[0] != coors1.shape[0]:
        print coors1[i1]
        print coors2[i2]
        print nm.abs(coors1[i1] - coors2[i2]).max(0)
        ii = nm.setdiff1d(nm.arange(coors1.shape[0]), i1)
        print coors1[ii]
        print coors2[ii]
        raise ValueError('cannot match nodes!')

    return i1, i2
Exemple #6
0
def match_coors(coors1, coors2):
    """
    Match coordinates `coors1` with `coors2`.
    """
    if coors1.shape != coors2.shape:
        raise ValueError('incompatible shapes: %s == %s'
                         % (coors1.shape, coors2.shape))

    i1, i2 = find_map(coors1, coors2, join=False)

    if i1.shape[0] != coors1.shape[0]:
        print coors1[i1]
        print coors2[i2]
        print nm.abs(coors1[i1] - coors2[i2]).max(0)
        ii = nm.setdiff1d(nm.arange(coors1.shape[0]), i1)
        print coors1[ii]
        print coors2[ii]
        raise ValueError('cannot match nodes!')

    return i1, i2
Exemple #7
0
def match_grid_plane(coor1, coor2, which):
    """
    Match coordinates `coor1` with `coor2` along the plane with normal axis
    `which`.
    """
    if coor1.shape != coor2.shape:
        raise ValueError, 'incompatible shapes: %s == %s'\
              % ( coor1.shape, coor2.shape)

    offset = coor1[0, which] - coor2[0, which]
    aux = coor2.copy()
    aux[:, which] += offset
    i1, i2 = find_map(coor1, aux, join=False)

    if i1.shape[0] != coor1.shape[0]:
        print coor1[i1]
        print coor2[i2]
        print nm.abs(coor1[i1] - coor2[i2]).max(0)
        ii = nm.setdiff1d(nm.arange(coor1.shape[0]), i1)
        print coor1[ii]
        print coor2[ii]
        raise ValueError('cannot match nodes!')

    return i1, i2
def compose_periodic_mesh(mesh_in, scale, repeat, eps, check_mvd=False):
    """
    Create a new mesh from a periodic mesh by scaling it and repeating
    along each axis,

    Parameters
    ----------
    mesh_in : Mesh instance
        The input periodic mesh.
    scale : float
        The scale parameter.
    repeat : array
        The number of repetitions of `mesh_in` along each axis.
    eps : float
        Tolerance for finding matching mesh vertices.
    check_mvd : bool
        If True, verify periodicity by checking approximate minimum
        vertex distance and minimum edge length.

    Returns
    -------
    mesh_out : Mesh instance
        The composed periodic mesh.
    """
    dim = mesh_in.dim
    bbox = mesh_in.get_bounding_box()
    mscale = bbox[1] - bbox[0]
    output('bbox:\n', bbox)

    centre0 = 0.5 * (bbox[1] + bbox[0])
    output('centre:\n', centre0)

    scale = float(scale)
    if repeat is None:
        repeat = [scale] * dim

    repeat = nm.asarray(repeat)

    # Normalize original coordinates.
    coor0 = (mesh_in.coors - centre0) / (mscale)

    aux = fix_double_nodes(coor0, mesh_in.ngroups, mesh_in.conns, eps)
    coor0, ngroups0, mesh_in.conns = aux
    
    if check_mvd:
        mes0 = get_min_edge_size(coor0, mesh_in.conns)
        mvd0 = get_min_vertex_distance(coor0, mes0)
        if mes0 > (mvd0 + eps):
            output('          original min. "edge" length: %.5e' % mes0)
            output('original approx. min. vertex distance: %.5e' % mvd0)
            output('-> still double nodes in input mesh!')
            output('try increasing eps')
            raise ValueError('cannot fix double nodes!')

    output('composing periodic mesh...')
    for indx in cycle(repeat):
        aindx = nm.array(indx, dtype=nm.float64)
        centre = 0.5 * (2.0 * aindx - repeat + 1.0)
        output(indx, centre)

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

            cmap = find_map(coor, coor1, eps=eps)
            if not cmap.size:
                raise ValueError('non-periodic mesh!')

            else:
                output(cmap.size / 2)

            coor, ngroups, conns = merge_mesh(coor, ngroups, conns,
                                              coor1, ngroups1, conns1,
                                              cmap, eps=eps)

    if check_mvd:
        mes = get_min_edge_size( coor, conns )
        mvd = get_min_vertex_distance( coor, mes0 )

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

    # Renormalize.
    coor = (coor * mscale) / scale
    mesh_out = make_mesh(coor, ngroups, conns, mesh_in)
    output('...done')

    return mesh_out
Exemple #9
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.'