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
from scipy.integrate import 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)/(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)/((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()