Exemplo n.º 1
0
def vtkDatasetToHdf5(g, name, ds):
    """
    store a vtk dataset ds, formated as vtk file, within a hdf character array dataset.
    The hdf dataset is created with name name under the group g.
  """
    #assert False # lol this is just copy pasted from some old code. needs to be done properly
    #assert type(ds) is vtk.vtkPolyData
    assert ds.GetClassName(
    ) == 'vtkPolyData'  # there needs to be a map from dataset type to writer type. Also the python type does not equal the wrapped c++ type.
    writer = vtk.vtkPolyDataWriter()
    writer.SetInput(ds)
    writer.WriteToOutputStringOn()
    writer.SetFileTypeToASCII()
    writer.Update()
    iso = writer.GetOutputString()
    l = writer.GetOutputStringLength()
    iso = iso[:l]  # iso is a string, but only the content up to l is valid!
    ds = g.create_dataset(name,
                          data=np.fromstring(iso, dtype=np.uint8),
                          compression='gzip',
                          compression_opts=9)
    ds.attrs["TYPE"] = "VTK_FILE"
    ds.attrs["VTK_DATASET_TYPE"] = type(ds).__name__
Exemplo n.º 2
0
    def __init__(self,
                 dataDir='data',
                 streamFileInit='streamInit.vtk',
                 streamFile='stream.vtk',
                 dumpFile='save.vtk',
                 interpolation='weighted',
                 s=[]):
        """
        Maps the streamlines from X to x.
        
        call signature:
        
          mapStream(dataDir = 'data', streamFileInit = 'streamInit.vtk', streamFile = 'stream.vtk', dumpFile = 'save.vtk', interpolation = 'weighted')
          
        Keyword arguments:
        
         *dataDir*:
            Data directory.
            
         *streamFileInit*:
            Read the initial streamline in this file.
        
         *streamFile*:
            Store the streamline in this file.
            
         *dumpFile*:
            Use this file for the mapping x(X,t).
            
         *interpolation*:
            Interpolation of the vector field.
            'mean': takes the mean of the adjacent grid point.
            'weighted': weights the adjacent grid points according to their distance.
            
          *s*:
            The streamlines object for t = 0. If not passed obtain it from 'streamFileInit'.
        """

        # read the stream lines at t = 0
        if (s == []):
            s = gm.readStream(dataDir=dataDir, streamFile=streamFileInit)
        #s = gm.readStream(dataDir = dataDir, streamFile = streamFileInit)
        # convert x0 and y0 into array in case of scalars
        try:
            len(s.x0)
        except:
            s.x0 = np.array([s.x0])
            s.y0 = np.array([s.y0])

        # read the current state
        data = gm.readDump(dataDir=dataDir, fileName=dumpFile)
        p = data.p
        xx = data.grid

        # mapped tracers
        tracersNew = np.zeros(s.tracers.shape, dtype=s.tracers.dtype)

        # interpolate x(X,t) at S to get x(S,t), where S is the initial streamline
        for i in range(len(s.x0)):
            for j in range(len(s.y0)):
                for sl in range(s.sl[i, j]):
                    tracersNew[:, i, j, sl] = vecInt(s.tracers[:, i, j, sl],
                                                     xx, p, interpolation)
        self.x0 = s.x0
        self.y0 = s.y0
        self.sl = s.sl
        self.tracers = tracersNew
        self.p = p
        #self.tracers = s.tracers
        self.sub = s.sub
        self.hMin = s.hMin
        self.hMax = s.hMax
        self.lMax = s.lMax
        self.tol = s.tol
        self.iterMax = s.iterMax

        # save into vtk file
        if (streamFile != []):
            writer = vtk.vtkPolyDataWriter()
            writer.SetFileName(dataDir + '/' + streamFile)
            polyData = vtk.vtkPolyData()
            fieldData = vtk.vtkFieldData()
            # fields containing initial x and y values
            field = VN.numpy_to_vtk(self.x0)
            field.SetName('x0')
            fieldData.AddArray(field)
            field = VN.numpy_to_vtk(self.y0)
            field.SetName('y0')
            fieldData.AddArray(field)
            # field containing length of stream lines for later decomposition
            field = VN.numpy_to_vtk(self.sl)
            field.SetName('sl')
            fieldData.AddArray(field)
            # streamline parameters
            tmp = range(10)
            tmp[0] = np.array([s.sub], dtype='int32')
            field = VN.numpy_to_vtk(tmp[0])
            field.SetName('sub')
            fieldData.AddArray(field)
            tmp[1] = np.array([s.hMin], dtype='float32')
            field = VN.numpy_to_vtk(tmp[1])
            field.SetName('hMin')
            fieldData.AddArray(field)
            tmp[2] = np.array([s.hMax], dtype='float32')
            field = VN.numpy_to_vtk(tmp[2])
            field.SetName('hMax')
            fieldData.AddArray(field)
            tmp[3] = np.array([s.lMax], dtype='float32')
            field = VN.numpy_to_vtk(tmp[3])
            field.SetName('lMax')
            fieldData.AddArray(field)
            tmp[4] = np.array([s.tol], dtype='float32')
            field = VN.numpy_to_vtk(tmp[4])
            field.SetName('tol')
            fieldData.AddArray(field)
            tmp[5] = np.array([s.iterMax], dtype='int32')
            field = VN.numpy_to_vtk(tmp[5])
            field.SetName('iterMax')
            fieldData.AddArray(field)
            # fields containing simulation parameters stored in paramFile
            dic = dir(p)
            params = range(len(dic))
            i = 0
            for attr in dic:
                if (attr[0] != '_'):
                    params[i] = getattr(p, attr)
                    params[i] = np.array([params[i]], dtype=type(params[i]))
                    field = VN.numpy_to_vtk(params[i])
                    field.SetName(attr)
                    fieldData.AddArray(field)
                    i += 1
            # all stremlines as continuous array of points
            points = vtk.vtkPoints()
            for i in range(len(s.x0)):
                for j in range(len(s.y0)):
                    for k in range(self.sl[i, j]):
                        points.InsertNextPoint(self.tracers[:, i, j, k])
            polyData.SetPoints(points)
            polyData.SetFieldData(fieldData)
            writer.SetInput(polyData)
            writer.SetFileTypeToBinary()
            writer.Write()
Exemplo n.º 3
0
    def __init__(self,
                 dataDir='data',
                 B0File='B0.vtk',
                 streamFileInit='streamInit.vtk',
                 paramFile='save.vtk',
                 interpolation='weighted',
                 integration='simple',
                 sub=1,
                 hMin=2e-3,
                 hMax=2e4,
                 lMax=500,
                 tol=1e-2,
                 iterMax=1e3,
                 x0=[],
                 y0=[]):
        """
        Creates, saves and returns the initial streamline map.
        
        call signature:
        
          streamInit(dataDir = 'data', B0File = 'B0.vtk', streamFileInit = 'streamInit.vtk', paramFile = 'save.vtk', interpolation = 'weighted', integration = 'simple', sub = 1, hMin = 2e-3, hMax = 2e2, lMax = 500, tol = 2e-3, iterMax = 1e3, x0 = [], y0 = [])
        
        Trace magnetic streamlines for t = 0 and store the positions in a file.
        
        Keyword arguments:
        
         *dataDir*:
            Data directory.
            
         *B0File*:
            Name of the file storing B(X,0) = B0.
            
         *streamFileInit*:
            Store the streamline in this file. If it is empty [] don't write.
             
         *paramFile*:
            Dump file from where to read the simulation parameters.
             
         *interpolation*:
            Interpolation of the vector field.
            'mean': takes the mean of the adjacent grid point.
            'weighted': weights the adjacent grid points according to their distance.
       
         *integration*:
            Integration method.
            'simple': low order method.
            'RK6': Runge-Kutta 6th order.
       
         *sub*:
            Subsampling of the streamlines.
            
         *hMin*:
            Minimum step length for and underflow to occur.
        
         *hMax*:
            Parameter for the initial step length.
        
         *lMax*:
            Maximum length of the streamline. Integration will stop if l >= lMax.
        
         *tol*:
            Tolerance for each integration step. Reduces the step length if error >= tol.
         
         *iterMax*:
            Maximum number of iterations.     
         
         *x0*:
            Initial seed in x-direction.
            
         *y0*:
            Initial seed in y-direction.
        """

        data = gm.readB0(dataDir=dataDir, fileName=B0File)
        B0 = data.bfield
        p = gm.readParams(dataDir=dataDir, fileName=paramFile)
        self.p = p
        self.p.t = 0

        # streamline parameters
        self.sub = sub
        self.hMin = hMin
        self.hMax = hMax
        self.lMax = lMax
        self.tol = tol
        self.iterMax = iterMax

        # create initial seeds
        if (x0 == []):
            x0 = np.float32(
                np.linspace(p.Ox - p.dx, p.Ox + p.Lx + p.dx,
                            np.round(1 + (2 * p.dx + p.Lx) / p.dx * sub)))
        if (y0 == []):
            y0 = np.float32(
                np.linspace(p.Oy - p.dy, p.Oy + p.Ly + p.dy,
                            np.round(1 + (2 * p.dy + p.Ly) / p.dy * sub)))
        self.x0 = x0
        self.y0 = y0

        try:
            len(x0)
        except:
            x0 = np.array([x0])
            y0 = np.array([y0])

        self.tracers = np.zeros([3, len(x0), len(y0), iterMax],
                                dtype='float32')  # tentative streamline length
        self.sl = np.zeros([len(x0), len(y0)], dtype='int32')

        tol2 = tol**2

        # declare vectors
        xMid = np.zeros(3)
        xSingle = np.zeros(3)
        xHalf = np.zeros(3)
        xDouble = np.zeros(3)

        # initialize the coefficient for the 6th order adaptive time step RK
        a = np.zeros(6)
        b = np.zeros((6, 5))
        c = np.zeros(6)
        cs = np.zeros(6)
        k = np.zeros((6, 3))
        a[1] = 0.2
        a[2] = 0.3
        a[3] = 0.6
        a[4] = 1
        a[5] = 0.875
        b[1, 0] = 0.2
        b[2, 0] = 3 / 40.
        b[2, 1] = 9 / 40.
        b[3, 0] = 0.3
        b[3, 1] = -0.9
        b[3, 2] = 1.2
        b[4, 0] = -11 / 54.
        b[4, 1] = 2.5
        b[4, 2] = -70 / 27.
        b[4, 3] = 35 / 27.
        b[5, 0] = 1631 / 55296.
        b[5, 1] = 175 / 512.
        b[5, 2] = 575 / 13824.
        b[5, 3] = 44275 / 110592.
        b[5, 4] = 253 / 4096.
        c[0] = 37 / 378.
        c[2] = 250 / 621.
        c[3] = 125 / 594.
        c[5] = 512 / 1771.
        cs[0] = 2825 / 27648.
        cs[2] = 18575 / 48384.
        cs[3] = 13525 / 55296.
        cs[4] = 277 / 14336.
        cs[5] = 0.25

        # do the streamline tracing
        r = 0
        for u in x0:
            s = 0
            for v in y0:
                # initialize the streamline
                xx = np.array([u, v, p.Oz])
                self.tracers[:, r, s, 0] = xx
                dh = np.sqrt(hMax * hMin)  # initial step size
                sl = 0
                l = 0
                outside = False

                if (integration == 'simple'):
                    while ((l < lMax) and (xx[2] < p.Oz + p.Lz)
                           and (sl < iterMax - 1) and (not (np.isnan(xx[0])))
                           and (outside == False)):
                        # (a) single step (midpoint method)
                        xMid = xx + 0.5 * dh * gm.vecInt(
                            xx, B0, p, interpolation)
                        xSingle = xx + dh * gm.vecInt(xMid, B0, p,
                                                      interpolation)

                        # (b) two steps with half stepsize
                        xMid = xx + 0.25 * dh * gm.vecInt(
                            xx, B0, p, interpolation)
                        xHalf = xx + 0.5 * dh * gm.vecInt(
                            xMid, B0, p, interpolation)
                        xMid = xHalf + 0.25 * dh * gm.vecInt(
                            xHalf, B0, p, interpolation)
                        xDouble = xHalf + 0.5 * dh * gm.vecInt(
                            xMid, B0, p, interpolation)

                        # (c) check error (difference between methods)
                        dist2 = np.sum((xSingle - xDouble)**2)
                        if (dist2 > tol2):
                            dh = 0.5 * dh
                            if (abs(dh) < hMin):
                                print("Error: stepsize underflow")
                                break
                        else:
                            l += np.sqrt(np.sum((xx - xDouble)**2))
                            xx = xDouble.copy()
                            if (abs(dh) < hMin):
                                dh = 2 * dh
                            sl += 1
                            self.tracers[:, r, s, sl] = xx.copy()
                            if ((dh > hMax) or (np.isnan(dh))):
                                dh = hMax
                            # check if this point lies outside the domain
                            if ((xx[0] < p.Ox - p.dx)
                                    or (xx[0] > p.Ox + p.Lx + p.dx)
                                    or (xx[1] < p.Oy - p.dy)
                                    or (xx[1] > p.Oy + p.Ly + p.dy)
                                    or (xx[2] < p.Oz)
                                    or (xx[2] > p.Oz + p.Lz)):
                                outside = True

                if (integration == 'RK6'):
                    while ((l < lMax) and (xx[2] < p.Oz + p.Lz)
                           and (sl < iterMax) and (not (np.isnan(xx[0])))
                           and (outside == False)):
                        k[0, :] = dh * gm.vecInt(xx, B0, p, interpolation)
                        k[1, :] = dh * gm.vecInt(xx + b[1, 0] * k[0, :], B0, p,
                                                 interpolation)
                        k[2, :] = dh * gm.vecInt(
                            xx + b[2, 0] * k[0, :] + b[2, 1] * k[1, :], B0, p,
                            interpolation)
                        k[3, :] = dh * gm.vecInt(
                            xx + b[3, 0] * k[0, :] + b[3, 1] * k[1, :] +
                            b[3, 2] * k[2, :], B0, p, interpolation)
                        k[4, :] = dh * gm.vecInt(
                            xx + b[4, 0] * k[0, :] + b[4, 1] * k[1, :] +
                            b[4, 2] * k[2, :] + b[4, 3] * k[3, :], B0, p,
                            interpolation)
                        k[5, :] = dh * gm.vecInt(
                            xx + b[5, 0] * k[0, :] + b[5, 1] * k[1, :] +
                            b[5, 2] * k[2, :] + b[5, 3] * k[3, :] +
                            b[5, 4] * k[4, :], B0, p, interpolation)

                        xNew = xx + c[0] * k[0, :] + c[1] * k[1, :] + c[2] * k[
                            2, :] + c[3] * k[3, :] + c[4] * k[4, :] + c[5] * k[
                                5, :]
                        xNewS = xx + cs[0] * k[0, :] + cs[1] * k[
                            1, :] + cs[2] * k[2, :] + cs[3] * k[
                                3, :] + cs[4] * k[4, :] + cs[5] * k[5, :]

                        delta2 = np.dot((xNew - xNewS), (xNew - xNewS))
                        delta = np.sqrt(delta2)

                        if (delta2 > tol2):
                            dh = dh * (0.9 * abs(tol / delta))**0.2
                            if (abs(dh) < hMin):
                                print("Error: step size underflow")
                                break
                        else:
                            l += np.sqrt(np.sum((xx - xNew)**2))
                            xx = xNew
                            if (abs(dh) < hMin):
                                dh = 2 * dh
                            sl += 1
                            self.tracers[:, r, s, sl] = xx
                            if ((dh > hMax) or (np.isnan(dh))):
                                dh = hMax
                            # check if this point lies outside the domain
                            if ((xx[0] < p.Ox - p.dx)
                                    or (xx[0] > p.Ox + p.Lx + p.dx)
                                    or (xx[1] < p.Oy - p.dy)
                                    or (xx[1] > p.Oy + p.Ly + p.dy)
                                    or (xx[2] < p.Oz)
                                    or (xx[2] > p.Oz + p.Lz)):
                                outside = True
                        if ((dh > hMax) or (delta == 0) or (np.isnan(dh))):
                            dh = hMax

                self.sl[r, s] = sl + 1
                s += 1
            r += 1

        # save into vtk file
        if (streamFileInit != []):
            writer = vtk.vtkPolyDataWriter()
            writer.SetFileName(dataDir + '/' + streamFileInit)
            polyData = vtk.vtkPolyData()
            fieldData = vtk.vtkFieldData()
            # fields containing initial x and y values
            field = VN.numpy_to_vtk(self.x0)
            field.SetName('x0')
            fieldData.AddArray(field)
            field = VN.numpy_to_vtk(self.y0)
            field.SetName('y0')
            fieldData.AddArray(field)
            # field containing length of stream lines for later decomposition
            field = VN.numpy_to_vtk(self.sl)
            field.SetName('sl')
            fieldData.AddArray(field)
            # streamline parameters
            tmp = range(10)
            tmp[0] = np.array([sub], dtype='int32')
            field = VN.numpy_to_vtk(tmp[0])
            field.SetName('sub')
            fieldData.AddArray(field)
            tmp[1] = np.array([hMin], dtype='float32')
            field = VN.numpy_to_vtk(tmp[1])
            field.SetName('hMin')
            fieldData.AddArray(field)
            tmp[2] = np.array([hMax], dtype='float32')
            field = VN.numpy_to_vtk(tmp[2])
            field.SetName('hMax')
            fieldData.AddArray(field)
            tmp[3] = np.array([lMax], dtype='float32')
            field = VN.numpy_to_vtk(tmp[3])
            field.SetName('lMax')
            fieldData.AddArray(field)
            tmp[4] = np.array([tol], dtype='float32')
            field = VN.numpy_to_vtk(tmp[4])
            field.SetName('tol')
            fieldData.AddArray(field)
            tmp[5] = np.array([iterMax], dtype='int32')
            field = VN.numpy_to_vtk(tmp[5])
            field.SetName('iterMax')
            fieldData.AddArray(field)
            # fields containing simulation parameters stored in paramFile
            dic = dir(p)
            params = range(len(dic))
            i = 0
            for attr in dic:
                if (attr[0] != '_'):
                    params[i] = getattr(p, attr)
                    params[i] = np.array([params[i]], dtype=type(params[i]))
                    field = VN.numpy_to_vtk(params[i])
                    field.SetName(attr)
                    fieldData.AddArray(field)
                    i += 1
            # all streamlines as continuous array of points
            points = vtk.vtkPoints()
            for r in range(len(x0)):
                for s in range(len(y0)):
                    for sl in range(self.sl[r, s]):
                        points.InsertNextPoint(self.tracers[:, r, s, sl])
            polyData.SetPoints(points)
            polyData.SetFieldData(fieldData)
            writer.SetInput(polyData)
            writer.SetFileTypeToBinary()
            writer.Write()
Exemplo n.º 4
0
    def __init__(self,
                 dataDir='data',
                 poincareInit='poincareInit.vtk',
                 poincare='poincare.vtk',
                 dumpFile='save.vtk',
                 interpolation='weighted',
                 po=[]):
        """
        Maps the streamlines from X to x.
        
        call signature:
        
          mapPoincare(dataDir = 'data', poincareInit = 'poincareInit.vtk', poincareFile = 'poincare.vtk', dumpFile = 'save.vtk', interpolation = 'weighted', po = [])
          
        Keyword arguments:
        
         *dataDir*:
            Data directory.
            
         *poincareInit*:
            Read the initial Poincare maps from this file.
        
         *poincareFile*:
            Store the Poincare map in this file.
            
         *dumpFile*:
            Use this file for the mapping x(X,t).
            
         *interpolation*:
            Interpolation of the vector field.
            'mean': takes the mean of the adjacent grid point.
            'weighted': weights the adjacent grid points according to their distance.
            
          *po*:
            The Poincare object for t = 0. If not passed obtain it from 'poincareInit'.
        """

        # read the Poincare map at t = 0
        if (po == []):
            po = gm.readPoincare(dataDir=dataDir, poincare=poincareInit)

        # read the current state
        data = gm.readDump(dataDir=dataDir, fileName=dumpFile)
        p = data.p
        xx = data.grid

        # mapped tracers
        tracersNew = np.zeros(po.tracers.shape, dtype=po.tracers.dtype)
        # mapped Poincare map
        xNew = np.zeros(po.x.shape)
        yNew = np.zeros(po.y.shape)

        # interpolate x(X,t) at S to get x(S,t), where S is the initial streamline
        for j in range(po.x.shape[1]):
            for sl in range(po.sl[j]):
                tracersNew[:, j, sl] = gm.vecInt(po.tracers[:, j, sl], xx, p,
                                                 interpolation)
            for i in range(po.x.shape[0]):
                if (i == 0):
                    #xyz = np.array([po.x[i,j], po.y[i,j], p.Oz-p.dz])
                    xyz = np.array([po.x[i, j], po.y[i, j], p.Oz])
                else:
                    #xyz = np.array([po.x[i,j], po.y[i,j], p.Oz+p.Lz+p.dz])
                    xyz = np.array([po.x[i, j], po.y[i, j], p.Oz + p.Lz])
                tmp = gm.vecInt(xyz, xx, p, interpolation)
                xNew[i, j] = tmp[0]
                yNew[i, j] = tmp[1]

        self.x = xNew
        self.y = yNew
        self.sl = po.sl
        self.tracers = tracersNew
        self.p = p
        self.hMin = po.hMin
        self.hMax = po.hMax
        self.lMax = po.lMax
        self.tol = po.tol
        self.iterMax = po.iterMax
        self.nIter = po.nIter
        self.nSeeds = po.nSeeds

        # save into vtk file
        if (poincare != []):
            writer = vtk.vtkPolyDataWriter()
            writer.SetFileName(dataDir + '/' + poincare)
            polyData = vtk.vtkPolyData()
            fieldData = vtk.vtkFieldData()
            # fields containing x and y values
            field = VN.numpy_to_vtk(self.x)
            field.SetName('x')
            fieldData.AddArray(field)
            field = VN.numpy_to_vtk(self.y)
            field.SetName('y')
            fieldData.AddArray(field)
            # field containing length of stream lines for later decomposition
            field = VN.numpy_to_vtk(self.sl)
            field.SetName('sl')
            fieldData.AddArray(field)
            # streamline parameters
            tmp = range(10)
            tmp[0] = np.array([po.hMin], dtype='float32')
            field = VN.numpy_to_vtk(tmp[0])
            field.SetName('hMin')
            fieldData.AddArray(field)
            tmp[1] = np.array([po.hMax], dtype='float32')
            field = VN.numpy_to_vtk(tmp[1])
            field.SetName('hMax')
            fieldData.AddArray(field)
            tmp[2] = np.array([po.lMax], dtype='float32')
            field = VN.numpy_to_vtk(tmp[2])
            field.SetName('lMax')
            fieldData.AddArray(field)
            tmp[3] = np.array([po.tol], dtype='float32')
            field = VN.numpy_to_vtk(tmp[3])
            field.SetName('tol')
            fieldData.AddArray(field)
            tmp[4] = np.array([po.iterMax], dtype='int32')
            field = VN.numpy_to_vtk(tmp[4])
            field.SetName('iterMax')
            fieldData.AddArray(field)
            tmp[5] = np.array([po.tol], dtype='int32')
            field = VN.numpy_to_vtk(tmp[5])
            field.SetName('nSeeds')
            fieldData.AddArray(field)
            tmp[6] = np.array([po.tol], dtype='int32')
            field = VN.numpy_to_vtk(tmp[6])
            field.SetName('nIter')
            fieldData.AddArray(field)
            # fields containing simulation parameters stored in paramFile
            dic = dir(p)
            params = range(len(dic))
            i = 0
            for attr in dic:
                if (attr[0] != '_'):
                    params[i] = getattr(p, attr)
                    params[i] = np.array([params[i]], dtype=type(params[i]))
                    field = VN.numpy_to_vtk(params[i])
                    field.SetName(attr)
                    fieldData.AddArray(field)
                    i += 1
            # all streamlines as continuous array of points
            points = vtk.vtkPoints()
            for q in range(self.x.shape[1]):
                for l in range(self.sl[q]):
                    points.InsertNextPoint(self.tracers[:, q, l])
            polyData.SetPoints(points)
            polyData.SetFieldData(fieldData)
            writer.SetInput(polyData)
            writer.SetFileTypeToBinary()
            writer.Write()
Exemplo n.º 5
0
    def __init__(self,
                 dataDir='data',
                 B0File='B0.vtk',
                 poincare='poincareInit.vtk',
                 paramFile='save.vtk',
                 dumpFile=[],
                 interpolation='weighted',
                 integration='simple',
                 hMin=2e-3,
                 hMax=2e2,
                 lMax=500,
                 tol=2e-3,
                 iterMax=1e3,
                 x0=[],
                 y0=[],
                 nSeeds=10,
                 nIter=10):
        """
        Creates, saves and returns the initial streamline map for a few lines and the Poincare map.
        
        call signature:
        
          streamInit(dataDir = 'data', B0File = 'B0.vtk', poincare = 'poincareInit.vtk', paramFile = 'save.vtk', dumpFile = [], interpolation = 'weighted', integration = 'simple', sub = 1, hMin = 2e-3, hMax = 2e2, lMax = 500, tol = 2e-3, iterMax = 1e3, x0 = [], y0 = [])
        
        Trace magnetic streamlines for t = 0 and store the positions in a file.
        
        Keyword arguments:
        
         *dataDir*:
            Data directory.
            
         *B0File*:
            Name of the file storing B(X,0) = B0.
            
         *poincare*:
            Store the Poincare map in this file.
             
         *paramFile*:
            Dump file from where to read the simulation parameters.
         
         *dumpFile*:
            If not empty map the streamlines from B0.vtk to the time of dumpFile.
            
         *interpolation*:
            Interpolation of the vector field.
            'mean': takes the mean of the adjacent grid point.
            'weighted': weights the adjacent grid points according to their distance.
       
         *integration*:
            Integration method.
            'simple': low order method.
            'RK6': Runge-Kutta 6th order.
       
         *hMin*:
            Minimum step length for and underflow to occur.
        
         *hMax*:
            Parameter for the initial step length.
        
         *lMax*:
            Maximum length of the streamline. Integration will stop if l >= lMax.
        
         *tol*:
            Tolerance for each integration step. Reduces the step length if error >= tol.
         
         *iterMax*:
            Maximum number of iterations.     
         
         *x0*:
            Initial seed in x-direction.
            
         *y0*:
            Initial seed in y-direction.
            
         *nSeeds*:
            Number of initial seeds.
            
         *nIter*:
            Number of times the streamlines go through the domain.
        """

        p = gm.readParams(dataDir=dataDir, fileName=paramFile)

        if (len(x0) != len(y0)):
            print("error: length of x0 != length of y0.")
            return -1
        if ((len(x0) == 0) and (len(y0) == 0)):
            x0 = np.random.random(nSeeds) * p.Lx + p.Ox
            y0 = np.random.random(nSeeds) * p.Ly + p.Oy
        else:
            nSeeds = len(x0)

        x = np.zeros((nIter + 1, nSeeds))
        y = np.zeros((nIter + 1, nSeeds))
        x[0, :] = x0
        y[0, :] = y0
        streams = range(nSeeds)
        tracers = range(nSeeds)
        sl = np.zeros(nSeeds, dtype='int32')
        for q in range(len(x0)):
            tracers[q] = []
            for i in range(nIter):
                # stream the lines until they hit the upper boundary
                s = gm.streamInit(dataDir=dataDir,
                                  B0File=B0File,
                                  streamFileInit=[],
                                  paramFile=paramFile,
                                  interpolation=interpolation,
                                  integration=integration,
                                  hMin=hMin,
                                  hMax=hMax,
                                  lMax=lMax,
                                  tol=tol,
                                  iterMax=iterMax,
                                  x0=x[i, q],
                                  y0=y[i, q])

                # in case the initial time is not 0, map the streamline accordingly
                if (dumpFile != []):
                    s = gm.mapStream(dataDir=dataDir,
                                     streamFileInit='streamInit.vtk',
                                     streamFile=[],
                                     dumpFile=dumpFile,
                                     interpolation=interpolation,
                                     s=s)

                # interpolate the final values for points hitting through the boundary
                l = (p.Oz + p.Lz - s.tracers[2, 0, 0, s.sl - 2]) / (
                    s.tracers[2, 0, 0, s.sl - 1] -
                    s.tracers[2, 0, 0, s.sl - 2])
                x[i + 1,
                  q] = (s.tracers[0, 0, 0, s.sl - 1] -
                        s.tracers[0, 0, 0, s.sl - 2]) * l + s.tracers[0, 0, 0,
                                                                      s.sl - 2]
                y[i + 1,
                  q] = (s.tracers[1, 0, 0, s.sl - 1] -
                        s.tracers[1, 0, 0, s.sl - 2]) * l + s.tracers[1, 0, 0,
                                                                      s.sl - 2]

                # add the tracers to the existing ones
                tracers[q].extend(
                    list(np.swapaxes(s.tracers[:, 0, 0, :s.sl], 0, 1)))
                sl[q] += s.sl

        p = s.p
        self.p = p
        self.x = x
        self.y = y
        self.sl = sl
        maxLen = sl.max()
        self.tracers = np.zeros((3, nSeeds, maxLen))
        for q in range(len(x0)):
            self.tracers[:, q, :sl[q]] = np.swapaxes(np.array(tracers[q]), 0,
                                                     1)

        # streamline parameters
        self.hMin = hMin
        self.hMax = hMax
        self.lMax = lMax
        self.tol = tol
        self.iterMax = iterMax
        self.nSeeds = nSeeds
        self.nIter = nIter

        # safe in vtk file
        if (poincare != []):
            writer = vtk.vtkPolyDataWriter()
            writer.SetFileName(dataDir + '/' + poincare)
            polyData = vtk.vtkPolyData()
            fieldData = vtk.vtkFieldData()
            # fields containing x and y values
            field = VN.numpy_to_vtk(self.x)
            field.SetName('x')
            fieldData.AddArray(field)
            field = VN.numpy_to_vtk(self.y)
            field.SetName('y')
            fieldData.AddArray(field)
            # field containing length of stream lines for later decomposition
            field = VN.numpy_to_vtk(self.sl)
            field.SetName('sl')
            fieldData.AddArray(field)
            # streamline parameters
            tmp = range(10)
            tmp[0] = np.array([s.hMin], dtype='float32')
            field = VN.numpy_to_vtk(tmp[0])
            field.SetName('hMin')
            fieldData.AddArray(field)
            tmp[1] = np.array([s.hMax], dtype='float32')
            field = VN.numpy_to_vtk(tmp[1])
            field.SetName('hMax')
            fieldData.AddArray(field)
            tmp[2] = np.array([s.lMax], dtype='float32')
            field = VN.numpy_to_vtk(tmp[2])
            field.SetName('lMax')
            fieldData.AddArray(field)
            tmp[3] = np.array([s.tol], dtype='float32')
            field = VN.numpy_to_vtk(tmp[3])
            field.SetName('tol')
            fieldData.AddArray(field)
            tmp[4] = np.array([s.iterMax], dtype='int32')
            field = VN.numpy_to_vtk(tmp[4])
            field.SetName('iterMax')
            fieldData.AddArray(field)
            tmp[5] = np.array([nSeeds], dtype='int32')
            field = VN.numpy_to_vtk(tmp[5])
            field.SetName('nSeeds')
            fieldData.AddArray(field)
            tmp[6] = np.array([nIter], dtype='int32')
            field = VN.numpy_to_vtk(tmp[6])
            field.SetName('nIter')
            fieldData.AddArray(field)
            # fields containing simulation parameters stored in paramFile
            dic = dir(p)
            params = range(len(dic))
            i = 0
            for attr in dic:
                if (attr[0] != '_'):
                    params[i] = getattr(p, attr)
                    params[i] = np.array([params[i]], dtype=type(params[i]))
                    field = VN.numpy_to_vtk(params[i])
                    field.SetName(attr)
                    fieldData.AddArray(field)
                    i += 1
            # all streamlines as continuous array of points
            points = vtk.vtkPoints()
            for q in range(len(x0)):
                for l in range(self.sl[q]):
                    points.InsertNextPoint(self.tracers[:, q, l])
            polyData.SetPoints(points)
            polyData.SetFieldData(fieldData)
            writer.SetInput(polyData)
            writer.SetFileTypeToBinary()
            writer.Write()