Source code for pyrk.th_system

import six
from th_component import THSuperComponent
from utilities.ur import units


[docs]class THSystem(object): """This class models: - lumped capacitance model for slab geometry - 1-D heat diffusion in spherical geometry, for heat generation at any radius in the sphere, - advective heat transfer by fluid - convective heat transfer at the solid surface to fluid. """ def __init__(self, kappa, components): self.kappa = kappa self.components = components
[docs] def comp_from_name(self, name): """Returns the component with the matching name """ for comp in self.components: if comp.name == name: return comp # uh oh, none was found msg = "There is no component with the name: " msg += name raise KeyError(msg)
[docs] def dtempdt(self, component, power, omegas, t_idx): '''compute the derivative dtemperature/dt :param component: name of the component that dtemp/dt is calculated :type component: str :param power: nuclear power density :type power: float :param omegas: decay heat nuclear data :type omegas: list :param t_idx: the timestep that dtempdt is calculated for :type t_idx: int :return: value of dtemp/dt :rtype: float, kelvin/s ''' to_ret = 0.0 if isinstance(component, THSuperComponent): # return 0 for superComponent, doesn't calculate the temperature # variation of superComponent return to_ret*units.kelvin/units.second else: cap = (component.rho(t_idx).magnitude*component.cp.magnitude) if component.sph and component.ri.magnitude == 0.0: Qcent = self.BC_center(component, t_idx) to_ret -= Qcent/cap for interface, d in six.iteritems(component.convBC): env = self.comp_from_name(interface) QconvBC = self.convBoundary(component, t_b=component.T[t_idx].magnitude, t_env=env.T[t_idx].magnitude, h=d["h"].h(env.rho(t_idx), env.mat.mu), R=d["R"]) to_ret -= QconvBC/cap if component.heatgen: to_ret += self.heatgen(component, power, omegas)/cap for interface, d in six.iteritems(component.cond): env = self.comp_from_name(interface) if component.sph: Qcond = self.conductionFVM(component, env, t_idx) else: Qcond = self.conduction_slab(component, env, t_idx, L=d["L"], A=d["area"]) to_ret -= Qcond/cap for interface, d in six.iteritems(component.conv): env = self.comp_from_name(interface) if isinstance(env, THSuperComponent): Tr = env.compute_tr(component.T[t_idx].magnitude, env.sub_comp[-2].T[t_idx].magnitude, h=d['h'].h(component.rho(t_idx), component.mat.mu).magnitude) Qconv = self.convection(t_b=component.T[t_idx].magnitude, t_env=Tr, h=d['h'].h(component.rho(t_idx), component.mat.mu), A=d['area']) assert (Qconv*(component.T[t_idx].magnitude-Tr)) >= 0, ''' convection from %s to %s, from low temperature %f to high %f is not physical: %f''' % ( component.name, env.name, component.T[t_idx].magnitude, Tr, Qconv.magnitude) else: Qconv = self.convection(t_b=component.T[t_idx].magnitude, t_env=env.T[t_idx].magnitude, h=d['h'].h(component.rho(t_idx), component.mat.mu), A=d['area']) assert (Qconv*(component.T[t_idx]-env.T[t_idx])).magnitude >= 0, \ 'convection from %s to %s, %fc to %fc is not physical' \ % (component.name, env.name, component.T[t_idx].magnitude, env.T[t_idx].magnitude) to_ret -= Qconv/cap/component.vol.magnitude for name, d in six.iteritems(component.adv): Qadv = self.advection(component, t_idx, t_in=d['t_in'].magnitude, m_flow=d['m_flow'], cp=d['cp']) to_ret -= Qadv/cap/component.vol.magnitude return to_ret*units.kelvin/units.seconds
[docs] def BC_center(self, component, t_idx): '''Volumetric conductive heat flux Qconduction from the center of a sphere to the first boundary (conduction without interface) in watts/meter**3 :param component: name of the inner most component(mesh element) :type component: str :param t_idx: timestep at which Qconduction is calculated :type t_idx: int :return : Qcondction :rtype:float, dimensionless ''' conductivity = component.k.magnitude T_b = component.T[t_idx].magnitude dr = (component.ro - component.ri).magnitude return (conductivity*T_b)/(dr**2)
[docs] def convBoundary(self, component, t_b, t_env, h, R): '''calculate heat transfer through convective boundray condition for the mesh element at the surface of the spherical Supercomponent (watts) :param component: name of the outer most solid component :type component: str :param t_b: temperature of the body :type t_b: float :param t_env: temperature of the environment(fluid) :type t_env: float :param h: convective heat transfer coefficient :type h: float :param R: outer radius of the component :type R: float :return: dimensionless quantity of Qconv :rtype: float ''' r_b = component.ro.magnitude k = component.k.magnitude dr = component.ri.magnitude-component.ro.magnitude T_R = (-h.magnitude/k*t_env + t_b/dr)/(1/dr-h.magnitude/k) to_ret = 1/r_b*k*(r_b*t_b-R.magnitude*T_R)/dr**2 return to_ret
[docs] def heatgen(self, component, power, omegas): """ calculate heat transfer by conduction(watts/m3) :param component: name of the component :type component: str :param power: normalized nuclear power generated in the component i.e.: power*power_tot = power (in watts) :type power: float """ return (power*component.power_tot.magnitude * (1-self.kappa) + sum(omegas))/component.vol.magnitude
[docs] def conductionFVM(self, component, env, t_idx, L=0.0*units.meter, k=0.0*units.meter, A=0.0*units.meter**2): """ compute volumetric conductive heat transfer by conduction(watts/m3) :param component: name of the component :type component: str :param env: name of the environment :type env: str :param t_idx: time step that conduction heat is computed :type t_idx: int :param L: conduction distance :type L: float, units meter :pram k: conductivity :type k: float, units w/mk :return: Qond, dimemsionless quantity :rtype: float """ T_b = component.T[t_idx].magnitude T_env = env.T[t_idx].magnitude r_b = component.ro.magnitude r_env = env.ro.magnitude dr = (component.ro-component.ri).magnitude k = component.k.magnitude return k/r_b * (r_b * T_b - r_env * T_env)/(dr**2)
[docs] def conduction_slab(self, component, env, t_idx, L, A): """ compute volumetric heat transfer by conduction(watts/m3) :param component: name of the component :type component: str :param env: name of the environment :type env: str :param t_idx: time step that conduction heat is computed :type t_idx: int :return: Qond, dimemsionless quantity :rtype: float """ assert(A.magnitude>0) assert(L.magnitude>0) T_b = component.T[t_idx].magnitude T_env = env.T[t_idx].magnitude num = (T_b-T_env) k = component.k denom = (L/(k*A)).magnitude return num/denom
[docs] def advection(self, component, t_idx, t_in, m_flow, cp): ''' calculate heat transfer by advection in watts :param component: name of the component :type component: str :param t_idx: time step that conduction heat is computed :type t_idx: int :param t_in: inlet temperature :type t_in: float :param m_flow: mass flow rate though the control volume :type m_flow: float :param cp: specific heat capacity of the fluid :type cp: float :return: dimemsionless quantity of Qadvective :rtype: float ''' #check if the temperature is the initial temperature 0degC #set Qadv=0 in this case for computation stability if component.T[t_idx] == 0*units.degC.to('kelvin'): Qadv = 0 else: t_out = component.T[t_idx].magnitude*2.0 - t_in Qadv = m_flow.magnitude*cp.magnitude*(t_out-t_in) return Qadv
[docs] def mass_trans(self, t_b, t_inlet, H, u): """ :param t_b: The temperature of the body :type t_b: float. :param t_inlet: The temperature of the flow inlet :type t_inlet: """ num = 2.0*u*(t_b - t_inlet) denom = H return num/denom
[docs] def convection(self, t_b, t_env, h, A): """ heat transfer by convection(watts) :param t_b: The temperature of the body :type t_b: float. :param t_env: The temperature of the environment :type t_env: float. :param h: the heat transfer coefficient between environment and body :type h: float. :param A: the surface area of heat transfer :type A: float. """ num = (t_b-t_env) denom = (1.0/(h.magnitude*A.magnitude)) return num/denom
[docs] def custom(self, t_b, t_env, res): num = (t_b-t_env) denom = res.to(units.kelvin/units.watt) return num/denom
[docs] def record(self, component): """a recorder function that calls down to each component. used for the th/th_timeseries table """ return self.comp_from_name(component).record()
[docs] def metadata(self, component): """a recorder function that calls down to each component. used for the th/th_params table """ return self.comp_from_name(component).metadata()