# Path: DiscEvolution/constants.py
# G = 1.
# AU = 1.496e13
# 
# Path: DiscEvolution/chemistry/base_chem.py
# class ChemicalAbund(object):
#     """Simple wrapper class to hold chemical species data.
# 
#     Holds the mass abundance (g) of the chemical species relative to Hydrogen.
# 
#     args:
#         species : list, maps species name to location in data array
#         masses  : array, molecular masses in atomic mass units
#         size    : Number of data points to hold chemistry for
#     """
#     def __init__(self, species, masses,*sizes):
#         # Sizes is dimension zero if not specified
#         sizes = sizes if sizes else (0,)
#         if len(masses) != len(species):
#             raise AttributeError("Number of masses must match the number of"
#                                  "species")
# 
#         self._indexes = dict([(name, i) for i, name in enumerate(species)])
#         self._names   = species
#         self._mass    = masses
#         self._Nspec = len(self._names)
# 
#         self._data = np.zeros((self.Nspec,) + sizes, dtype='f8')
# 
#     def __getitem__(self, k):
#         return self._data[self._indexes[k]]
# 
#     def __setitem__(self, k, val):
#         self._data[self._indexes[k]] = val
# 
#     def __iadd__(self, other):
#         if self.names != other.names:
#             raise AttributeError("Chemical species must be the same")
# 
#         self._data += other._data    
#         return self
# 
#     def __iter__(self):
#         return iter(self._names)
# 
#     def copy(self):
#         return copy.deepcopy(self)
#             
#     def number_abund(self, k):
#         """Number abundance of species k, n_k= rho_k / m_k"""
#         return self[k]/self.mass(k)
# 
#     @property
#     def total_abund(self):
#         return self._data.sum(0)
#     
#     def set_number_abund(self, k, n_k):
#         """Set the mass abundance from the number abundance"""
#         self[k] = n_k * self.mass(k)
# 
#     def to_array(self):
#         """Get the raw data"""
#         return self.data
# 
#     def from_array(self, data):
#         """Set the raw data"""
#         if data.shape[0] == self.Nspec:
#             raise AttributeError("Error: shape must be [Nspec, *]")
#         self._data = data
# 
#    #def resize(self, n):
#     #    '''Resize the data array, keeping any elements that we already have'''
#     #    dn = n - self.size
#     #    if dn < 0:
#     #        self._data = self._data[:,:n].copy()
#     #    else:
#     #        self._data = np.concatenate([self._data,
#     #                                     np.empty([self.Nspec,dn],dtype='f8')])
#     def resize(self, shape):
#         '''Resize the data array, keeping any elements that we already have'''
#         try:
#             shape = (self.Nspec, ) + tuple(shape)
#         except TypeError:
#             if type(shape) != type(1):
#                 raise TypeError("shape must be int, or array of int")
#             shape = (self.Nspec, shape)
# 
#         new_data = np.zeros(shape, dtype='f8')
#         
#         idx = [ slice(0, min(ni)) for ni in zip(shape, self._data.shape)]
# 
#         # Copy accross the old data
#         new_data[idx] = self._data[idx]
# 
#         self._data = new_data
# 
#     def append(self, other):
#         """Append chemistry data from another container"""
#         if self.names != other.names:
#             raise  AttributeError("Chemical species must be the same")
# 
#         self._data = np.append(self._data, other.data)
#             
#     def mass(self, k):
#         """Mass of species in atomic mass units"""
#         return self._mass[self._indexes[k]]
# 
#     def mu(self):
#         '''Mean molecular weight'''
#         return self._data.sum(0) / (self._data.T / self._mass).sum(1)
# 
#     @property
#     def masses(self):
#         """Masses of all species in amu"""
#         return self._mass
# 
#     @property
#     def names(self):
#         """Names of the species in order"""
#         return self._names
# 
#     @property
#     def Nspec(self):
#         return self._Nspec
# 
#     @property
#     def species(self):
#         """Names of the chemical species held."""
#         return self._indexes.keys()
# 
#     @property
#     def data(self):
#         return self._data
# 
#     @property
#     def size(self):
#         return self._data.shape[1]


from ..constants import m_H
from multiprocessing import Pool
from .base_chem import ChemicalAbund
from pykrome import PyKROME
    from ..eos import LocallyIsothermalEOS
    from ..star import SimpleStar
    from ..grid import Grid
    from ..constants import Msun, AU
import sys, os
import numpy as np
import ctypes
    import matplotlib.pyplot as plt
    import time
            N = int(os.environ['OMP_NUM_THREADS'])
        except KeyError:
            N = None
        self._pool = Pool(N)

    def ASCII_header(self):
        """Header for ASCII dump file"""
        return ('# {} '.format(self.__class__.__name__) +
                'renormalize: {}, fixed_mu: {}, '.format(self._renormalize,
                                                         self._mu) + 
                'KROME_PATH {}'.format(KROME_PATH))

    def HDF5_attributes(self):
        """Class information for HDF5 headers"""
        header = { 
            'renormalize' : "{}".format(self._renormalize),
            'fixed_mu'    : "{}".format(self._mu),
            'KROME_PATH'  : "{}".format(KROME_PATH),
            }

        return self.__class__.__name__, header

    def update(self, dt, T, rho, dust_frac, chem, **kwargs):
        """Integrate the chemistry for time dt"""


        # Convert dt to seconds:
        dt *= _krome.krome_seconds_per_year/(2*np.pi)

        m_gas = chem.gas.masses * m_H

# Path: DiscEvolution/constants.py
# G = 1.
# AU = 1.496e13
# 
# Path: DiscEvolution/chemistry/base_chem.py
# class ChemicalAbund(object):
#     """Simple wrapper class to hold chemical species data.
# 
#     Holds the mass abundance (g) of the chemical species relative to Hydrogen.
# 
#     args:
#         species : list, maps species name to location in data array
#         masses  : array, molecular masses in atomic mass units
#         size    : Number of data points to hold chemistry for
#     """
#     def __init__(self, species, masses,*sizes):
#         # Sizes is dimension zero if not specified
#         sizes = sizes if sizes else (0,)
#         if len(masses) != len(species):
#             raise AttributeError("Number of masses must match the number of"
#                                  "species")
# 
#         self._indexes = dict([(name, i) for i, name in enumerate(species)])
#         self._names   = species
#         self._mass    = masses
#         self._Nspec = len(self._names)
# 
#         self._data = np.zeros((self.Nspec,) + sizes, dtype='f8')
# 
#     def __getitem__(self, k):
#         return self._data[self._indexes[k]]
# 
#     def __setitem__(self, k, val):
#         self._data[self._indexes[k]] = val
# 
#     def __iadd__(self, other):
#         if self.names != other.names:
#             raise AttributeError("Chemical species must be the same")
# 
#         self._data += other._data    
#         return self
# 
#     def __iter__(self):
#         return iter(self._names)
# 
#     def copy(self):
#         return copy.deepcopy(self)
#             
#     def number_abund(self, k):
#         """Number abundance of species k, n_k= rho_k / m_k"""
#         return self[k]/self.mass(k)
# 
#     @property
#     def total_abund(self):
#         return self._data.sum(0)
#     
#     def set_number_abund(self, k, n_k):
#         """Set the mass abundance from the number abundance"""
#         self[k] = n_k * self.mass(k)
# 
#     def to_array(self):
#         """Get the raw data"""
#         return self.data
# 
#     def from_array(self, data):
#         """Set the raw data"""
#         if data.shape[0] == self.Nspec:
#             raise AttributeError("Error: shape must be [Nspec, *]")
#         self._data = data
# 
#    #def resize(self, n):
#     #    '''Resize the data array, keeping any elements that we already have'''
#     #    dn = n - self.size
#     #    if dn < 0:
#     #        self._data = self._data[:,:n].copy()
#     #    else:
#     #        self._data = np.concatenate([self._data,
#     #                                     np.empty([self.Nspec,dn],dtype='f8')])
#     def resize(self, shape):
#         '''Resize the data array, keeping any elements that we already have'''
#         try:
#             shape = (self.Nspec, ) + tuple(shape)
#         except TypeError:
#             if type(shape) != type(1):
#                 raise TypeError("shape must be int, or array of int")
#             shape = (self.Nspec, shape)
# 
#         new_data = np.zeros(shape, dtype='f8')
#         
#         idx = [ slice(0, min(ni)) for ni in zip(shape, self._data.shape)]
# 
#         # Copy accross the old data
#         new_data[idx] = self._data[idx]
# 
#         self._data = new_data
# 
#     def append(self, other):
#         """Append chemistry data from another container"""
#         if self.names != other.names:
#             raise  AttributeError("Chemical species must be the same")
# 
#         self._data = np.append(self._data, other.data)
#             
#     def mass(self, k):
#         """Mass of species in atomic mass units"""
#         return self._mass[self._indexes[k]]
# 
#     def mu(self):
#         '''Mean molecular weight'''
#         return self._data.sum(0) / (self._data.T / self._mass).sum(1)
# 
#     @property
#     def masses(self):
#         """Masses of all species in amu"""
#         return self._mass
# 
#     @property
#     def names(self):
#         """Names of the species in order"""
#         return self._names
# 
#     @property
#     def Nspec(self):
#         return self._Nspec
# 
#     @property
#     def species(self):
#         """Names of the chemical species held."""
#         return self._indexes.keys()
# 
#     @property
#     def data(self):
#         return self._data
# 
#     @property
#     def size(self):
#         return self._data.shape[1]


# Path: DiscEvolution/chemistry/krome_chem.py
from ..constants import m_H
from multiprocessing import Pool
from .base_chem import ChemicalAbund
from pykrome import PyKROME
    from ..eos import LocallyIsothermalEOS
    from ..star import SimpleStar
    from ..grid import Grid
    from ..constants import Msun, AU
import sys, os
import numpy as np
import ctypes
    import matplotlib.pyplot as plt
    import time

            N = int(os.environ['OMP_NUM_THREADS'])
        except KeyError:
            N = None
        self._pool = Pool(N)

    def ASCII_header(self):
        """Header for ASCII dump file"""
        return ('# {} '.format(self.__class__.__name__) +
                'renormalize: {}, fixed_mu: {}, '.format(self._renormalize,
                                                         self._mu) + 
                'KROME_PATH {}'.format(KROME_PATH))

    def HDF5_attributes(self):
        """Class information for HDF5 headers"""
        header = { 
            'renormalize' : "{}".format(self._renormalize),
            'fixed_mu'    : "{}".format(self._mu),
            'KROME_PATH'  : "{}".format(KROME_PATH),
            }

        return self.__class__.__name__, header

    def update(self, dt, T, rho, dust_frac, chem, **kwargs):
        """Integrate the chemistry for time dt"""


        # Convert dt to seconds:
        dt *= _krome.krome_seconds_per_year/(2*np.pi)

        m_gas = chem.gas.masses * m_H

        m_ice = chem.ice.masses * m_H