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
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
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.'