MAGEMin_C.jl: options
General options / functionality
Name solvus
- When performing calculations, it is usually recommended to use the argument
name_solvus = true, e.g.,
out = single_point_minimization(P, T, data, X=X, Xoxides=Xoxides, sys_in=sys_unit, name_solvus = true)This option checks the composition of the stable solution phases and tries to name them accordingly. For instance, this allows distinguishing feldspar as plagioclase or alkali-feldspar. Details about how solvus phases are named are provided in the Method section.
Solver option
- It is usually best to use the solver option
solver = 0when performing calculations. This is easily activated by initializingMAGEMin_C.jlsuch as:
data = Initialize_MAGEMin("mb", verbose=false, solver = 0);Solution-phase optimizer (optimizer)
With the legacy solver (solver = 0), the local minimization of the solution phases can use either NLopt or a nullspace minimizer. Select it with the optimizer keyword of Initialize_MAGEMin:
optimizer | Local minimization of the solution phases |
|---|---|
0 (default) | NLopt |
1 | Nullspace minimizer, with NLopt as fallback for any phase it cannot handle |
data = Initialize_MAGEMin("ig", verbose=false, solver=0, optimizer=1)The option applies to the THERMOCALC databases and to the Stixrude & Lithgow-Bertelloni databases (
sb11,sb21,sb24). It is ignored withsolver = 1(PGE) andsolver = 2(hybrid).On ordinary bulk-rock compositions both optimizers give the same equilibrium. For example, for KLB-1 (
ig, 15 kbar, 1300 °C) both returncpx opx spl liq olwith G = −845.6099 kJ.The nullspace minimizer is what makes reduced chemical systems possible.
The method is described in Methods. From the command line, the same choice is made with --ss_solver (see Command-line reference).
Reduced chemical systems
NLopt needs every core oxide of a database to be present. With optimizer = 0, any core oxide set to 0 in the bulk is therefore raised to 1e-4 mol fraction before the minimization. The core oxides are SiO2, Al2O3, MgO and FeO (plus Fe and O for sb24). The other (optional) oxides can always be set to zero.
With optimizer = 1, an oxide set exactly to 0 is removed from the system, core oxides included. Systems below FMAS (e.g. MS, MAS, CMAS, FASH, MgO–FeO) can therefore be computed directly:
data = Initialize_MAGEMin("ig", verbose=false, solver=0, optimizer=1)
out = single_point_minimization(10.0, 1200.0, data, X=[45.0, 10.0, 8.0, 35.0],
Xoxides=["SiO2", "Al2O3", "CaO", "MgO"], sys_in="mol")
out.ph # ["opx", "fsp", "cpx", "spl"], FeO stays exactly 0 in the bulk and in every phaseAt these conditions, the same CMAS bulk with optimizer = 0 (FeO raised to 1e-4) gives fsp cpx spl and a Gibbs energy 0.34 kJ higher: the floor is enough to destabilize orthopyroxene.
Note
"Reduced" means exactly zero: an amount between 0 and 1e-4 mol fraction is still raised to 1e-4 with both optimizers.
Orepresents ferric iron (FeO + O → Fe₂O₃). IfFeOis absent, no phase can hostO, soOis set to 0 (with a warning).For
sb11,sb21andsb24, exact zeros of the core oxides are kept withoptimizer = 0as well.A reduced system needs at least one phase able to host the remaining oxides; for instance MgO–FeO has no host phase in
mp,mborum.
Buffers
- When using buffers, note that you need to provide enough oxide to oversaturate the system across the whole P-T(-X) range of interest. While this applies to oxygen buffers, it also applies to activity buffers (e.g.,
aTiO2,aH2O,aSiO2, etc.).
Fixed chemical potentials (mu_fix_idx / mu_fix_val)
Instead of fixing the bulk content of an oxide, its chemical potential can be fixed directly, for one or several oxides at once. This generalizes buffer to any oxide and any target value, and is the mechanism behind the μ-μ diagrams of MAGEMinApp.
mu_fix_idx(inInitialize_MAGEMin): names of the oxides whose chemical potential is fixed.mu_fix_val(insingle_point_minimization/multi_point_minimization): target chemical potentials in kJ/mol, in the same order asmu_fix_idx, i.e. in the same unit asout.Gamma. They can change from one call (or grid point) to the next.
Xoxides = ["SiO2", "Al2O3", "CaO", "MgO", "FeO", "K2O", "Na2O", "TiO2", "O", "Cr2O3", "H2O"]
X = [48.43, 15.19, 11.57, 10.13, 6.65, 1.64, 2.59, 1.33, 0.12, 0.02, 3.0]
data = Initialize_MAGEMin("ig", verbose=false, solver=0, mu_fix_idx=["K2O", "H2O"])
Xm = copy(X)
Xm[6] = 100.0 # K2O in large excess
Xm[11] = 100.0 # H2O in large excess
out = single_point_minimization(10.0, 1100.0, data, X=Xm, Xoxides=Xoxides, sys_in="mol",
mu_fix_val=[-989.0, -459.891])
out.Gamma[[6, 11]] # [-989.0, -459.891]
out.ph # ["spl", "ilm", "cpx", "fsp", "liq", "mK2O", "mH2O"]Warning
The target is enforced by a fictive phase per fixed oxide (
mK2O,mH2Oabove), which appears inout.ph. It only becomes stable if the bulk contains far more of that oxide than the target requires (several times its natural amount;MAGEMinAppuses 100 mol before normalization).With too little of the oxide, the target is silently missed: there is no automatic check. Compare
out.Gammaof the fixed oxides withmu_fix_val.A target that no real phase of the database can support at the given P–T cannot be reached either.
Database dependent choices
Metabasite (mb)
- When using the metabasite database (Green et al., 2016), it is important to activate the correct clinopyroxene depending on the temperature conditions. By default,
aug(the high-temperature solution model) is active. If you need to use the low-temperature solution modeldioinstead, you can initializeMAGEMin_C.jlsuch as:
data = Initialize_MAGEMin("mb", verbose=false, mbCpx = 0);Note
The default value is mbCpx = 1
- Similarly,
mbIlm,mpSp, andmpIlmswitch between paired solution models on the metabasite/metapelite databases:
| Option | Database | = 0 | = 1 | Default |
|---|---|---|---|---|
mbCpx | mb | Omphacite (dio, low-T) | Augite (aug, high-T) | 1 |
mbIlm | mb | Ilmenite-hematite (ilmm) | Ilmenite (ilm) | 0 |
mpSp | mp | Spinel (sp) | Spinel (spl) | 0 |
mpIlm | mp | Ilmenite-hematite (ilmm) | Ilmenite (ilm) | 0 |
data = Initialize_MAGEMin("mb", verbose=false, mbIlm = 1);Warning
None of mbCpx/mbIlm/mpSp/mpIlm apply to the all database - its dispatch deliberately keeps both phase variants each toggle would otherwise switch between as independent, separately selectable phases (e.g. both dio_G16 and aug_G16 are always present). Use select_phases/pp_list=/ss_list= or remove_phases/rm_list= to pick between them there instead.
Selecting which phases to consider
Two complementary ways to restrict which pure/solution phases MAGEMin considers during minimization - an exclude-list and an include-list. Use whichever is shorter to write for your case; passing both at once raises an error.
Exclude a list of phases (remove_phases/rm_list=)
remove_phases(list, dtb) resolves phase names against the given database and returns an index list (rm_list) to pass to single_point_minimization/multi_point_minimization/ AMR_minimization. See example E.5.
Keep only a list of phases (select_phases/pp_list=/ss_list=)
select_phases is the inverse: give it the pure phases (pp_list=) and/or solution phases (ss_list=) you want to keep active, and every other phase in that category is deactivated automatically. pp_list and ss_list are independent - passing only one leaves the other phase category untouched.
data = Initialize_MAGEMin("mp", verbose=false);
out = single_point_minimization(P, T, data, X=X, Xoxides=Xoxides, sys_in=sys_in,
ss_list=["liq_W14", "g_W14", "bi_W14"])is equivalent to writing out the complement by hand with remove_phases, but self-updates if the database's phase list changes. The 13 oxygen-fugacity buffer / fixed-activity pure phases (qfm, mw, qif, nno, hm, iw, cco, aH2O, aO2, aMgO, aFeO, aAl2O3, aTiO2) never need to be listed in pp_list - select_phases always leaves them untouched, since their activation is governed solely by the buffer="..." keyword (see Buffers above), not by phase selection.
Note
select_phases/pp_list=/ss_list= and remove_phases/rm_list= are mutually exclusive on a single call - combining them raises an error rather than silently guessing intent.
Discovering phase names (print_phase_info)
Both remove_phases and select_phases need exact phase names, which can be hard to guess for an unfamiliar database (particularly all, with its citation-tagged names like liq_W14 vs liq_G16). print_phase_info(dtb; level=0|1) prints them directly:
print_phase_info("mp") # database info, solution-phase names, pure-phase names
print_phase_info("mp"; level=1) # same, plus every solution phase's endmember list