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, 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, 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)
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, 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 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)
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, 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, 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, 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, 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, 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
from magic import MagicSetup import glob import os ''' This script is used to reorder a directory in which the output files from MagIC have lost their original writing time. It will sort the log files and then touch all the output files to recreate a consistent series. ''' logFiles = sorted(glob.glob('log.*')) # Determine the last log lastLog = logFiles[-1] restarted_from = [] for log in logFiles: stp = MagicSetup(nml=log, quiet=True) if stp.l_start_file == 'T': l_start_file = True else: l_start_file = False if l_start_file: tag = stp.tag lst = stp.start_file.split('.') oldtag = ''.join(lst[1:]) if os.path.exists('log.' + oldtag): # all logFile exists restarted_from.append('log.' + oldtag) diff = list(set(logFiles) - set(restarted_from)) if len(diff) == 1: lastLog = diff[0] else: x = raw_input('Enter last tag: ')