Source code for magic.radial

# -*- coding: utf-8 -*-
import os
import re
import copy
import matplotlib.pyplot as plt
import numpy as np
from .log import MagicSetup
from .libmagic import fast_read,scanDir
import scipy.interpolate as sint


[docs] class MagicRadial(MagicSetup): """ This class can be used to read and display the time and horizontally averaged files: * Kinetic energy: :ref:`eKinR.TAG <secEkinRFile>` * Magnetic energy: :ref:`eMagR.TAG <secEmagRfile>` * Anelastic reference state: :ref:`anel.TAG <secAnelFile>` * Variable electrical conductivity: :ref:`varCond.TAG <secVarCondFile>` * Variable thermal diffusivity: :ref:`varDiff.TAG <secVarDiffFile>` * Variable kinematic viscosity: :ref:`varVisc.TAG <secVarViscFile>` * Diagnostic parameters: :ref:`parR.TAG <secPaRfile>` * Power budget: :ref:`powerR.TAG <secPowerRfile>` * Phase field: :ref:`phiR.TAG <secPhiRfile>` * Heat fluxes: :ref:`fluxesR.TAG <secFluxesRfile>` * Mean entropy, temperature and pressure: :ref:`heatR.TAG <secHeatRfile>` * Radial profiles used for boundary layers: :ref:`bLayersR.TAG <secBLayersRfile>` * Parallel/perpendicular decomposition: :ref:`perpParR.TAG <secPerpParRfile>` >>> rad = MagicRadial(field='eKinR') # display the content of eKinR.tag >>> print(rad.radius, rad.ekin_pol_axi) # print radius and poloidal energy """
[docs] def __init__(self, datadir='.', field='eKin', iplot=True, tag=None, tags=None, normalize_radius=False, quiet=False): """ :param datadir: working directory :type datadir: str :param field: the field you want to plot :type field: str :param iplot: to plot the output, default is True :type iplot: bool :param tag: a specific tag, default is None :type tag: str :param tags: a list that contains multiple tags: useful to sum several radial files :type tags: list :param quiet: when set to True, makes the output silent (default False) :type quiet: bool """ if field in ('eKin', 'ekin', 'e_kin', 'Ekin', 'E_kin', 'eKinR'): self.name ='eKinR' elif field in ('eMag', 'emag', 'e_mag', 'Emag', 'E_mag', 'eMagR'): self.name = 'eMagR' elif field in ('anel', 'ref', 'rho', 'density', 'background'): self.name = 'anel' elif field in ('varDiff', 'vardiff'): self.name = 'varDiff' elif field in ('varVisc', 'varvisc'): self.name = 'varVisc' elif field in ('varCond', 'varcond'): self.name = 'varCond' elif field in ('power', 'powerR'): self.name = 'powerR' elif field in ('parrad'): self.name = 'parrad' elif field in ('bLayersR'): self.name = 'bLayersR' elif field in ('parR'): self.name = 'parR' elif field in ('fluxesR'): self.name = 'fluxesR' elif field in ('heatR'): self.name = 'heatR' elif field in ('perpParR'): self.name = 'perpParR' elif field in ('phiR', 'phaseR'): self.name = 'phiR' else: print('No corresponding radial profiles... Try again') self.normalize_radius = normalize_radius if tags is None: if tag is not None: pattern = os.path.join(datadir, '{}.{}'.format(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.{}'.format(tag))): MagicSetup.__init__(self, datadir=datadir, quiet=True, nml='log.{}'.format(tag)) # Or the tag is a bit more complicated and we need to find # the corresponding log file else: mask = re.compile(r'{}\/{}\.(.*)'.format(datadir, self.name)) if mask.match(files[-1]): ending = mask.search(files[-1]).groups(0)[0] pattern = os.path.join(datadir, 'log.{}'.format(ending)) if os.path.exists(pattern): MagicSetup.__init__(self, datadir=datadir, quiet=True, nml='log.{}'.format(ending)) # Sum the files that correspond to the tag mask = re.compile(r'{}\.(.*)'.format(self.name)) for k, file in enumerate(files): if not quiet: print('reading {}'.format(file)) tag = mask.search(file).groups(0)[0] nml = MagicSetup(nml='log.{}'.format(tag), datadir=datadir, quiet=True) filename = file if self.name == 'varCond' or self.name == 'varVisc' or \ self.name == 'varDiff' or self.name == 'anel': data = fast_read(filename, skiplines=1) else: data = fast_read(filename, skiplines=0) if k == 0: radlut = RadLookUpTable(data, self.name, nml.start_time, nml.stop_time) else: radlut += RadLookUpTable(data, self.name, nml.start_time, nml.stop_time) else: # Tag is None: take the most recent one pattern = os.path.join(datadir, '{}.*'.format(self.name)) files = scanDir(pattern) filename = files[-1] if not quiet: print('reading {}'.format(filename)) # Determine the setup mask = re.compile(r'{}\.(.*)'.format(self.name)) ending = mask.search(files[-1]).groups(0)[0] if os.path.exists(os.path.join(datadir, 'log.{}'.format(ending))): try: MagicSetup.__init__(self, datadir=datadir, quiet=True, nml='log.{}'.format(ending)) except AttributeError: self.start_time = None self.stop_time = None pass if self.name == 'varCond' or self.name == 'varVisc' or \ self.name == 'varDiff' or self.name == 'anel': data = fast_read(filename, skiplines=1) else: data = fast_read(filename, skiplines=0) if not hasattr(self, 'stop_time'): self.stop_time = self.start_time radlut = RadLookUpTable(data, self.name, self.start_time, self.stop_time) else: if os.path.exists(os.path.join(datadir, 'log.{}'.format(tags[-1]))): MagicSetup.__init__(self, datadir=datadir, quiet=True, nml='log.{}'.format(tags[-1])) else: self.start_time = None self.stop_time = None for k, tagg in enumerate(tags): nml = MagicSetup(nml='log.{}'.format(tagg), datadir=datadir, quiet=True) file = '{}.{}'.format(self.name, tagg) filename = os.path.join(datadir, file) if not quiet: print('reading {}'.format(filename)) if os.path.exists(filename): if self.name == 'varCond' or self.name == 'varVisc' or \ self.name == 'varDiff' or self.name == 'anel': data = fast_read(filename, skiplines=1) else: data = fast_read(filename, skiplines=0) if k == 0: radlut = RadLookUpTable(data, self.name, nml.start_time, nml.stop_time) else: radlut += RadLookUpTable(data, self.name, nml.start_time, nml.stop_time) # Copy look-up table arguments into MagicRadial object if 'radlut' in locals(): for attr in radlut.__dict__: setattr(self, attr, radlut.__dict__[attr]) # Plotting function if iplot: self.plot()
[docs] def plot(self): """ Display the result when ``iplot=True`` """ if self.normalize_radius: x_axis = self.radius/self.radius[0] else: x_axis = self.radius if self.name == 'eKinR': fig = plt.figure() ax = fig.add_subplot(111) ax.plot(x_axis, self.ekin_pol, ls='-', c='C0', label='ekin pol') ax.plot(x_axis, self.ekin_tor, ls='-', c='C1', label='ekin tor') ax.plot(x_axis, self.ekin_pol_axi, ls='--', c='C0', label='ekin pol axi') ax.plot(x_axis, self.ekin_tor_axi, ls='--', c='C1', label='ekin tor axi') ax.plot(x_axis, self.ekin_pol+self.ekin_tor, ls='-', c='0.25', label='ekin tot') ax.set_xlabel('Radius') ax.set_ylabel('Kinetic energy') ax.set_xlim(x_axis.min(), x_axis.max()) ax.legend(loc='best', frameon=False) fig.tight_layout() elif self.name == 'eMagR': fig = plt.figure() ax = fig.add_subplot(111) ax.plot(x_axis, self.emag_pol, ls='-', c='C0', label='emag pol') ax.plot(x_axis, self.emag_tor, ls='-', c='C1', label='emag tor') ax.plot(x_axis, self.emag_pol_axi, ls='--', c='C0', label='emag pol axi') ax.plot(x_axis, self.emag_tor_axi, ls='--', c='C1', label='emag tor axi') ax.plot(x_axis, self.emag_pol+self.emag_tor, ls='-', c='0.25', label='emag tot') ax.legend(loc='best', frameon=False) ax.set_xlabel('Radius') ax.set_ylabel('Magnetic energy') ax.set_xlim(x_axis.min(), x_axis.max()) if hasattr(self, 'con_radratio'): if self.nVarCond == 2: ax.axvline(self.con_radratio*self.radius[0], color='k', linestyle='--') fig.tight_layout() fig = plt.figure() ax = fig.add_subplot(111) ax.plot(x_axis, self.dip_ratio) ax.set_xlabel('Radius') ax.set_ylabel('Dipolarity') ax.set_xlim(x_axis.min(), x_axis.max()) fig.tight_layout() elif self.name == 'anel': fig = plt.figure() ax = fig.add_subplot(111) ax.semilogy(x_axis, self.temp0, label='Temperature') ax.semilogy(x_axis, self.rho0, label='Density') ax.set_ylabel('Reference state') ax.set_xlabel('Radius') ax.set_xlim(x_axis.min(), x_axis.max()) ax.legend(loc='best', frameon=False) fig.tight_layout() fig = plt.figure() ax = fig.add_subplot(111) ax.plot(x_axis, self.beta, label='beta') ax.plot(x_axis, self.dbeta, label='dbeta/dr') ax.set_xlabel('Radius') ax.set_ylabel('Derivatives of rho') ax.set_xlim(x_axis.min(), x_axis.max()) ax.legend(loc='best', frameon=False) fig.tight_layout() fig = plt.figure() ax = fig.add_subplot(111) ax.plot(x_axis, self.grav) ax.set_xlabel('Radius') ax.set_ylabel('Gravity') ax.set_xlim(x_axis.min(), x_axis.max()) fig.tight_layout() elif self.name == 'varDiff': fig = plt.figure() ax = fig.add_subplot(111) ax.semilogy(x_axis, self.conduc, label='conductivity') ax.semilogy(x_axis, self.kappa, label='diffusivity') ax.semilogy(x_axis, self.prandtl, label='Prandtl') ax.set_ylabel('Thermal properties') ax.set_xlabel('Radius') ax.set_xlim(x_axis.min(), x_axis.max()) ax.legend(loc='best', frameon=False) fig.tight_layout() fig = plt.figure() ax = fig.add_subplot(111) ax.plot(x_axis, self.dLkappa, label='dLkappa') ax.set_xlabel('Radius') ax.set_ylabel('$d\ln\kappa / dr$') ax.set_xlim(x_axis.min(), x_axis.max()) ax.legend(loc='best', frameon=False) fig.tight_layout() elif self.name == 'varVisc': fig = plt.figure() ax = fig.add_subplot(111) ax.semilogy(x_axis, self.dynVisc, label='dyn. visc') ax.semilogy(x_axis, self.kinVisc, label='kin. visc') ax.semilogy(x_axis, self.prandtl, label='Prandtl') if self.mode not in (1,5): ax.semilogy(x_axis, self.prandtlmag, label='Pm') ax.semilogy(x_axis, self.ekman, label='Ekman') ax.set_ylabel('Thermal properties') ax.set_xlabel('Radius') ax.set_xlim(x_axis.min(), x_axis.max()) ax.legend(loc='best', frameon=False) fig.tight_layout() fig = plt.figure() ax = fig.add_subplot(111) ax.plot(x_axis, self.dLvisc, label='dLvisc') ax.set_xlabel('Radius') ax.set_ylabel(r'$d\ln\nu / dr$') ax.set_xlim(self.radius.min(), self.radius.max()) ax.legend(loc='best', frameon=False) fig.tight_layout() elif self.name == 'varCond': fig = plt.figure() ax = fig.add_subplot(111) ax.semilogy(x_axis, self.conduc, label='conductivity') ax.set_ylabel('Electrical conductivity') ax.set_xlabel('Radius') ax.set_xlim(x_axis.min(), x_axis.max()) ax.legend(loc='best', frameon=False) fig.tight_layout() elif self.name == 'powerR': fig = plt.figure() ax = fig.add_subplot(111) ax.plot(self.radius, self.buoPower, label='Power therm') if hasattr(self, 'buoPower_SD'): ax.fill_between(x_axis, self.buoPower-self.buoPower_SD, self.buoPower+self.buoPower_SD, color='C0', alpha=0.3) ax.plot(self.radius, self.viscDiss, label='visc diss') if hasattr(self, 'viscDiss_SD'): ax.fill_between(x_axis, self.viscDiss-self.viscDiss_SD, self.viscDiss+self.viscDiss_SD, color='C1', alpha=0.3) if abs(self.buoPower_chem).max() > 0: ax.plot(self.radius, self.buoPower_chem, color='C3', label='Power chem') if hasattr(self, 'buoPower_chem_SD'): ax.fill_between(x_axis, self.buoPower_chem-self.buoPower_chem_SD, self.buoPower_chem+self.buoPower_chem_SD, color='C3', alpha=0.3) if self.ohmDiss.max() != 0.: ax.plot(x_axis, self.ohmDiss, label='ohm diss', color='C2') if hasattr(self, 'ohmDiss_SD'): ax.fill_between(x_axis, self.ohmDiss-self.ohmDiss_SD, self.ohmDiss+self.ohmDiss_SD, color='C2', alpha=0.3) ax.set_xlabel('Radius') ax.set_xlim(x_axis.min(), x_axis.max()) ax.legend(loc='best', frameon=False) fig.tight_layout() elif self.name == 'parrad' or self.name == 'bLayersR': fig = plt.figure() ax = fig.add_subplot(111) ax.plot(x_axis, self.entropy, label='Entropy') ax1 = ax.twinx() ax1.plot(x_axis, self.entropy_SD, color='C1', label='Standard dev. of Entropy') ax.set_xlabel('Radius') ax.set_xlim(x_axis.min(), x_axis.max()) ax.legend(loc='best', frameon=False) fig.tight_layout() if abs(self.xi).max() > 0.: fig = plt.figure() ax = fig.add_subplot(111) ax.plot(x_axis, self.xi, label='Composition') ax1 = ax.twinx() ax1.plot(x_axis, self.xi_SD, color='C1', label='Standard dev. of Composition') ax.set_xlabel('Radius') ax.set_xlim(x_axis.min(), x_axis.max()) ax.legend(loc='best', frameon=False) fig.tight_layout() fig = plt.figure() ax = fig.add_subplot(111) ax.plot(x_axis, self.uh, label='uh') if hasattr(self, 'uh_SD'): ax.fill_between(x_axis, self.uh-self.uh_SD, self.uh+self.uh_SD, color='C0', alpha=0.3) ax.plot(x_axis, self.duhdr, label='duhdr') if hasattr(self, 'duhdr_SD'): ax.fill_between(x_axis, self.duhdr-self.duhdr_SD, self.duhdr+self.duhdr_SD, color='C1', alpha=0.3) ax.set_xlabel('Radius') ax.set_xlim(x_axis.min(), x_axis.max()) ax.legend(loc='best', frameon=False) fig.tight_layout() elif self.name == 'parR': fig = plt.figure() ax = fig.add_subplot(111) ax.plot(x_axis, self.rm) if hasattr(self, 'rm_SD'): ax.fill_between(x_axis, self.rm-self.rm_SD, self.rm+self.rm_SD, color='C0', alpha=0.3) ax.set_xlim(x_axis.min(), x_axis.max()) ax.set_xlabel('Radius') ax.set_ylabel('Rm') fig.tight_layout() fig = plt.figure() ax = fig.add_subplot(111) ax.plot(x_axis, self.rol, label='Rol') if hasattr(self, 'rol_SD'): ax.fill_between(x_axis, self.rol-self.rol_SD, self.rol+self.rol_SD, color='C1', alpha=0.3) ax.plot(x_axis, self.urol, label='u Rol') if hasattr(self, 'urol_SD'): ax.fill_between(x_axis, self.urol-self.urol_SD, self.urol+self.urol_SD, color='C2', alpha=0.3) ax.set_xlabel('Radius') ax.set_ylabel('Rol') ax.set_xlim(x_axis.min(), x_axis.max()) ax.legend(loc='best', frameon=False) fig.tight_layout() fig = plt.figure() ax = fig.add_subplot(111) ax.plot(x_axis[1:-1], self.dlV[1:-1], label='dlV') if hasattr(self, 'dlV_SD'): ax.fill_between(x_axis[1:-1], self.dlV[1:-1]-self.dlV_SD[1:-1], self.dlV[1:-1]+self.dlV_SD[1:-1], color='C0', alpha=0.3) ax.plot(x_axis[1:-1], self.dlVc[1:-1], label='dlVc') if hasattr(self, 'dlVc_SD'): ax.fill_between(x_axis[1:-1], self.dlVc[1:-1]-self.dlVc_SD[1:-1], self.dlVc[1:-1]+self.dlVc_SD[1:-1], color='C1', alpha=0.3) if hasattr(self, 'dlPolPeak'): ax.plot(x_axis[1:-1], self.dlPolPeak[1:-1], label='dl pol. peak') ax.fill_between(x_axis[1:-1], self.dlPolPeak[1:-1]-self.dlPolPeak_SD[1:-1], self.dlPolPeak[1:-1]+self.dlPolPeak_SD[1:-1], color='C2', alpha=0.3) ax.set_yscale('log') ax.set_xlabel('Radius') ax.set_ylabel('Lengthscales') ax.set_xlim(x_axis.min(), x_axis.max()) ax.legend(loc='best', frameon=False) fig.tight_layout() elif self.name == 'fluxesR': fig = plt.figure() ax = fig.add_subplot(111) ax.plot(x_axis, self.fcond, label='Fcond') if hasattr(self, 'fcond_SD'): ax.fill_between(x_axis, self.fcond-self.fcond_SD, self.fcond+self.fcond_SD, color='C0', alpha=0.3) ax.plot(x_axis, self.fconv, label='Fconv') if hasattr(self, 'fconv_SD'): ax.fill_between(x_axis, self.fconv-self.fconv_SD, self.fconv+self.fconv_SD, color='C1', alpha=0.3) ax.plot(x_axis, self.fkin, label='Fkin') if hasattr(self, 'fkin_SD'): ax.fill_between(x_axis, self.fkin-self.fkin_SD, self.fkin+self.fkin_SD, color='C2', alpha=0.3) ax.plot(x_axis, self.fvisc, label='Fvisc') if hasattr(self, 'fvisc_SD'): ax.fill_between(x_axis, self.fvisc-self.fvisc_SD, self.fvisc+self.fvisc_SD, color='C3', alpha=0.3) if self.prmag != 0: ax.plot(x_axis, self.fpoyn, label='Fpoyn') if hasattr(self, 'fpoyn_SD'): ax.fill_between(x_axis, self.fpoyn-self.fpoyn_SD, self.fpoyn+self.fpoyn_SD, color='C4', alpha=0.3) ax.plot(x_axis, self.fres/self.fcond[0], label='Fres') if hasattr(self, 'fres_SD'): ax.fill_between(x_axis, self.fres-self.fres_SD, self.fres+self.fres_SD, color='C5', alpha=0.3) ax.set_xlabel('Radius') ax.set_ylabel('Fluxes') ax.plot(x_axis, self.ftot, label='Ftot') ax.legend(loc='best', frameon=False) ax.set_xlim(x_axis[-1], x_axis[0]) fig.tight_layout() elif self.name == 'phiR': fig = plt.figure() ax = fig.add_subplot(111) ax.plot(x_axis, self.phase) ax.fill_between(x_axis, self.phase-self.phase_SD, self.phase+self.phase_SD, color='C0', alpha=0.3) ax.set_xlim(x_axis[-1], x_axis[0]) ax.set_xlabel('Radius') ax.set_ylabel('Phase field') fig.tight_layout() elif self.name == 'heatR': fig = plt.figure() ax = fig.add_subplot(111) if self.DissNb == 0.: label = 'T' else: label = 's' ax.plot(x_axis, self.entropy, label=label, color='C0') if hasattr(self, 'entropy_SD'): ax.fill_between(x_axis, self.entropy-self.entropy_SD, self.entropy+self.entropy_SD, color='C0', alpha=0.3) #if self.DissNb > 0: # ax.plot(x_axis, self.temperature, label='T', color='C1') # if hasattr(self, 'temperature_SD'): # ax.fill_between(x_axis, self.temperature-self.temperature_SD, # self.temperature+self.temperature_SD, # color='C1', alpha=0.3) if abs(self.xi).max() > 1e-10: ax.plot(x_axis, self.xi, label='xi', color='C2') if hasattr(self, 'xi_SD'): ax.fill_between(x_axis, self.xi-self.xi_SD, self.xi+self.xi_SD, color='C2', alpha=0.3) ax.set_xlabel('Radius') if self.DissNb == 0: ax.set_ylabel('Temperature, Composition') else: ax.set_ylabel('Entropy, Composition') ax.legend(loc='best', frameon=False) ax.set_xlim(x_axis[-1], x_axis[0]) fig.tight_layout() elif self.name == 'perpParR': fig = plt.figure() ax = fig.add_subplot(111) ax.plot(x_axis, self.Eperp, ls='-', color='C0', label='E perp.') if hasattr(self, 'Eperp_SD'): ax.fill_between(x_axis, self.Eperp-self.Eperp_SD, self.Eperp+self.Eperp_SD, color='C0', alpha=0.3) ax.plot(x_axis, self.Epar, ls='-', color='C1', label='E par.') if hasattr(self, 'Epar_SD'): ax.fill_between(x_axis, self.Epar-self.Epar_SD, self.Epar+self.Epar_SD, color='C1', alpha=0.3) ax.plot(x_axis, self.Eperp_axi, ls='--', color='C0', label='E eperp. ax.') if hasattr(self, 'Eperp_axi_SD'): ax.fill_between(x_axis, self.Eperp_axi-self.Eperp_axi_SD, self.Eperp_axi+self.Eperp_axi_SD, color='C0', alpha=0.3) ax.plot(x_axis, self.Epar_axi, ls='--', color='C1', label='E par. ax.') if hasattr(self, 'Epar_axi_SD'): ax.fill_between(x_axis, self.Epar_axi-self.Epar_axi_SD, self.Epar_axi+self.Epar_axi_SD, color='C1', alpha=0.3) ax.set_xlabel('Radius') ax.set_ylabel('Kinetic energy') ax.set_xlim(x_axis.min(), x_axis.max()) ax.legend(loc='best', frameon=False) fig.tight_layout() if hasattr(self, 'con_radratio'): if self.nVarCond == 2: ax.axvline(self.con_radratio*self.radius[0], color='k', linestyle='--')
class RadLookUpTable: """ The purpose of this class is to create a lookup table between the numpy array that comes from the reading of the radial file and the corresponding column. """ def __init__(self, data, name, tstart=None, tstop=None): """ :param data: numpy array that contains the data :type data: numpy.ndarray :param name: name of the field (i.e. 'eKinR', 'eMagR', 'powerR', ...) :type name: str :param tstart: starting time that was used to compute the time average :type tstart: float :param tstop: stop time that was used to compute the time average :type tstop: float """ self.name = name self.start_time = tstart self.stop_time = tstop if self.name == 'eKinR': self.radius = data[:, 0] self.ekin_pol = data[:, 1] self.ekin_pol_axi = data[:, 2] self.ekin_tor = data[:, 3] self.ekin_tor_axi = data[:, 4] self.ekin_pol_surf = data[:, 5] self.ekin_pol_axi_surf = data[:, 6] self.ekin_tor_surf = data[:, 7] self.ekin_tor_axi_surf = data[:, 8] self.ekin_tot_r = self.ekin_pol + self.ekin_tor elif self.name == 'eMagR': self.radius = data[:, 0] self.emag_pol = data[:, 1] self.emag_pol_axi = data[:, 2] self.emag_tor = data[:, 3] self.emag_tor_axi = data[:, 4] self.emag_pol_surf = data[:, 5] self.emag_pol_axi_surf = data[:, 6] self.emag_tor_surf = data[:, 7] self.emag_tor_axi_surf = data[:, 8] self.dip_ratio = data[:, 9] self.emag_tot_r = self.emag_pol+self.emag_tor self.ecmb = self.emag_tot_r[0] elif self.name == 'anel': self.radius = data[:, 0] self.temp0 = data[:, 1] self.rho0 = data[:, 2] self.beta = data[:, 3] self.dbeta = data[:, 4] self.grav = data[:, 5] try: self.dsdr = data[:, 6] except IndexError: self.dsdr = np.zeros_like(self.radius) try: self.divkgradT = data[:, 7] except IndexError: self.divkgradT = np.zeros_like(self.radius) try: self.alpha0 = data[:, 8] except IndexError: self.alpha0 = np.zeros_like(self.radius) try: self.ogrun = data[:, 9] except IndexError: self.ogrun = np.zeros_like(self.radius) try: self.dLtemp0 = data[:, 10] except IndexError: self.dLtemp0 = np.zeros_like(self.radius) elif self.name == 'varDiff': self.radius = data[:, 0] self.conduc = data[:, 1] self.kappa = data[:, 2] self.dLkappa = data[:, 3] self.prandtl = data[:, 4] elif self.name == 'varVisc': self.radius = data[:, 0] self.dynVisc = data[:, 1] self.kinVisc = data[:, 2] self.dLvisc = data[:, 3] self.ekman = data[:, 4] self.prandtl = data[:, 5] self.prandtlmag = data[:, 6] elif self.name == 'varCond': self.radius = data[:, 0] self.conduc = data[:, 1] self.lmbda = data[:, 2] elif self.name == 'powerR': self.radius = data[:, 0] self.buoPower = data[:, 1] if data.shape[1] == 9 or data.shape[1] == 5: self.buoPower_chem = data[:, 2] self.viscDiss = data[:, 3] self.ohmDiss = data[:, 4] if data.shape[1] == 9: self.buoPower_SD = data[:, 5] self.buoPower_chem_SD = data[:, 6] self.viscDiss_SD = data[:, 7] self.ohmDiss_SD = data[:, 8] elif data.shape[1] == 7 or data.shape[1] == 4: self.viscDiss = data[:, 2] self.ohmDiss = data[:, 3] if data.shape[0] == 7: self.buoPower_SD = data[:, 4] self.viscDiss_SD = data[:, 5] self.ohmDiss_SD = data[:, 6] elif self.name == 'parrad': self.radius = data[:, 0] self.rm = data[:, 1] self.rol = data[:, 2] self.urol = data[:, 3] self.dlV = data[:, 4] self.udlV = data[:, 5] self.udlVc = data[:, 8] self.entropy = data[:, 9] self.entropy_SD = np.sqrt(abs(data[:, 10])) self.uh = data[:, 11] self.duhdr = data[:, 12] elif self.name == 'parR': self.radius = data[:, 0] self.rm = data[:, 1] self.rol = data[:, 2] self.urol = data[:, 3] self.dlV = data[:, 4] self.dlVc = data[:, 5] if data.shape[1] == 8: self.udlV = data[:, 6] self.udlVc = data[:, 7] elif data.shape[1] == 13: self.dlPolPeak = data[:, 6] self.rm_SD = data[:, 7] self.rol_SD = data[:, 8] self.urol_SD = data[:, 9] self.dlV_SD = data[:, 10] self.dlVc_SD = data[:, 11] self.dlPolPeak_SD = data[:, 12] elif self.name == 'bLayersR': self.radius = data[:, 0] self.entropy = data[:, 1] if data.shape[1] == 5: self.entropy_SD = np.sqrt(abs(data[:, 2])) self.uh = data[:, 3] self.duhdr = data[:, 4] elif data.shape[1] == 6: self.entropy_SD = np.sqrt(abs(data[:, 2])) self.uh = data[:, 3] self.duhdr = data[:, 4] self.dissS = data[:, 5] elif data.shape[1] == 9: self.uh = data[:, 2] self.duhdr = data[:, 3] self.dissS = data[:, 4] self.entropy_SD = data[:, 5] self.uh_SD = data[:, 6] self.duhdr_SD = data[:, 7] self.dissS_SD = data[:, 8] elif data.shape[1] == 11: self.xi = data[:, 2] self.uh = data[:, 3] self.duhdr = data[:, 4] self.dissS = data[:, 5] self.entropy_SD = data[:, 6] self.xi_SD = data[:, 7] self.uh_SD = data[:, 8] self.duhdr_SD = data[:, 8] self.dissS_SD = data[:, 9] elif self.name == 'fluxesR': self.radius = data[:, 0] self.fcond = data[:, 1] self.fconv = data[:, 2] self.fkin = data[:, 3] self.fvisc = data[:, 4] self.fpoyn = data[:, 5] self.fres = data[:, 6] self.ftot = self.fcond+self.fconv+self.fkin+self.fvisc+\ self.fpoyn+self.fres if data.shape[1] == 13: self.fcond_SD = data[:, 7] self.fconv_SD = data[:, 8] self.fkin_SD = data[:, 9] self.fvisc_SD = data[:, 10] self.fpoyn_SD = data[:, 11] self.fres_SD = data[:, 12] elif self.name == 'heatR': self.radius = data[:, 0] self.entropy = data[:, 1] self.temperature = data[:, 2] self.pressure = data[:, 3] self.density = data[:, 4] self.xi = data[:, 5] if data.shape[1] == 11: self.entropy_SD = data[:, 6] self.temperature_SD = data[:, 7] self.pressure_SD = data[:, 8] self.density_SD = data[:, 9] self.xi_SD = data[:, 10] elif self.name == 'phiR': self.radius = data[:, 0] self.phase = data[:, 1] self.phase_SD = data[:, 2] elif self.name == 'perpParR': self.radius = data[:, 0] self.Eperp = data[:, 1] self.Epar = data[:, 2] self.Eperp_axi = data[:, 3] self.Epar_axi = data[:, 4] if data.shape[1] == 9: self.Eperp_SD = data[:, 5] self.Epar_SD = data[:, 6] self.Eperp_axi_SD = data[:, 7] self.Epar_axi_SD = data[:, 8] def __add__(self, new): """ This method allows to sum two look up tables together. It is also working if the number of radial grid points has changed. In that case a spline interpolation is done to match the newest grid """ out = copy.deepcopy(new) if self.start_time is not None: fac_old = self.stop_time-self.start_time out.start_time = self.start_time else: fac_old = 0. if new.stop_time is not None: fac_new = new.stop_time-new.start_time out.stop_time = new.stop_time else: fac_new = 0. if fac_old != 0 or fac_new != 0: fac_tot = fac_new+fac_old else: fac_tot = 1. n_r_new = len(new.radius) n_r_old = len(self.radius) if n_r_new == n_r_old and abs(self.radius[10]-new.radius[10]) <= 1e-8: for attr in new.__dict__.keys(): if attr not in ['radius', 'name', 'start_time', 'stop_time']: # Only stack if both new and old have the attribute available if attr in self.__dict__: # Standard deviation if attr.endswith('SD'): out.__dict__[attr] = np.sqrt(( \ fac_new*new.__dict__[attr]**2 + \ fac_old*self.__dict__[attr]**2) / \ fac_tot) # Regular field else: out.__dict__[attr] = (fac_new*new.__dict__[attr] + \ fac_old*self.__dict__[attr]) / \ fac_tot else: # Different radial grid then interpolate on the new grid using splines rold = self.radius[::-1] # Splines need r increasing rnew = new.radius[::-1] for attr in new.__dict__.keys(): if attr not in ['radius', 'name', 'start_time', 'stop_time']: # Only stack if both new and old have the attribute available if attr in self.__dict__: datOldGrid = self.__dict__[attr] tckp = sint.splrep(rold, datOldGrid[::-1]) datNewGrid = sint.splev(rnew, tckp) self.__dict__[attr] = datNewGrid[::-1] # Standard deviation if attr.endswith('SD'): out.__dict__[attr] = np.sqrt(( \ fac_new*new.__dict__[attr]**2 + \ fac_old*self.__dict__[attr]**2) / \ fac_tot) # Regular field else: out.__dict__[attr] = (fac_new*new.__dict__[attr] + \ fac_old*self.__dict__[attr]) / \ fac_tot return out