Skip to content

Zalmoxis.melting curves

melting_curves

Melting curve functions for the mantle EOS phase routing.

Provides analytic solidus and liquidus curves from:

  • Monteux et al. (2016, EPSL 448, 140-149): piecewise Simon-Glatzel fits (Eqs. 10-13). Valid up to ~400-500 GPa.
  • Stixrude (2014, Phil. Trans. R. Soc. A 372, 20130076): Simon-like power laws fitted to Lindemann melting theory and experiments (Eqs. 1.9-1.10). Valid over the full super-Earth pressure range.
Available identifiers

Solidus: 'Monteux16-solidus' Monteux+2016 Eqs. 10/12, piecewise (P <= 20 GPa / P > 20 GPa). 'Stixrude14-solidus' Stixrude (2014) Eq. 1.9 + cryoscopic Eq. 1.10 with x0=0.79. 'Monteux600-solidus-tabulated' Tabulated: melting_curves_Monteux-600/solidus.dat.

Liquidus: 'Monteux16-liquidus-A-chondritic' Monteux+2016 Eqs. 11/13 A-chondritic. 'Monteux16-liquidus-F-peridotitic' Monteux+2016 Eqs. 11/13 F-peridotitic. 'Stixrude14-liquidus' Stixrude (2014) Eq. 1.9: pure MgSiO3 Simon-like power law. 'PALEOS-liquidus' PALEOS MgSiO3 melting curve: Belonoshko+2005 (P < 2.55 GPa) / Fei+2021 (P >= 2.55 GPa). Consistent with the PALEOS unified EOS table phase boundaries. 'Monteux600-liquidus-tabulated' Tabulated: melting_curves_Monteux-600/liquidus.dat.

get_melting_curve_function(curve_id)

Return a callable melting curve f(P [Pa]) -> T [K] for the given identifier.

Parameters:

Name Type Description Default
curve_id str

Melting curve identifier. See module docstring for valid values.

required

Returns:

Type Description
callable

Function accepting pressure in Pa (scalar or array) and returning temperature in K.

Raises:

Type Description
ValueError

If curve_id is not recognized.

Source code in src/zalmoxis/melting_curves.py
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
def get_melting_curve_function(curve_id):
    """Return a callable melting curve f(P [Pa]) -> T [K] for the given identifier.

    Parameters
    ----------
    curve_id : str
        Melting curve identifier. See module docstring for valid values.

    Returns
    -------
    callable
        Function accepting pressure in Pa (scalar or array) and returning
        temperature in K.

    Raises
    ------
    ValueError
        If ``curve_id`` is not recognized.
    """
    if curve_id == 'Monteux16-solidus':
        return monteux16_solidus

    elif curve_id == 'Monteux16-liquidus-A-chondritic':

        def _liq(P):
            return monteux16_liquidus(P, model='A-chondritic')

        return _liq

    elif curve_id == 'Monteux16-liquidus-F-peridotitic':

        def _liq(P):
            return monteux16_liquidus(P, model='F-peridotitic')

        return _liq

    elif curve_id == 'Stixrude14-solidus':
        return stixrude14_solidus

    elif curve_id == 'Stixrude14-liquidus':
        return stixrude14_liquidus

    elif curve_id == 'PALEOS-liquidus':
        return paleos_liquidus

    elif curve_id == 'Monteux600-solidus-tabulated':
        return _load_tabulated_curve(
            os.path.join(ZALMOXIS_ROOT, 'data', 'melting_curves_Monteux-600', 'solidus.dat')
        )

    elif curve_id == 'Monteux600-liquidus-tabulated':
        return _load_tabulated_curve(
            os.path.join(ZALMOXIS_ROOT, 'data', 'melting_curves_Monteux-600', 'liquidus.dat')
        )

    else:
        all_valid = sorted(VALID_SOLIDUS | VALID_LIQUIDUS)
        raise ValueError(f"Unknown melting curve '{curve_id}'. Valid values: {all_valid}")

get_solidus_liquidus_functions(solidus_id='Stixrude14-solidus', liquidus_id='Stixrude14-liquidus')

Load solidus and liquidus functions by config identifier.

Parameters:

Name Type Description Default
solidus_id str

Solidus curve identifier.

'Stixrude14-solidus'
liquidus_id str

Liquidus curve identifier.

'Stixrude14-liquidus'

Returns:

Type Description
tuple of callable

(solidus_func, liquidus_func)

Source code in src/zalmoxis/melting_curves.py
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
def get_solidus_liquidus_functions(
    solidus_id='Stixrude14-solidus',
    liquidus_id='Stixrude14-liquidus',
):
    """Load solidus and liquidus functions by config identifier.

    Parameters
    ----------
    solidus_id : str
        Solidus curve identifier.
    liquidus_id : str
        Liquidus curve identifier.

    Returns
    -------
    tuple of callable
        ``(solidus_func, liquidus_func)``
    """
    return get_melting_curve_function(solidus_id), get_melting_curve_function(liquidus_id)

monteux16_liquidus(P, model='A-chondritic')

Monteux+2016 liquidus temperature.

Piecewise: Eq. 11 (P <= 20 GPa) and Eq. 13 (P > 20 GPa).

Parameters:

Name Type Description Default
P float or array - like

Pressure in Pa (must be >= 0).

required
model str

'A-chondritic' or 'F-peridotitic'.

'A-chondritic'

Returns:

Type Description
float or ndarray

Liquidus temperature in K.

Source code in src/zalmoxis/melting_curves.py
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
def monteux16_liquidus(P, model='A-chondritic'):
    """Monteux+2016 liquidus temperature.

    Piecewise: Eq. 11 (P <= 20 GPa) and Eq. 13 (P > 20 GPa).

    Parameters
    ----------
    P : float or array-like
        Pressure in Pa (must be >= 0).
    model : str
        ``'A-chondritic'`` or ``'F-peridotitic'``.

    Returns
    -------
    float or ndarray
        Liquidus temperature in K.
    """
    P_arr = np.atleast_1d(np.asarray(P, dtype=float))
    T = np.empty_like(P_arr)
    lo = P_arr <= _P_TRANSITION
    hi = ~lo
    T[lo] = _liquidus_low(P_arr[lo])

    if model == 'A-chondritic':
        T[hi] = _liquidus_high_A(P_arr[hi])
    elif model == 'F-peridotitic':
        T[hi] = _liquidus_high_F(P_arr[hi])
    else:
        raise ValueError(f"Unknown model '{model}'. Use 'A-chondritic' or 'F-peridotitic'.")

    return float(T[0]) if np.ndim(P) == 0 else T

monteux16_solidus(P)

Monteux+2016 solidus temperature.

Piecewise: Eq. 10 (P <= 20 GPa) and Eq. 12 (P > 20 GPa). Both composition models share the same solidus.

Parameters:

Name Type Description Default
P float or array - like

Pressure in Pa (must be >= 0).

required

Returns:

Type Description
float or ndarray

Solidus temperature in K.

Source code in src/zalmoxis/melting_curves.py
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
def monteux16_solidus(P):
    """Monteux+2016 solidus temperature.

    Piecewise: Eq. 10 (P <= 20 GPa) and Eq. 12 (P > 20 GPa).
    Both composition models share the same solidus.

    Parameters
    ----------
    P : float or array-like
        Pressure in Pa (must be >= 0).

    Returns
    -------
    float or ndarray
        Solidus temperature in K.
    """
    P_arr = np.atleast_1d(np.asarray(P, dtype=float))
    T = np.empty_like(P_arr)
    lo = P_arr <= _P_TRANSITION
    hi = ~lo
    T[lo] = _solidus_low(P_arr[lo])
    T[hi] = _solidus_high(P_arr[hi])
    return float(T[0]) if np.ndim(P) == 0 else T

paleos_liquidus(P)

PALEOS MgSiO3 liquidus from Belonoshko+2005 / Fei+2021.

Piecewise Simon-Glatzel fit:

  • P < 2.55 GPa: T = 1831 * (1 + P/4.6)^0.33 (Belonoshko+2005)
  • P >= 2.55 GPa: T = 6000 * (P/140)^0.26 (Fei+2021)

This is the melting curve used internally by the PALEOS unified EOS tables. Using it for the mushy zone calculation ensures consistency between the table's phase boundaries and the derived solidus.

Parameters:

Name Type Description Default
P float or array - like

Pressure in Pa (must be >= 0).

required

Returns:

Type Description
float or ndarray

Liquidus temperature in K.

Source code in src/zalmoxis/melting_curves.py
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
def paleos_liquidus(P):
    """PALEOS MgSiO3 liquidus from Belonoshko+2005 / Fei+2021.

    Piecewise Simon-Glatzel fit:

    - P < 2.55 GPa: T = 1831 * (1 + P/4.6)^0.33  (Belonoshko+2005)
    - P >= 2.55 GPa: T = 6000 * (P/140)^0.26      (Fei+2021)

    This is the melting curve used internally by the PALEOS unified EOS
    tables. Using it for the mushy zone calculation ensures consistency
    between the table's phase boundaries and the derived solidus.

    Parameters
    ----------
    P : float or array-like
        Pressure in Pa (must be >= 0).

    Returns
    -------
    float or ndarray
        Liquidus temperature in K.
    """
    P_arr = np.atleast_1d(np.asarray(P, dtype=float))
    P_GPa = P_arr * 1e-9
    T = np.where(
        P_GPa < _PALEOS_P0_GPA,
        1831.0 * (1.0 + P_GPa / 4.6) ** 0.33,
        6000.0 * (P_GPa / 140.0) ** 0.26,
    )
    # Guard P=0: avoid 0^0.26 = NaN
    T = np.where(P_arr > 0, T, 0.0)
    return float(T[0]) if np.ndim(P) == 0 else T

stixrude14_liquidus(P)

Silicate (MgSiO3) liquidus from Stixrude (2014) Eq. 1.9.

Simon-like power law fitted to Lindemann melting theory: T_rock = 5400 K * (P / 140 GPa)^0.480

Defined for all P > 0. At P = 0, returns 0 K (extrapolation).

Parameters:

Name Type Description Default
P float or array - like

Pressure in Pa (must be >= 0).

required

Returns:

Type Description
float or ndarray

Liquidus temperature in K.

Source code in src/zalmoxis/melting_curves.py
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
def stixrude14_liquidus(P):
    """Silicate (MgSiO3) liquidus from Stixrude (2014) Eq. 1.9.

    Simon-like power law fitted to Lindemann melting theory:
    T_rock = 5400 K * (P / 140 GPa)^0.480

    Defined for all P > 0. At P = 0, returns 0 K (extrapolation).

    Parameters
    ----------
    P : float or array-like
        Pressure in Pa (must be >= 0).

    Returns
    -------
    float or ndarray
        Liquidus temperature in K.
    """
    P_arr = np.atleast_1d(np.asarray(P, dtype=float))
    # Guard P=0: the power law gives 0 K at P=0
    T = np.where(
        P_arr > 0,
        _STIX14_T_REF * (P_arr / _STIX14_P_REF) ** _STIX14_EXPONENT,
        0.0,
    )
    return float(T[0]) if np.ndim(P) == 0 else T

stixrude14_solidus(P)

Silicate solidus from Stixrude (2014) Eqs. 1.9 + 1.10.

The solidus is the pure-substance liquidus (Eq. 1.9) depressed by the cryoscopic equation (Eq. 1.10) with x0 = 0.79 (mole fraction of pure MgSiO3 in an Earth-like mantle composition):

T_solidus = T_liquidus * (1 - ln(x0))^{-1}

With x0 = 0.79 this gives ~4370 K at 140 GPa, approximately consistent with the experimentally measured solidus of an Earth-like mantle composition (~4100 K at 140 GPa, Fiquet et al. 2010). The ~270 K offset is within the uncertainty of the cryoscopic model.

Parameters:

Name Type Description Default
P float or array - like

Pressure in Pa (must be >= 0).

required

Returns:

Type Description
float or ndarray

Solidus temperature in K.

Source code in src/zalmoxis/melting_curves.py
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
def stixrude14_solidus(P):
    """Silicate solidus from Stixrude (2014) Eqs. 1.9 + 1.10.

    The solidus is the pure-substance liquidus (Eq. 1.9) depressed by
    the cryoscopic equation (Eq. 1.10) with x0 = 0.79 (mole fraction
    of pure MgSiO3 in an Earth-like mantle composition):

    T_solidus = T_liquidus * (1 - ln(x0))^{-1}

    With x0 = 0.79 this gives ~4370 K at 140 GPa, approximately
    consistent with the experimentally measured solidus of an Earth-like
    mantle composition (~4100 K at 140 GPa, Fiquet et al. 2010). The
    ~270 K offset is within the uncertainty of the cryoscopic model.

    Parameters
    ----------
    P : float or array-like
        Pressure in Pa (must be >= 0).

    Returns
    -------
    float or ndarray
        Solidus temperature in K.
    """
    return stixrude14_liquidus(P) * _STIX14_CRYO_FACTOR