Beispiel #1
0
    def __init__(self, intQ = ['Jp'], dataDir = 'data', streamFileInit = 'streamInit.vtk', streamFile = 'stream.vtk', dumpFile = 'save.vtk', mapFile = 'map.vtk', interpolation = 'weighted', s0 = [], s = []):
        """
        Compute the integrated quantities. If the streamline objects are not passed, read them.
        Make sure 'streamFile' and 'dumpFile' are from the same time or you will get unexpected results.
        
        call signature:
        
          intStreamintQ = ['Jp'], dataDir = 'data', streamFileInit = 'streamInit.vtk', streamFile = 'stream.vtk', dumpFile = 'save.vtk', mapFile = 'map.vtk', interpolation = 'weighted', s0 = [], s = [])
          
        Keyword arguments:
        
         *intQ*:
           Quantity to be integrated along the streamlines.
           Options: 'Jp', 'JB', 'lam', 'lamS', 'deltaLam', 'epsilon', 'epsilonS', 'l', 'twist', 'mu'
           
         *dataDir*:
            Data directory.
            
         *streamFileInit*:
            Read the initial streamline at t = 0 from this file.
            
         *streamFile*:
            Read the streamline at t from this file.
            
         *dumpFile:
            File containing the physical values.
            
         *mapFile*:
            Store the mapping here.
            
         *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.
            
          *s0*:
            The streamlines object for t = 0. If not passed obtain it from 'streamFileInit'.
            
          *s*:
            The streamlines object at t. If not passed obtain it from 'streamFile'.
        """

        if (s0 == []):
            s0 = gm.readStream(dataDir = dataDir, streamFile = streamFileInit)
        if (s == []):
            s = gm.readStream(dataDir = dataDir, streamFile = streamFile)
        data = gm.readDump(dataDir = dataDir, fileName = dumpFile)
        p    = s.p
        
        self.x0 = s.x0
        self.y0 = s.y0
        self.tracers0 = s.tracers[:,:,:,0]  
        self.p  = p
        self.sub = s.sub
        self.hMin = s.hMin
        self.hMax = s.hMax
        self.lMax = s.lMax
        self.tol = s.tol
        self.iterMax = s.iterMax
        
        # vtk object containing the grid
        points = vtk.vtkPoints()
        xx = s.tracers[:,:,:,0]
        xx = xx[:,:,:,np.newaxis]
        for i in range(len(s.x0)):
            for j in range(len(s.y0)):
                points.InsertNextPoint(xx[:,j,i,0])
        grid = vtk.vtkStructuredGrid()
        grid.SetDimensions([len(s.y0),len(s.x0),1])
        grid.SetPoints(points)
        
        # make intQ iterable even if it contains only one element
        if (isinstance(intQ, str)):
            intQ = [intQ]
        intQ = np.array(intQ)
            
        # check if we need to J
        needJ = np.any(np.array(['Jp', 'JB', 'lam', 'lamS', 'deltaLam', 'epsilon', 'epsilonS', 'twist', 'mu']) == intQ.reshape((intQ.shape[0],1)))        
        # check if we need B
        needB = np.any(np.array(['JB', 'lam', 'lamS', 'deltaLam', 'epsilon', 'epsilonS', 'twist', 'mu']) == intQ.reshape((intQ.shape[0],1)))
        # check if we need the length dl
        needDl = np.any(np.array(['JB', 'lam', 'lamS', 'deltaLam', 'epsilon', 'epsilonS', 'l', 'twist', 'mu']) == intQ.reshape((intQ.shape[0],1)))
        
        # check if the data has the necessarry attributes
        if (needJ and not(hasattr(data, 'jfield'))):
            print("Error: missing attribute 'jfield' in data.")
            return -1
        if (needJ and not(hasattr(data, 'bfield'))):
            print("Error: missing attribute 'bfield' in data.")
            return -1

        # add integrated quantities to intQ (because we can)
        addQ = set([])
        if needJ:
            addQ = addQ.union(set(['Jp', 'JB', 'lam', 'lamS', 'deltaLam', 'epsilon', 'epsilonS', 'twist', 'mu']))
        if needB:
            addQ = addQ.union(set(['JB', 'lam', 'lamS', 'deltaLam', 'epsilon', 'epsilonS', 'twist', 'mu']))
        if needDl:
            addQ = addQ.union(set(['JB', 'lam', 'lamS', 'deltaLam', 'epsilon', 'epsilonS', 'l', 'twist', 'mu']))
        intQ = np.array(list(addQ))
        
        # create arrays for the vtk i/o
        arrays = {}
        for q in intQ:
            arr = vtk.vtkFloatArray()
            arr.SetName(q)
            arr.SetNumberOfComponents(1)
            arr.SetNumberOfTuples(grid.GetNumberOfPoints())            
            arrays[q] = arr
         
        # initialize all arrays
        print(s.tracers.shape[1:3])
        if needJ:
            Jp = np.zeros(s.tracers.shape[1:3])
        if (needJ and needB):
            JB = np.zeros(s.tracers.shape[1:3])
            lam = np.zeros(s.tracers.shape[1:3])
            lamS = np.zeros(s.tracers.shape[1:3])
            deltaLam = np.zeros(s.tracers.shape[1:3])
            epsilon = np.zeros(s.tracers.shape[1:3])
            epsilonS = np.zeros(s.tracers.shape[1:3])
            twist = np.zeros(s.tracers.shape[1:3])
            mu = np.zeros(s.tracers.shape[1:3])
            Jn = np.zeros(3)    # normalized current
        if needDl:
            l2d = np.zeros(s.tracers.shape[1:3])
            
        for i in range(len(s.x0)):
            for j in range(len(s.y0)):
                xx1 = s.tracers[:,i,j,0]
                if needJ:
                    JJ1 = gm.vecInt(s0.tracers[:,i,j,0], data.jfield, p, interpolation = interpolation)
                if needB:
                    BB1 = gm.vecInt(s0.tracers[:,i,j,0], data.bfield, p, interpolation = interpolation)
                    lamTmp = np.zeros(s.sl[i,j])
                    lamTmp[0] = np.dot(JJ1, BB1)/np.dot(BB1, BB1)
                    epsilonTmp = np.zeros(s.sl[i,j])
                    epsilonTmp[0] = np.linalg.norm(np.cross(JJ1, BB1))/np.dot(BB1, BB1)
                if needDl:
                    l = 0
                    ll = np.zeros(s.sl[i,j])
                    ll[0] = l
                for k in range(1, s.sl[i,j]):
                    xx2 = s.tracers[:,i,j,k]
                    if needJ:
                        JJ2 = gm.vecInt(s0.tracers[:,i,j,k], data.jfield, p, interpolation = interpolation)
                    if needB:
                        BB2 = gm.vecInt(s0.tracers[:,i,j,k], data.bfield, p, interpolation = interpolation)
                    if needDl:
                        dl = np.linalg.norm(xx2-xx1)
                        l += dl
                        ll[k-1] = l
                    # integrate the quantities
                    if needJ:
                        Jp[i,j] += np.dot((JJ2+JJ1), (xx2-xx1)) # division by 2 done later
                    if (needJ and needB):
                        JB[i,j] += np.dot((JJ2+JJ1), (BB2+BB1))*dl   # division by 4 done later
                        #lamTmp[k-1] = np.dot((JJ2+JJ1), (BB2+BB1))/np.dot((BB2+BB1), (BB2+BB1))
                        lamTmp[k] = np.dot(JJ2, BB2)/np.dot(BB2, BB2)
                        lam[i,j] += (lamTmp[k]+lamTmp[k-1])*dl/2
                        deltaLam[i,j] += (np.dot(JJ2,BB2)/np.dot(BB2,BB2) - np.dot(JJ1,BB1)/np.dot(BB1,BB1))/dl
                        #epsilonTmp[k-1] = np.linalg.norm(np.cross((JJ2+JJ1), (BB2+BB1)))/np.dot((BB2+BB1), (BB2+BB1))
                        epsilonTmp[k] = np.linalg.norm(np.cross(JJ2, BB2))/np.dot(BB2, BB2)
                        epsilon[i,j] += epsilonTmp[k]*dl
                        #twist[i,j] += np.dot((JJ2+JJ1), (BB2+BB1))/(np.linalg.norm(JJ2+JJ1)*np.linalg.norm(BB2+BB1))*dl
                        # take the norm such that for small vectors errors are small
                        Jtmp = (JJ2+JJ1)
                        Jn[0] = np.sign(Jtmp[0])/np.sqrt(1 + (Jtmp[1]/Jtmp[0])**2 + (Jtmp[2]/Jtmp[0])**2)
                        Jn[1] = np.sign(Jtmp[1])/np.sqrt(1 + (Jtmp[2]/Jtmp[1])**2 + (Jtmp[0]/Jtmp[1])**2)
                        Jn[2] = np.sign(Jtmp[2])/np.sqrt(1 + (Jtmp[0]/Jtmp[2])**2 + (Jtmp[1]/Jtmp[2])**2)
                        Jn = Jn/np.linalg.norm(Jn)
                        twist[i,j] += np.dot(Jn, (BB2+BB1))/np.linalg.norm(BB2+BB1)*dl
                    xx1 = xx2
                    if needJ:
                        JJ1 = JJ2
                    if needB:
                        BB1 = BB2
                if needJ:
                    Jp[i,j] = Jp[i,j]/2
                    arrays['Jp'].SetValue(i+j*len(s.x0), Jp[i,j])
                if (needJ and needB):
                    JB = JB/4
                    lam[i,j] = lam[i,j]/l
                    
                    dLamTmp = abs((lamTmp[1:] - lamTmp[:-1]) / (ll[1:] - ll[:-1]))
                    dLamTmp[np.isnan(dLamTmp)] = 0
                    lamS[i,j] = np.max(dLamTmp)
                    
                    epsilon[i,j] = epsilon[i,j]/l
                    epsilonTmp = (epsilonTmp[1:] - epsilonTmp[:-1]) / (ll[1:] - ll[:-1])
                    epsilonTmp[np.isnan(epsilonTmp)] = 0
                    epsilonS[i,j] = np.max(abs(epsilonTmp))
                    
                    twist[i,j] = twist[i,j]/l
                    if (ll.shape[0] > 1):
                        idx = np.where(dLamTmp == lamS[i,j])[0][0]
                        mu[i,j] = lamS[i,j]*2*(ll[idx+1] - ll[idx])/(lamTmp[idx+1] + lamTmp[idx])
                    else:
                        mu[i,j] = lamS[i,j]*2*ll[0]/lamTmp[0]
                        
                    arrays['JB'].SetValue(i+j*len(s.x0), JB[i,j])
                    arrays['lam'].SetValue(i+j*len(s.x0), lam[i,j])
                    arrays['lamS'].SetValue(i+j*len(s.x0), lamS[i,j])
                    arrays['deltaLam'].SetValue(i+j*len(s.x0), deltaLam[i,j])
                    arrays['epsilon'].SetValue(i+j*len(s.x0), epsilon[i,j])
                    arrays['epsilonS'].SetValue(i+j*len(s.x0), epsilonS[i,j])
                    arrays['twist'].SetValue(i+j*len(s.x0), twist[i,j])
                    arrays['mu'].SetValue(i+j*len(s.x0), mu[i,j])
                if needDl:
                    l2d[i,j] = l
                    arrays['l'].SetValue(i+j*len(s.x0), l2d[i,j])
        if needJ:
            self.Jp = Jp
        if (needJ and needB):
            self.JB = JB
            self.lam = lam
            self.lamS = lamS
            self.deltaLam = deltaLam
            self.epsilon = epsilon
            self.epsilonS = epsilonS
            self.twist = twist
            self.mu = mu
        if needDl:
            self.l = l2d
        # add results to the vtk array
        for q in intQ:
            grid.GetPointData().AddArray(arrays[q])
       
        fieldData = vtk.vtkFieldData()
        
        # save parameter x0, y0        
        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)
        
        # 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
                
        grid.SetFieldData(fieldData)
        
        # write into vtk file
        writer = vtk.vtkStructuredGridWriter()
        writer.SetFileName(dataDir + '/' + mapFile)
        writer.SetInput(grid)
        writer.SetFileTypeToBinary()
        writer.Write()
Beispiel #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()
Beispiel #3
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()
Beispiel #4
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()
Beispiel #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()