Critical Radii: Contact Systems

Setup

Let's first make sure we have the latest version of PHOEBE 2.2 installed. (You can comment out this line if you don't use pip for your installation or don't want to update to the latest release).


In [ ]:
!pip install -I "phoebe>=2.2,<2.3"

As always, let's do imports and initialize a logger and a new Bundle. See Building a System for more details.


In [1]:
%matplotlib inline

In [2]:
import phoebe
from phoebe import u # units
import numpy as np
import matplotlib.pyplot as plt

logger = phoebe.logger()

b = phoebe.default_binary(contact_binary=True)

Contact Systems

Contact systems are created by passing contact_binary=True to phoebe.default_binary() or by manually adding an envelope and setting the hierarchy correctly.

By default, requiv@primary is the free Parameter, with requiv@secondary, pot@contact_envelope, and fillout_factor@contact_envelope constrained such that there is one single surface defining the envelope.


In [3]:
print(b.filter(qualifier=['requiv', 'pot', 'fillout_factor']))


ParameterSet: 7 parameters
        requiv@primary@component: 1.5 solRad
*     requiv@secondary@component: 1.4999999999999074 solRad
* fillout_factor@contact_enve...: 0.6417897080768679
* pot@contact_envelope@component: 3.4013774072298766
                  pot@constraint: requiv_to_pot_contact({requiv@primary@component}, {q@binary@component}, {sma@binary@component}, 1)
               requiv@constraint: pot_to_requiv_contact({pot@contact_envelope@component}, {q@binary@component}, {sma@binary@component}, 2)
       fillout_factor@constraint: pot_to_fillout_factor({q@binary@component}, {pot@contact_envelope@component})

In order to pass the system checks, these values must be between their minimum and maximum value ensuring the system is not underflowing (in which case it should be detached or semi-detached) or overflowing and losing mass.

These limiting values are constrained parameters, allowing us to see the allowed range for any parameterization.


In [4]:
print(b.filter(qualifier=['requiv_max', 'requiv_min', 'pot_max', 'pot_min']))


ParameterSet: 12 parameters
*   requiv_max@primary@component: 1.6724563972838384 solRad
*   requiv_min@primary@component: 1.2725418568681297 solRad
* requiv_max@secondary@component: 1.6724563972838378 solRad
* requiv_min@secondary@component: 1.2725418568681297 solRad
* pot_min@contact_envelope@co...: 3.2067962240861534
* pot_max@contact_envelope@co...: 3.75
              pot_min@constraint: potential_contact_L23({q@binary@component})
              pot_max@constraint: potential_contact_L1({q@binary@component})
   requiv_max@primary@constraint: requiv_contact_L23({q@binary@component}, {sma@binary@component}, 1)
   requiv_min@primary@constraint: requiv_contact_L1({q@binary@component}, {sma@binary@component}, 1)
  requiv_max@secondary@constr...: requiv_contact_L23({q@binary@component}, {sma@binary@component}, 2)
  requiv_min@secondary@constr...: requiv_contact_L1({q@binary@component}, {sma@binary@component}, 2)

Changing Parameterization

It is possible to change this parameterization to allow any one of the four parameters (requiv@primary, requiv@secondary, pot@contact_envelope, fillout_factor@contact_envelope) to be adjustable and the other two to be constrained. Doing so requires flipping one or two constraints via b.flip_constraint().

Let's first flip the constraints so that we can provide the potential of the envelope.


In [5]:
b.flip_constraint('pot', solve_for='requiv@primary')


Out[5]:
<ConstraintParameter: {requiv@primary@component} = pot_to_requiv_contact({pot@contact_envelope@component}, {q@binary@component}, {sma@binary@component}, 1) (solar units) => 1.5 solRad>

In [6]:
print(b.filter(qualifier=['requiv', 'pot', 'fillout_factor']))


ParameterSet: 7 parameters
*       requiv@primary@component: 1.5 solRad
*     requiv@secondary@component: 1.4999999999999074 solRad
* fillout_factor@contact_enve...: 0.6417897080768679
  pot@contact_envelope@component: 3.4013774072298766
       requiv@primary@constraint: pot_to_requiv_contact({pot@contact_envelope@component}, {q@binary@component}, {sma@binary@component}, 1)
     requiv@secondary@constraint: pot_to_requiv_contact({pot@contact_envelope@component}, {q@binary@component}, {sma@binary@component}, 2)
       fillout_factor@constraint: pot_to_fillout_factor({q@binary@component}, {pot@contact_envelope@component})

Or we could instead flip two constraints to have fillout factor of the envelope as the adjustable parameter (we'll start with a fresh bundle just to avoid confusion with the flipping we just did):


In [7]:
b = phoebe.default_binary(contact_binary=True)
b.flip_constraint('pot', solve_for='requiv@primary')
b.flip_constraint('fillout_factor', solve_for='pot')


Out[7]:
<ConstraintParameter: {pot@contact_envelope@component} = fillout_factor_to_pot({q@binary@component}, {fillout_factor@contact_envelope@component}) (solar units) => 3.40137740723>

In [8]:
print(b.filter(qualifier=['requiv', 'pot', 'fillout_factor']))


ParameterSet: 7 parameters
*       requiv@primary@component: 1.5 solRad
*     requiv@secondary@component: 1.4999999999999074 solRad
  fillout_factor@contact_enve...: 0.6417897080768679
* pot@contact_envelope@component: 3.40137740723
       requiv@primary@constraint: pot_to_requiv_contact({pot@contact_envelope@component}, {q@binary@component}, {sma@binary@component}, 1)
     requiv@secondary@constraint: pot_to_requiv_contact({pot@contact_envelope@component}, {q@binary@component}, {sma@binary@component}, 2)
                  pot@constraint: fillout_factor_to_pot({q@binary@component}, {fillout_factor@contact_envelope@component})

Or instead we could allow providing the equivalent radius of the secondary star.


In [9]:
b = phoebe.default_binary(contact_binary=True)
b.flip_constraint('pot', solve_for='requiv@primary')
b.flip_constraint('requiv@secondary', solve_for='pot')


Out[9]:
<ConstraintParameter: {pot@contact_envelope@component} = requiv_to_pot_contact({requiv@secondary@component}, {q@binary@component}, {sma@binary@component}, 2) (solar units) => 3.401377407229995>

In [10]:
print(b.filter(qualifier=['requiv', 'pot', 'fillout_factor']))


ParameterSet: 7 parameters
*       requiv@primary@component: 1.5 solRad
      requiv@secondary@component: 1.4999999999999074 solRad
* fillout_factor@contact_enve...: 0.6417897080768679
* pot@contact_envelope@component: 3.401377407229995
               requiv@constraint: pot_to_requiv_contact({pot@contact_envelope@component}, {q@binary@component}, {sma@binary@component}, 1)
                  pot@constraint: requiv_to_pot_contact({requiv@secondary@component}, {q@binary@component}, {sma@binary@component}, 2)
       fillout_factor@constraint: pot_to_fillout_factor({q@binary@component}, {pot@contact_envelope@component})