Source code for magic.bLayers

# -*- coding: utf-8 -*-
import matplotlib.pyplot as plt
import numpy as np
import os
from magic import MagicRadial, matder, intcheb, MagicSetup, scanDir, AvgField
from magic.setup import labTex
from scipy.signal import argrelextrema
try:
    from scipy.integrate import simps
except:
    from scipy.integrate import simpson as simps
from scipy.interpolate import splrep, splev

[docs]def getAccuratePeaks(rad, uh, uhTop, uhBot, ri, ro): """ This functions performs a spline extrapolation around the maxima of the input array uh to define a more accurate location of the boundary layer. :param rad: radius :type rad: numpy.ndarray :param uh: the horizontal velocity profile :type uh: numpy.ndarray :param uhTop: first peak value of uh close to the outer boundary :type uhTop: float :param uhBot: first peak value of uh close to the inner boundary :type uhBot: float :param ri: the inner core radius :type ri: float :param ro: the outer core radius :type ro: float :returns: four floats: thickness of the bottom boundary layer, thickness of the top boundary layer, extrapolated value of uh at the bottom boundary layer, extrapolated value of uh at the top boundary layer :rtype: list """ idxT = np.nonzero(np.where(uh==uhTop, 1, 0))[0][0] x = rad[idxT-3:idxT+4] y = uh[idxT-3:idxT+4] newx = np.linspace(x[0], x[-1], 128) tckp = splrep(x[::-1], y[::-1]) newy = splev(newx, tckp) ind = argrelextrema(newy, np.greater)[0] bcTopUh = ro-newx[ind] topUh = newy[ind] idxT = np.nonzero(np.where(uh==uhBot, 1, 0))[0][0] x = rad[idxT-3:idxT+4] y = uh[idxT-3:idxT+4] newx = np.linspace(x[0], x[-1], 128) tckp = splrep(x[::-1], y[::-1]) newy = splev(newx, tckp) ind = argrelextrema(newy, np.greater)[0] bcBotUh = newx[ind]-ri botUh = newy[ind] return bcBotUh[0], bcTopUh[0], botUh[0], topUh[0]
[docs]def integBulkBc(rad, field, ri, ro, lambdai, lambdao, normed=False): """ This function evaluates the radial integral of the input array field in the boundary layer and in the bulk separately. :param rad: radius :type rad: numpy.ndarray :param field: the input radial profile :type field: numpy.ndarray :param ri: the inner core radius :type ri: float :param ro: the outer core radius :type ro: float :param lambdai: thickness of the inner boundary layer :type lambdai: float :param lambdao: thickness of the outer boundary layer :type lambdao: float :param normed: when set to True, the outputs are normalised by the volumes of the boundary layers and the fluid bulk, respectively. In that case, the outputs are volume-averaged quantities. :type normed: bool :returns: two floats that contains the boundary layer and the bulk integrations (integBc, integBulk) :rtype: list """ # Dissipation in the boundary layers field2 = field.copy() mask = (rad<=ro-lambdao) * (rad>=ri+lambdai) field2[mask] = 0. integBc = intcheb(field2, len(field2)-1, ri, ro) if normed: volBc1 = 4./3.*np.pi*(ro**3-(ro-lambdao)**3) volBc2 = 4./3.*np.pi*((ri+lambdai)**3-(ri)**3) volBc = volBc1+volBc2 integBc = integBc/volBc # Dissipation in the bulk field2 = field.copy() mask = (rad>ro-lambdao) field2[mask] = 0. mask = (rad<ri+lambdai) field2[mask] = 0. integBulk = intcheb(field2, len(field2)-1, ri, ro) if normed: volBulk = 4./3.*np.pi*((ro-lambdao)**3-(ri+lambdai)**3) integBulk = integBulk/volBulk return integBc, integBulk
[docs]def integBotTop(rad, field, ri, ro, lambdai, lambdao, normed=False): """ This function evaluates the radial integral of the input array field in the bottom and top boundary layers separately. :param rad: radius :type rad: numpy.ndarray :param field: the input radial profile :type field: numpy.ndarray :param ri: the inner core radius :type ri: float :param ro: the outer core radius :type ro: float :param lambdai: thickness of the inner boundary layer :type lambdai: float :param lambdao: thickness of the outer boundary layer :type lambdao: float :param normed: when set to True, the outputs are normalised by the volumes of the boundary layers. In that case, the outputs are volume-averaged quantities. :type normed: bool :returns: two floats that contains the bottom and top boundary layers integrations (integBot, integTop) :rtype: list """ field2 = field.copy() mask = (rad<=ro-lambdao) field2[mask] = 0. integTop = intcheb(field2, len(field2)-1, ri, ro) field2 = field.copy() mask = (rad>=ri+lambdai) field2[mask] = 0. integBot = intcheb(field2, len(field2)-1, ri, ro) if normed: volBc1 = 4./3.*np.pi*(ro**3-(ro-lambdao)**3) volBc2 = 4./3.*np.pi*((ri+lambdai)**3-(ri)**3) integTop /= volBc1 integBot /= volBc2 return integBot, integTop
[docs]def getMaxima(field): """ This function determines the local maxima of the input array field :param field: the input array :type field: numpy.ndarray :returns: a list containing the indices of the local maxima :rtype: list """ maxS = [] for k in range(len(field)): if k > 3 and k < len(field)-3: if field[k] > field[k-1] and field[k] > field[k+1]: maxS.append(k) return maxS
json_model = { 'time_series': { 'heat': ['topnuss', 'botnuss'], 'e_kin': ['ekin_pol', 'ekin_tor', 'ekin_pol_axi', 'ekin_tor_axi'], 'par': ['rm'] }, 'spectra': {}, 'radial_profiles': {'powerR': ['viscDiss', 'buoPower'], 'eKinR': ['ekin_pol', 'ekin_tor', 'ekin_pol_axi', 'ekin_tor_axi'], 'parR': ['dlVc']} }
[docs]class BLayers(MagicSetup): """ This class allows to determine the viscous and thermal boundary layers using several classical methods (slope method, peak values, dissipation rates, etc.). It uses the following files: * Kinetic energy: :ref:`eKinR.TAG <secEkinRFile>` * Power budget: :ref:`powerR.TAG <secPowerRfile>` * Radial profiles used for boundary layers: :ref:`bLayersR.TAG <secBLayersRfile>` This function can thus **only** be used when both :ref:`powerR.TAG <secPowerRfile>` and :ref:`bLayersR.TAG <secBLayersRfile>` exist in the working directory. .. warning:: This function works well as long as rigid boundaries and fixed temperature boundary conditions are employed. Other combination of boundary conditions (fixed fluxes and/or stress-free) might give wrong results, since boundary layers become awkward to define in that case. Since this function is supposed to use time-averaged quantities, the usual procedure is first to define the initial averaging time using :py:class:`AvgField <magic.AvgField>`: (this needs to be done only once) >>> a = AvgField(tstart=2.58) Once the ``tInitAvg`` file exists, the boundary layer calculation can be done: >>> bl = BLayers(iplot=True) >>> # print the formatted output >>> print(bl) """
[docs] 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.radius = par.radius self.ro = self.radius[0] self.ri = self.radius[-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.radius**2*self.uh, len(self.radius)-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.radius**2*self.dissS, len(self.radius)-1, self.ro, self.ri) self.epsTR = 4.*np.pi*self.radius**2*self.dissS ind = getMaxima(-abs(self.epsTR-self.epsT)) try: self.dissTopS = self.ro-self.radius[ind[0]] self.dissBotS = self.radius[ind[-1]]-self.ri self.dissEpsTbl, self.dissEpsTbulk = integBulkBc(self.radius, 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.radius, self.varS) ind = argrelextrema(self.varS, np.greater)[0] if len(ind) != 0: self.bcTopVarS = self.ro-self.radius[ind[0]] self.bcBotVarS = self.radius[ind[-1]]-self.ri else: self.bcTopVarS = 1. self.bcBotVarS = 1. if hasattr(self, 'epsT'): self.varSEpsTbl, self.varSEpsTbulk = integBulkBc(self.radius, 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 if self.radial_scheme == 'CHEB' and self.l_newmap == False: d1 = matder(len(self.radius)-1, self.ro, self.ri) self.ttm = 3.*intcheb(self.ss*self.radius**2, len(self.radius)-1, self.ri, self.ro) \ /(self.ro**3-self.ri**3) if self.radial_scheme == 'CHEB' and self.l_newmap == False: dsdr = np.dot(d1, self.ss) else: dsdr = np.zeros_like(self.ss) dsdr[:-1] = np.diff(self.ss) / np.diff(self.radius) dsdr[-1] = (self.ss[-1]-self.ss[-2]) / (self.radius[-1]-self.radius[-2]) self.beta = dsdr[len(dsdr)//2] print('beta={:.2f}'.format(self.beta)) self.slopeTop = dsdr[2]*(self.radius-self.ro)+self.ss[0] self.slopeBot = dsdr[-1]*(self.radius-self.ri)+self.ss[-1] self.dtdrm = dsdr[len(self.ss)//2] tmid = self.ss[len(self.ss)//2] self.slopeMid = self.dtdrm*(self.radius-self.radius[len(self.radius)//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.radius <= self.ri+self.bcBotSlope/4.].mean() tSlope = dsdr[self.radius >= self.ro-self.bcTopSlope/4.].mean() self.slopeBot = bSlope*(self.radius-self.ri)+self.ss[-1] self.slopeTop = tSlope*(self.radius-self.ro)+self.ss[0] #self.bcTopSlope = -(self.ttm-self.ss[0])/tSlope self.bcTopSlope = -(tmid-self.dtdrm*self.radius[len(self.radius)//2] - self.ss[0] \ + tSlope*self.ro)/(self.dtdrm-tSlope) self.bcBotSlope = -(tmid-self.dtdrm*self.radius[len(self.radius)//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.radius, 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.radius)-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.radius[i] elif self.vi[i-1]-self.epsV < 0 and self.vi[i+1]-self.epsV > 0: self.dissBotV = self.radius[i]-self.ri else: self.dissTopV = self.ro-self.radius[ind[0]] self.dissBotV = self.radius[ind[-1]]-self.ri try: self.dissEpsVbl, self.dissEpsVbulk = integBulkBc(self.radius, 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.radius, 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.radius[ind[1]] else: self.bcTopduh = self.ro-self.radius[ind[0]] if len(self.radius)-ind[-1] < 4: self.bcBotduh = self.radius[ind[-2]]-self.ri else: self.bcBotduh = self.radius[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.radius[ind[1]] else: self.bcTopduh = self.ro-self.radius[ind[0]] if len(self.radius)-ind[-1] < 4: self.bcBotduh = self.radius[ind[-2]]-self.ri else: self.bcBotduh = self.radius[ind[-1]]-self.ri self.uhTop = self.uh[self.radius==self.ro-self.bcTopduh][0] self.uhBot = self.uh[self.radius==self.ri+self.bcBotduh][0] self.bcBotduh, self.bcTopduh, self.uhBot, self.uhTop = \ getAccuratePeaks(self.radius, self.uh, self.uhTop, \ self.uhBot, self.ri, self.ro) if self.radial_scheme == 'CHEB' and self.l_newmap == False: duhdr = np.dot(d1, self.uh) else: duhdr = np.zeros_like(self.uh) duhdr[:-1] = np.diff(self.uh)/np.diff(self.radius) duhdr[-1] = (self.uh[-1]-self.uh[-2])/(self.radius[-1]-self.radius[-2]) #1st round mask = (self.radius>=self.ro-self.bcTopduh/4)*(self.radius<self.ro) slopeT = duhdr[mask].mean() mask = (self.radius<=self.ri+self.bcBotduh/4)*(self.radius>self.ri) slopeB = duhdr[mask].mean() self.slopeTopU = slopeT*(self.radius-self.ro)+self.uh[0] self.slopeBotU = slopeB*(self.radius-self.ri)+self.uh[-1] self.uhTopSlope = -self.uhTop/slopeT self.uhBotSlope = self.uhBot/slopeB #2nd round mask = (self.radius>=self.ro-self.uhTopSlope/4)*(self.radius<self.ro) slopeT = duhdr[mask].mean() mask = (self.radius<=self.ri+self.uhBotSlope/4)*(self.radius>self.ri) slopeB = duhdr[mask].mean() self.uhTopSlope = -self.uhTop/slopeT self.uhBotSlope = self.uhBot/slopeB self.slopeEpsUbl, self.slopeEpsUbulk = integBulkBc(self.radius, self.vi, self.ri, self.ro, self.uhBotSlope, self.uhTopSlope) self.uhEpsVbl, self.uhEpsVbulk = integBulkBc(self.radius, 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.radius**2/(4.*np.pi)) self.dl = a.dlVcR_av RolC = ReR*self.ek / self.dl y = RolC[self.radius >= self.ro-self.bcTopSlope] x = self.radius[self.radius >= self.ro-self.bcTopSlope] try: self.rolTop = simps(3.*y*x**2, x=x)/(self.ro**3-(self.ro-self.bcTopSlope)**3) except IndexError: self.rolTop = 0. self.rolbl, self.rolbulk = integBulkBc(self.radius, 4.*np.pi*RolC*self.radius**2, self.ri, self.ro, self.bcBotSlope, self.bcTopSlope, normed=True) self.rebl, self.rebulk = integBulkBc(self.radius, 4.*np.pi*ReR*self.radius**2, self.ri, self.ro, self.bcBotSlope, self.bcTopSlope, normed=True) self.lengthbl, self.lengthbulk = integBulkBc(self.radius, self.dl*4.*np.pi*self.radius**2, self.ri, self.ro, self.bcBotSlope, self.bcTopSlope, normed=True) self.rehbl, self.rehbulk = integBulkBc(self.radius, self.uh*4.*np.pi*self.radius**2, self.ri, self.ro, self.bcBotduh, self.bcTopduh, normed=True) y = RolC[self.radius <= self.ri+self.bcBotSlope] x = self.radius[self.radius <= self.ri+self.bcBotSlope] self.rolBot = simps(3.*y*x**2, x=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.radius, 4.*np.pi*self.radius**2*self.dl, self.ri, self.ro, self.bcBotSlope, self.bcTopSlope, normed=True) uhbm, utbm = integBotTop(self.radius, 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.radius, 4.*np.pi*RePerp*self.radius**2, self.ri, self.ro, self.bcBotSlope, self.bcTopSlope, normed=True) self.reparbl, self.reparbulk = integBulkBc(self.radius, 4.*np.pi*RePar*self.radius**2, self.ri, self.ro, self.bcBotSlope, self.bcTopSlope, normed=True) self.reperpnasbl, self.reperpnasbulk = integBulkBc(self.radius, 4.*np.pi*RePerpNas*self.radius**2, self.ri, self.ro, self.bcBotSlope, self.bcTopSlope, normed=True) self.reparnasbl, self.reparnasbulk = integBulkBc(self.radius, 4.*np.pi*ReParNas*self.radius**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)
[docs] def plot(self): """ Plotting function """ #plt.rcdefaults() fig = plt.figure() ax = fig.add_subplot(211) ax.plot(self.radius, self.ss) ax.axhline(self.ttm, color='gray', linestyle='-') ax.plot(self.radius, self.slopeTop, 'k--') ax.plot(self.radius, self.slopeBot, 'k--') ax.plot(self.radius, self.slopeMid, 'k--') ax.axvline(self.ri+self.bcBotSlope, color='r') ax.axvline(self.ro-self.bcTopSlope, color='r') ax.set_ylim(self.ss[0], self.ss[-1]) ax.set_ylabel('Entropy') ax1 = ax.twinx() ax1.plot(self.radius, self.varS/self.varS.max(), 'g-') ax1.axvline(self.ro-self.bcTopVarS, color='k', linestyle=':') ax1.axvline(self.ri+self.bcBotVarS, color='k', linestyle=':') ax1.set_ylim(0, 1) ax1.set_ylabel('var(s)') ax.set_xlabel('Radius') ax.set_xlim(self.radius[-1], self.radius[0]) ax = fig.add_subplot(212) if self.kbotv == 1 and self.ktopv == 1: ax.plot(self.radius, self.duh/self.duh.max()) if labTex: ax.set_ylabel(r'$\partial u_h/\partial r$') else: ax.set_ylabel('duh/dr') else: ax.set_ylim(0., 1.1*self.uh.max()) ax.plot(self.radius, self.uh) ax.plot(self.radius, self.slopeTopU, 'k--') ax.plot(self.radius, self.slopeBotU, 'k--') mask = (np.abs(self.radius-self.ri-self.bcBotduh)==np.abs(self.radius-self.ri-self.bcBotduh).min()) ax.axhline(self.uh[mask], color='k', linestyle='--', xmin=0., xmax=self.bcBotduh) mask = (np.abs(self.radius-self.ro+self.bcTopduh)==np.abs(self.radius-self.ro+self.bcTopduh).min()) ax.axhline(self.uh[mask], color='k', linestyle='--', xmin=1.-self.bcTopduh, xmax=1.) if labTex: ax.set_ylabel(r'$u_h$') else: ax.set_ylabel('uh') ax.axvline(self.ro-self.bcTopduh, color='k', linestyle='--') ax.axvline(self.ri+self.bcBotduh, color='k', linestyle='--') ax.plot(self.radius, self.vi/self.vi.max()) ax.set_xlim(self.radius[-1], self.radius[0]) ax.set_xlabel('Radius') fig = plt.figure() ax = fig.add_subplot(211) ax.semilogy(self.radius, self.vi) ax.axhline(self.epsV, color='k', linestyle='--') ax.axvline(self.ro-self.dissTopV, color='k', linestyle='--') ax.axvline(self.ri+self.dissBotV, color='k', linestyle='--') ax.axvline(self.ro-self.uhTopSlope, color='g', linestyle='-', lw=1.5) ax.axvline(self.ri+self.uhBotSlope, color='g', linestyle='-', lw=1.5) ax.set_xlim(self.radius[-1], self.radius[0]) ax.set_xlabel('Radius') ax.set_ylabel('Viscous dissipation') if hasattr(self, 'dissS'): ax = fig.add_subplot(212) ax.semilogy(self.radius, self.epsTR) ax.axhline(self.epsT, color='k', linestyle=':') ax.axvline(self.ro-self.dissTopS, color='k', linestyle='--') ax.axvline(self.ri+self.dissBotS, color='k', linestyle='--') ax.axvline(self.ro-self.bcTopSlope, color='g', linestyle='-', lw=1.5) ax.axvline(self.ri+self.bcBotSlope, color='g', linestyle='-', lw=1.5) ax.set_xlim(self.radius[-1], self.radius[0]) ax.set_xlabel('Radius') ax.set_ylabel('Thermal Dissipation')
[docs] def __str__(self): """ Formatted output """ if self.ek == -1: ek = 0. # to avoid the -1 for the non-rotating cases else: ek = self.ek if self.mode == 0: st ='{:9.3e}{:9.2e}{:9.2e}{:9.2e}{:5.2f}'.format(self.ra, ek, self.pr, self.prmag, self.strat) else: st = '{:.3e}{:12.5e}{:5.2f}{:6.2f}{:6.2f}'.format(self.ra, ek, self.strat, self.pr, self.radratio) st += '{:12.5e}{:12.5e}{:12.5e}'.format(self.nuss, self.reynolds, self.rey_fluct) st += '{:12.5e}'.format(self.epsT) st += '{:12.5e}{:12.5e}{:5.2f}{:5.2f}'.format(self.bcBotSlope, self.bcTopSlope, self.slopeEpsTbl/self.epsT, self.slopeEpsTbulk/self.epsT) st += '{:12.5e}{:12.5e}{:5.2f}{:5.2f}'.format(self.bcBotVarS, self.bcTopVarS, self.varSEpsTbl/self.epsT, self.varSEpsTbulk/self.epsT) st += '{:12.5e}{:12.5e}{:5.2f}{:5.2f}'.format(self.dissBotS, self.dissTopS, self.dissEpsTbl/self.epsT, self.dissEpsTbulk/self.epsT) st += '{:12.5e}'.format(self.epsV) st += '{:12.5e}{:12.5e}{:5.2f}{:5.2f}'.format(self.bcBotduh, self.bcTopduh, self.uhEpsVbl/self.epsV, self.uhEpsVbulk/self.epsV) st += '{:12.5e}{:12.5e}{:5.2f}{:5.2f}'.format(self.uhBotSlope, self.uhTopSlope, self.slopeEpsUbl/self.epsV, self.slopeEpsUbulk/self.epsV) st += '{:12.5e}{:12.5e}{:5.2f}{:5.2f}'.format(self.dissBotV, self.dissTopV, self.dissEpsVbl/self.epsV, self.dissEpsVbulk/self.epsV) st += ' {:12.5e}'.format(self.beta) st += '{:12.5e}{:12.5e}'.format(abs(self.rolbl), abs(self.rolbulk)) st += '{:12.5e}{:12.5e}'.format(self.rebl, self.rebulk) st += '{:12.5e}{:12.5e}'.format(self.rehbl, self.rehbulk) st += '{:12.5e}{:12.5e}'.format(self.lengthbl, self.lengthbulk) st += '{:12.5e}{:12.5e}'.format(self.ss[len(self.ss)//2]-self.ss[0], self.ttm-self.ss[0]) st += '{:12.5e}{:12.5e}'.format(self.dti, self.dto) st += '{:12.5e}{:12.5e}{:12.5e}'.format(self.reh, self.uhBot, self.uhTop) st += '{:12.5e}{:12.5e}'.format(self.lBot, self.lTop) st += '{:12.5e}{:12.5e}{:12.5e}{:12.5e}'.format(self.reperpbl, self.reperpbulk, self.reparbl, self.reparbulk) st += '{:12.5e}{:12.5e}{:12.5e}{:12.5e}'.format(self.reperpnasbl, self.reperpnasbulk, self.reparnasbl, self.reparnasbulk) return st
if __name__ == '__main__': b = BLayers(iplot=True) print(b) plt.show()