Exemple #1
0
def geometry_to_arrays(geobj):
    arrays = [
        Array(type='points', name='vertices', data=geobj.grid_points),
        Array(type='indices', name='elements', data=geobj.grid_elements),
        Array(type='indices', name='domains', data=geobj.grid_domains),
    ]
    return arrays
Exemple #2
0
def fake_meshres():
    return Result(name="fakemesh", type="mesh",
                  arrays=[Array(name='domains', type='elscalar', data=numpy.asarray((33,))),
                          Array(name='vertices', type='points', data=numpy.asarray(((1.,0.,0.),
                                                                                    (0.,1.,0.),
                                                                                    (0.,0.,1.)))),
                          Array(name='elements', type='triangles', data=numpy.asarray(((0,1,2),)))])
Exemple #3
0
def triangle(parents = (),          # wires result
             offsetx = 20*units.mm, # where points are in x
             domains = (109,209,309), # domain index of wires on which to produce a grid of points
             splittings = 6,          # number of time to split the overall triangle 
             embiggenings = 2,        # how many times bigger than the fundamental wire crossing triangle
              **kwds):
    '''
    Produce points inside a triangle defined by the wires as given by
    their domains.

    Enlarge the triangle by the integral embiggening factor.

    Split up the larger triangle into triangular bins by bifurcating
    edges splittings number of times.
    '''

    dom_rays = wires_by_domains(parents[0], domains)    
    vertices = ray_triangle([dr[1] for dr in dom_rays])
    for v in vertices:
        v[0] = offsetx
    vertices = embiggen(vertices, embiggenings)
    top = Triangle((0,1,2), Edges(vertices), splittings)

    arrays = list()
    arrays.append(Array(type='points', name='triangle', data=numpy.vstack(top.points)))
    arrays.append(Array(type='indices', name='elements', data=numpy.vstack(top.leaf_indicies)))
    
    return arrays
Exemple #4
0
def linear_lowlevel(grid, dfun, sol,
           linspaces=[(-1.,1.,10), (-2.,2.,20), (-3.,3.,30)], **kwds):
    '''
    Evaluate the potential on a linear grid space.
    '''
    # "piecewise const/linear space"
    pcspace, plspace = spaces(grid)
    ndim = len(linspaces)
    linspaces = [np.linspace(*ls) for ls in linspaces]
    mgrid = np.meshgrid(*linspaces, indexing='ij')
    points = np.vstack([mgrid[i].ravel() for i in range(ndim)])

    slp_pot = bempp.api.operators.potential.laplace.single_layer(pcspace, points)
    #dlp_pot = bempp.api.operators.potential.laplace.double_layer(plspace, points)
    #u_evaluated = slp_pot*nfun-dlp_pot*dfun
    u_evaluated = slp_pot * sol

    print 'u_evaluated.shape=',u_evaluated.shape, u_evaluated.T[0], points.T[0]
    u_reshaped = u_evaluated.reshape(mgrid[0].shape)
    print 'u_reshaped.shape=',u_reshaped.shape

    dxyz = [(ls[1]-ls[0])/(ls[2]-1) for ls in linspaces]
    u_grad = np.asarray(np.gradient(u_reshaped, *dxyz))

    return [
        Array(type='linspace', name='bins', data = np.asarray(linspaces)),
        Array(type='mgrid', name='domain', data=mgrid),
        Array(type='gscalar', name='scalar', data = u_reshaped),
        Array(type='gvector', name='gradient', data = u_grad),
#        Array(type='points', name='points', data = points.T),
    ]
Exemple #5
0
def cmd_waveforms(ctx, waveform, velocity, current, name):
    '''
    Convert steps to electrode current as a function of time
    '''
    import larf.store
    import larf.config
    from larf.models import Result, Array

    if not waveform:
        waveform = name

    cfg = ctx.obj['cfg']
    tocall = larf.config.methods_params(cfg, 'waveform %s' % waveform)

    ses = ctx.obj['session']
    velores = larf.store.result_typed(ses, 'velocity', velocity)
    varrs = velores.array_data_by_type()
    velo = varrs['gvector']
    vgrid = varrs['mgrid']

    curres= larf.store.result_typed(ses, 'raster', current)
    carr = curres.array_data_by_type()
    cfield = carr['gscalar']
    cgrid = carr['mgrid']
    
    if velo[0].shape != cfield.shape:
        click.error("Velocity and current fields have incompatible shapes.")
        return 1
    if not numpy.all(vgrid == cgrid):
        click.error("Velocity and current fields have incompatible grids.")
        return 1

    # fixme: allow multiple
    methname, params = tocall[0]
    meth = larf.util.get_method(methname)
    par = ctx.obj['params']
    params.update(par)

    pts, waveforms = meth(velo, cfield, vgrid, **params)
    res = Result(name=name, type='waveforms', parents=[velores, curres],
                 params=dict(method=methname, params=params),
                 arrays=[
                     Array(name='points', type='path', data=pts),
                     Array(name='current', type='pscalar', data=waveforms)]) # fixme, pscalar is wrong type
    ses.add(res)
    ses.flush()
    resid = res.id
    ses.commit()
    announce_result('waveforms', res)

    return
Exemple #6
0
def cmd_oldcurrent(ctx, stepping, weight, charge, name):
    '''
    Produce currents along steps.
    '''
    from larf.models import Result, Array
    from larf.vector import Scalar
    from larf.util import mgrid_to_linspace
    import larf.current

    ses = ctx.obj['session']

    sres= larf.store.result_typed(ses, 'stepping', stepping)

    wres= larf.store.result_typed(ses, 'raster', weight)
    warr = wres.array_data_by_type()
    linspaces = mgrid_to_linspace(warr['mgrid'])
    weight = Scalar(warr['gscalar'], linspaces)

    # fixme: this needs to go in a module with the usual "tocall" pattern.
    arrays = list()
    for pname, path in sorted(sres.array_data_by_name().items()):
        wf = larf.current.stepwise(weight, path, charge)
        arrays.append(Array(name=pname, type='pscalar', data=wf))

    res = Result(name=name, type='current', parents=[sres, wres],
                 params=dict(),
                 arrays=arrays)
    ses.add(res)
    ses.flush()
    ses.commit()
    announce_result('current', res)
    return
Exemple #7
0
def cmd_stepfilter(ctx, stepfilter, stepping, name):
    import larf.store
    from larf.models import Result, Array

    if stepfilter is None:
        stepfilter = name

    cfg = ctx.obj['cfg']
    tocall = larf.config.methods_params(cfg, 'stepfilter %s' % stepfilter)
    
    ses = ctx.obj['session']
    stepres= larf.store.result_typed(ses, 'stepping', stepping)
    arrays = [(a.name, a.data) for a in stepres.arrays]

    calls = list()
    par = ctx.obj['params']
    for methname, params in tocall:
        meth = larf.util.get_method(methname)
        params.update(par)
        calls.append(dict(method=methname, params=params))
        arrays = meth(arrays, **params)


    sarrays = [Array(type='path', name=n, data=a) for n,a in arrays]
    res = Result(name=name, type='stepping', parents=[stepres], params = calls, arrays = sarrays)
    ses.add(res)

    ses.flush()
    resid = res.id
    ses.commit()
    announce_result('stepfilter', res)
Exemple #8
0
def result_to_velocity(result, temperature=89 * units.Kelvin, **kwds):
    '''
    Return an N-field matrix calculated assuming result holds a potential.
    '''
    arrs = result.array_data_by_type()
    field = arrs['gvector']  # N-D array of scalar potential values
    mgrid = arrs['mgrid']  # forward to output

    mag = numpy.sqrt(field[0]**2 + field[1]**2 + field[2]**2)
    mu = mobility(mag, temperature)
    velo = mu * field

    from larf.models import Array
    return [
        Array(name='domain', type='mgrid', data=mgrid),
        Array(name='velocity', type='gvector', data=numpy.asarray(velo))
    ]
Exemple #9
0
def scalar(parents=(), potential="drift", **kwds):
    '''
    Solve Nuemann boundary condition using pure scalar calculation.
    '''
    kwds = knobs(**kwds)  # set BEM++ accuracy knobs

    sres = parents[0]
    grid = larf.surface.grid(sres)

    DirichletClass = get_method("larf.potentials.%s" % potential)
    dirichlet_data = DirichletClass(**kwds)
    dfunarr, nfunarr = larf.solve.boundary_functions(grid, dirichlet_data)

    arrays = [
        Array(type='scalar', name='dirichlet', data=dfunarr),
        Array(type='scalar', name='neumann', data=nfunarr),
    ]
    return arrays
Exemple #10
0
def cmd_copy_boundary(ctx, boundary, name):
    '''
    Read in boundary and its grid and save a copy under a new name.

    This is meant for testing.
    '''
    from larf.models import Result, Array
    import larf.mesh
    import bempp.api

    ses = ctx.obj['session']

    old_potres = larf.store.result_typed(ses, 'boundary', boundary)
    potarrs = old_potres.array_data_by_name()

    old_meshres = old_potres.parent_by_type('mesh')
    grid = larf.mesh.result_to_grid(old_meshres)

    dfun = bempp.api.GridFunction(grid, coefficients = potarrs['dirichlet'])
    nfun = bempp.api.GridFunction(grid, coefficients = potarrs['neumann'])

    lv = grid.leaf_view
    
    meshres = Result(name=name, type='mesh',
                     params = old_meshres.params,
                     arrays = [
                         Array(type='elscalar', name='domains', data=lv.domain_indices),
                         Array(type='points', name='points', data=lv.vertices.T),
                         Array(type='triangles', name='triangles', data=lv.elements.T),
                     ])
    ses.add(meshres)
    ses.flush()
    announce_result('mesh', meshres)

    potres = Result(name=name, type='boundary', parents=[meshres],
                    params=old_meshres.params,
                    arrays = [
                        Array(name='dirichlet', type='ptscalar', data=dfun.coefficients),
                        Array(name='neumann', type='elscalar', data=nfun.coefficients),
                    ])
    ses.add(potres)
    ses.flush()
    announce_result('boundary', potres)
    ses.commit()
Exemple #11
0
def combine_arrays(*triplets):
    '''
    Give a list of triplet of (vertices, elements, domains) Arrays,
    return a single triplet of Arrays which combine each taking care
    to renumber the element indices.
    '''

    pts = list()
    ele = list()
    dom = list()
    point_offset = 0
    for p, e, d in triplets:
        pts.append(p.data)
        ele.append(e.data + point_offset)
        point_offset += len(p.data)
        dom.append(d.data)
    arrays = [
        Array(type='points', name='vertices', data=numpy.vstack(pts)),
        Array(type='indices', name='elements', data=numpy.vstack(ele)),
        Array(type='indices', name='domains', data=numpy.hstack(dom)),
    ]
    return arrays
Exemple #12
0
def cmd_velocity(ctx, method, raster, name):
    '''
    Calculation a velocity vector field.
    '''
    from larf.models import Result, Array
    from larf.util import mgrid_to_linspace

    if method == 'drift':       # pretend like I actually give an option!
        methname = 'larf.drift.velocity'
    else:
        click.echo('Unknown velocity calculation method: "%s"' % method)
        return 1

    ses = ctx.obj['session']
    import larf.store
    potres = larf.store.result_typed(ses, 'raster', raster)
    arrs = potres.array_data_by_type()
    potential = arrs['gscalar']
    mgrid = arrs['mgrid']
    linspaces = mgrid_to_linspace(mgrid, expand = False)


    import larf.util
    meth = larf.util.get_method(methname)
    par = ctx.obj['params']
    velo = meth(potential, linspaces, **par)

    res = Result(name=name, type='velocity', parents=[potres],
                 params=dict(method=methname, params=par),
                 arrays = [
                     Array(name='domain', type='mgrid', data=mgrid),
                     Array(name='velocity', type='gvector', data = numpy.asarray(velo))])
    ses.add(res)
    ses.flush()
    resid = res.id
    ses.commit()
    announce_result('velocity', res)
Exemple #13
0
def cmd_oldboundary(ctx, boundary, mesh, name):
    '''
    Solve surface boundary potentials.
    '''
    import larf.bem
    import larf.solve
    cfg = ctx.obj['cfg']
    tocall = larf.config.methods_params(cfg, 'boundary %s' % boundary)
    methname, methparams = tocall[0] # just first

    methparams = larf.bem.knobs(**methparams)


    import larf.config
    import larf.util
    import larf.mesh
    from larf.models import Result, Array

    if not boundary:
        boundary = name

    ses = ctx.obj['session']
    meshres = larf.store.result_typed(ses, 'mesh', mesh)
    grid = larf.mesh.result_to_grid(meshres)


    par = ctx.obj['params']
    methparams.update(**par)
    meth = larf.util.get_method(methname)

    dirichlet_data = meth(**methparams)
    #print dirichlet_data
    
    #dfun, nfun = larf.solve.boundary_functions(grid, dirichlet_data)
    tna = larf.solve.boundary_functions(grid, dirichlet_data)
    arrays = [Array(name=n, type=t, data=a) for t,n,a in tna]
#                     Array(name='dirichlet', type='ptscalar', data=dfun.coefficients),
#                     Array(name='neumann', type='elscalar', data=nfun.coefficients),

    res = Result(name=name, type='boundary', parents=[meshres],
                 params=dict(method=methname, params=methparams),
                 arrays = arrays)
    ses.add(res)
    ses.flush()
    #click.echo("produced solution result #%d" % res.id)
    ses.commit()
    announce_result('boundary', res)
    return
Exemple #14
0
def wires(parents=(),           # wire result
          offsetx = 20*units.mm, # where points are in x
          domains = (109,209,309), # domain index of wires on which to produce a grid of points
          long_step = 1*units.mm, # longitudinal step size of grid
          long_hheight = 10*units.cm, # half-height of grid in direction along wire
          long_offset = 0.0,          # offset for grid in longitudinal direction
          perp_step = 1*units.mm, # perpendicular step size of grid
          perp_hheight= 10*units.cm, # half-height of grid in direction perpendicular to wire
          perp_offset = 0.0,         # offset for grid in perpendicular direction
          **kwds):
    '''
    Return N_point x 4 array of 4-points on grids based on wire
    locations.

    For each wire plane in the parent wire result, produce points
    which are on a rectangular grid aligned with the wire direction
    and pitch.  One array for each plane is returned.
    '''

    origin = numpy.asarray((offsetx, 0.0, 0.0))

    def aligned_grid(tail, head):
        center = 0.5*(head+tail)
        vec = head-tail
        length = math.sqrt(numpy.dot(vec,vec))
        longv = vec/length
        perpv = numpy.cross((1.,0.,0.), longv)
        points = list()
        for l in numpy.linspace(-long_hheight, long_hheight, 1 + 2*long_hheight/long_step):
            vl = origin + (l+long_offset)*longv
            row = list()
            for p in numpy.linspace(-perp_hheight, perp_hheight, 1 + 2*perp_hheight/perp_step):
                point = vl + (p+perp_offset)*perpv
                row.append(point)
            points.append(row)
        return numpy.asarray(points)
                    

    center_wires = wires_by_domains(parents[0], domains)
    
    arrays = list()
    for dom, wire in center_wires:
        points = aligned_grid(*wire)
        arrays.append(Array(type='points', name='domain%03d'%dom, data=points))

    return arrays
Exemple #15
0
def cmd_step(ctx, step, velocity, name):
    '''
    Step through a velocity field.
    '''
    import larf.store
    from larf.models import Result, Array

    if step is None:
        step = name

    cfg = ctx.obj['cfg']
    tocall = larf.config.methods_params(cfg, 'step %s' % step)
    
    ses = ctx.obj['session']
    velores= larf.store.result_typed(ses, 'velocity', velocity)
    varr = velores.array_data_by_type()
    vfield = varr['gvector']
    mgrid = varr['mgrid']

    par = ctx.obj['params']
    all_steps = list()
    
    arrays = list()
    calls = list()
    for methname, params in tocall:

        meth = larf.util.get_method(methname)
        params.update(par)
        calls.append(dict(method=methname, params=params))

        arrays += meth(vfield, mgrid, **params)


    sarrays = [Array(type='path', name=n, data=a) for n,a in arrays]

    res = Result(name=name, type='stepping', parents=[velores], params = calls, arrays = sarrays)
    ses.add(res)

    ses.flush()
    resid = res.id
    ses.commit()
    announce_result('steps', res)
    return
Exemple #16
0
def line(parents=None,          # no parents
         point = (20*units.mm, 0*units.mm, 0*units.mm), # starting point for line
         direction = (0.0, 0.0, 1.0*units.mm),          # direction of line
         step = 1*units.mm,                             # step size between points
         length = 1*units.cm,                           # length of line
         **kwds):
    '''
    Return N_point x 4 array of 4-points on a line
    '''
    center = numpy.asarray(point)
    direction = numpy.asarray(direction)

    points = list()
    row = list()
    for dist in numpy.linspace(0, length, 1 + length/step, endpoint=True):
        pt = center + dist*direction
        row.append(pt)
    points.append(row)
    return Array(type='points', name='line', data=numpy.asarray(points))
Exemple #17
0
def cmd_oldrogue(ctx, drift_boundary, rogue, name):
    '''
    Make paths through a dark and dangerous dungeon.
    '''
    import larf.bem

    cfg = ctx.obj['cfg']
    tocall = larf.config.methods_params(cfg, 'rogue %s' % rogue)
    methname, params = tocall[0] # eg: larf.rogue.patch

    params = larf.bem.knobs(**params)

    import larf.store
    import larf.boundary
    from larf.models import Result, Array
    import bempp.api
    from larf.raster import Points

    if rogue is None:
        rogue = name

    ses = ctx.obj['session']
    bres = larf.store.result_typed(ses, 'boundary', drift_boundary)

    # fixme: this unpacking really depends on vagaries of the order in
    # which arrays were saved in the result.  Brittle!
    potential = Points(*larf.boundary.result_to_grid_funs(bres))


    meth = larf.util.get_method(methname)
    par = ctx.obj['params']
    params.update(par)
    type_name_paths = meth(potential, **params)
    
    sarrays = [Array(type=t, name=n, data=a) for t,n,a in type_name_paths]
    res = Result(name=name, type='stepping', parents=[bres], params = params, arrays = sarrays)
    ses.add(res)

    ses.flush()
    ses.commit()
    announce_result('rogue', res)
    return
Exemple #18
0
def scalar(parents=(), **kwds):
    '''
    Evaluate potential on volumes.
    '''
    kwds = knobs(**kwds)  # set BEM++ accuracy knobs

    bres = parents[0]
    vreses = parents[1:]
    grid, dfun, nfun = result_to_grid_funs(bres)
    pcspace, plspace = spaces(grid)

    arrays = list()
    for vres in vreses:
        points = vres.array_data_by_type()['points']
        npoints = len(points)
        points = points.T
        slp_pot = bempp.api.operators.potential.laplace.single_layer(
            pcspace, points)
        pot = slp_pot * nfun
        arrays.append(Array(type='scalar', name=vres.name, data=pot.T))
    return arrays
Exemple #19
0
def cmd_dqdt(ctx, stepping, boundary, charge, name):
    '''
    Produce currents along steps using dQ/dt method
    '''
    from larf.models import Result, Array
    from larf.util import mgrid_to_linspace
    from larf.raster import Points
    from larf.boundary import result_to_grid_funs
    import bempp.api
    import larf.mesh
    import larf.raster

    ses = ctx.obj['session']

    sres= larf.store.result_typed(ses, 'stepping', stepping)

    bres= larf.store.result_typed(ses, 'boundary', boundary)
    barrs = bres.array_data_by_name()
    weight = Points(*result_to_grid_funs(bres))

    arrays = list()
    for typ,nam,arr in sorted(sres.triplets()):
        if typ != "path":
            continue

        points = arr[:,:3]
        times = arr[:,3]
        weights = weight(*points)
        dqdt = charge * (weights[1:] - weights[:-1])/(times[1:] - times[:-1])
        dqdt = numpy.hstack(([0], dqdt)) # gain back missed point
        print nam, dqdt.shape
        arrays.append(Array(name=nam, type='pscalar', data=dqdt))

    res = Result(name=name, type='current', parents=[sres, bres],
                 params=dict(), arrays=arrays)
    ses.add(res)
    ses.flush()
    ses.commit()
    announce_result('current', res)
    return
Exemple #20
0
def wireplanes(parents=(),
               radius_linspace=(0.30 * mm, 2.10 * mm, 13),
               nsegments_linspace=(9, 21, 13),
               **kwds):
    '''
    Produce a lot of points near wire surfaces and less so as we go away
    '''
    wrayres = parents[0]
    wrays = wrayres.get_matching(type='rays')

    points = list()
    for radius, nsegments in zip(numpy.linspace(*radius_linspace),
                                 numpy.linspace(*nsegments_linspace)):
        for params, wires in zip(wrayres.params, wrays):
            params = dict(params['params'], nsegments=nsegments)
            orig_radius = params.pop('radius')
            delta_radius = radius - orig_radius
            print orig_radius, delta_radius
            wires = enlarge_rays(wires, delta_radius)
            plane = WirePlane(radius, wires, **params)
            points.append(plane.grid_points)
    return [Array(type='points', name='volume', data=numpy.vstack(points))]
Exemple #21
0
def combine_arrays(*arrs):
    return [
        Array(type='points',
              name='volume',
              data=numpy.vstack([a[0].data for a in arrs]))
    ]
Exemple #22
0
def cmd_mesh(ctx, mesh, name):
    '''
    Produce a mesh.

    Result is stored with given name.  

    If no explicit "[mesh]" configuration file section is given then
    the one with the same name as supplied for the result is tried.

    '''
    import larf.util
    from larf.models import Array, Result

    if not mesh:
        mesh = name

    cfg = ctx.obj['cfg']        

    tocall = larf.config.methods_params(cfg, 'mesh %s' % mesh, recurse_key = 'meshes')

    calls = list()
    molist = list()

    geometry_data = list()

    for methname,params in tocall:
        meth = larf.util.get_method(methname)
        calls.append(dict(method=methname, params=params))
        mo = meth(**params)
        if not type(mo) == list:
            mo = [mo]

        first = len(molist)+1
        last = first + len(mo)-1
        print "%s produces domain %d-%d, inclusive." % (methname, first, last)
        print "\tdomains: %s" % (', '.join(['%d'%m.domain for m in mo]), )
        molist += mo
        
    from larf.mesh import Scene
    scene = Scene()
    for mo in molist:
        scene.add(mo)
        try:
            geometry_data.append(mo.geometry_data)
        except AttributeError:
            pass


    grid = scene.grid()
    lv = grid.leaf_view

    arrays = [
        Array(type='elscalar', name='domains', data=lv.domain_indices),
        Array(type='points', name='points', data=lv.vertices.T),
        Array(type='triangles', name='triangles', data=lv.elements.T),
    ]
    if geometry_data:
        arrays.append(Array(type='wiregeo', name='wires', data=numpy.asarray(geometry_data)))

    res = Result(name=name, type='mesh', params = calls, arrays = arrays)
    ses = ctx.obj['session']
    ses.add(res)
    ses.flush()
    ses.commit()

    #click.echo("produced mesh result #%d: %d domains, %d points, %d triangles" % \
    # (res.id, len(set(lv.domain_indices)), len(lv.vertices.T), len(lv.elements.T)))
    announce_result('mesh', res)
    return
Exemple #23
0
def drift(
    parents=(),  # boundary, wires, points
    start_time=0.0,
    gradlcar=10 * units.um,
    steptime=0.1 * units.us,
    stuck=1 * units.um,
    maxiter=300,
    maxtime=30 * units.us,
    stop_radius=0.2 * units.mm,
    temperature=89 * units.Kelvin,
    namepat="{source}-{count:05d}",  # pattern to name path arrays
    stepper='rkck',
    batch_paths=100,  # max number of paths to run in parallel, not including x7 at each step for gradient
    **kwds):
    '''
    From parent results (boundary, wires, points) return paths stepped
    through drift field given by boundary starting at given points and
    until hitting on of the wires or other halt conditions.  A
    collection of (name, path) pairs are returned.  Each path is a
    numpy array of ( (x,y,z), (vx,vy,vz), (ex,ey,ez), t).
    '''
    kwds = knobs(**kwds)

    bres, wres, pres = parents

    wire_arrays = [a.data for a in wres.arrays]
    print[a.shape for a in wire_arrays]
    stop = StopStepping(stuck, stop_radius, *wire_arrays)

    potential = Points(*result_to_grid_funs(bres))
    efield = BatchedGradientFunction(potential, gradlcar)
    velo = BatchedVelocity(efield, temperature)

    if stepper == 'rkck':
        stepper = BatchedStepper_rkck(velo)
    if stepper == 'jump':
        stepper = BatchedStepper_jump(velo)

    points = list()
    point_set_desc = list()
    for typ, nam, arr in pres.triplets():
        if typ != 'points':
            continue
        point_set_desc.append((nam, arr.size / 3))
        points.append(numpy.vstack(arr))

    points = numpy.vstack(points)
    npoints = len(points)
    times = numpy.asarray([start_time] * npoints)
    points = numpy.hstack((points, times.reshape(npoints, 1)))

    batches = larf.points.batch(points, batch_paths)

    paths = list()
    for batch in batches:
        print "Stepping batch of %d paths" % len(batch)

        all_paths = [[p] for p in batch]
        active_paths = list(all_paths)

        tips = batch
        for istep in range(maxiter):
            if 0 == len(tips):
                break
            if 0 == len(active_paths):
                break
            print "step %d/%d with %d paths, %d points" % (
                istep, maxiter, len(active_paths), len(tips))
            print "batch[0] tip point: %s" % tips[0]
            next_points = stepper(steptime, tips)
            tips, active_paths = step_maybe(active_paths, next_points, stop)
            if len(points) <= 0:
                break
            if points[0, 3] > maxtime:
                break
        paths += all_paths

    arrays = list()
    for name, size in point_set_desc:
        for ipt in range(size):
            print name, size, ipt, len(paths)
            path = paths.pop(0)
            aname = namepat.format(count=ipt, source=name)
            array = Array(type='path', name=aname, data=numpy.asarray(path))
            arrays.append(array)

    extra = [
        ('points', 'potential_points', efield.scalar_points),
        ('pscalar', 'potential', efield.scalars),
        ('points', 'gradient_points', efield.gradient_points),
        ('ptuple', 'gradient', efield.gradients),
        ('points', 'velocity_points', velo.points),
        ('ptuple', 'velocity', velo.velocities),
    ]
    for t, n, a in extra:
        arrays.append(Array(type=t, name=n, data=numpy.asarray(a)))

    return arrays
Exemple #24
0
def dqdt(parents=(), charge=1,
         batch_paths = 100, # max number of paths to run in parallel, not including x7 at each step for gradient
         **kwds):
    '''
    Using the dQ/dt method and for the weight given by the "boundary"
    parent and for each path in the "drift" parent result, produce
    instantaneous current waveforms.
    '''
    bres, dres = parents
    
    weight = Points(*result_to_grid_funs(bres))

    path_points = list()
    path_lengths = list()
    path_names = list()
    for typ,nam,arr in sorted(dres.triplets()):
        if typ != "path":
            continue
        path_points.append(arr)
        path_lengths.append(len(arr))
        path_names.append(nam)

    all_points = numpy.vstack(path_points)
        
    batches = larf.points.batch(all_points, batch_paths)
    nbatches = len(batches)
    print '%d batches' % nbatches

    all_weights = list()
    for count, batch in enumerate(batches):
        points = batch[:,:3]
        times = batch[:,3]
        weights = weight(*points)
        print 'batch %d/%d batch=%s pts=%s times=%s weights=%s' % \
            (count, nbatches, batch.shape, points.shape, times.shape, weights.shape)
        all_weights.append(weights)
    all_weights = numpy.hstack(all_weights)
    print 'all weights: %s' % str(all_weights.shape)

    path_weights = list()
    pind = 0
    for plen in path_lengths:
        pweights = all_weights[pind:pind+plen]
        #print 'collate: weights=%s pind=%d plen=%d' % (pweights.shape, pind, plen)
        pind += plen
        path_weights.append(pweights)

    assert len(path_points) == len(path_weights)

    arrays = list()
    for count, (path, weights, nam) in enumerate(zip(path_points, path_weights, path_names)):
        points = path[:,:3]
        times = path[:,3]
        print 'zip %d pts=%s times=%s weights=%s' % (count, points.shape, times.shape, weights.shape)

        dqdt = charge * (weights[1:] - weights[:-1])/(times[1:] - times[:-1])
        dqdt = numpy.hstack(([0], dqdt)) # gain back missed point
        print nam, dqdt.shape
        arrays.append(Array(name=nam, type='pscalar', data=dqdt))
        

    # arrays = list()
    # for typ,nam,arr in sorted(dres.triplets()):
    #     if typ != "path":
    #         continue

    #     points = arr[:,:3]
    #     times = arr[:,3]
    #     weights = weight(*points)
    #     dqdt = charge * (weights[1:] - weights[:-1])/(times[1:] - times[:-1])
    #     dqdt = numpy.hstack(([0], dqdt)) # gain back missed point
    #     print nam, dqdt.shape
    #     arrays.append(Array(name=nam, type='pscalar', data=dqdt))

    return arrays
Exemple #25
0
def fake_boundres():
    meshres = fake_meshres()
    return Result(name="fakeboundary", type="boundary",
                  arrays=[Array(name='dirichlet', type='ptscalar', data=numpy.asarray((6.9, 42, 3.1415))),
                          Array(name='neumann', type='elscalar', data=numpy.asarray((42,)))],
                  parents = [meshres])