Example #1
0
    def __init__(self, tag, field='Br', precision='Float32', avg=False):
        """
        :param tag: if you specify a pattern, it tries to read the corresponding 
                    files and stack them.
        :type tag: str
        :param field: nature of the radial spectra. Possible choices are
                      'Bt' or 'Bp'
        :type field: str
        :param precision: single or double precision (default single, i.e. 'Float32')
        :type precision: str
        :param avg: when set to True, display time averaged quantities
        :type avg: bool
        """

        logFiles = scanDir('log.*')
        if len(logFiles) != 0:
            MagicSetup.__init__(self, quiet=True, nml=logFiles[-1])
            self.n_r_max = int(self.n_r_max)
            self.n_r_ic_max = int(self.n_r_ic_max)
        else:
            n_r_max = 'n_r_max ?\n'
            self.n_r_max = int(input(str1))
            n_r_ic_max = 'n_r_ic_max ?\n'
            self.n_r_ic_max = int(input(str1))
            str1 = 'Aspect ratio ?\n'
            self.radratio = float(input(str1))

        self.n_r_tot = self.n_r_max+self.n_r_ic_max

        self.ricb = self.radratio/(1.-self.radratio)
        self.rcmb = 1./(1.-self.radratio)
        outerCoreGrid = chebgrid(self.n_r_max-1, self.rcmb, self.ricb)
        n_r_ic_tot = 2*self.n_r_ic_max-1
        innerCoreGrid = chebgrid(n_r_ic_tot-1, self.ricb, -self.ricb)

        self.radius = np.zeros((self.n_r_tot-1), dtype=precision)

        self.radius[:self.n_r_max] = outerCoreGrid
        self.radius[self.n_r_max-1:] = innerCoreGrid[:self.n_r_ic_max]

        pattern = 'r%s' % field +'Spec'
        files = scanDir('%s.%s' % (pattern, tag))

        # Read the rB[rp]Spec.TAG files (stack them)
        data = []
        for k, file in enumerate(files):
            print('Reading %s' % file)
            f = npfile(file, endian='B')

            while 1:
                try:
                    data.append(f.fort_read(precision))
                except TypeError:
                    break
        data = np.array(data, dtype=precision)

        # Time (every two lines only)
        self.time = data[::2, 0]

        # Poloidal/Toroidal energy for all radii for the 6 first spherical harmonic
        # degrees
        self.e_pol = np.zeros((len(self.time), self.n_r_tot-1, 6), dtype=precision)
        self.e_pol_axi = np.zeros_like(self.e_pol)

        self.e_pol[:, :, 0] = data[::2, 1:self.n_r_tot]
        self.e_pol[:, :, 1] = data[::2, self.n_r_tot-1:2*(self.n_r_tot-1)]
        self.e_pol[:, :, 2] = data[::2, 2*(self.n_r_tot-1):3*(self.n_r_tot-1)]
        self.e_pol[:, :, 3] = data[::2, 3*(self.n_r_tot-1):4*(self.n_r_tot-1)]
        self.e_pol[:, :, 4] = data[::2, 4*(self.n_r_tot-1):5*(self.n_r_tot-1)]
        self.e_pol[:, :, 5] = data[::2, 5*(self.n_r_tot-1):6*(self.n_r_tot-1)]

        self.e_pol_axi[:, :, 0] = data[1::2, 1:self.n_r_tot]
        self.e_pol_axi[:, :, 1] = data[1::2, self.n_r_tot-1:2*(self.n_r_tot-1)]
        self.e_pol_axi[:, :, 2] = data[1::2, 2*(self.n_r_tot-1):3*(self.n_r_tot-1)]
        self.e_pol_axi[:, :, 3] = data[1::2, 3*(self.n_r_tot-1):4*(self.n_r_tot-1)]
        self.e_pol_axi[:, :, 4] = data[1::2, 4*(self.n_r_tot-1):5*(self.n_r_tot-1)]
        self.e_pol_axi[:, :, 5] = data[1::2, 5*(self.n_r_tot-1):6*(self.n_r_tot-1)]

        if avg:
            self.plotAvg()
Example #2
0
    def __init__(self,
                 field='V',
                 datadir='.',
                 tag=None,
                 ave=False,
                 ipot=None,
                 precision=np.float32,
                 verbose=True,
                 ic=False):
        """
        :param field: 'B', 'V', 'T' or 'Xi' (magnetic field, velocity field,
                      temperature or chemical composition)
        :type field: str
        :param datadir: the working directory
        :type datadir: str
        :param tag: if you specify a pattern, it tries to read the
                    corresponding files
        :type tag: str
        :param ave: plot a time-averaged spectrum when set to True
        :type ave: bool
        :param ipot: the number of the lmr file you want to plot
        :type ipot: int
        :param precision: single or double precision
        :type precision: str
        :param verbose: some info about the SHT layout
        :type verbose: bool
        :param ic: read or don't read the inner core
        :type ic: bool
        """

        if field != 'B':
            ic = False

        if hasattr(self, 'radial_scheme'):
            if self.radial_scheme == 'FD':
                self.rcheb = False
            else:
                self.rcheb = True
        else:
            self.rcheb = True

        if ave:
            self.name = '{}_lmr_ave'.format(field)
        else:
            self.name = '{}_lmr_'.format(field)

        if tag is not None:
            if ipot is not None:
                file = '{}{}.{}'.format(self.name, ipot, tag)
                filename = os.path.join(datadir, file)
            else:
                pattern = os.path.join(datadir, '{}*{}'.format(self.name, tag))
                files = scanDir(pattern)
                if len(files) != 0:
                    filename = files[-1]
                else:
                    print('No such tag... try again')
                    return

            if os.path.exists(os.path.join(datadir, 'log.{}'.format(tag))):
                MagicSetup.__init__(self,
                                    datadir=datadir,
                                    quiet=True,
                                    nml='log.{}'.format(tag))
        else:
            if ipot is not None:
                pattern = os.path.join(datadir,
                                       '{}{}*'.format(self.name, ipot))
                files = scanDir(pattern)
                filename = files[-1]
            else:
                pattern = os.path.join(datadir, '{}*'.format(self.name))
                files = scanDir(pattern)
                filename = files[-1]
            # Determine the setup
            mask = re.compile(r'.*\.(.*)')
            ending = mask.search(files[-1]).groups(0)[0]
            if os.path.exists(os.path.join(datadir, 'log.{}'.format(ending))):
                MagicSetup.__init__(self,
                                    datadir=datadir,
                                    quiet=True,
                                    nml='log.{}'.format(ending))

        # Determine file endianness
        endian, record_marker = getPotEndianness(filename)
        if record_marker:
            self.version = 0
        else:
            self.version = 1  # This will be over-written later

        t1 = time.time()
        self.read(filename,
                  field,
                  endian,
                  record_marker,
                  ic,
                  precision=precision)
        t2 = time.time()
        if verbose:
            print('Time to read {}: {:.2e}'.format(filename, t2 - t1))

        self.n_theta_max = int(3 * self.l_max / 2)
        if self.n_theta_max % 2:  # odd number
            self.n_theta_max += 1
        self.n_phi_max = int(2 * self.n_theta_max / self.minc)
        t1 = time.time()
        self.sh = SpectralTransforms(l_max=self.l_max,
                                     minc=self.minc,
                                     lm_max=self.lm_max,
                                     n_theta_max=self.n_theta_max,
                                     verbose=verbose)
        t2 = time.time()
        if verbose:
            print('Time to set up the spectral transforms: {:.2e}'.format(t2 -
                                                                          t1))
        self.colat = self.sh.colat

        self.idx = self.sh.idx
        self.ell = self.sh.ell
Example #3
0
    def __init__(self, iplot=False, angle=10, pickleName='thHeat.pickle'):
        """
        :param iplot: a boolean to toggle the plots on/off
        :type iplot: bool
        :param angle: the integration angle in degrees
        :type angle: float
        :pickleName: calculations a
        """

        angle = angle * np.pi / 180

        if os.path.exists('tInitAvg'):
            file = open('tInitAvg', 'r')
            tstart = float(file.readline())
            file.close()
            logFiles = scanDir('log.*')
            tags = []
            for lg in logFiles:
                nml = MagicSetup(quiet=True, nml=lg)
                if nml.start_time >  tstart:
                    if os.path.exists('bLayersR.%s' % nml.tag):
                        tags.append(nml.tag)
            if len(tags) == 0:
                tags = [nml.tag]
                print('Only 1 tag: %s' % tags)
            MagicSetup.__init__(self, quiet=True, nml=logFiles[-1])

            a = AvgField()
            self.nuss = a.nuss
        else:
            logFiles = scanDir('log.*')
            MagicSetup.__init__(self, quiet=True, nml=logFiles[-1])


        if not os.path.exists(pickleName):
            # reading ATmov
            k = 0
            for tag in tags:
                file = 'ATmov.%s' % tag
                if os.path.exists(file):
                    if k == 0:
                        m = Movie(file=file, iplot=False)
                        print(file)
                    else:
                        m += Movie(file=file, iplot=False)
                        print(file)
                    k += 1

            # reading AHF_mov
            kk = 0
            for tag in tags:
                file = 'AHF_mov.%s' % tag
                if os.path.exists(file):
                    if kk == 0:
                        m1 = Movie(file=file, iplot=False)
                        print(file)
                    else:
                        m1 += Movie(file=file, iplot=False)
                        print(file)
                    kk += 1

            self.tempmean = m.data[0, ...].mean(axis=0)
            self.tempstd = m.data[0, ...].std(axis=0)
            self.colat = m.theta


            if kk > 0: # i.e. at least one AHF_mov file has been found
                self.fluxmean = m1.data[0, ...].mean(axis=0)
                self.fluxstd = m1.data[0, ...].std(axis=0)
            else:
                self.fluxmean = rderavg(self.tempmean, eta=self.radratio,
                                        exclude=False, spectral=False)
                self.fluxstd = rderavg(self.tempstd, eta=self.radratio,
                                        exclude=False, spectral=False)

            # Pickle saving
            file = open(pickleName, 'wb')
            pickle.dump([self.colat, self.tempmean, self.tempstd,\
                         self.fluxmean, self.fluxstd], file)
            file.close()
        else:
            file = open(pickleName, 'r')
            dat = pickle.load(file)
            if len(dat) == 5:
                self.colat, self.tempmean, self.tempstd, \
                            self.fluxmean, self.fluxstd = dat
            else:
                self.colat, self.tempmean, self.fluxmean = dat
                self.fluxstd = np.zeros_like(self.fluxmean)
                self.tempstd = np.zeros_like(self.fluxmean)
            file.close()

        self.ri = self.radratio/(1.-self.radratio)
        self.ro = 1./(1.-self.radratio)

        self.ntheta, self.nr = self.tempmean.shape
        self.radius = chebgrid(self.nr-1, self.ro, self.ri)
        th2D = np.zeros((self.ntheta, self.nr), dtype=self.radius.dtype)
        #self.colat = np.linspace(0., np.pi, self.ntheta)

        for i in range(self.ntheta):
            th2D[i, :] = self.colat[i]

        self.temprmmean = 0.5*simps(self.tempmean*np.sin(th2D), th2D, axis=0)
        self.temprmstd = 0.5*simps(self.tempstd*np.sin(th2D), th2D, axis=0)
        sinTh = np.sin(self.colat)
        d1 = matder(self.nr-1, self.ro, self.ri)

        # Conducting temperature profile (Boussinesq only!)
        self.tcond = self.ri*self.ro/self.radius-self.ri+self.temprmmean[0]
        self.fcond = -self.ri*self.ro/self.radius**2
        self.nusstopmean = self.fluxmean[:, 0] / self.fcond[0]
        self.nussbotmean = self.fluxmean[:, -1] / self.fcond[-1]
        self.nusstopstd = self.fluxstd[:, 0] / self.fcond[0]
        self.nussbotstd = self.fluxstd[:, -1] / self.fcond[-1]


        # Close to the equator
        mask2D = (th2D>=np.pi/2.-angle/2.)*(th2D<=np.pi/2+angle/2.)
        mask = (self.colat>=np.pi/2.-angle/2.)*(self.colat<=np.pi/2+angle/2.)
        fac = 1./simps(sinTh[mask], self.colat[mask])
        self.nussBotEq = fac*simps(self.nussbotmean[mask]*sinTh[mask], self.colat[mask])
        self.nussTopEq = fac*simps(self.nusstopmean[mask]*sinTh[mask], self.colat[mask])
        sinC = sinTh.copy()
        sinC[~mask] = 0.
        fac = 1./simps(sinC, self.colat)
        tempC = self.tempmean.copy()
        tempC[~mask2D] = 0.
        self.tempEqmean = fac*simps(tempC*np.sin(th2D), th2D, axis=0)
        tempC = self.tempstd.copy()
        tempC[~mask2D] = 0.
        self.tempEqstd = fac*simps(tempC*np.sin(th2D), th2D, axis=0)

        dtempEq = np.dot(d1, self.tempEqmean)
        self.betaEq = dtempEq[self.nr/2]

        # 45\deg inclination
        mask2D = (th2D>=np.pi/4.-angle/2.)*(th2D<=np.pi/4+angle/2.)
        mask = (self.colat>=np.pi/4.-angle/2.)*(self.colat<=np.pi/4+angle/2.)
        fac = 1./simps(np.sin(self.colat[mask]), self.colat[mask])
        nussBot45NH = fac*simps(self.nussbotmean[mask]*sinTh[mask], self.colat[mask])
        nussTop45NH = fac*simps(self.nusstopmean[mask]*sinTh[mask], self.colat[mask])
        sinC = sinTh.copy()
        sinC[~mask] = 0.
        fac = 1./simps(sinC, self.colat)
        tempC = self.tempmean.copy()
        tempC[~mask2D] = 0.
        temp45NH = fac*simps(tempC*np.sin(th2D), th2D, axis=0)

        mask2D = (th2D>=3.*np.pi/4.-angle/2.)*(th2D<=3.*np.pi/4+angle/2.)
        mask = (self.colat>=3.*np.pi/4.-angle/2.)*(self.colat<=3.*np.pi/4+angle/2.)
        fac = 1./simps(np.sin(self.colat[mask]), self.colat[mask])
        nussBot45SH = fac*simps(self.nussbotmean[mask]*sinTh[mask], self.colat[mask])
        nussTop45SH = fac*simps(self.nusstopmean[mask]*sinTh[mask], self.colat[mask])
        sinC = sinTh.copy()
        sinC[~mask] = 0.
        fac = 1./simps(sinC, self.colat)
        tempC = self.tempmean.copy()
        tempC[~mask2D] = 0.
        temp45SH = fac*simps(tempC*np.sin(th2D), th2D, axis=0)

        self.nussTop45 = 0.5*(nussTop45NH+nussTop45SH)
        self.nussBot45 = 0.5*(nussBot45NH+nussBot45SH)
        self.temp45 = 0.5*(temp45NH+temp45SH)

        dtemp45 = np.dot(d1, self.temp45)
        self.beta45 = dtemp45[self.nr/2]

        # Polar regions
        mask2D = (th2D<=angle/2.)
        mask = (self.colat<=angle/2.)
        fac = 1./simps(np.sin(self.colat[mask]), self.colat[mask])
        nussBotPoNH = fac*simps(self.nussbotmean[mask]*sinTh[mask], self.colat[mask])
        nussTopPoNH = fac*simps(self.nusstopmean[mask]*sinTh[mask], self.colat[mask])
        sinC = sinTh.copy()
        sinC[~mask] = 0.
        fac = 1./simps(sinC, self.colat)
        tempC = self.tempmean.copy()
        tempC[~mask2D] = 0.
        tempPolNHmean = fac*simps(tempC*np.sin(th2D), th2D, axis=0)
        tempC = self.tempstd.copy()
        tempC[~mask2D] = 0.
        tempPolNHstd = fac*simps(tempC*np.sin(th2D), th2D, axis=0)

        mask2D = (th2D>=np.pi-angle/2.)
        mask = (self.colat>=np.pi-angle/2.)
        fac = 1./simps(np.sin(self.colat[mask]), self.colat[mask])
        nussBotPoSH = fac*simps(self.nussbotmean[mask]*sinTh[mask], self.colat[mask])
        nussTopPoSH = fac*simps(self.nusstopmean[mask]*sinTh[mask], self.colat[mask])
        sinC = sinTh.copy()
        sinC[~mask] = 0.
        fac = 1./simps(sinC, self.colat)
        tempC = self.tempmean.copy()
        tempC[~mask2D] = 0.
        tempPolSHmean = fac*simps(tempC*np.sin(th2D), th2D, axis=0)
        tempC = self.tempstd.copy()
        tempC[~mask2D] = 0.
        tempPolSHstd = fac*simps(tempC*np.sin(th2D), th2D, axis=0)

        self.nussBotPo = 0.5*(nussBotPoNH+nussBotPoSH)
        self.nussTopPo = 0.5*(nussTopPoNH+nussTopPoSH)
        self.tempPolmean = 0.5*(tempPolNHmean+tempPolSHmean)
        self.tempPolstd= 0.5*(tempPolNHstd+tempPolSHstd)

        dtempPol = np.dot(d1, self.tempPolmean)
        self.betaPol = dtempPol[self.nr/2]


        # Inside and outside TC
        angleTC = np.arcsin(self.ri/self.ro)
        mask2D = (th2D<=angleTC)
        mask = (self.colat<=angleTC)
        fac = 1./simps(np.sin(self.colat[mask]), self.colat[mask])
        nussITC_NH = fac*simps(self.nusstopmean[mask]*sinTh[mask], self.colat[mask])

        mask2D = (th2D>=np.pi-angleTC)
        mask = (self.colat>=np.pi-angleTC)
        fac = 1./simps(np.sin(self.colat[mask]), self.colat[mask])
        nussITC_SH = fac*simps(self.nusstopmean[mask]*sinTh[mask], self.colat[mask])

        self.nussITC = 0.5*(nussITC_NH+nussITC_SH)

        mask2D = (th2D>=angleTC)*(th2D<=np.pi-angleTC)
        mask = (self.colat>=angleTC)*(self.colat<=np.pi-angleTC)
        fac = 1./simps(sinTh[mask], self.colat[mask])
        self.nussOTC = fac*simps(self.nusstopmean[mask]*sinTh[mask], self.colat[mask])

        if iplot:
            self.plot()

        print(self)
Example #4
0
    def __init__(self, field='V', datadir='.', tag=None, ave=False, ipot=None,
                 precision='Float32'):
        """
        :param field: 'B', 'V' or 'T' (magnetic field, velocity field or temperature)
        :type field: str
        :param datadir: the working directory
        :type datadir: str
        :param tag: if you specify a pattern, it tries to read the corresponding files
        :type tag: str
        :param ave: plot a time-averaged spectrum when set to True
        :type ave: bool
        :param ipot: the number of the lmr file you want to plot
        :type ipot: int
        :param precision: single or double precision
        :type precision: str
        """

        if hasattr(self, 'radial_scheme'):
            if self.radial_scheme == 'FD':
                self.rcheb = False
            else:
                self.rcheb = True
        else:
            self.rcheb = True

        if ave:
            self.name = '%s_lmr_ave' % field
        else:
            self.name = '%s_lmr_' % field

        if tag is not None:
            if ipot is not None:
                file = '%s%i.%s' % (self.name, ipot, tag)
                filename = os.path.join(datadir, file)
            else:
                pattern = os.path.join(datadir, '%s*%s' % (self.name, tag))
                files = scanDir(pattern)
                if len(files) != 0:
                    filename = files[-1]
                else:
                    print('No such tag... try again')
                    return

            if os.path.exists(os.path.join(datadir, 'log.%s' % tag)):
                MagicSetup.__init__(self, datadir=datadir, quiet=True,
                                    nml='log.%s' % tag)
        else:
            if ipot is not None:
                pattern = os.path.join(datadir, '%s%i*' % (self.name, ipot))
                files = scanDir(pattern)
                filename = files[-1]
            else:
                pattern = os.path.join(datadir, '%s*' % self.name)
                files = scanDir(pattern)
                filename = files[-1]
            # Determine the setup
            mask = re.compile(r'.*\.(.*)')
            ending = mask.search(files[-1]).groups(0)[0]
            if os.path.exists(os.path.join(datadir, 'log.%s' % ending)):
                MagicSetup.__init__(self, datadir=datadir, quiet=True,
                                    nml='log.%s' % ending)


        # Determine file endianness
        endian = getPotEndianness(filename)

        t1 = time.time()
        if readingMode  == 'python':

            infile = npfile(filename, endian=endian)

            # Read header
            self.l_max, self.n_r_max, self.n_r_ic_max, self.minc, \
                                          self.lm_max = infile.fort_read('i4')
            self.m_max = int((self.l_max/self.minc)*self.minc)
            self.n_m_max = int(self.m_max/self.minc+1)
            self.ra, self.ek, self.pr, self.prmag, self.radratio, self.sigma_ratio, \
                         self.omega_ma, self.omega_ic = infile.fort_read(precision)
            self.time = infile.fort_read(precision)
            dat = infile.fort_read(precision)

            # Read radius and density
            self.radius = dat[:self.n_r_max]
            self.rho0 = dat[self.n_r_max:]

            # Read field in the outer core
            self.pol = infile.fort_read('Complex32')
            self.pol = self.pol.reshape((self.n_r_max, self.lm_max))
            self.pol = self.pol.T
            if ( field != 'T' and field != 'Xi' ):
                self.tor = infile.fort_read('Complex32')
                self.tor = self.tor.reshape((self.n_r_max, self.lm_max))
                self.tor = self.tor.T

            infile.close()

        else: # F2py reader

            if ( field != 'T' and field != 'Xi' ):
                l_read_tor = True
            else:
                l_read_tor = False

            Prd = Psngl.potreader_single
            Prd.readpot(filename, endian, l_read_tor)
            self.n_r_max = Prd.n_r_max
            self.l_max = Prd.l_max
            self.n_r_ic_max = Prd.n_r_ic_max
            self.minc = Prd.minc
            self.lm_max = Prd.lm_max
            self.m_max = int((self.l_max/self.minc)*self.minc)
            self.n_m_max = int(self.m_max/self.minc+1)
            self.ra = Prd.ra
            self.ek = Prd.ek
            self.radratio = Prd.radratio
            self.sigma_ratio = Prd.sigma_ratio
            self.prmag = Prd.prmag
            self.pr = Prd.pr
            self.omega_ic = Prd.omega_ic
            self.omega_ma = Prd.omega_ma
            self.radius = Prd.radius
            self.rho0 = Prd.rho0

            self.pol = Prd.pol
            if ( field != 'T' and field != 'Xi' ):
                self.tor = Prd.tor
        t2 = time.time()
        print('Time to read %s: %.2f' % (filename, t2-t1))

        self.n_theta_max = int(3*self.l_max/2)
        if self.n_theta_max % 2: # odd number
            self.n_theta_max += 1
        self.n_phi_max = int(2*self.n_theta_max/self.minc)
        t1 = time.time()
        self.sh = SpectralTransforms(l_max=self.l_max, minc=self.minc,
                                     lm_max=self.lm_max, n_theta_max=self.n_theta_max)
        t2 = time.time()
        print('Time to set up the spectral transforms: %.2f' % (t2-t1))
        self.colat = self.sh.colat

        self.idx = self.sh.idx
        self.ell = self.sh.ell
Example #5
0
    def __init__(self,
                 tag,
                 ratio_cmb_surface=1,
                 scale_b=1,
                 iplot=True,
                 field='B',
                 r=1,
                 precision='Float64',
                 lCut=None,
                 quiet=False):
        """
        :param tag: if you specify a pattern, it tries to read the corresponding files
        :type tag: str
        :param ratio_cmb_surface: ratio of surface ratio to CMB radius (default is 1)
        :type ratio_cmb_surface: float
        :param scale_b: magnetic field unit (default is 1)
        :type scale_b: float
        :param iplot: a logical to toggle the plot (default is True)
        :type iplot: bool
        :param field: 'B', 'V' or 'T' (magnetic field, velocity field or temperature)
        :type field: str
        :param r: an integer to characterise which file we want to plot
        :type r: int
        :param precision: single or double precision
        :type precision: str
        :param lCut: reduce the spherical harmonic truncation to l <= lCut
        :type lCut: int
        :param quiet: verbose when toggled to True (default is True)
        :type quiet: bool
        """

        logFiles = scanDir('log.*')
        if len(logFiles) != 0:
            MagicSetup.__init__(self, quiet=True, nml=logFiles[-1])
        else:
            str1 = 'Aspect ratio ?\n'
            self.radratio = float(input(str1))

        self.rcmb = 1. / (1. - self.radratio)
        ricb = self.radratio / (1. - self.radratio)

        files = scanDir('%s_coeff_r%i.%s' % (field, r, tag))

        # Read the B_coeff files (by stacking the different tags)
        data = []
        for k, file in enumerate(files):
            if not quiet: print('Reading %s' % file)
            f = npfile(file, endian='B')
            out = f.fort_read('3i4,%s' % precision)[0]
            self.l_max_r, self.minc, n_data = out[0]
            self.m_max_r = int((self.l_max_r / self.minc) * self.minc)
            self.radius = out[1]

            while 1:
                try:
                    data.append(f.fort_read(precision))
                except TypeError:
                    break
        self.lm_max_r = self.m_max_r*(self.l_max_r+1)//self.minc - \
                        self.m_max_r*(self.m_max_r-self.minc)//(2*self.minc) + \
                        self.l_max_r-self.m_max_r+1

        # Get indices location
        self.idx = np.zeros((self.l_max_r + 1, self.m_max_r + 1), 'i')
        self.ell = np.zeros(self.lm_max_r, 'i')
        self.ms = np.zeros(self.lm_max_r, 'i')
        self.idx[0:self.l_max_r + 2, 0] = np.arange(self.l_max_r + 1)
        self.ell[0:self.l_max_r + 2] = np.arange(self.l_max_r + 2)
        k = self.l_max_r + 1
        for m in range(self.minc, self.l_max_r + 1, self.minc):
            for l in range(m, self.l_max_r + 1):
                self.idx[l, m] = k
                self.ell[self.idx[l, m]] = l
                self.ms[self.idx[l, m]] = m
                k += 1

        # Rearange data
        data = np.array(data, dtype=precision)
        self.nstep = data.shape[0]
        self.wlm = np.zeros((self.nstep, self.lm_max_r), 'Complex64')
        self.dwlm = np.zeros((self.nstep, self.lm_max_r), 'Complex64')
        self.zlm = np.zeros((self.nstep, self.lm_max_r), 'Complex64')

        # Get time
        self.time = np.zeros(self.nstep, dtype=precision)
        self.time = data[:, 0]

        # wlm
        self.wlm[:, 1:self.l_max_r + 1] = data[:, 1:self.l_max_r + 1]
        k = self.l_max_r + 1
        for m in range(self.minc, self.l_max_r + 1, self.minc):
            for l in range(m, self.l_max_r + 1):
                self.wlm[:, self.idx[l, m]] = data[:, k] + 1j * data[:, k + 1]
                k += 2

        # dwlm
        self.dwlm[:, 1:self.l_max_r + 1] = data[:, k:k + self.l_max_r]
        k += self.l_max_r
        for m in range(self.minc, self.l_max_r + 1, self.minc):
            for l in range(m, self.l_max_r + 1):
                self.dwlm[:, self.idx[l, m]] = data[:, k] + 1j * data[:, k + 1]
                k += 2
        # zlm
        self.zlm[:, 1:self.l_max_r + 1] = data[:, k:k + self.l_max_r]
        k += self.l_max_r
        for m in range(self.minc, self.l_max_r + 1, self.minc):
            for l in range(m, self.l_max_r + 1):
                self.zlm[:, self.idx[l, m]] = data[:, k] + 1j * data[:, k + 1]
                k += 2

        # ddw in case B is stored
        if field == 'B':
            self.ddwlm = np.zeros((self.nstep, self.lm_max_r), 'Complex64')
            self.ddwlm[:, 1:self.l_max_r + 1] = data[:, k:k + self.l_max_r]
            k += self.l_max_r
            for m in range(self.minc, self.l_max_r + 1, self.minc):
                for l in range(m, self.l_max_r + 1):
                    self.ddwlm[:,
                               self.idx[l,
                                        m]] = data[:, k] + 1j * data[:, k + 1]
                    k += 2

        # Truncate!
        if lCut is not None:
            if lCut < self.l_max_r:
                self.truncate(lCut, field=field)

        self.e_pol_axi_l = np.zeros((self.nstep, self.l_max_r + 1), precision)
        self.e_tor_axi_l = np.zeros((self.nstep, self.l_max_r + 1), precision)
        self.e_pol_l = np.zeros((self.nstep, self.l_max_r + 1), precision)
        self.e_tor_l = np.zeros((self.nstep, self.l_max_r + 1), precision)

        for l in range(1, self.l_max_r + 1):
            self.e_pol_l[:, l] = 0.
            self.e_tor_l[:, l] = 0.
            self.e_pol_axi_l[:, l] = 0.
            self.e_tor_axi_l[:, l] = 0.
            for m in range(0, l + 1, self.minc):
                lm = self.idx[l, m]

                if m == 0:
                    epol = 0.5*self.ell[lm]*(self.ell[lm]+1)*( \
                           self.ell[lm]*(self.ell[lm]+1)/self.radius**2* \
                           abs(self.wlm[:,lm])**2+ abs(self.dwlm[:,lm])**2 )
                    etor = 0.5 * self.ell[lm] * (self.ell[lm] + 1) * abs(
                        self.zlm[:, lm])**2

                    self.e_pol_axi_l[:, l] += epol
                    self.e_tor_axi_l[:, l] += etor
                else:
                    epol = self.ell[lm]*(self.ell[lm]+1)*( \
                           self.ell[lm]*(self.ell[lm]+1)/self.radius**2* \
                           abs(self.wlm[:,lm])**2+ abs(self.dwlm[:,lm])**2 )
                    etor = self.ell[lm] * (self.ell[lm] + 1) * abs(
                        self.zlm[:, lm])**2

                self.e_pol_l[:, l] += epol
                self.e_tor_l[:, l] += etor

        # Time-averaged energy
        facT = 1. / (self.time[-1] - self.time[0])

        self.e_pol_lM = facT * np.trapz(self.e_pol_l, self.time, axis=0)
        self.e_tor_lM = facT * np.trapz(self.e_tor_l, self.time, axis=0)
        self.e_pol_axi_lM = facT * np.trapz(
            self.e_pol_axi_l, self.time, axis=0)
        self.e_tor_axi_lM = facT * np.trapz(
            self.e_tor_axi_l, self.time, axis=0)
Example #6
0
    def __init__(self,
                 tag=None,
                 datadir='.',
                 ratio_cmb_surface=1,
                 scale_b=1,
                 iplot=True,
                 lCut=None,
                 precision='Float64',
                 ave=False,
                 sv=False,
                 quiet=False):
        """
        A class to read the B_coeff_cmb files

        :param tag: if you specify a pattern, it tries to read the corresponding files
        :type tag: str
        :param ratio_cmb_surface: ratio of surface ratio to CMB radius (default is 1)
        :type ratio_cmb_surface: float
        :param scale_b: magnetic field unit (default is 1)
        :type scale_b: float
        :param iplot: a logical to toggle the plot (default is True)
        :type iplot: int
        :param precision: single or double precision
        :type precision: char
        :param ave: load a time-averaged CMB file when set to True
        :type ave: bool
        :param sv: load a dt_b CMB file when set to True
        :type sv: bool
        :param quiet: verbose when toggled to True (default is True)
        :type quiet: bool
        :param lCut: reduce the spherical harmonic truncation to l <= lCut
        :type lCut: int
        :param datadir: working directory
        :type datadir: str
        """
        pattern = os.path.join(datadir, 'log.*')
        logFiles = scanDir(pattern)

        if ave:
            self.name = 'B_coeff_cmb_ave'
        elif sv:
            self.name = 'B_coeff_dt_cmb'
        else:
            self.name = 'B_coeff_cmb'

        if tag is not None:
            pattern = os.path.join(datadir, '%s.%s' % (self.name, tag))
            files = scanDir(pattern)

            # Either the log.tag directly exists and the setup is easy to obtain
            if os.path.exists(os.path.join(datadir, 'log.%s' % tag)):
                MagicSetup.__init__(self,
                                    datadir=datadir,
                                    quiet=True,
                                    nml='log.%s' % tag)
            # Or the tag is a bit more complicated and we need to find
            # the corresponding log file
            else:
                pattern = os.path.join(datadir, '%s' % self.name)
                mask = re.compile(r'%s\.(.*)' % pattern)
                if mask.match(files[-1]):
                    ending = mask.search(files[-1]).groups(0)[0]
                    pattern = os.path.join(datadir, 'log.%s' % ending)
                    if logFiles.__contains__(pattern):
                        MagicSetup.__init__(self,
                                            datadir=datadir,
                                            quiet=True,
                                            nml='log.%s' % ending)
        else:
            pattern = os.path.join(datadir, '%s.*' % self.name)
            files = scanDir(pattern)
            filename = files[-1]
            # Determine the setup
            mask = re.compile(r'%s\.(.*)' % self.name)
            ending = mask.search(files[-1]).groups(0)[0]
            if os.path.exists('log.%s' % ending):
                try:
                    MagicSetup.__init__(self,
                                        datadir=datadir,
                                        quiet=True,
                                        nml='log.%s' % ending)
                except AttributeError:
                    pass

        self.rcmb = 1. / (1. - self.radratio)
        ricb = self.radratio / (1. - self.radratio)

        # Read the B_coeff files (by stacking the different tags)
        data = []
        for k, file in enumerate(files):
            if not quiet: print('Reading %s' % file)
            f = npfile(file, endian='B')
            self.l_max_cmb, self.minc, n_data = f.fort_read('i')
            self.m_max_cmb = int((self.l_max_cmb / self.minc) * self.minc)

            while 1:
                try:
                    data.append(f.fort_read(precision))
                except TypeError:
                    break
        self.lm_max_cmb = self.m_max_cmb*(self.l_max_cmb+1)//self.minc - \
                          self.m_max_cmb*(self.m_max_cmb-self.minc)//(2*self.minc) + \
                          self.l_max_cmb-self.m_max_cmb+1

        # Get indices location
        self.idx = np.zeros((self.l_max_cmb + 1, self.m_max_cmb + 1), 'i')
        self.ell = np.zeros(self.lm_max_cmb, 'i')
        self.ms = np.zeros(self.lm_max_cmb, 'i')
        self.idx[0:self.l_max_cmb + 2, 0] = np.arange(self.l_max_cmb + 1)
        self.ell[0:self.l_max_cmb + 2] = np.arange(self.l_max_cmb + 2)
        k = self.l_max_cmb + 1
        for m in range(self.minc, self.l_max_cmb + 1, self.minc):
            for l in range(m, self.l_max_cmb + 1):
                self.idx[l, m] = k
                self.ell[self.idx[l, m]] = l
                self.ms[self.idx[l, m]] = m
                k += 1

        # Rearange data
        data = np.array(data, dtype=precision)
        self.nstep = data.shape[0]
        self.blm = np.zeros((self.nstep, self.lm_max_cmb), 'Complex64')
        self.blm[:, 1:self.l_max_cmb + 1] = data[:, 1:self.l_max_cmb + 1]
        self.blm[:, self.l_max_cmb+1:] = data[:, self.l_max_cmb+1::2]+\
                                         1j*data[:, self.l_max_cmb+2::2]

        # Truncate!
        if lCut is not None:
            if lCut < self.l_max_cmb:
                self.truncate(lCut)

        # Get time
        self.time = np.zeros(self.nstep, precision)
        self.time = data[:, 0]

        # Get Gauss coefficients
        self.glm = np.zeros((self.nstep, self.lm_max_cmb), precision)
        self.hlm = np.zeros((self.nstep, self.lm_max_cmb), precision)

        self.glm, self.hlm = getGauss(self.blm.real, self.blm.imag, self.ell,
                                      self.ms, scale_b, ratio_cmb_surface,
                                      self.rcmb)

        # Time-averaged Gauss coefficient
        if not ave:
            facT = 1. / (self.time[-1] - self.time[0])
            self.glmM = facT * np.trapz(self.glm, self.time, axis=0)
            self.hlmM = facT * np.trapz(self.hlm, self.time, axis=0)

            if len(self.time) > 3:
                self.dglmdt = deriv(self.time, self.glm.T, axis=1)
                self.dhlmdt = deriv(self.time, self.hlm.T, axis=1)
                self.dglmdt = self.dglmdt.T
                self.dhlmdt = self.dhlmdt.T

            else:
                self.dglmdt = np.zeros_like(self.glm)
                self.dhlmdt = np.zeros_like(self.hlm)

        # Magnetic energy (Lowes)
        self.El = np.zeros((self.nstep, self.l_max_cmb + 1), precision)
        self.Em = np.zeros((self.nstep, self.m_max_cmb + 1), precision)
        self.ESVl = np.zeros((self.nstep, self.l_max_cmb + 1), precision)
        E = 0.
        for l in range(1, self.l_max_cmb + 1):
            self.El[:, l] = 0.
            self.ESVl[:, l] = 0.
            for m in range(0, l + 1, self.minc):
                lm = self.idx[l, m]
                self.El[:, l] += (self.ell[lm]+1)*\
                                (self.glm[:,lm]**2+self.hlm[:,lm]**2)
                self.Em[:, m] += (self.ell[lm]+1)*\
                                (self.glm[:,lm]**2+self.hlm[:,lm]**2)
                if not ave:
                    self.ESVl[:, l] += (self.ell[lm]+1)*\
                                      (self.dglmdt[:, lm]**2+self.dhlmdt[:, lm]**2)

        if not ave:
            # Time-averaged energy
            self.ElM = facT * np.trapz(self.El, self.time, axis=0)
            self.EmM = facT * np.trapz(self.Em, self.time, axis=0)

            # Secular variation
            self.ESVlM = facT * np.trapz(self.ESVl, self.time, axis=0)
            self.taul = np.sqrt(self.ElM[1:] / self.ESVlM[1:])

        if iplot:
            self.plot()
def MagicCheck(tstart=None):
    """
    This function is used to compute several sanity checks that can be evaluated
    if the power.TAG and some spectra have been produced in the current directory.
    If in addition the tInitAvg file is also there in the directory it averages
    only from this starting time.
    
    >>> MagicCheck(tstart=10.)
    """

    if os.path.exists('tInitAvg'):
        file = open('tInitAvg', 'r')
        tstart = float(file.readline().strip('\n'))
        file.close()

    if tstart is None:
        tstart = 0.

    ts = MagicTs(field='power', all=True, iplot=False)
    ts1 = MagicTs(field='dtE', all=True, iplot=False)
    mask = (ts.time >= tstart)
    # Not super accurate if n_log_step changed but better that nothing
    n_steps = len(ts.time[mask]) * ts.n_log_step

    dEdt = ts.buoPower + ts.buoPower_chem + ts.ohmDiss + ts.viscDiss

    # Power balance:
    buoPower_avg = avgField(ts.time[mask], ts.buoPower[mask])
    buoPower_chem_avg = avgField(ts.time[mask], ts.buoPower_chem[mask])
    ohmDiss_avg = avgField(ts.time[mask], ts.ohmDiss[mask])
    viscDiss_avg = avgField(ts.time[mask], ts.viscDiss[mask])
    ratio = 100*abs(buoPower_avg+buoPower_chem_avg+ohmDiss_avg+viscDiss_avg) / \
            (buoPower_avg+buoPower_chem_avg)

    print(bcolors.BOLD + bcolors.UNDERLINE + 'Power balance:' + bcolors.ENDC)
    print('Power injected   : {:.5e}'.format(buoPower_avg + buoPower_chem_avg))
    print('Power dissipated : {:.5e}'.format(-ohmDiss_avg - viscDiss_avg))
    st = 'Power mis-balance: {:.3f} %%'.format(ratio)
    if ratio <= 0.5:
        print(bcolors.OKGREEN + st + bcolors.ENDC)
    elif ratio > 0.5 and ratio <= 1.:
        print(bcolors.MODERATE + st + bcolors.ENDC)
    elif ratio > 1.:
        print(bcolors.WARNING + st + bcolors.ENDC)

    # Spikes catcher in the time series of power/dEdt
    print('\n' + bcolors.BOLD + bcolors.UNDERLINE + 'Time resolution:' +
          bcolors.ENDC)
    absdEdt_avg = avgField(ts1.time[mask], abs(ts1.dEdt[mask]))
    field = abs(dEdt[mask] - ts1.dEdt[mask])
    mask_spike = (field >= absdEdt_avg)
    l_spikes = False
    if mask_spike.any():
        l_spikes = True
    if l_spikes:
        print(bcolors.MODERATE +
              'Sudden variations detected in power balance!' + bcolors.ENDC)
        ones = np.ones_like(ts.time[mask])
        ones[~mask_spike] = 0.
        ttot_spikes = np.trapz(ones, ts.time[mask])
        ttot = ts.time[-1] - ts.time[0]
        ratio = ttot_spikes / ttot
        print('    -Time fraction with spikes: {:.3f} %%'.format(100. * ratio))
        largest = abs(field).max() / absdEdt_avg
        st = '    -Largest event            : {:.2f} <|dE/dt|>'.format(largest)
        if largest > 10:
            print(bcolors.WARNING + st + bcolors.ENDC)
        else:
            print(bcolors.MODERATE + st + bcolors.ENDC)
    else:
        print(bcolors.OKGREEN + 'Power balance clean!' + bcolors.ENDC)

    # Timestep change occurence
    files = scanDir('timestep.*')
    if len(files) > 0:
        ts = MagicTs(field='timestep', iplot=False, all=True)
        mask = (ts.time >= tstart)
        ddt = np.diff(ts.time[mask])
        ddt_neq_zero = (ddt != 0.)
        ddt = ddt[ddt_neq_zero]
        print('\nNumber of time step changes   : {}'.format(len(ddt)))
        print('Number of iterations          : {}'.format(n_steps))
        freq = int(float(n_steps) / float(len(ddt)))
        print('Average number of iterations with fixed time step size: {}'.
              format(freq))
        time = ts.time[mask][1:][ddt_neq_zero]
        dt = ts.dt[mask][1:][ddt_neq_zero]
        dtMean = avgField(time, dt)
        mask_changes = (ddt <= 50 * dtMean)
        ones = np.ones_like(time)
        ones[~mask_changes] = 0.
        ttot_changes = np.sum(ones * ddt)
        fast_change_ratio = 100 * ttot_changes / (time[-1] - time[0])
        st = 'Fraction of time with frequent timestep changes (< 50 steps): {:.2f} %%'.format(
            fast_change_ratio)
        if fast_change_ratio < 2:
            print(bcolors.OKGREEN + st + bcolors.ENDC)
        elif fast_change_ratio >= 2 and fast_change_ratio <= 10:
            print(bcolors.MODERATE + st + bcolors.ENDC)
            print(bcolors.MODERATE + 'Maybe increase Courant factors!' +
                  bcolors.ENDC)
        else:
            print(bcolors.WARNING + st + bcolors.ENDC)
            print(bcolors.WARNING + 'Probably increase Courant factors!' +
                  bcolors.ENDC)

    # Dissipation lengthscales
    ts = MagicTs(field='par', all=True, iplot=False)
    mask = (ts.time >= tstart)
    lbDiss_avg = avgField(ts.time[mask], ts.lbDiss[mask])
    lvDiss_avg = avgField(ts.time[mask], ts.lvDiss[mask])

    ri = ts.radratio / (1. - ts.radratio)
    ro = 1. / (1. - ts.radratio)
    dmean = 0.5 * (ri + ro)
    lTrunc = dmean * np.pi / ts.l_max

    print('\n' + bcolors.BOLD + bcolors.UNDERLINE + 'Angular resolution:' +
          bcolors.ENDC)
    print('Viscous dissipation scale: {:.3e}'.format(lvDiss_avg))
    print('Ohmic dissipation scale  : {:.3e}'.format(lbDiss_avg))
    st = 'Angular truncation       : {:.3e}'.format(lTrunc)
    lMin = min(lvDiss_avg, lbDiss_avg)
    ellMin = int(np.pi * dmean / lMin)
    nphi = int(3. * ellMin)
    if lTrunc < lMin:
        print(bcolors.OKGREEN + st + bcolors.ENDC)
    elif lTrunc >= lMin and lTrunc < 1.5 * lMin:
        print(bcolors.MODERATE + st + bcolors.WARNING)
        st = 'You might need l_max={}, N_phi={}'.format(ellMin, nphi)
        print(bcolors.MODERATE + st + bcolors.WARNING)
    else:
        print(bcolors.WARNING + st + bcolors.WARNING)
        st = 'You might need l_max={}, N_phi={}'.format(ellMin, nphi)
        print(bcolors.WARNING + st + bcolors.WARNING)

    # Spectra
    dats = scanDir('kin_spec_ave.*')
    if len(dats) > 0:
        ave = True
    else:
        ave = False
    sp = MagicSpectrum(field='kin', iplot=False, ave=ave, quiet=True)
    ekin_l = sp.ekin_poll + sp.ekin_torl
    ratio = ekin_l.max() / ekin_l[-2]
    sp = MagicSpectrum(field='mag', iplot=False, ave=ave, quiet=True)
    emag_l = sp.emag_poll + sp.emag_torl
    ratio_mag = emag_l[2:].max() / emag_l[-2]
    ratio_cmb = sp.emagcmb_l[2:].max() / sp.emagcmb_l[-2]

    st = 'Vol. kin. energy spectra (largest/smallest): {:.2e}'.format(ratio)
    st_mag = 'Vol. mag. energy spectra (largest/smallest): {:.2e}'.format(
        ratio_mag)
    st_cmb = 'CMB mag. energy spectra (largest/smallest) : {:.2e}'.format(
        ratio_cmb)

    if ratio > 100:
        print(bcolors.OKGREEN + st + bcolors.ENDC)
    elif ratio <= 100 and ratio > 50:
        print(bcolors.MODERATE + st + bcolors.ENDC)
    else:
        print(bcolors.WARNING + st + bcolors.ENDC)
    if ratio_mag > 100:
        print(bcolors.OKGREEN + st_mag + bcolors.ENDC)
    elif ratio_mag <= 100 and ratio_mag > 50:
        print(bcolors.MODERATE + st_mag + bcolors.ENDC)
    else:
        print(bcolors.WARNING + st_mag + bcolors.ENDC)
    if ratio_cmb > 100:
        print(bcolors.OKGREEN + st_cmb + bcolors.ENDC)
    elif ratio_cmb <= 100 and ratio_cmb > 50:
        print(bcolors.MODERATE + st_cmb + bcolors.ENDC)
    else:
        print(bcolors.WARNING + st_cmb + bcolors.ENDC)

    # determine the relevant tags
    logs = scanDir('log.*')
    tags = []
    for lg in logs:
        stp = MagicSetup(nml=lg, quiet=True)
        if stp.start_time >= tstart and os.path.exists('eKinR.{}'.format(
                stp.tag)):
            tags.append(stp.tag)

    if len(tags) > 0:
        rad = MagicRadial(field='eKinR', iplot=False, quiet=True, tags=tags)
    else:
        rad = MagicRadial(field='eKinR', iplot=False, quiet=True)

    # Number of points in viscous BL
    print('\n' + bcolors.BOLD + bcolors.UNDERLINE + 'Radial resolution:' +
          bcolors.ENDC)
    if rad.ktopv != 1 and rad.kbotv != 1:
        eKR = rad.ekin_pol + rad.ekin_tor
    else:
        eKR = rad.ekin_pol
    ind = argrelextrema(eKR, np.greater)[0]
    ntop = ind[0] + 1
    nbot = len(eKR) - ind[-1]
    nmin = min(nbot, ntop)
    st_bot = 'Number of points in bottom viscous B.L.: {}'.format(nbot)
    st_top = 'Number of points in top viscous B.L.   : {}'.format(ntop)

    if nbot >= 10:
        print(bcolors.OKGREEN + st_bot + bcolors.ENDC)
    elif nbot >= 5 and nbot < 10:
        print(bcolors.MODERATE + st_bot + bcolors.ENDC)
    else:
        print(bcolors.WARNING + st_bot + bcolors.ENDC)
    if ntop >= 10:
        print(bcolors.OKGREEN + st_top + bcolors.ENDC)
    elif ntop >= 5 and ntop < 10:
        print(bcolors.MODERATE + st_top + bcolors.ENDC)
    else:
        print(bcolors.WARNING + st_top + bcolors.ENDC)

    # Number of points in thermal BL
    if len(tags) > 0:
        rad = MagicRadial(field='heatR', iplot=False, quiet=True, tags=tags)
    else:
        rad = MagicRadial(field='heatR', iplot=False, quiet=True)
    if rad.ktops == 1:
        ind = argrelextrema(rad.entropy_SD, np.greater)[0]
        ntop = ind[0] + 1
        st_top = 'Number of points in top thermal B.L.   : {}'.format(ntop)
        if ntop >= 10:
            print(bcolors.OKGREEN + st_top + bcolors.ENDC)
        elif ntop >= 5 and ntop < 10:
            print(bcolors.MODERATE + st_top + bcolors.ENDC)
        else:
            print(bcolors.WARNING + st_top + bcolors.ENDC)

    if rad.kbots == 1:
        ind = argrelextrema(rad.entropy_SD, np.greater)[0]
        nbot = len(rad.radius) - ind[-1]
        st_bot = 'Number of points in bottom thermal B.L.: {}'.format(nbot)
        if nbot >= 10:
            print(bcolors.OKGREEN + st_bot + bcolors.ENDC)
        elif nbot >= 5 and nbot < 10:
            print(bcolors.MODERATE + st_bot + bcolors.ENDC)
        else:
            print(bcolors.WARNING + st_bot + bcolors.ENDC)
Example #8
0
    def __init__(self, iplot=False, quiet=False):
        """
        :param iplot: display the result when set to True (default False)
        :type iplot: bool
        :param quiet: less verbose when set to True (default is False)
        :type quiet: bool
        """
        if os.path.exists('tInitAvg'):
            file = open('tInitAvg', 'r')
            tstart = float(file.readline())
            file.close()
            logFiles = scanDir('log.*')
            tags = []
            for lg in logFiles:
                nml = MagicSetup(quiet=True, nml=lg)
                if nml.start_time > tstart:
                    if os.path.exists('bLayersR.{}'.format(nml.tag)):
                        tags.append(nml.tag)
            if len(tags) > 0:
                print(tags)
            else:
                tags = None
            MagicSetup.__init__(self, quiet=True, nml=logFiles[-1])

            a = AvgField(model=json_model, write=False)
            self.nuss = 0.5 * (a.topnuss_av + a.botnuss_av)
            self.reynolds = a.rm_av
            e2fluct = a.ekin_pol_av + a.ekin_tor_av - a.ekin_pol_axi_av - a.ekin_tor_axi_av
        else:
            logFiles = scanDir('log.*')
            MagicSetup.__init__(self, quiet=True, nml=logFiles[-1])
            tags = None
            self.nuss = 1.
            self.reynolds = 1.
            e2fluct = 1.
        par = MagicRadial(field='bLayersR', iplot=False, tags=tags)
        self.varS = abs(par.entropy_SD)
        self.ss = par.entropy

        if os.path.exists('tInitAvg'):
            logFiles = scanDir('log.*', tfix=1409827718.0)
            # Workaround for code mistake before this time
            tfix = 1409827718.0
            tagsFix = []
            for lg in logFiles:
                nml = MagicSetup(quiet=True, nml=lg)
                if nml.start_time > tstart:
                    if os.path.exists('bLayersR.{}'.format(nml.tag)):
                        tagsFix.append(nml.tag)
            if len(tagsFix) > 0:
                print('Fix temp. tags', tagsFix)
                parFix = MagicRadial(field='bLayersR',
                                     iplot=False,
                                     tags=tagsFix)
                self.varS = abs(parFix.entropy_SD)
                self.ss = parFix.entropy

            self.tags = tagsFix
        self.uh = par.uh
        self.duh = par.duhdr
        self.rad = par.radius
        self.ro = self.rad[0]
        self.ri = self.rad[-1]

        vol_oc = 4. / 3. * np.pi * (self.ro**3 - self.ri**3)
        self.rey_fluct = np.sqrt(2. * e2fluct / vol_oc)

        self.reh = 4. * np.pi * intcheb(self.rad**2 * self.uh,
                                        len(self.rad) - 1, self.ri,
                                        self.ro) / (4. / 3. * np.pi *
                                                    (self.ro**3 - self.ri**3))

        # Thermal dissipation boundary layer
        if hasattr(par, 'dissS'):
            self.dissS = par.dissS
            self.epsT = -4. * np.pi * intcheb(self.rad**2 * self.dissS,
                                              len(self.rad) - 1, self.ro,
                                              self.ri)
            self.epsTR = 4. * np.pi * self.rad**2 * self.dissS
            ind = getMaxima(-abs(self.epsTR - self.epsT))

            try:
                self.dissTopS = self.ro - self.rad[ind[0]]
                self.dissBotS = self.rad[ind[-1]] - self.ri
                self.dissEpsTbl, self.dissEpsTbulk = integBulkBc(
                    self.rad, self.epsTR, self.ri, self.ro, self.dissBotS,
                    self.dissTopS)
            except IndexError:
                self.dissTopS = self.ro
                self.dissBotS = self.ri
                self.dissEpsTbl, self.dissEpsTbulk = 0., 0.

            print('thDiss bl, bulk', self.dissEpsTbl / self.epsT,
                  self.dissEpsTbulk / self.epsT)
        # First way of defining the thermal boundary layers: with var(S)
        #rThLayer = getMaxima(self.rad, self.varS)
        ind = argrelextrema(self.varS, np.greater)[0]
        if len(ind) != 0:
            self.bcTopVarS = self.ro - self.rad[ind[0]]
            self.bcBotVarS = self.rad[ind[-1]] - self.ri
        else:
            self.bcTopVarS = 1.
            self.bcBotVarS = 1.
        if hasattr(self, 'epsT'):
            self.varSEpsTbl, self.varSEpsTbulk = integBulkBc(
                self.rad, self.epsTR, self.ri, self.ro, self.bcBotVarS,
                self.bcTopVarS)
            print('var(S) bl, bulk', self.varSEpsTbl / self.epsT,
                  self.varSEpsTbulk / self.epsT)

        # Second way of defining the thermal boundary layers: intersection of the slopes
        d1 = matder(len(self.rad) - 1, self.ro, self.ri)
        self.ttm = 3.*intcheb(self.ss*self.rad**2, len(self.rad)-1, self.ri, self.ro) \
                   /(self.ro**3-self.ri**3)
        dsdr = np.dot(d1, self.ss)
        self.beta = dsdr[len(dsdr) // 2]
        print('beta={:.2f}'.format(self.beta))
        self.slopeTop = dsdr[2] * (self.rad - self.ro) + self.ss[0]
        self.slopeBot = dsdr[-1] * (self.rad - self.ri) + self.ss[-1]

        self.dtdrm = dsdr[len(self.ss) // 2]
        tmid = self.ss[len(self.ss) // 2]
        self.slopeMid = self.dtdrm * (self.rad -
                                      self.rad[len(self.rad) // 2]) + tmid

        self.bcTopSlope = (tmid - self.ss[0]) / (self.dtdrm - dsdr[2])
        self.bcBotSlope = -(tmid - self.ss[-1]) / (self.dtdrm - dsdr[-1])

        # 2nd round with a more accurate slope
        bSlope = dsdr[self.rad <= self.ri + self.bcBotSlope / 4.].mean()
        tSlope = dsdr[self.rad >= self.ro - self.bcTopSlope / 4.].mean()
        self.slopeBot = bSlope * (self.rad - self.ri) + self.ss[-1]
        self.slopeTop = tSlope * (self.rad - self.ro) + self.ss[0]
        #self.bcTopSlope = -(self.ttm-self.ss[0])/tSlope
        self.bcTopSlope = -(tmid-self.dtdrm*self.rad[len(self.rad)//2] - self.ss[0] \
                          + tSlope*self.ro)/(self.dtdrm-tSlope)
        self.bcBotSlope = -(tmid-self.dtdrm*self.rad[len(self.rad)//2] - self.ss[-1] \
                          + bSlope*self.ri)/(self.dtdrm-bSlope)
        self.dto = tSlope * (self.bcTopSlope - self.ro) + self.ss[0]
        self.dti = bSlope * (self.bcBotSlope - self.ri) + self.ss[-1]
        self.dto = self.dto - self.ss[0]
        self.dti = self.ss[-1] - self.dti

        self.bcTopSlope = self.ro - self.bcTopSlope
        self.bcBotSlope = self.bcBotSlope - self.ri

        if hasattr(self, 'epsT'):
            self.slopeEpsTbl, self.slopeEpsTbulk = integBulkBc(
                self.rad, self.epsTR, self.ri, self.ro, self.bcBotSlope,
                self.bcTopSlope)

            print('slopes bl, bulk', self.slopeEpsTbl / self.epsT,
                  self.slopeEpsTbulk / self.epsT)

        self.vi = a.viscDissR_av
        self.buo = a.buoPowerR_av

        self.epsV = -intcheb(self.vi, len(self.rad) - 1, self.ro, self.ri)
        ind = getMaxima(-abs(self.vi - self.epsV))
        if len(ind) > 2:
            for i in ind:
                if self.vi[i - 1] - self.epsV > 0 and self.vi[
                        i + 1] - self.epsV < 0:
                    self.dissTopV = self.ro - self.rad[i]
                elif self.vi[i - 1] - self.epsV < 0 and self.vi[
                        i + 1] - self.epsV > 0:
                    self.dissBotV = self.rad[i] - self.ri
        else:
            self.dissTopV = self.ro - self.rad[ind[0]]
            self.dissBotV = self.rad[ind[-1]] - self.ri
        try:
            self.dissEpsVbl, self.dissEpsVbulk = integBulkBc(
                self.rad, self.vi, self.ri, self.ro, self.dissBotV,
                self.dissTopV)
        except AttributeError:
            self.dissTopV = 0.
            self.dissBotV = 0.
            self.dissEpsVbl = 0.
            self.dissEpsVbulk = 0.

        print('visc Diss bl, bulk', self.dissEpsVbl / self.epsV,
              self.dissEpsVbulk / self.epsV)

        # First way of defining the viscous boundary layers: with duhdr
        #rViscousLayer = getMaxima(self.rad, self.duh)
        if self.kbotv == 1 and self.ktopv == 1:
            ind = argrelextrema(self.duh, np.greater)[0]
            if len(ind) == 0:
                self.bcTopduh = 1.
                self.bcBotduh = 1.
            else:
                if ind[0] < 4:
                    self.bcTopduh = self.ro - self.rad[ind[1]]
                else:
                    self.bcTopduh = self.ro - self.rad[ind[0]]
                if len(self.rad) - ind[-1] < 4:
                    self.bcBotduh = self.rad[ind[-2]] - self.ri
                else:
                    self.bcBotduh = self.rad[ind[-1]] - self.ri
            self.slopeTopU = 0.
            self.slopeBotU = 0.
            self.uhTopSlope = 0.
            self.uhBotSlope = 0.
            self.slopeEpsUbl = 0.
            self.slopeEpsUbulk = 0.
            self.uhBot = 0.
            self.uhTop = 0.
        else:
            ind = argrelextrema(self.uh, np.greater)[0]
            if len(ind) == 1:
                ind = argrelextrema(self.uh, np.greater_equal)[0]
            if len(ind) == 0:
                self.bcTopduh = 1.
                self.bcBotduh = 1.
            else:
                if ind[0] < 4:
                    self.bcTopduh = self.ro - self.rad[ind[1]]
                else:
                    self.bcTopduh = self.ro - self.rad[ind[0]]
                if len(self.rad) - ind[-1] < 4:
                    self.bcBotduh = self.rad[ind[-2]] - self.ri
                else:
                    self.bcBotduh = self.rad[ind[-1]] - self.ri

            self.uhTop = self.uh[self.rad == self.ro - self.bcTopduh][0]
            self.uhBot = self.uh[self.rad == self.ri + self.bcBotduh][0]

            self.bcBotduh, self.bcTopduh, self.uhBot, self.uhTop =      \
                        getAccuratePeaks(self.rad, self.uh, self.uhTop, \
                                         self.uhBot, self.ri, self.ro)

            duhdr = np.dot(d1, self.uh)

            #1st round
            mask = (self.rad >= self.ro - self.bcTopduh / 4) * (self.rad <
                                                                self.ro)
            slopeT = duhdr[mask].mean()
            mask = (self.rad <= self.ri + self.bcBotduh / 4) * (self.rad >
                                                                self.ri)
            slopeB = duhdr[mask].mean()
            self.slopeTopU = slopeT * (self.rad - self.ro) + self.uh[0]
            self.slopeBotU = slopeB * (self.rad - self.ri) + self.uh[-1]
            self.uhTopSlope = -self.uhTop / slopeT
            self.uhBotSlope = self.uhBot / slopeB

            #2nd round
            mask = (self.rad >= self.ro - self.uhTopSlope / 4.) * (self.rad <
                                                                   self.ro)
            slopeT = duhdr[mask].mean()
            mask = (self.rad <= self.ri + self.uhBotSlope / 4) * (self.rad >
                                                                  self.ri)
            slopeB = duhdr[mask].mean()
            self.uhTopSlope = -self.uhTop / slopeT
            self.uhBotSlope = self.uhBot / slopeB

            self.slopeEpsUbl, self.slopeEpsUbulk = integBulkBc(
                self.rad, self.vi, self.ri, self.ro, self.uhBotSlope,
                self.uhTopSlope)

        self.uhEpsVbl, self.uhEpsVbulk = integBulkBc(self.rad, self.vi,
                                                     self.ri, self.ro,
                                                     self.bcBotduh,
                                                     self.bcTopduh)
        print('uh bl, bulk', self.uhEpsVbl / self.epsV,
              self.uhEpsVbulk / self.epsV)

        # Convective Rol in the thermal boundary Layer
        ekinNas = a.ekin_polR_av + a.ekin_torR_av - a.ekin_pol_axiR_av - a.ekin_tor_axiR_av
        ReR = np.sqrt(2. * abs(ekinNas) / self.rad**2 / (4. * np.pi))

        self.dl = a.dlVcR_av
        RolC = ReR * self.ek / self.dl

        y = RolC[self.rad >= self.ro - self.bcTopSlope]
        x = self.rad[self.rad >= self.ro - self.bcTopSlope]
        try:
            self.rolTop = simps(3. * y * x**2,
                                x) / (self.ro**3 -
                                      (self.ro - self.bcTopSlope)**3)
        except IndexError:
            self.rolTop = 0.

        self.rolbl, self.rolbulk = integBulkBc(self.rad,
                                               4. * np.pi * RolC * self.rad**2,
                                               self.ri,
                                               self.ro,
                                               self.bcBotSlope,
                                               self.bcTopSlope,
                                               normed=True)

        self.rebl, self.rebulk = integBulkBc(self.rad,
                                             4. * np.pi * ReR * self.rad**2,
                                             self.ri,
                                             self.ro,
                                             self.bcBotSlope,
                                             self.bcTopSlope,
                                             normed=True)

        self.lengthbl, self.lengthbulk = integBulkBc(self.rad,
                                                     self.dl * 4. * np.pi *
                                                     self.rad**2,
                                                     self.ri,
                                                     self.ro,
                                                     self.bcBotSlope,
                                                     self.bcTopSlope,
                                                     normed=True)

        self.rehbl, self.rehbulk = integBulkBc(self.rad,
                                               self.uh * 4. * np.pi *
                                               self.rad**2,
                                               self.ri,
                                               self.ro,
                                               self.bcBotduh,
                                               self.bcTopduh,
                                               normed=True)

        y = RolC[self.rad <= self.ri + self.bcBotSlope]
        x = self.rad[self.rad <= self.ri + self.bcBotSlope]
        self.rolBot = simps(3. * y * x**2, x) / (
            (self.ri + self.bcBotSlope)**3 - self.ri**3)
        print('reynols bc, reynolds bulk', self.rebl, self.rebulk)
        print('reh bc, reh bulk', self.rehbl, self.rehbulk)
        print('rolbc, rolbulk, roltop, rolbot', self.rolbl, self.rolbulk,
              self.rolBot, self.rolTop)

        self.dl[0] = 0.
        self.dl[-1] = 0.
        self.lBot, self.lTop = integBotTop(self.rad,
                                           4. * np.pi * self.rad**2 * self.dl,
                                           self.ri,
                                           self.ro,
                                           self.bcBotSlope,
                                           self.bcTopSlope,
                                           normed=True)

        uhbm, utbm = integBotTop(self.rad,
                                 4. * np.pi * self.uh,
                                 self.ri,
                                 self.ro,
                                 self.bcBotSlope,
                                 self.bcTopSlope,
                                 normed=True)

        # Convective Rol in the thermal boundary Layer
        if len(scanDir('perpParR.*')) != 0:
            tags = []
            for lg in logFiles:
                nml = MagicSetup(quiet=True, nml=lg)
                if nml.start_time > tstart:
                    if os.path.exists('perpParR.{}'.format(nml.tag)):
                        tags.append(nml.tag)
            perpPar = MagicRadial(field='perpParR', iplot=False, tags=tags)
            eperpNas = perpPar.Eperp - perpPar.Eperp_axi
            eparNas = perpPar.Epar - perpPar.Epar_axi
            RePerpNas = np.sqrt(2. * abs(eperpNas))
            ReParNas = np.sqrt(2. * abs(eparNas))
            RePerp = np.sqrt(2. * abs(perpPar.Eperp))
            RePar = np.sqrt(2. * abs(perpPar.Epar))

            self.reperpbl, self.reperpbulk = integBulkBc(self.rad,
                                                         4. * np.pi * RePerp *
                                                         self.rad**2,
                                                         self.ri,
                                                         self.ro,
                                                         self.bcBotSlope,
                                                         self.bcTopSlope,
                                                         normed=True)
            self.reparbl, self.reparbulk = integBulkBc(self.rad,
                                                       4. * np.pi * RePar *
                                                       self.rad**2,
                                                       self.ri,
                                                       self.ro,
                                                       self.bcBotSlope,
                                                       self.bcTopSlope,
                                                       normed=True)
            self.reperpnasbl, self.reperpnasbulk = integBulkBc(
                self.rad,
                4. * np.pi * RePerpNas * self.rad**2,
                self.ri,
                self.ro,
                self.bcBotSlope,
                self.bcTopSlope,
                normed=True)
            self.reparnasbl, self.reparnasbulk = integBulkBc(
                self.rad,
                4. * np.pi * ReParNas * self.rad**2,
                self.ri,
                self.ro,
                self.bcBotSlope,
                self.bcTopSlope,
                normed=True)
        else:
            self.reperpbl = 0.
            self.reperpbulk = 0.
            self.reparbl = 0.
            self.reparbulk = 0.
            self.reperpnasbl = 0.
            self.reperpnasbulk = 0.
            self.reparnasbl = 0.
            self.reparnasbulk = 0.

        if iplot:
            self.plot()

        if not quiet:
            print(self)
Example #9
0
    def __init__(self, tag, field='Br', precision=np.float32, avg=False):
        """
        :param tag: if you specify a pattern, it tries to read the corresponding
                    files and stack them.
        :type tag: str
        :param field: nature of the radial spectra. Possible choices are
                      'Bt' or 'Bp'
        :type field: str
        :param precision: single or double precision (default single, i.e.
                          np.float32)
        :type precision: str
        :param avg: when set to True, display time averaged quantities
        :type avg: bool
        """

        logFiles = scanDir('log.*')
        if len(logFiles) != 0:
            MagicSetup.__init__(self, quiet=True, nml=logFiles[-1])
            self.n_r_max = int(self.n_r_max)
            self.n_r_ic_max = int(self.n_r_ic_max)
        else:
            n_r_max = 'n_r_max ?\n'
            self.n_r_max = int(input(str1))
            n_r_ic_max = 'n_r_ic_max ?\n'
            self.n_r_ic_max = int(input(str1))
            str1 = 'Aspect ratio ?\n'
            self.radratio = float(input(str1))

        self.n_r_tot = self.n_r_max + self.n_r_ic_max

        self.ricb = self.radratio / (1. - self.radratio)
        self.rcmb = 1. / (1. - self.radratio)
        outerCoreGrid = chebgrid(self.n_r_max - 1, self.rcmb, self.ricb)
        n_r_ic_tot = 2 * self.n_r_ic_max - 1
        innerCoreGrid = chebgrid(n_r_ic_tot - 1, self.ricb, -self.ricb)

        self.radius = np.zeros((self.n_r_tot - 1), dtype=precision)

        self.radius[:self.n_r_max] = outerCoreGrid
        self.radius[self.n_r_max - 1:] = innerCoreGrid[:self.n_r_ic_max]

        pattern = 'r{}'.format(field) + 'Spec'
        files = scanDir('{}.{}'.format(pattern, tag))

        # Read the rB[rp]Spec.TAG files (stack them)
        data = []
        for k, file in enumerate(files):
            print('Reading {}'.format(file))
            f = npfile(file, endian='B')

            while 1:
                try:
                    data.append(f.fort_read(precision))
                except TypeError:
                    break
        data = np.array(data, dtype=precision)

        # Time (every two lines only)
        self.time = data[::2, 0]

        # Poloidal/Toroidal energy for all radii for the 6 first spherical harmonic
        # degrees
        self.e_pol = np.zeros((len(self.time), self.n_r_tot - 1, 6),
                              dtype=precision)
        self.e_pol_axi = np.zeros_like(self.e_pol)

        self.e_pol[:, :, 0] = data[::2, 1:self.n_r_tot]
        self.e_pol[:, :, 1] = data[::2,
                                   self.n_r_tot - 1:2 * (self.n_r_tot - 1)]
        self.e_pol[:, :,
                   2] = data[::2,
                             2 * (self.n_r_tot - 1):3 * (self.n_r_tot - 1)]
        self.e_pol[:, :,
                   3] = data[::2,
                             3 * (self.n_r_tot - 1):4 * (self.n_r_tot - 1)]
        self.e_pol[:, :,
                   4] = data[::2,
                             4 * (self.n_r_tot - 1):5 * (self.n_r_tot - 1)]
        self.e_pol[:, :,
                   5] = data[::2,
                             5 * (self.n_r_tot - 1):6 * (self.n_r_tot - 1)]

        self.e_pol_axi[:, :, 0] = data[1::2, 1:self.n_r_tot]
        self.e_pol_axi[:, :, 1] = data[1::2,
                                       self.n_r_tot - 1:2 * (self.n_r_tot - 1)]
        self.e_pol_axi[:, :,
                       2] = data[1::2,
                                 2 * (self.n_r_tot - 1):3 * (self.n_r_tot - 1)]
        self.e_pol_axi[:, :,
                       3] = data[1::2,
                                 3 * (self.n_r_tot - 1):4 * (self.n_r_tot - 1)]
        self.e_pol_axi[:, :,
                       4] = data[1::2,
                                 4 * (self.n_r_tot - 1):5 * (self.n_r_tot - 1)]
        self.e_pol_axi[:, :,
                       5] = data[1::2,
                                 5 * (self.n_r_tot - 1):6 * (self.n_r_tot - 1)]

        if avg:
            self.plotAvg()
Example #10
0
    def __init__(self, iplot=False, quiet=False):
        """
        :param iplot: display the result when set to True (default False)
        :type iplot: bool
        :param quiet: less verbose when set to True (default is False)
        :type quiet: bool
        """
        if os.path.exists('tInitAvg'):
            file = open('tInitAvg', 'r')
            tstart = float(file.readline())
            file.close()
            logFiles = scanDir('log.*')
            tags = []
            for lg in logFiles:
                nml = MagicSetup(quiet=True, nml=lg)
                if nml.start_time >  tstart:
                    if os.path.exists('bLayersR.%s' % nml.tag):
                        tags.append(nml.tag)
            if len(tags) > 0:
                print(tags)
            else:
                tags = None
            MagicSetup.__init__(self, quiet=True, nml=logFiles[-1])

            a = AvgField()
            self.nuss = a.nuss
            self.reynolds = a.reynolds
        else:
            logFiles = scanDir('log.*')
            MagicSetup.__init__(self, quiet=True, nml=logFiles[-1])
            tags = None
            self.nuss = 1.
            self.reynolds = 1.
        par = MagicRadial(field='bLayersR', iplot=False, tags=tags)
        self.varS = N.sqrt(N.abs(par.varS))
        self.ss = par.entropy

        if os.path.exists('tInitAvg'):
            logFiles = scanDir('log.*', tfix=1409827718.0)
            # Workaround for code mistake before this time
            tfix = 1409827718.0
            tagsFix = []
            for lg in logFiles:
                nml = MagicSetup(quiet=True, nml=lg)
                if nml.start_time >  tstart:
                    if os.path.exists('bLayersR.%s' % nml.tag):
                        tagsFix.append(nml.tag)
            if len(tagsFix) > 0:
                print('Fix temp. tags', tagsFix)
                parFix = MagicRadial(field='bLayersR', iplot=False, tags=tagsFix)
                self.varS = N.sqrt(N.abs(parFix.varS))
                self.ss = parFix.entropy

            self.tags = tagsFix
        self.uh = par.uh
        self.duh = par.duhdr
        self.rad = par.radius
        self.ro = self.rad[0]
        self.ri = self.rad[-1]

        self.reh = 4.*N.pi*intcheb(self.rad**2*self.uh, len(self.rad)-1, 
                        self.ri, self.ro)/(4./3.*N.pi*(self.ro**3-self.ri**3))

        # Thermal dissipation boundary layer
        if hasattr(par, 'dissS'):
            self.dissS = par.dissS
            self.epsT = -4.*N.pi*intcheb(self.rad**2*self.dissS, len(self.rad)-1, 
                                         self.ro, self.ri)
            self.epsTR = 4.*N.pi*self.rad**2*self.dissS
            ind = getMaxima(-abs(self.epsTR-self.epsT))

            try:
                self.dissTopS = self.ro-self.rad[ind[0]]
                self.dissBotS = self.rad[ind[-1]]-self.ri
                self.dissEpsTbl, self.dissEpsTbulk = integBulkBc(self.rad, self.epsTR, 
                             self.ri, self.ro, self.dissBotS, self.dissTopS)
            except IndexError:
                self.dissTopS = self.ro
                self.dissBotS = self.ri
                self.dissEpsTbl, self.dissEpsTbulk = 0., 0.


            print('thDiss bl, bulk',  self.dissEpsTbl/self.epsT, self.dissEpsTbulk/self.epsT)
        # First way of defining the thermal boundary layers: with var(S)
        #rThLayer = getMaxima(self.rad, self.varS)
        ind = argrelextrema(self.varS, N.greater)[0]
        if len(ind) != 0:
            self.bcTopVarS = self.ro-self.rad[ind[0]]
            self.bcBotVarS = self.rad[ind[-1]]-self.ri
        else:
            self.bcTopVarS = 1.
            self.bcBotVarS = 1.
        if hasattr(self, 'epsT'):
            self.varSEpsTbl, self.varSEpsTbulk = integBulkBc(self.rad, self.epsTR, 
                         self.ri, self.ro, self.bcBotVarS, self.bcTopVarS)
            print('var(S) bl, bulk', self.varSEpsTbl/self.epsT, self.varSEpsTbulk/self.epsT)

        # Second way of defining the thermal boundary layers: intersection of the slopes
        d1 = matder(len(self.rad)-1, self.ro, self.ri)
        self.ttm = 3.*intcheb(self.ss*self.rad**2, len(self.rad)-1, self.ri, self.ro) \
                   /(self.ro**3-self.ri**3)
        dsdr = N.dot(d1, self.ss)
        self.beta = dsdr[len(dsdr)/2]
        print('beta', self.beta)
        self.slopeTop = dsdr[2]*(self.rad-self.ro)+self.ss[0]
        self.slopeBot = dsdr[-1]*(self.rad-self.ri)+self.ss[-1]

        self.dtdrm = dsdr[len(self.ss)/2]
        self.slopeMid = self.dtdrm*(self.rad-(self.ri+self.ro)/2.)+self.ss[len(self.ss)/2]

        #self.bcTopSlope = -(self.ttm-self.ss[0])/dsdr[2]
        self.bcTopSlope = (self.ss[len(self.ss)/2]-self.ss[0])/(self.dtdrm-dsdr[2])
        #self.bcBotSlope = (self.ttm-self.ss[-1])/(dsdr[-1])
        self.bcBotSlope = -(self.ss[len(self.ss)/2]-self.ss[-1])/(self.dtdrm-dsdr[-1])

        # 2nd round with a more accurate slope
        bSlope = dsdr[self.rad <= self.ri+self.bcBotSlope/4.].mean()
        tSlope = dsdr[self.rad >= self.ro-self.bcTopSlope/4.].mean()
        self.slopeBot = bSlope*(self.rad-self.ri)+self.ss[-1]
        self.slopeTop = tSlope*(self.rad-self.ro)+self.ss[0]
        #self.bcTopSlope = -(self.ttm-self.ss[0])/tSlope
        self.bcTopSlope = (self.ss[len(self.ss)/2]-self.ss[0])/(self.dtdrm-tSlope)
        #self.bcBotSlope = (self.ttm-self.ss[-1])/bSlope
        self.bcBotSlope = -(self.ss[len(self.ss)/2]-self.ss[-1])/(self.dtdrm-bSlope)


        if hasattr(self, 'epsT'):
            self.slopeEpsTbl, self.slopeEpsTbulk = integBulkBc(self.rad, self.epsTR, 
                         self.ri, self.ro, self.bcBotSlope, self.bcTopSlope)

            print('slopes bl, bulk', self.slopeEpsTbl/self.epsT, self.slopeEpsTbulk/self.epsT)
            
        pow = MagicRadial(field='powerR', iplot=False, tags=tags)
        self.vi = pow.viscDiss
        self.buo = pow.buoPower


        self.epsV = -intcheb(self.vi, len(self.rad)-1, self.ro, self.ri)
        ind = getMaxima(-abs(self.vi-self.epsV))
        if len(ind) > 2:
            for i in ind:
                if self.vi[i-1]-self.epsV > 0 and self.vi[i+1]-self.epsV < 0:
                    self.dissTopV = self.ro-self.rad[i]
                elif self.vi[i-1]-self.epsV < 0 and self.vi[i+1]-self.epsV > 0:
                    self.dissBotV = self.rad[i]-self.ri
        else:
            self.dissTopV = self.ro-self.rad[ind[0]]
            self.dissBotV = self.rad[ind[-1]]-self.ri
        self.dissEpsVbl, self.dissEpsVbulk = integBulkBc(self.rad, self.vi, 
                         self.ri, self.ro, self.dissBotV, self.dissTopV)
        print('visc Diss bl, bulk', self.dissEpsVbl/self.epsV, self.dissEpsVbulk/self.epsV)

        # First way of defining the viscous boundary layers: with duhdr
        #rViscousLayer = getMaxima(self.rad, self.duh)
        if self.kbotv == 1 and self.ktopv == 1:
            ind = argrelextrema(self.duh, N.greater)[0]
            if len(ind) == 0:
                self.bcTopduh = 1.
                self.bcBotduh = 1.
            else:
                if ind[0] < 4:
                    self.bcTopduh = self.ro-self.rad[ind[1]]
                else:
                    self.bcTopduh = self.ro-self.rad[ind[0]]
                if len(self.rad)-ind[-1] < 4:
                    self.bcBotduh = self.rad[ind[-2]]-self.ri
                else:
                    self.bcBotduh = self.rad[ind[-1]]-self.ri
            self.slopeTopU = 0.
            self.slopeBotU = 0.
            self.uhTopSlope = 0.
            self.uhBotSlope = 0.
            self.slopeEpsUbl = 0.
            self.slopeEpsUbulk = 0.
            self.uhBot = 0.
            self.uhTop = 0.
        else:
            ind = argrelextrema(self.uh, N.greater)[0]
            if len(ind) == 1:
                ind = argrelextrema(self.uh, N.greater_equal)[0]
            if len(ind) == 0:
                self.bcTopduh = 1.
                self.bcBotduh = 1.
            else:
                if ind[0] < 4:
                    self.bcTopduh = self.ro-self.rad[ind[1]]
                else:
                    self.bcTopduh = self.ro-self.rad[ind[0]]
                if len(self.rad)-ind[-1] < 4:
                    self.bcBotduh = self.rad[ind[-2]]-self.ri
                else:
                    self.bcBotduh = self.rad[ind[-1]]-self.ri

            self.uhTop = self.uh[self.rad==self.ro-self.bcTopduh][0]
            self.uhBot = self.uh[self.rad==self.ri+self.bcBotduh][0]

            self.bcBotduh, self.bcTopduh, self.uhBot, self.uhTop =      \
                        getAccuratePeaks(self.rad, self.uh, self.uhTop, \
                                         self.uhBot, self.ri, self.ro)

            duhdr = N.dot(d1, self.uh)

            #1st round
            mask = (self.rad>=self.ro-self.bcTopduh/4)*(self.rad<self.ro)
            slopeT = duhdr[mask].mean()
            mask = (self.rad<=self.ri+self.bcBotduh/4)*(self.rad>self.ri)
            slopeB = duhdr[mask].mean()
            self.slopeTopU = slopeT*(self.rad-self.ro)+self.uh[0]
            self.slopeBotU = slopeB*(self.rad-self.ri)+self.uh[-1]
            self.uhTopSlope = -self.uhTop/slopeT
            self.uhBotSlope = self.uhBot/slopeB

            #2nd round
            mask = (self.rad>=self.ro-self.uhTopSlope/4.)*(self.rad<self.ro)
            slopeT = duhdr[mask].mean()
            mask = (self.rad<=self.ri+self.uhBotSlope/4)*(self.rad>self.ri)
            slopeB = duhdr[mask].mean()
            self.uhTopSlope = -self.uhTop/slopeT
            self.uhBotSlope = self.uhBot/slopeB

            self.slopeEpsUbl, self.slopeEpsUbulk = integBulkBc(self.rad, self.vi, 
                         self.ri, self.ro, self.uhBotSlope, self.uhTopSlope)

        self.uhEpsVbl, self.uhEpsVbulk = integBulkBc(self.rad, self.vi, 
                         self.ri, self.ro, self.bcBotduh, self.bcTopduh)
        print('uh bl, bulk', self.uhEpsVbl/self.epsV, self.uhEpsVbulk/self.epsV)

        # Convective Rol in the thermal boundary Layer
        par = MagicRadial(field='parR', iplot=False, tags=tags)
        kin = MagicRadial(field='eKinR', iplot=False, tags=tags)
        ekinNas = kin.ekin_pol+kin.ekin_tor-kin.ekin_pol_axi-kin.ekin_tor_axi
        ReR = N.sqrt(2.*abs(ekinNas)/par.radius**2/(4.*N.pi))
        RolC = ReR*par.ek/par.dlVc

        self.dl = par.dlVc
        y = RolC[par.radius >= self.ro-self.bcTopSlope]
        x = par.radius[par.radius >= self.ro-self.bcTopSlope]
        self.rolTop = simps(3.*y*x**2, x)/(self.ro**3-(self.ro-self.bcTopSlope)**3)

        self.rolbl, self.rolbulk = integBulkBc(self.rad, 4.*N.pi*RolC*self.rad**2, 
                                     self.ri, self.ro, self.bcBotSlope, self.bcTopSlope,
                                     normed=True)

        self.rebl, self.rebulk = integBulkBc(self.rad, 4.*N.pi*ReR*self.rad**2, 
                                     self.ri, self.ro, self.bcBotduh, self.bcTopduh,
                                     normed=True)

        self.lengthbl, self.lengthbulk = integBulkBc(self.rad, par.dlVc, 
                                     self.ri, self.ro, self.bcBotSlope, self.bcTopSlope,
                                     normed=True)

        self.rehbl, self.rehbulk = integBulkBc(self.rad, self.uh*4.*N.pi*self.rad**2, 
                                     self.ri, self.ro, self.bcBotduh, self.bcTopduh,
                                     normed=True)

        y = RolC[par.radius <= self.ri+self.bcBotSlope]
        x = par.radius[par.radius <= self.ri+self.bcBotSlope]
        self.rolBot = simps(3.*y*x**2, x)/((self.ri+self.bcBotSlope)**3-self.ri**3)
        print('reynols bc, reynolds bulk', self.rebl, self.rebulk)
        print('reh bc, reh bulk', self.rehbl, self.rehbulk)
        print('rolbc, rolbulk, roltop, rolbot', self.rolbl, self.rolbulk, self.rolBot, self.rolTop)

        par.dlVc[0] = 0.
        par.dlVc[-1] = 0.
        self.lBot, self.lTop = integBotTop(self.rad, 4.*N.pi*self.rad**2*par.dlVc, 
                         self.ri, self.ro, self.bcBotSlope, self.bcTopSlope, normed=True)

        uhbm, utbm = integBotTop(self.rad, 4.*N.pi*self.uh, 
                         self.ri, self.ro, self.bcBotSlope, self.bcTopSlope, normed=True)

        if iplot:
            self.plot()

        if not quiet:
            print(self)
Example #11
0
    def __init__(self, tag, ratio_cmb_surface=1, scale_b=1, iplot=True,
                 precision='Float64', ave=False, sv=False):
        """
        A class to read the B_coeff_cmb files

        :param tag: if you specify a pattern, it tries to read the corresponding files
        :type tag: str
        :param ratio_cmb_surface: ratio of surface ratio to CMB radius (default is 1)
        :type ratio_cmb_surface: float
        :param scale_b: magnetic field unit (default is 1)
        :type scale_b: float
        :param iplot: a logical to toggle the plot (default is True)
        :type iplot: int
        :param precision: single or double precision
        :type precision: char
        :param ave: load a time-averaged CMB file when set to True
        :type ave: bool
        :param sv: load a dt_b CMB file when set to True
        :type sv: bool
        """

        logFiles = scanDir('log.*')
        if len(logFiles) != 0:
            MagicSetup.__init__(self, quiet=True, nml=logFiles[-1])
        else:
            str1 = 'Aspect ratio ?\n'
            self.radratio = float(input(str1))

        rcmb = 1./(1.-self.radratio)
        ricb = self.radratio/(1.-self.radratio)

        if ave:
            files = scanDir('B_coeff_cmb_ave.%s' % tag)
        elif sv:
            files = scanDir('B_coeff_dt_cmb.%s' % tag)
        else:
            files = scanDir('B_coeff_cmb.%s' % tag)

        # Read the B_coeff files (by stacking the different tags)
        data = []
        for k, file in enumerate(files):
            print('Reading %s' % file)
            f = npfile(file, endian='B')
            self.l_max_cmb, self.minc, n_data = f.fort_read('i')
            self.m_max_cmb = int((self.l_max_cmb/self.minc)*self.minc)

            while 1:
                try:
                    data.append(f.fort_read(precision))
                except TypeError:
                    break
        data = N.array(data, dtype=precision)

        self.ell = N.arange(self.l_max_cmb+1)
        self.nstep = data.shape[0]

        # Get time
        self.time = N.zeros(self.nstep, precision)
        self.time = data[:, 0]

        # Rearange and get Gauss coefficients
        self.alm = N.zeros((self.nstep, self.l_max_cmb+1, self.m_max_cmb+1), precision)
        self.blm = N.zeros((self.nstep, self.l_max_cmb+1, self.m_max_cmb+1), precision)
        self.glm = N.zeros((self.nstep, self.l_max_cmb+1, self.m_max_cmb+1), precision)
        self.hlm = N.zeros((self.nstep, self.l_max_cmb+1, self.m_max_cmb+1), precision)

        # Axisymmetric coefficients (m=0)
        self.alm[:, 1:, 0] = data[:, 1:self.l_max_cmb+1]
        self.glm[:, 1:, 0], self.hlm[:, 1:, 0] = getGauss(self.alm[:, 1:, 0], 
                     self.blm[:, 1:, 0], self.ell[1:], 0, scale_b, 
                     ratio_cmb_surface, rcmb)
        # Other coefficients (m!=0)
        k = self.l_max_cmb+1
        for m in range(self.minc, self.l_max_cmb+1, self.minc):
            for l in range(m, self.l_max_cmb+1):
                self.alm[:, l, m] = data[:, k]
                self.blm[:, l, m] = data[:, k+1]
                self.glm[:, l, m], self.hlm[:, l, m] = getGauss(self.alm[:, l, m], 
                                    self.blm[:, l, m], l, m,
                                    scale_b, ratio_cmb_surface, rcmb)
                k += 2

        # Time-averaged Gauss coefficient
        facT = 1./(self.time[-1]-self.time[0])
        self.glmM = facT * N.trapz(self.glm, self.time, axis=0)
        self.hlmM = facT * N.trapz(self.hlm, self.time, axis=0)

        if len(self.time) > 3:
            self.dglmdt = deriv(self.time, self.glm.T, axis=2)
            self.dhlmdt = deriv(self.time, self.hlm.T, axis=2)
            self.dglmdt = self.dglmdt.T
            self.dhlmdt = self.dhlmdt.T

        else:
            self.dglmdt = N.zeros_like(self.glm)
            self.dhlmdt = N.zeros_like(self.hlm)

        # Magnetic energy (Lowes)
        self.El = (self.ell+1)*(self.glm**2+self.hlm**2).sum(axis=2)
        self.Em = N.zeros((self.nstep, self.m_max_cmb+1), precision)
        # For m, we need to unfold the loop in case of minc != 1
        for m in range(0, self.m_max_cmb+1, self.minc):
            self.Em[:,m] = ((self.ell+1)*(self.glm[:, :, m]**2+self.hlm[:, :, m]**2)).sum(axis=1)
        #self.Em = ((self.ell+1)*(self.glm**2+self.hlm**2)).sum(axis=1)

        # Time-averaged energy
        self.ElM = facT * N.trapz(self.El, self.time, axis=0)
        self.EmM = facT * N.trapz(self.Em, self.time, axis=0)

        # Secular variation
        self.ESVl = (self.ell+1)*(self.dglmdt**2+self.dhlmdt**2).sum(axis=2)
        self.ESVlM = facT * N.trapz(self.ESVl, self.time, axis=0)
        self.taul = N.sqrt(self.ElM[1:]/self.ESVlM[1:])

        if iplot:
            self.plot()
Example #12
0
    def __init__(self, tag, ratio_cmb_surface=1, scale_b=1, iplot=True,
                 field='B', r=1, precision='Float64'):
        """
        :param tag: if you specify a pattern, it tries to read the corresponding files
        :type tag: str
        :param ratio_cmb_surface: ratio of surface ratio to CMB radius (default is 1)
        :type ratio_cmb_surface: float
        :param scale_b: magnetic field unit (default is 1)
        :type scale_b: float
        :param iplot: a logical to toggle the plot (default is True)
        :type iplot: bool
        :param field: 'B', 'V' or 'T' (magnetic field, velocity field or temperature)
        :type field: str
        :param r: an integer to characterise which file we want to plot
        :type r: int
        :param precision: single or double precision
        :type precision: str
        """

        logFiles = scanDir('log.*')
        if len(logFiles) != 0:
            MagicSetup.__init__(self, quiet=True, nml=logFiles[-1])
        else:
            str1 = 'Aspect ratio ?\n'
            self.radratio = float(input(str1))

        rcmb = 1./(1.-self.radratio)
        ricb = self.radratio/(1.-self.radratio)

        files = scanDir('%s_coeff_r%i.%s' % (field,r,tag))

        # Read the B_coeff files (by stacking the different tags)
        data = []
        for k, file in enumerate(files):
            print('Reading %s' % file)
            f = npfile(file, endian='B')
            out = f.fort_read('3i4,%s' % precision)[0]
            self.l_max_cmb, self.minc, n_data = out[0]
            self.m_max_cmb = int((self.l_max_cmb/self.minc)*self.minc)
            self.radius = out[1]

            while 1:
                try:
                    data.append(f.fort_read(precision))
                except TypeError:
                    break
        data = N.array(data, dtype=precision)

        self.ell = N.arange(self.l_max_cmb+1)
        self.nstep = data.shape[0]

        # Get time
        self.time = N.zeros(self.nstep, dtype=precision)
        self.time = data[:, 0]

        # Rearange and get Gauss coefficients
        self.wlm = N.zeros((self.nstep, self.l_max_cmb+1, self.m_max_cmb+1), 'Complex64')
        self.dwlm = N.zeros((self.nstep, self.l_max_cmb+1, self.m_max_cmb+1), 'Complex64')
        self.zlm = N.zeros((self.nstep, self.l_max_cmb+1, self.m_max_cmb+1), 'Complex64')

        # wlm
        # Axisymmetric coefficients (m=0)
        self.wlm[:, 1:, 0] = data[:, 1:self.l_max_cmb+1]
        # Other coefficients (m!=0)
        k = self.l_max_cmb+1
        for m in range(self.minc, self.l_max_cmb+1, self.minc):
            for l in range(m, self.l_max_cmb+1):
                self.wlm[:, l, m] = data[:, k]+1j*data[:, k+1]
                k += 2

        # dwlm
        self.dwlm[:, 1:, 0] = data[:, k:k+self.l_max_cmb]
        k += self.l_max_cmb
        for m in range(self.minc, self.l_max_cmb+1, self.minc):
            for l in range(m, self.l_max_cmb+1):
                self.dwlm[:, l, m] = data[:, k]+1j*data[:, k+1]
                k += 2
        # zlm
        self.zlm[:, 1:, 0] = data[:, k:k+self.l_max_cmb]
        k += self.l_max_cmb
        for m in range(self.minc, self.l_max_cmb+1, self.minc):
            for l in range(m, self.l_max_cmb+1):
                self.zlm[:, l, m] = data[:, k]+1j*data[:, k+1]
                k += 2

        # ddw in case B is stored
        if field == 'B':
            self.ddwlm = N.zeros((self.nstep, self.l_max_cmb+1, self.m_max_cmb+1), 'Complex64')
            self.ddwlm[:, 1:, 0] = data[:, k:k+self.l_max_cmb]
            k += self.l_max_cmb
            for m in range(self.minc, self.l_max_cmb+1, self.minc):
                for l in range(m, self.l_max_cmb+1):
                    self.ddwlm[:, l, m] = data[:, k]+1j*data[:, k+1]
                    k += 2

        #self.epolLM = 0.5*self.ell*(self.ell+1)* (self.ell*(self.ell+1)* \
        #                            abs(self.wlm)**2+abs(self.dwlm)**2)
        self.epolAxiL = 0.5*self.ell*(self.ell+1)*(self.ell*(self.ell+1)* \
                                    abs(self.wlm[:,:,0])**2+abs(self.dwlm[:,:,0])**2)
        #self.etorLM = 0.5*self.ell*(self.ell+1)*abs(self.zlm)**2
        self.etorAxiL = 0.5*self.ell*(self.ell+1)*abs(self.zlm[:,:,0])**2

        #epolTot = self.epolLM.sum(axis=1).sum(axis=1)
        #etorTot = self.etorLM.sum(axis=1).sum(axis=1)
        etorAxiTot = self.etorAxiL.sum(axis=1)
        epolAxiTot = self.epolAxiL.sum(axis=1)
        
        if iplot:
            P.plot(self.time, epolTot)
            P.plot(self.time, etorTot)
            P.plot(self.time, epolAxiTot)
            P.plot(self.time, etorAxiTot)
        
        """
Example #13
0
    def __init__(self, tag, ratio_cmb_surface=1, scale_b=1, iplot=True,
                 precision='Float64', ave=False, sv=False, quiet=False):
        """
        A class to read the B_coeff_cmb files

        :param tag: if you specify a pattern, it tries to read the corresponding files
        :type tag: str
        :param ratio_cmb_surface: ratio of surface ratio to CMB radius (default is 1)
        :type ratio_cmb_surface: float
        :param scale_b: magnetic field unit (default is 1)
        :type scale_b: float
        :param iplot: a logical to toggle the plot (default is True)
        :type iplot: int
        :param precision: single or double precision
        :type precision: char
        :param ave: load a time-averaged CMB file when set to True
        :type ave: bool
        :param sv: load a dt_b CMB file when set to True
        :type sv: bool
        :param quiet: verbose when toggled to True (default is True)
        :type quiet: bool
        """

        logFiles = scanDir('log.*')
        if len(logFiles) != 0:
            MagicSetup.__init__(self, quiet=True, nml=logFiles[-1])
        else:
            str1 = 'Aspect ratio ?\n'
            self.radratio = float(input(str1))

        self.rcmb = 1./(1.-self.radratio)
        ricb = self.radratio/(1.-self.radratio)

        if ave:
            files = scanDir('B_coeff_cmb_ave.%s' % tag)
        elif sv:
            files = scanDir('B_coeff_dt_cmb.%s' % tag)
        else:
            files = scanDir('B_coeff_cmb.%s' % tag)

        # Read the B_coeff files (by stacking the different tags)
        data = []
        for k, file in enumerate(files):
            if not quiet: print('Reading %s' % file)
            f = npfile(file, endian='B')
            self.l_max_cmb, self.minc, n_data = f.fort_read('i')
            self.m_max_cmb = int((self.l_max_cmb/self.minc)*self.minc)

            while 1:
                try:
                    data.append(f.fort_read(precision))
                except TypeError:
                    break
        self.lm_max_cmb = self.m_max_cmb*(self.l_max_cmb+1)//self.minc - \
                          self.m_max_cmb*(self.m_max_cmb-self.minc)//(2*self.minc) + \
                          self.l_max_cmb-self.m_max_cmb+1

        # Get indices location
        self.idx = np.zeros((self.l_max_cmb+1, self.m_max_cmb+1), 'i')
        self.ell = np.zeros(self.lm_max_cmb, 'i')
        self.ms = np.zeros(self.lm_max_cmb, 'i')
        self.idx[0:self.l_max_cmb+2, 0] = np.arange(self.l_max_cmb+1)
        self.ell[0:self.l_max_cmb+2] = np.arange(self.l_max_cmb+2)
        k = self.l_max_cmb+1
        for m in range(self.minc, self.l_max_cmb+1, self.minc):
            for l in range(m, self.l_max_cmb+1):
                self.idx[l, m] = k
                self.ell[self.idx[l,m]] = l
                self.ms[self.idx[l,m]] = m
                k +=1

        # Rearange data
        data = np.array(data, dtype=precision)
        self.nstep = data.shape[0]
        self.blm = np.zeros((self.nstep, self.lm_max_cmb), 'Complex64')
        self.blm[:, 1:self.l_max_cmb+1] = data[:, 1:self.l_max_cmb+1]
        self.blm[:, self.l_max_cmb+1:] = data[:, self.l_max_cmb+1::2]+\
                                         1j*data[:, self.l_max_cmb+2::2]

        # Get time
        self.time = np.zeros(self.nstep, precision)
        self.time = data[:, 0]

        # Get Gauss coefficients
        self.glm = np.zeros((self.nstep, self.lm_max_cmb), precision)
        self.hlm = np.zeros((self.nstep, self.lm_max_cmb), precision)

        self.glm, self.hlm = getGauss(self.blm.real, self.blm.imag, 
                                      self.ell, self.ms, scale_b, 
                                      ratio_cmb_surface, self.rcmb)

        # Time-averaged Gauss coefficient
        if not ave:
            facT = 1./(self.time[-1]-self.time[0])
            self.glmM = facT * np.trapz(self.glm, self.time, axis=0)
            self.hlmM = facT * np.trapz(self.hlm, self.time, axis=0)

            if len(self.time) > 3:
                self.dglmdt = deriv(self.time, self.glm.T, axis=1)
                self.dhlmdt = deriv(self.time, self.hlm.T, axis=1)
                self.dglmdt = self.dglmdt.T
                self.dhlmdt = self.dhlmdt.T

            else:
                self.dglmdt = np.zeros_like(self.glm)
                self.dhlmdt = np.zeros_like(self.hlm)

        # Magnetic energy (Lowes)
        self.El = np.zeros((self.nstep, self.l_max_cmb+1), precision)
        self.Em = np.zeros((self.nstep, self.m_max_cmb+1), precision)
        self.ESVl = np.zeros((self.nstep, self.l_max_cmb+1), precision)
        E = 0.
        for l in range(1, self.l_max_cmb+1):
            self.El[:, l] = 0.
            self.ESVl[:, l] = 0.
            for m in range(0, l+1, self.minc):
                lm = self.idx[l, m]
                self.El[:, l] += (self.ell[lm]+1)*\
                                (self.glm[:,lm]**2+self.hlm[:,lm]**2)
                self.Em[:, m] += (self.ell[lm]+1)*\
                                (self.glm[:,lm]**2+self.hlm[:,lm]**2)
                if not ave:
                    self.ESVl[:, l] += (self.ell[lm]+1)*\
                                      (self.dglmdt[:, lm]**2+self.dhlmdt[:, lm]**2)

        if not ave:
            # Time-averaged energy
            self.ElM = facT * np.trapz(self.El, self.time, axis=0)
            self.EmM = facT * np.trapz(self.Em, self.time, axis=0)

            # Secular variation
            self.ESVlM = facT * np.trapz(self.ESVl, self.time, axis=0)
            self.taul = np.sqrt(self.ElM[1:]/self.ESVlM[1:])

        if iplot:
            self.plot()
Example #14
0
    def __init__(self, tag, ratio_cmb_surface=1, scale_b=1, iplot=True,
                 field='B', r=1, precision='Float64', lCut=None, quiet=False):
        """
        :param tag: if you specify a pattern, it tries to read the corresponding files
        :type tag: str
        :param ratio_cmb_surface: ratio of surface ratio to CMB radius (default is 1)
        :type ratio_cmb_surface: float
        :param scale_b: magnetic field unit (default is 1)
        :type scale_b: float
        :param iplot: a logical to toggle the plot (default is True)
        :type iplot: bool
        :param field: 'B', 'V' or 'T' (magnetic field, velocity field or temperature)
        :type field: str
        :param r: an integer to characterise which file we want to plot
        :type r: int
        :param precision: single or double precision
        :type precision: str
        :param lCut: reduce the spherical harmonic truncation to l <= lCut
        :type lCut: int
        :param quiet: verbose when toggled to True (default is True)
        :type quiet: bool
        """

        logFiles = scanDir('log.*')
        if len(logFiles) != 0:
            MagicSetup.__init__(self, quiet=True, nml=logFiles[-1])
        else:
            str1 = 'Aspect ratio ?\n'
            self.radratio = float(input(str1))

        self.rcmb = 1./(1.-self.radratio)
        ricb = self.radratio/(1.-self.radratio)

        files = scanDir('%s_coeff_r%i.%s' % (field,r,tag))

        # Read the B_coeff files (by stacking the different tags)
        data = []
        for k, file in enumerate(files):
            if not quiet: print('Reading %s' % file)
            f = npfile(file, endian='B')
            out = f.fort_read('3i4,%s' % precision)[0]
            self.l_max_r, self.minc, n_data = out[0]
            self.m_max_r = int((self.l_max_r/self.minc)*self.minc)
            self.radius = out[1]

            while 1:
                try:
                    data.append(f.fort_read(precision))
                except TypeError:
                    break
        self.lm_max_r = self.m_max_r*(self.l_max_r+1)//self.minc - \
                        self.m_max_r*(self.m_max_r-self.minc)//(2*self.minc) + \
                        self.l_max_r-self.m_max_r+1

        # Get indices location
        self.idx = np.zeros((self.l_max_r+1, self.m_max_r+1), 'i')
        self.ell = np.zeros(self.lm_max_r, 'i')
        self.ms = np.zeros(self.lm_max_r, 'i')
        self.idx[0:self.l_max_r+2, 0] = np.arange(self.l_max_r+1)
        self.ell[0:self.l_max_r+2] = np.arange(self.l_max_r+2)
        k = self.l_max_r+1
        for m in range(self.minc, self.l_max_r+1, self.minc):
            for l in range(m, self.l_max_r+1):
                self.idx[l, m] = k
                self.ell[self.idx[l,m]] = l
                self.ms[self.idx[l,m]] = m
                k +=1


        # Rearange data
        data = np.array(data, dtype=precision)
        self.nstep = data.shape[0]
        self.wlm = np.zeros((self.nstep, self.lm_max_r), 'Complex64')
        self.dwlm = np.zeros((self.nstep, self.lm_max_r), 'Complex64')
        self.zlm = np.zeros((self.nstep, self.lm_max_r), 'Complex64')

        # Get time
        self.time = np.zeros(self.nstep, dtype=precision)
        self.time = data[:, 0]

        # wlm
        self.wlm[:, 1:self.l_max_r+1] = data[:, 1:self.l_max_r+1]
        k = self.l_max_r+1
        for m in range(self.minc, self.l_max_r+1, self.minc):
            for l in range(m, self.l_max_r+1):
                self.wlm[:, self.idx[l, m]] = data[:, k]+1j*data[:, k+1]
                k += 2

        # dwlm
        self.dwlm[:, 1:self.l_max_r+1] = data[:, k:k+self.l_max_r]
        k += self.l_max_r
        for m in range(self.minc, self.l_max_r+1, self.minc):
            for l in range(m, self.l_max_r+1):
                self.dwlm[:, self.idx[l, m]] = data[:, k]+1j*data[:, k+1]
                k += 2
        # zlm
        self.zlm[:, 1:self.l_max_r+1] = data[:, k:k+self.l_max_r]
        k += self.l_max_r
        for m in range(self.minc, self.l_max_r+1, self.minc):
            for l in range(m, self.l_max_r+1):
                self.zlm[:, self.idx[l, m]] = data[:, k]+1j*data[:, k+1]
                k += 2

        # ddw in case B is stored
        if field == 'B':
            self.ddwlm = np.zeros((self.nstep, self.lm_max_r), 'Complex64')
            self.ddwlm[:, 1:self.l_max_r+1] = data[:, k:k+self.l_max_r]
            k += self.l_max_r
            for m in range(self.minc, self.l_max_r+1, self.minc):
                for l in range(m, self.l_max_r+1):
                    self.ddwlm[:, self.idx[l, m]] = data[:, k]+1j*data[:, k+1]
                    k += 2

        # Truncate!
        if lCut is not None:
            if lCut < self.l_max_r:
                self.truncate(lCut, field=field)

        self.e_pol_axi_l = np.zeros((self.nstep, self.l_max_r+1), precision)
        self.e_tor_axi_l = np.zeros((self.nstep, self.l_max_r+1), precision)
        self.e_pol_l = np.zeros((self.nstep, self.l_max_r+1), precision)
        self.e_tor_l = np.zeros((self.nstep, self.l_max_r+1), precision)

        for l in range(1, self.l_max_r+1):
            self.e_pol_l[:, l] = 0.
            self.e_tor_l[:, l] = 0.
            self.e_pol_axi_l[:, l] = 0.
            self.e_tor_axi_l[:, l] = 0.
            for m in range(0, l+1, self.minc):
                lm = self.idx[l, m]

                if m == 0:
                    epol = 0.5*self.ell[lm]*(self.ell[lm]+1)*( \
                           self.ell[lm]*(self.ell[lm]+1)/self.radius**2* \
                           abs(self.wlm[:,lm])**2+ abs(self.dwlm[:,lm])**2 ) 
                    etor = 0.5*self.ell[lm]*(self.ell[lm]+1)*abs(self.zlm[:, lm])**2

                    self.e_pol_axi_l[:, l] += epol
                    self.e_tor_axi_l[:, l] += etor
                else:
                    epol = self.ell[lm]*(self.ell[lm]+1)*( \
                           self.ell[lm]*(self.ell[lm]+1)/self.radius**2* \
                           abs(self.wlm[:,lm])**2+ abs(self.dwlm[:,lm])**2 ) 
                    etor = self.ell[lm]*(self.ell[lm]+1)*abs(self.zlm[:, lm])**2

                self.e_pol_l[:, l] += epol
                self.e_tor_l[:, l] += etor
        

        # Time-averaged energy
        facT = 1./(self.time[-1]-self.time[0])

        self.e_pol_lM = facT * np.trapz(self.e_pol_l, self.time, axis=0)
        self.e_tor_lM = facT * np.trapz(self.e_tor_l, self.time, axis=0)
        self.e_pol_axi_lM = facT * np.trapz(self.e_pol_axi_l, self.time, axis=0)
        self.e_tor_axi_lM = facT * np.trapz(self.e_tor_axi_l, self.time, axis=0)
Example #15
0
    def __init__(self, iplot=False, angle=10, pickleName='thHeat.pickle'):
        """
        :param iplot: a boolean to toggle the plots on/off
        :type iplot: bool
        :param angle: the integration angle in degrees
        :type angle: float
        :pickleName: calculations a
        """

        angle = angle * np.pi / 180

        if os.path.exists('tInitAvg'):
            file = open('tInitAvg', 'r')
            tstart = float(file.readline())
            file.close()
            logFiles = scanDir('log.*')
            tags = []
            for lg in logFiles:
                nml = MagicSetup(quiet=True, nml=lg)
                if nml.start_time >  tstart:
                    if os.path.exists('bLayersR.%s' % nml.tag):
                        tags.append(nml.tag)
            if len(tags) == 0:
                tags = [nml.tag]
                print('Only 1 tag: %s' % tags)
            MagicSetup.__init__(self, quiet=True, nml=logFiles[-1])

            a = AvgField()
            self.nuss = a.nuss
        else:
            logFiles = scanDir('log.*')
            MagicSetup.__init__(self, quiet=True, nml=logFiles[-1])
        

        if not os.path.exists(pickleName):
            # reading ATmov
            k = 0
            for tag in tags:
                file = 'ATmov.%s' % tag
                if os.path.exists(file):
                    if k == 0:
                        m = Movie(file=file, iplot=False)
                        print(file)
                    else:
                        m += Movie(file=file, iplot=False)
                        print(file)
                    k += 1

            # reading AHF_mov
            kk = 0
            for tag in tags:
                file = 'AHF_mov.%s' % tag
                if os.path.exists(file):
                    if kk == 0:
                        m1 = Movie(file=file, iplot=False)
                        print(file)
                    else:
                        m1 += Movie(file=file, iplot=False)
                        print(file)
                    kk += 1

            self.tempmean = m.data.mean(axis=0)
            self.colat = m.theta


            if kk > 0: # i.e. at least one AHF_mov file has been found
                self.flux = m1.data.mean(axis=0)
            else:
                self.flux = rderavg(self.tempmean, eta=self.radratio, 
                                exclude=False, spectral=False)

            # Pickle saving
            file = open(pickleName, 'wb')
            pickle.dump([self.colat, self.tempmean, self.flux], file)
            file.close()
        else:
            file = open(pickleName, 'r')
            self.colat, self.tempmean, self.flux = pickle.load(file)
            file.close()

        self.ri = self.radratio/(1.-self.radratio)
        self.ro = 1./(1.-self.radratio)

        self.ntheta, self.nr = self.tempmean.shape
        self.radius = chebgrid(self.nr-1, self.ro, self.ri)
        th2D = np.zeros((self.ntheta, self.nr), dtype=self.radius.dtype)
        #self.colat = np.linspace(0., np.pi, self.ntheta)

        for i in range(self.ntheta):
            th2D[i, :] = self.colat[i]

        self.temprm = 0.5*simps(self.tempmean*np.sin(th2D), th2D, axis=0)
        sinTh = np.sin(self.colat)
        d1 = matder(self.nr-1, self.ro, self.ri)

        # Conducting temperature profile (Boussinesq only!)
        self.tcond = self.ri*self.ro/self.radius-self.ri+self.temprm[0]
        self.fcond = -self.ri*self.ro/self.radius**2
        self.nusstop = self.flux[:, 0] / self.fcond[0]
        self.nussbot = self.flux[:, -1] / self.fcond[-1]

        # Close to the equator
        mask2D = (th2D>=np.pi/2.-angle/2.)*(th2D<=np.pi/2+angle/2.)
        mask = (self.colat>=np.pi/2.-angle/2.)*(self.colat<=np.pi/2+angle/2.)
        fac = 1./simps(sinTh[mask], self.colat[mask])
        self.nussBotEq = fac*simps(self.nussbot[mask]*sinTh[mask], self.colat[mask])
        self.nussTopEq = fac*simps(self.nusstop[mask]*sinTh[mask], self.colat[mask])
        sinC = sinTh.copy()
        sinC[~mask] = 0.
        fac = 1./simps(sinC, self.colat)
        tempC = self.tempmean.copy()
        tempC[~mask2D] = 0.
        self.tempEq = fac*simps(tempC*np.sin(th2D), th2D, axis=0)

        dtempEq = np.dot(d1, self.tempEq)
        self.betaEq = dtempEq[self.nr/2]

        # 45\deg inclination
        mask2D = (th2D>=np.pi/4.-angle/2.)*(th2D<=np.pi/4+angle/2.)
        mask = (self.colat>=np.pi/4.-angle/2.)*(self.colat<=np.pi/4+angle/2.)
        fac = 1./simps(np.sin(self.colat[mask]), self.colat[mask])
        nussBot45NH = fac*simps(self.nussbot[mask]*sinTh[mask], self.colat[mask])
        nussTop45NH = fac*simps(self.nusstop[mask]*sinTh[mask], self.colat[mask])
        sinC = sinTh.copy()
        sinC[~mask] = 0.
        fac = 1./simps(sinC, self.colat)
        tempC = self.tempmean.copy()
        tempC[~mask2D] = 0.
        temp45NH = fac*simps(tempC*np.sin(th2D), th2D, axis=0)

        mask2D = (th2D>=3.*np.pi/4.-angle/2.)*(th2D<=3.*np.pi/4+angle/2.)
        mask = (self.colat>=3.*np.pi/4.-angle/2.)*(self.colat<=3.*np.pi/4+angle/2.)
        fac = 1./simps(np.sin(self.colat[mask]), self.colat[mask])
        nussBot45SH = fac*simps(self.nussbot[mask]*sinTh[mask], self.colat[mask])
        nussTop45SH = fac*simps(self.nusstop[mask]*sinTh[mask], self.colat[mask])
        sinC = sinTh.copy()
        sinC[~mask] = 0.
        fac = 1./simps(sinC, self.colat)
        tempC = self.tempmean.copy()
        tempC[~mask2D] = 0.
        temp45SH = fac*simps(tempC*np.sin(th2D), th2D, axis=0)

        self.nussTop45 = 0.5*(nussTop45NH+nussTop45SH)
        self.nussBot45 = 0.5*(nussBot45NH+nussBot45SH)
        self.temp45 = 0.5*(temp45NH+temp45SH)

        dtemp45 = np.dot(d1, self.temp45)
        self.beta45 = dtemp45[self.nr/2]

        # Polar regions
        mask2D = (th2D<=angle/2.)
        mask = (self.colat<=angle/2.)
        fac = 1./simps(np.sin(self.colat[mask]), self.colat[mask])
        nussBotPoNH = fac*simps(self.nussbot[mask]*sinTh[mask], self.colat[mask])
        nussTopPoNH = fac*simps(self.nusstop[mask]*sinTh[mask], self.colat[mask])
        sinC = sinTh.copy()
        sinC[~mask] = 0.
        fac = 1./simps(sinC, self.colat)
        tempC = self.tempmean.copy()
        tempC[~mask2D] = 0.
        tempPolNH = fac*simps(tempC*np.sin(th2D), th2D, axis=0)

        mask2D = (th2D>=np.pi-angle/2.)
        mask = (self.colat>=np.pi-angle/2.)
        fac = 1./simps(np.sin(self.colat[mask]), self.colat[mask])
        nussBotPoSH = fac*simps(self.nussbot[mask]*sinTh[mask], self.colat[mask])
        nussTopPoSH = fac*simps(self.nusstop[mask]*sinTh[mask], self.colat[mask])
        sinC = sinTh.copy()
        sinC[~mask] = 0.
        fac = 1./simps(sinC, self.colat)
        tempC = self.tempmean.copy()
        tempC[~mask2D] = 0.
        tempPolSH = fac*simps(tempC*np.sin(th2D), th2D, axis=0)

        self.nussBotPo = 0.5*(nussBotPoNH+nussBotPoSH)
        self.nussTopPo = 0.5*(nussTopPoNH+nussTopPoSH)
        self.tempPol = 0.5*(tempPolNH+tempPolSH)

        dtempPol = np.dot(d1, self.tempPol)
        self.betaPol = dtempPol[self.nr/2]

        if iplot:
            self.plot()

        print(self)