<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Critical Radii
Step1:  As always, let's do imports and initialize a logger and a new Bundle.  See Building a System for more details.
Step2:  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.
Step3:  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.
Step4:  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.
Step5:  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)
Step6:  Or instead we could allow providing the equivalent radius of the secondary star.
<ASSISTANT_TASK:>
Python Code:
!pip install -I "phoebe>=2.2,<2.3"
Explanation: 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).
End of explanation
%matplotlib inline
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)
Explanation: As always, let's do imports and initialize a logger and a new Bundle.  See Building a System for more details.
End of explanation
print(b.filter(qualifier=['requiv', 'pot', 'fillout_factor']))
Explanation: 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.
End of explanation
print(b.filter(qualifier=['requiv_max', 'requiv_min', 'pot_max', 'pot_min']))
Explanation: 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.
End of explanation
b.flip_constraint('pot', solve_for='requiv@primary')
print(b.filter(qualifier=['requiv', 'pot', 'fillout_factor']))
Explanation: 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.
End of explanation
b = phoebe.default_binary(contact_binary=True)
b.flip_constraint('pot', solve_for='requiv@primary')
b.flip_constraint('fillout_factor', solve_for='pot')
print(b.filter(qualifier=['requiv', 'pot', 'fillout_factor']))
Explanation: 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):
End of explanation
b = phoebe.default_binary(contact_binary=True)
b.flip_constraint('pot', solve_for='requiv@primary')
b.flip_constraint('requiv@secondary', solve_for='pot')
print(b.filter(qualifier=['requiv', 'pot', 'fillout_factor']))
Explanation: Or instead we could allow providing the equivalent radius of the secondary star.
End of explanation
<END_TASK>