Source code for burnman.material

from__future__importprint_function# This file is part of BurnMan - a thermoelastic and thermodynamic toolkit for the Earth and Planetary Sciences# Copyright (C) 2012 - 2017 by the BurnMan team, released under the GNU# GPL v2 or later.importnumpyasnpdefmaterial_property(func):""" Decorator @material_property to be used for cached properties of materials. To be used on function in Material or derived classes that should be exposed as read-only properties that are cached. The function Material.reset() will reset the cached values. Internally, the values are stored in a dictionary member called _cached, which is emptied by .reset(). """classmat_obj():def__init__(self,func):self.func=funcself.varname=self.func.__name__defget(self,obj):ifnothasattr(obj,"_cached"):raiseException("The material_property decorator could not find class member _cached. ""Did you forget to call Material.__init__(self) in __init___?")cache_array=getattr(obj,"_cached")ifself.varnamenotincache_array:cache_array[self.varname]=self.func(obj)returncache_array[self.varname]returnproperty(mat_obj(func).get,doc=func.__doc__)

[docs]classMaterial(object):""" Base class for all materials. The main functionality is unroll() which returns a list of objects of type :class:`~burnman.mineral.Mineral` and their molar fractions. This class is available as ``burnman.Material``. The user needs to call set_method() (once in the beginning) and set_state() before querying the material with unroll() or density(). """def__init__(self):self._pressure=Noneself._temperature=Noneifnothasattr(self,"name"):# if a derived class decides to set .name before calling this# constructor (I am looking at you, SLB_2011.py!), do not# overwrite the name here.self._name=self.__class__.__name__self._cached={}@propertydefname(self):""" Human-readable name of this material. By default this will return the name of the class, but it can be set to an arbitrary string. Overriden in Mineral. """returnself._name@name.setterdefname(self,value):self._name=value

[docs]defset_method(self,method):""" Set the averaging method. See :doc:`averaging` for details. Notes ----- Needs to be implemented in derived classes. """raiseNotImplementedError("need to implement set_method() in derived class!")

[docs]defto_string(self):""" Returns a human-readable name of this material. The default implementation will return the name of the class, which is a reasonable default. Returns ------- name : string Name of this material. """return"'"+self.name+"'"

[docs]defdebug_print(self,indent=""):""" Print a human-readable representation of this Material. """raiseNotImplementedError("Derived classes need to implement debug_print(). This is '"+self.__class__.__name__+"'")

[docs]defprint_minerals_of_current_state(self):""" Print a human-readable representation of this Material at the current P, T as a list of minerals. This requires set_state() has been called before. """(minerals,fractions)=self.unroll()iflen(minerals)==1:print(minerals[0].to_string())else:print("Material %s:"%self.to_string())for(mineral,fraction)inzip(minerals,fractions):print(" %g of phase %s"%(fraction,mineral.to_string()))

[docs]defset_state(self,pressure,temperature):""" Set the material to the given pressure and temperature. Parameters ---------- pressure : float The desired pressure in [Pa]. temperature : float The desired temperature in [K]. """ifnothasattr(self,"_pressure"):raiseException("Material.set_state() could not find class member _pressure. ""Did you forget to call Material.__init__(self) in __init___?")self.reset()self._pressure=pressureself._temperature=temperature

[docs]defreset(self):""" Resets all cached material properties. It is typically not required for the user to call this function. """self._cached={}

[docs]defunroll(self):""" Unroll this material into a list of :class:`burnman.Mineral` and their molar fractions. All averaging schemes then operate on this list of minerals. Note that the return value of this function may depend on the current state (temperature, pressure). Notes ----- Needs to be implemented in derived classes. Returns ------- fractions : list of float List of molar fractions, should sum to 1.0. minerals : list of :class:`burnman.Mineral` List of minerals. """raiseNotImplementedError("need to implement unroll() in derived class!")

[docs]defevaluate(self,vars_list,pressures,temperatures):""" Returns an array of material properties requested through a list of strings at given pressure and temperature conditions. At the end it resets the set_state to the original values. The user needs to call set_method() before. Parameters ---------- vars_list : list of strings Variables to be returned for given conditions pressures : ndlist or ndarray of float n-dimensional array of pressures in [Pa]. temperatures : ndlist or ndarray of float n-dimensional array of temperatures in [K]. Returns ------- output : array of array of float Array returning all variables at given pressure/temperature values. output[i][j] is property vars_list[j] and temperatures[i] and pressures[i]. """old_pressure=self.pressureold_temperature=self.temperaturepressures=np.array(pressures)temperatures=np.array(temperatures)assert(pressures.shape==temperatures.shape)output=np.empty((len(vars_list),)+pressures.shape)fori,pinnp.ndenumerate(pressures):self.set_state(p,temperatures[i])forjinrange(len(vars_list)):output[(j,)+i]=getattr(self,vars_list[j])ifold_pressureisNoneorold_temperatureisNone:# do not set_state if old values were None. Just reset to None# manuallyself._pressure=self._temperature=Noneself.reset()else:self.set_state(old_pressure,old_temperature)returnoutput