[cig-commits] [commit] master: Add parameter validation to equations of state (1a2a382)

cig_noreply at geodynamics.org cig_noreply at geodynamics.org
Fri Dec 12 16:37:33 PST 2014


Repository : https://github.com/geodynamics/burnman

On branch  : master
Link       : https://github.com/geodynamics/burnman/compare/916ee6acd98bd253c534a4b858b8d86ec62c3fd5...5e9eb1c42d6dd00a30a59872a2b31d1c0f8bd09c

>---------------------------------------------------------------

commit 1a2a38250cd39a038e5764066108d9e457a187b4
Author: ian-r-rose <ian.r.rose at gmail.com>
Date:   Mon Oct 13 19:24:27 2014 -0700

    Add parameter validation to equations of state
    
    Conflicts:
    	burnman/equation_of_state.py


>---------------------------------------------------------------

1a2a38250cd39a038e5764066108d9e457a187b4
 burnman/eos/birch_murnaghan.py      | 36 +++++++++++++++++++++++++++-
 burnman/eos/equation_of_state.py    | 20 +++++++++++++++-
 burnman/eos/mie_grueneisen_debye.py | 45 ++++++++++++++++++++++++++++++++++
 burnman/eos/slb.py                  | 48 +++++++++++++++++++++++++++++++++++++
 burnman/mineral.py                  |  6 +++++
 burnman/mineral_helpers.py          |  5 ++++
 misc/benchmarks/benchmark.py        |  5 ++++
 7 files changed, 163 insertions(+), 2 deletions(-)

diff --git a/burnman/eos/birch_murnaghan.py b/burnman/eos/birch_murnaghan.py
index 4983939..5e208a1 100644
--- a/burnman/eos/birch_murnaghan.py
+++ b/burnman/eos/birch_murnaghan.py
@@ -4,7 +4,7 @@
 
 import scipy.optimize as opt
 import equation_of_state as eos
-
+import warnings
 
 def bulk_modulus(volume, params):
     """
@@ -134,6 +134,40 @@ class BirchMurnaghanBase(eos.EquationOfState):
         """
         return 0.
 
+    def validate_parameters(self, params):
+        """
+        Check for existence and validity of the parameters
+        """
+     
+        #if G and Gprime are not included this is presumably deliberate,
+        #as we can model density and bulk modulus just fine without them,
+        #so just add them to the dictionary as zeros
+        if 'G_0' not in params:
+            params['G_0'] = 0.
+        if 'Gprime_0' not in params:
+            params['Gprime_0'] = 0.
+  
+        #check that all the required keys are in the dictionary
+        expected_keys = ['V_0', 'K_0', 'Kprime_0', 'G_0', 'Gprime_0']
+        for k in expected_keys:
+            if k not in params:
+                raise KeyError('params object missing parameter : ' + k)
+        
+        #now check that the values are reasonable.  I mostly just
+        #made up these values from experience, and we are only 
+        #raising a warning.  Better way to do this? [IR]
+        if params['V_0'] < 1.e-7 or params['V_0'] > 1.e-3:
+            warnings.warn( 'Unusual value for V_0' )
+        if params['K_0'] < 1.e9 or params['K_0'] > 1.e13:
+            warnings.warn( 'Unusual value for K_0' )
+        if params['Kprime_0'] < -5. or params['Kprime_0'] > 10.:
+            warnings.warn( 'Unusual value for Kprime_0' )
+        if params['G_0'] < 0.0 or params['G_0'] > 1.e13:
+            warnings.warn( 'Unusual value for G_0' )
+        if params['Gprime_0'] < -5. or params['Gprime_0'] > 10.:
+            warnings.warn( 'Unusual value for Gprime_0' )
+
+
 
 class BM3(BirchMurnaghanBase):
     """
diff --git a/burnman/eos/equation_of_state.py b/burnman/eos/equation_of_state.py
index dade9f4..1f36133 100644
--- a/burnman/eos/equation_of_state.py
+++ b/burnman/eos/equation_of_state.py
@@ -245,7 +245,6 @@ class EquationOfState(object):
         else:
             return 300.0
 
-
     def gibbs_free_energy( self, pressure, temperature, volume, params ):
         """
         Parameters
@@ -331,3 +330,22 @@ class EquationOfState(object):
             Internal energy of the mineral
         """
         raise NotImplementedError("")
+
+    def validate_parameters(self, params):
+        """
+        The params object is just a dictionary associating mineral physics parameters 
+        for the equation of state.  Different equation of states can have different parameters,
+        and the parameters may have ranges of validity.  The intent of this function is 
+        twofold. First, it can check for the existence of the parameters that the 
+        equation of state needs, and second, it can check whether the parameters have reasonable
+        values.  Unreasonable values will frequently be due to unit issues (e.g., supplying 
+        bulk moduli in GPa instead of Pa). In the base class this function does nothing,
+        and an equation of state is not required to implement it.  This function will
+        not return anything, though it may raise warnings or errors.
+
+        Params
+        ------
+        params : dictionary
+            Dictionary containing material parameters required by the equation of state.
+        """
+        pass
diff --git a/burnman/eos/mie_grueneisen_debye.py b/burnman/eos/mie_grueneisen_debye.py
index d339049..66b5f9c 100644
--- a/burnman/eos/mie_grueneisen_debye.py
+++ b/burnman/eos/mie_grueneisen_debye.py
@@ -4,6 +4,7 @@
 
 import numpy as np
 import scipy.optimize as opt
+import warnings
 
 import equation_of_state as eos
 import birch_murnaghan as bm
@@ -167,6 +168,50 @@ class MGDBase(eos.EquationOfState):
         return K_th
 
 
+    def validate_parameters(self, params):
+        """
+        Check for existence and validity of the parameters
+        """
+
+        #if G and Gprime are not included this is presumably deliberate,
+        #as we can model density and bulk modulus just fine without them,
+        #so just add them to the dictionary as zeros
+        if 'G_0' not in params:
+            params['G_0'] = 0.
+        if 'Gprime_0' not in params:
+            params['Gprime_0'] = 0.
+  
+        #check that all the required keys are in the dictionary
+        expected_keys = ['V_0', 'K_0', 'Kprime_0', 'G_0', 'Gprime_0', 'molar_mass', 'n', 'Debye_0', 'grueneisen_0', 'q_0']
+        for k in expected_keys:
+            if k not in params:
+                raise KeyError('params object missing parameter : ' + k)
+        
+        #now check that the values are reasonable.  I mostly just
+        #made up these values from experience, and we are only 
+        #raising a warning.  Better way to do this? [IR]
+        if params['V_0'] < 1.e-7 or params['V_0'] > 1.e-3:
+            warnings.warn( 'Unusual value for V_0' )
+        if params['K_0'] < 1.e9 or params['K_0'] > 1.e13:
+            warnings.warn( 'Unusual value for K_0' )
+        if params['Kprime_0'] < -5. or params['Kprime_0'] > 10.:
+            warnings.warn( 'Unusual value for Kprime_0' )
+        if params['G_0'] < 0. or params['G_0'] > 1.e13:
+            warnings.warn( 'Unusual value for G_0' )
+        if params['Gprime_0'] < -5. or params['Gprime_0'] > 10.:
+            warnings.warn( 'Unusual value for Gprime_0' )
+        if params['molar_mass'] < 0.001 or params['molar_mass'] > 1.:
+            warnings.warn( 'Unusual value for molar_mass' )
+        if params['n'] < 1. or params['n'] > 100. or not float(params['n']).is_integer():
+            warnings.warn( 'Unusual value for n' )
+        if params['Debye_0'] < 1. or params['Debye_0'] > 10000.:
+            warnings.warn( 'Unusual value for Debye_0' )
+        if params['grueneisen_0'] < 0. or params['grueneisen_0'] > 10.:
+            warnings.warn( 'Unusual value for grueneisen_0' )
+        if params['q_0'] < -10. or params['q_0'] > 10.:
+            warnings.warn( 'Unusual value for q_0' )
+
+
 class MGD3(MGDBase):
     """
     MGD equation of state with third order finite strain expansion for the
diff --git a/burnman/eos/slb.py b/burnman/eos/slb.py
index 46efbc8..b650477 100644
--- a/burnman/eos/slb.py
+++ b/burnman/eos/slb.py
@@ -253,6 +253,54 @@ class SLBBase(eos.EquationOfState):
 
         return F
 
+    def validate_parameters(self, params):
+        """
+        Check for existence and validity of the parameters
+        """
+
+        #if G and Gprime are not included this is presumably deliberate,
+        #as we can model density and bulk modulus just fine without them,
+        #so just add them to the dictionary as zeros
+        if 'G_0' not in params:
+            params['G_0'] = 0.
+        if 'Gprime_0' not in params:
+            params['Gprime_0'] = 0.
+        if 'eta_s_0' not in params:
+            params['eta_s_0'] = 0.
+  
+        #check that all the required keys are in the dictionary
+        expected_keys = ['V_0', 'K_0', 'Kprime_0', 'G_0', 'Gprime_0', 'molar_mass', 'n', 'Debye_0', 'grueneisen_0', 'q_0', 'eta_s_0']
+        for k in expected_keys:
+            if k not in params:
+                raise KeyError('params object missing parameter : ' + k)
+        
+        #now check that the values are reasonable.  I mostly just
+        #made up these values from experience, and we are only 
+        #raising a warning.  Better way to do this? [IR]
+        if params['V_0'] < 1.e-7 or params['V_0'] > 1.e-3:
+            warnings.warn( 'Unusual value for V_0' )
+        if params['K_0'] < 1.e9 or params['K_0'] > 1.e13:
+            warnings.warn( 'Unusual value for K_0' )
+        if params['Kprime_0'] < -5. or params['Kprime_0'] > 10.:
+            warnings.warn( 'Unusual value for Kprime_0' )
+        if params['G_0'] < 0. or params['G_0'] > 1.e13:
+            warnings.warn( 'Unusual value for G_0' )
+        if params['Gprime_0'] < -5. or params['Gprime_0'] > 10.:
+            warnings.warn( 'Unusual value for Gprime_0' )
+        if params['molar_mass'] < 0.001 or params['molar_mass'] > 1.:
+            warnings.warn( 'Unusual value for molar_mass' )
+        if params['n'] < 1. or params['n'] > 100. or not float(params['n']).is_integer():
+            warnings.warn( 'Unusual value for n' )
+        if params['Debye_0'] < 1. or params['Debye_0'] > 10000.:
+            warnings.warn( 'Unusual value for Debye_0' )
+        if params['grueneisen_0'] < 0. or params['grueneisen_0'] > 10.:
+            warnings.warn( 'Unusual value for grueneisen_0' )
+        if params['q_0'] < -10. or params['q_0'] > 10.:
+            warnings.warn( 'Unusual value for q_0' )
+        if params['eta_s_0'] < -10. or params['eta_s_0'] > 10.:
+            warnings.warn( 'Unusual value for eta_s_0' )
+            
+
 
 class SLB3(SLBBase):
     """
diff --git a/burnman/mineral.py b/burnman/mineral.py
index 8c915bb..7a0d574 100644
--- a/burnman/mineral.py
+++ b/burnman/mineral.py
@@ -68,6 +68,12 @@ class Mineral(Material):
 
         self.method = new_method
 
+        #Validate the params object on the requested EOS. 
+        try:
+            self.method.validate_parameters(self.params)
+        except Exception as e:
+            raise Exception('Mineral ' + self.to_string() + 'failed to validate parameters with message : \" ' + e.message + '\"' )
+
     def to_string(self):
         """
         Returns the name of the mineral class
diff --git a/burnman/mineral_helpers.py b/burnman/mineral_helpers.py
index cd605d7..9a41bc7 100644
--- a/burnman/mineral_helpers.py
+++ b/burnman/mineral_helpers.py
@@ -62,6 +62,11 @@ class HelperSolidSolution(Mineral):
             print "%s%g of" % (indent, fraction)
             mat.debug_print(indent + "  ")
 
+    def set_method(self, method):
+        for mat in self.base_materials:
+            mat.set_method(method)
+        self.method = self.base_materials[0].method
+
     def set_state(self, pressure, temperature):
         for mat in self.base_materials:
             mat.set_state(pressure, temperature)
diff --git a/misc/benchmarks/benchmark.py b/misc/benchmarks/benchmark.py
index 967c0ce..e39ce27 100644
--- a/misc/benchmarks/benchmark.py
+++ b/misc/benchmarks/benchmark.py
@@ -71,6 +71,8 @@ def check_mgd_shim_duffy_kenichi():
                    'V_0': 10.22e-6,
                    'K_0': 167.0e9,
                    'Kprime_0': 5.0,
+                   'G_0': 0.0e9,
+                   'Gprime_0': 0.0,
                    'molar_mass': .196966,
                    'n': 1.0,
                    'Debye_0': 170.,
@@ -110,6 +112,8 @@ def check_mgd_fei_mao_shu_hu():
                     'V_0': 11.657e-6,
                     'K_0': 157.0e9,
                     'Kprime_0': 4.0,
+                    'G_0': 0.0e9,
+                    'Gprime_0': 0.0,
                     'molar_mass': .196966,
                     'n': 2.0,
                     'Debye_0': 500.,
@@ -295,6 +299,7 @@ def check_slb_fig7():
                     'G_0' : 82.0e9,
                     'Gprime_0' : 1.4,
                     'n': 7.0,
+                    'molar_mass': .140695,
                     'Debye_0': 809.,
                     'grueneisen_0': .99,
                     'q_0': 2.1, 



More information about the CIG-COMMITS mailing list