66from burnman import minerals , Composite , RelaxedComposite
77from burnman .minerals import HP_2011_ds62 , mp50MnNCKFMASHTO
88from burnman .tools .eos import check_eos_consistency
9+ from burnman .tools .equilibration import equilibrate
10+
11+ properties_extensive = [
12+ "internal_energy" ,
13+ "helmholtz" ,
14+ "gibbs" ,
15+ "enthalpy" ,
16+ "entropy" ,
17+ "volume" ,
18+ "heat_capacity_p" ,
19+ "heat_capacity_v" ,
20+ "mass" ,
21+ "H" ,
22+ "S" ,
23+ "V" ,
24+ "C_p" ,
25+ "C_v" ,
26+ ]
27+
28+ properties_intensive = [
29+ "molar_internal_energy" ,
30+ "molar_helmholtz" ,
31+ "molar_gibbs" ,
32+ "molar_enthalpy" ,
33+ "molar_entropy" ,
34+ "molar_volume" ,
35+ "molar_heat_capacity_p" ,
36+ "molar_heat_capacity_v" ,
37+ "isothermal_bulk_modulus_reuss" ,
38+ "isentropic_bulk_modulus_reuss" ,
39+ "isothermal_compressibility_reuss" ,
40+ "isentropic_compressibility_reuss" ,
41+ "grueneisen_parameter" ,
42+ "thermal_expansivity" ,
43+ "molar_mass" ,
44+ "density" ,
45+ ]
946
1047
1148def setup_assemblage ():
@@ -523,6 +560,37 @@ def test_single_phase_composite_aliases(self):
523560 for i in range (len (properties )):
524561 self .assertFloatEqual (rock_prps [i ], alias_prps [i ])
525562
563+ def test_number_of_moles_composite (self ):
564+ min1 = minerals .SLB_2011 .mg_perovskite ()
565+ min2 = minerals .SLB_2011 .periclase ()
566+ molar_fractions = [0.5 , 0.5 ]
567+ c1 = burnman .Composite ([min1 , min2 ], molar_fractions , fraction_type = "molar" )
568+ c2 = burnman .Composite ([min1 , min2 ], molar_fractions , fraction_type = "molar" )
569+ c1 .set_state (40.0e9 , 2000.0 )
570+ c2 .set_state (40.0e9 , 2000.0 )
571+
572+ for prop in properties_extensive :
573+ val1 = getattr (c1 , prop )
574+ val2 = getattr (c2 , prop )
575+ self .assertFloatEqual (val1 , val2 )
576+
577+ for prop in properties_intensive :
578+ val1 = getattr (c1 , prop )
579+ val2 = getattr (c2 , prop )
580+ self .assertFloatEqual (val1 , val2 )
581+
582+ c2 .number_of_moles = 2.0
583+
584+ for prop in properties_extensive :
585+ val1 = getattr (c1 , prop )
586+ val2 = getattr (c2 , prop )
587+ self .assertFloatEqual (val1 , val2 / 2.0 )
588+
589+ for prop in properties_intensive :
590+ val1 = getattr (c1 , prop )
591+ val2 = getattr (c2 , prop )
592+ self .assertFloatEqual (val1 , val2 )
593+
526594 def test_relaxed_composite (self ):
527595 assemblage = setup_assemblage ()
528596 old_formula = assemblage .formula .copy ()
@@ -595,47 +663,11 @@ def test_property_extensivity_composite(self):
595663 c1 .set_state (40.0e9 , 2000.0 )
596664 c2 .set_state (40.0e9 , 2000.0 )
597665
598- properties_extensive = [
599- "internal_energy" ,
600- "helmholtz" ,
601- "gibbs" ,
602- "enthalpy" ,
603- "entropy" ,
604- "volume" ,
605- "heat_capacity_p" ,
606- "heat_capacity_v" ,
607- "mass" ,
608- "V" ,
609- "S" ,
610- "H" ,
611- "C_v" ,
612- "C_p" ,
613- ]
614-
615666 for prop in properties_extensive :
616667 val1 = getattr (c1 , prop )
617668 val2 = getattr (c2 , prop )
618669 self .assertFloatEqual (val1 , val2 / 2.0 )
619670
620- properties_intensive = [
621- "molar_internal_energy" ,
622- "molar_helmholtz" ,
623- "molar_gibbs" ,
624- "molar_enthalpy" ,
625- "molar_entropy" ,
626- "molar_volume" ,
627- "molar_heat_capacity_p" ,
628- "molar_heat_capacity_v" ,
629- "isothermal_bulk_modulus_reuss" ,
630- "isentropic_bulk_modulus_reuss" ,
631- "isothermal_compressibility_reuss" ,
632- "isentropic_compressibility_reuss" ,
633- "grueneisen_parameter" ,
634- "thermal_expansivity" ,
635- "molar_mass" ,
636- "density" ,
637- ]
638-
639671 for prop in properties_intensive :
640672 val1 = getattr (c1 , prop )
641673 val2 = getattr (c2 , prop )
@@ -663,18 +695,28 @@ def test_formula_extensivity_relaxed_composite(self):
663695 formula = c1_unrelaxed .formula .copy ()
664696 formula2 = c2_unrelaxed .formula .copy ()
665697
666- self .assertFloatEqual (formula ["Mg" ] * 2.0 , formula2 ["Mg" ])
698+ for element in ["Na" , "Fe" , "Mg" , "Al" , "Si" , "O" , "Cr" ]:
699+ self .assertFloatEqual (formula [element ], formula2 [element ] / 2.0 )
667700
668701 c1 = RelaxedComposite (c1_unrelaxed , c1_unrelaxed .reaction_basis )
669702 c2 = RelaxedComposite (c2_unrelaxed , c2_unrelaxed .reaction_basis )
670703
704+ for element in ["Na" , "Fe" , "Mg" , "Al" , "Si" , "O" , "Cr" ]:
705+ self .assertFloatEqual (c1 .formula [element ], c2 .formula [element ] / 2.0 )
706+ self .assertFloatEqual (c1 .unrelaxed .formula [element ], c1 .formula [element ])
707+ self .assertFloatEqual (c2 .unrelaxed .formula [element ], c2 .formula [element ])
708+
671709 c1 .set_state (40.0e9 , 2000.0 )
672710 c2 .set_state (40.0e9 , 2000.0 )
673711
712+ self .assertArraysAlmostEqual (c1 .molar_fractions , c2 .molar_fractions )
713+
714+ for element in ["Na" , "Fe" , "Mg" , "Al" , "Si" , "O" , "Cr" ]:
715+ self .assertFloatEqual (c1 .formula [element ], c2 .formula [element ] / 2.0 )
716+ self .assertFloatEqual (c1 .unrelaxed .formula [element ], c1 .formula [element ])
717+ self .assertFloatEqual (c2 .unrelaxed .formula [element ], c2 .formula [element ])
718+
674719 self .assertFloatEqual (c1 .number_of_moles , c2 .number_of_moles / 2.0 )
675- self .assertFloatEqual (c1 .formula ["Mg" ], c2 .formula ["Mg" ] / 2.0 )
676- self .assertFloatEqual (c1 .formula ["Si" ], c2 .formula ["Si" ] / 2.0 )
677- self .assertFloatEqual (c1 .formula ["O" ], c2 .formula ["O" ] / 2.0 )
678720 self .assertFloatEqual (c1 .molar_mass , c2 .molar_mass )
679721 self .assertFloatEqual (c1 .mass , c2 .mass / 2.0 )
680722
@@ -699,52 +741,33 @@ def test_property_extensivity_relaxed_composite(self):
699741 c1 .set_state (40.0e9 , 2000.0 )
700742 c2 .set_state (40.0e9 , 2000.0 )
701743
702- properties_extensive = [
703- "internal_energy" ,
704- "helmholtz" ,
705- "gibbs" ,
706- "enthalpy" ,
707- "entropy" ,
708- "volume" ,
709- "heat_capacity_p" ,
710- "heat_capacity_v" ,
711- "mass" ,
712- "H" ,
713- "S" ,
714- "V" ,
715- "C_p" ,
716- "C_v" ,
717- ]
718-
719744 for prop in properties_extensive :
720745 val1 = getattr (c1 , prop )
721746 val2 = getattr (c2 , prop )
722747 self .assertFloatEqual (val1 , val2 / 2.0 )
723748
724- properties_intensive = [
725- "molar_internal_energy" ,
726- "molar_helmholtz" ,
727- "molar_gibbs" ,
728- "molar_enthalpy" ,
729- "molar_entropy" ,
730- "molar_volume" ,
731- "molar_heat_capacity_p" ,
732- "molar_heat_capacity_v" ,
733- "isothermal_bulk_modulus_reuss" ,
734- "isentropic_bulk_modulus_reuss" ,
735- "isothermal_compressibility_reuss" ,
736- "isentropic_compressibility_reuss" ,
737- "grueneisen_parameter" ,
738- "thermal_expansivity" ,
739- "molar_mass" ,
740- "density" ,
741- ]
742-
743749 for prop in properties_intensive :
744750 val1 = getattr (c1 , prop )
745751 val2 = getattr (c2 , prop )
746752 self .assertFloatEqual (val1 , val2 )
747753
754+ def test_equilibrate_relaxed_composite (self ):
755+
756+ assemblage = setup_assemblage ()
757+ relaxed_assemblage = RelaxedComposite (assemblage , assemblage .reaction_basis )
758+ equality_constraints = [["P" , 0.5e9 ], ["T" , 900.0 ]]
759+ equilibrate (
760+ relaxed_assemblage .formula , relaxed_assemblage , equality_constraints
761+ )
762+ f1 = relaxed_assemblage .molar_fractions .copy ()
763+
764+ assemblage = setup_assemblage ()
765+ relaxed_assemblage = RelaxedComposite (assemblage , assemblage .reaction_basis )
766+ relaxed_assemblage .set_state (0.5e9 , 900.0 )
767+ f2 = relaxed_assemblage .molar_fractions .copy ()
768+
769+ self .assertArraysAlmostEqual (f1 , f2 )
770+
748771
749772if __name__ == "__main__" :
750773 unittest .main ()
0 commit comments