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
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
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()
def __init__(self, ivar=1, datadir='.', ns=None): """ :param ivar: the number of the Graphic file :type ivar: int :param datadir: working directory :type datadir: str :param ns: number of grid points in the radial direction :type ns: int """ MagicSetup.__init__(self, datadir) self.datadir = datadir filename = '%sG_%i.%s' % ('cyl', ivar, self.tag) if not os.path.exists(filename): print("sph2cyl...") gr = MagicGraph(ivar=ivar, datadir=self.datadir) if ns is None: self.ns = gr.nr self.nz = 2*self.ns else: self.ns = ns self.nz = 2*ns self.nphi = gr.nphi self.npI = gr.npI self.minc = gr.minc self.ro = gr.radius[0] self.ri = gr.radius[-1] self.S, self.Z, self.vs, self.vphi, self.vz = sph2cyl(gr, self.ns, self.nz) file = open(filename, 'wb') pickle.dump([self.ns, self.nz, self.nphi, self.npI, self.minc], file) pickle.dump([self.ro, self.ri], file) pickle.dump([self.S, self.Z, self.vs, self.vphi, self.vz], file) file.close() else: print("read cyl file") file = open(filename, 'r') self.ns, self.nz, self.nphi, self.npI, self.minc = pickle.load(file) self.ro, self.ri = pickle.load(file) self.S, self.Z, self.vs, self.vphi, self.vz = \ pickle.load(file) file.close() self.radius = np.linspace(0., self.ro, self.ns) temp0, rho0, beta0 = anelprof(np.linspace(self.ro, self.ri, self.ns), self.strat, self.polind) rho = np.zeros((self.nphi/2, self.ns), dtype=self.vr.dtype) beta = np.zeros_like(rho) for i in range(self.nphi/2): rho[i, :] = rho0 beta[i, :] = beta0 Z, S, [rho, beta] = sph2cyl_plane([rho,beta], np.linspace(self.ro, self.ri, self.ns), self.ns, self.nz) self.rho = np.zeros_like(self.vs) self.beta = np.zeros_like(self.vs) for i in range(self.npI): self.rho[i, ...] = rho self.beta[i, ...] = beta self.z = np.linspace(-self.ro, self.ro, self.nz)
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)
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 __init__(self, ivar=1, datadir='.', ns=None): """ :param ivar: the number of the Graphic file :type ivar: int :param datadir: working directory :type datadir: str :param ns: number of grid points in the radial direction :type ns: int """ MagicSetup.__init__(self, datadir) self.datadir = datadir filename = '{}G_{}.{}'.format('cyl', ivar, self.tag) if not os.path.exists(filename): print("sph2cyl...") gr = MagicGraph(ivar=ivar, datadir=self.datadir) if ns is None: self.ns = gr.nr self.nz = 2*self.ns else: self.ns = ns self.nz = 2*ns self.nphi = gr.nphi self.npI = gr.npI self.minc = gr.minc self.ro = gr.radius[0] self.ri = gr.radius[-1] self.S, self.Z, self.vs, self.vphi, self.vz = sph2cyl(gr, self.ns, self.nz) file = open(filename, 'wb') pickle.dump([self.ns, self.nz, self.nphi, self.npI, self.minc], file) pickle.dump([self.ro, self.ri], file) pickle.dump([self.S, self.Z, self.vs, self.vphi, self.vz], file) file.close() else: print("read cyl file") file = open(filename, 'r') self.ns, self.nz, self.nphi, self.npI, self.minc = pickle.load(file) self.ro, self.ri = pickle.load(file) self.S, self.Z, self.vs, self.vphi, self.vz = \ pickle.load(file) file.close() self.radius = np.linspace(0., self.ro, self.ns) temp0, rho0, beta0 = anelprof(np.linspace(self.ro, self.ri, self.ns), self.strat, self.polind) rho = np.zeros((self.nphi/2, self.ns), dtype=self.vr.dtype) beta = np.zeros_like(rho) for i in range(self.nphi/2): rho[i, :] = rho0 beta[i, :] = beta0 Z, S, [rho, beta] = sph2cyl_plane([rho,beta], np.linspace(self.ro, self.ri, self.ns), self.ns, self.nz) self.rho = np.zeros_like(self.vs) self.beta = np.zeros_like(self.vs) for i in range(self.npI): self.rho[i, ...] = rho self.beta[i, ...] = beta self.z = np.linspace(-self.ro, self.ro, self.nz)
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)
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)
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()
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)
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()
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) """
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()
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)
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)