[cig-commits] [commit] add_thermodynamic_potentials: More work on setting up the gibbs minimization problem (655901b)

cig_noreply at geodynamics.org cig_noreply at geodynamics.org
Tue Dec 9 09:56:36 PST 2014


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

On branch  : add_thermodynamic_potentials
Link       : https://github.com/geodynamics/burnman/compare/2e5646d93cedbbf8eae54cc37cffc14e0aa85180...d5ddad03ff9f30f5a4efaddb4e3ec585ea1a7c51

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

commit 655901ba5b2b9e782e6d8926346836a506291847
Author: ian-r-rose <ian.r.rose at gmail.com>
Date:   Fri Sep 19 10:00:26 2014 -0700

    More work on setting up the gibbs minimization problem


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

655901ba5b2b9e782e6d8926346836a506291847
 burnman/equilibriumassemblage.py | 42 ++++++++++++++++++++++++++++++++++++++++
 burnman/gibbsminimization.py     |  6 +++---
 test_gibbs.py                    |  5 ++---
 3 files changed, 47 insertions(+), 6 deletions(-)

diff --git a/burnman/equilibriumassemblage.py b/burnman/equilibriumassemblage.py
index e71c3ea..779a82f 100644
--- a/burnman/equilibriumassemblage.py
+++ b/burnman/equilibriumassemblage.py
@@ -4,6 +4,7 @@
 
 import numpy as np
 import scipy.optimize as opt
+import scipy.linalg as linalg
 import warnings
 
 import burnman
@@ -54,6 +55,12 @@ class EquilibriumAssemblage(burnman.Material):
         self.bulk_composition_vector = np.array([ (composition[e] if e in composition.keys() else 0.0) \
                                                    for e in self.elements] )
  
+        self.nullspace = gm.compute_nullspace( self.stoichiometric_matrix )
+        self.pseudoinverse = np.dot(linalg.pinv2( self.stoichiometric_matrix ) , self.bulk_composition_vector)
+
+        self.__setup_subspaces()
+        
+
     def set_method(self, method):
         for phase in self.phases:
             phase.set_method(method)
@@ -91,6 +98,7 @@ class EquilibriumAssemblage(burnman.Material):
             else:
                 raise Exception('Unsupported mineral type, can only read burnman.Mineral or burnman.SolidSolution')
 
+        print tmp_gibbs
         return tmp_gibbs
                 
         
@@ -99,3 +107,37 @@ class EquilibriumAssemblage(burnman.Material):
         return np.dot( self.stoichiometric_matrix, species_vector) - self.bulk_composition_vector
 
 
+    def __setup_subspaces (self):
+ 
+        eps = 1.e-10
+        U, S, Vh = linalg.svd( self.stoichiometric_matrix)
+
+        right_null_mask = ( np.append(S, np.zeros(len(Vh)-len(S))) <= eps)
+        self.right_nullspace = np.transpose(np.compress(right_null_mask, Vh, axis=0))
+
+        left_null_mask = ( S <= eps)
+        self.left_nullspace = np.compress(left_null_mask, U, axis=1)
+ 
+        #It is possible to give a bag of elements that cannot be represented by the list of
+        #minerals.  This corresponds to the bulk_composition_vector having power in the left nullspace
+        #of the stoichiometric matrix.  Here we check for this, and if it is the case, project
+        #it out of the left nullspace.  For most mantle assemblages, this is probably due to the
+        #amount of oxygen given being inconsistent with the possible minerals.
+        null_power = np.dot(self.left_nullspace.T, self.bulk_composition_vector)
+        if np.any( null_power > eps ):
+            print "Composition cannot be represented by the given minerals. We are projecting the composition onto the closest we can do, but you should probably recheck the composition vector"
+            for col in range(self.left_nullspace.shape[1]):
+                self.bulk_composition_vector -= self.left_nullspace[:,col]*null_power[col]
+            self.bulk_composition_vector = self.bulk_composition_vector/sum(self.bulk_composition_vector)
+            print "New vector: ", zip(self.elements, self.bulk_composition_vector)
+        
+
+        self.baseline_assemblage = np.dot(linalg.pinv2( self.stoichiometric_matrix ) , self.bulk_composition_vector)
+        assert( np.all(np.abs(np.dot(self.stoichiometric_matrix, self.baseline_assemblage)\
+                                                     - self.bulk_composition_vector) < eps) )
+        print zip(self.endmember_formulae, self.baseline_assemblage)#/np.sum(self.baseline_assemblage))
+    
+  
+
+
+
diff --git a/burnman/gibbsminimization.py b/burnman/gibbsminimization.py
index b63a463..fe04bda 100644
--- a/burnman/gibbsminimization.py
+++ b/burnman/gibbsminimization.py
@@ -65,9 +65,9 @@ def compute_nullspace ( stoichiometric_matrix ):
     """
 
     eps = 1.e-10
-    U, S, V = linalg.svd( stoichiometric_matrix)
-    S=np.append(S, [0. for i in range(len(V)-len(S))])
+    U, S, Vh = linalg.svd( stoichiometric_matrix)
+    S=np.append(S, [0. for i in range(len(Vh)-len(S))])
     null_mask = (S <= eps)
-    null_space = np.compress(null_mask, V, axis=0)
+    null_space = np.compress(null_mask, Vh, axis=0)
     return np.transpose(null_space)
     
diff --git a/test_gibbs.py b/test_gibbs.py
index e231407..a2bd4f7 100644
--- a/test_gibbs.py
+++ b/test_gibbs.py
@@ -4,9 +4,8 @@ import numpy as np
 import matplotlib.pyplot as plt
 
 
-minlist = [mg_fe_olivine(), wuestite(), periclase(), stishovite(), jadeite()]
-composition = {'Mg': 0.2, 'Si': 0.2, 'Fe': 0.1, 'O': 0.5}
+minlist = [mg_fe_olivine(), ferropericlase(), stishovite()]
+composition = {'Fe': 1./7., 'Mg': 1./7., 'O': 4./7., 'Si': 1./7}
 
 ea = burnman.EquilibriumAssemblage(composition, minlist)
 ea.set_method('slb3')
-ea.set_state(100.e9, 3000.)



More information about the CIG-COMMITS mailing list