-
Notifications
You must be signed in to change notification settings - Fork 308
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Create plasmapy.formulary.shocks and add initial functionality #864
base: main
Are you sure you want to change the base?
Conversation
(#PlasmaPy 815)
Codecov Report
@@ Coverage Diff @@
## master #864 +/- ##
==========================================
+ Coverage 96.21% 96.23% +0.01%
==========================================
Files 61 62 +1
Lines 5423 5443 +20
==========================================
+ Hits 5218 5238 +20
Misses 205 205
Continue to review full report at Codecov.
|
Add module `shocks` and function `entropy_across_shock_polytropic` to the fomulary
I want to add to the tests that ensure that when ds is negative, an error occurs and tells you that entropy change can't be negative, but I'm not sure how to go about it |
Co-authored-by: Erik Everson <[email protected]>
Co-authored-by: Erik Everson <[email protected]>
Co-authored-by: Erik Everson <[email protected]>
Co-authored-by: Erik Everson <[email protected]>
Co-authored-by: Erik Everson <[email protected]>
Co-authored-by: Erik Everson <[email protected]>
Co-authored-by: Erik Everson <[email protected]>
Co-authored-by: Erik Everson <[email protected]>
Co-authored-by: Erik Everson <[email protected]>
Co-authored-by: Erik Everson <[email protected]>
@pheuer Would you mind giving a review of this? The equation is taken straight from Drake, but I want to make sure the documentation is correct. |
# Conflicts: # docs/formulary/index.rst # plasmapy/formulary/__init__.py
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@KhalilBryant Thanks for starting this shocks package! Here's a quick review of this function.
c_v={"can_be_negative": False}, | ||
) | ||
def entropy_jump_polytropic( | ||
c_v: u.J / u.K, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Personally I rarely know the specific heat of the plasmas I'm dealing with, so using this function would always require some extra leg work. I would definitely suggest substituting Eq. 4.26 in Drake (which is equivalent to Eq. 3.3) to eliminate c_v, then replacing this input with a plasmapy.Particle
instance that represents the ion species to get the atomic number and charge. You can then present Eq. 4.24 and Eq. 4.26 in the documentation to make clear what's happening.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would keep c_v
as is because people could use different methods to calculate it. Instead, we should add a separate function (in a separate PR) to calculate c_v
. In the 2006 version of drake c_v
is given in eqn 3.5.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are there different methods that would be valid under this polytropic gas assumption? I haven't been able to find much information on this outside of Drake. Unless there are obvious, well-known models (like there are for resistivity, for example), I think that at the very least the documentation for this function should provide an appropriate equation or point to at least one function in PlasmaPy that will calculate it.
c_v: u.J / u.K, | ||
p_1: u.Pa, | ||
p_2: u.Pa, | ||
rho_1: u.kg / u.m ** 3, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The choice of mass density vs. number density is definitely field-specific: I think using rho is more common in ICF while in space physics/lab astro I see number density more. I'll just point out that if you do use a Particle
input for the species, this could be changed to number density and then converted to mass density within the function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you can just get away with annotating with [u.kg / u.m ** 3, u.m ** -3]
. This should allow either number density or mass density to pass through. Then below when you to calculate the ratio you can do something like...
try:
pressure_ratio = (p_2 / p_1).to(u.dimensionless_unscaled)
density_ratio = (rho_1 / rho_2).to(u.dimensionless_unscaled)
except u.UnitConversionError as err:
raise u.UnitConversionError(
f"Upstream and downstream parameters must have the same units, {err}"
)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
^Yes, this is the right answer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd like to note...Drake's derivation of this uses mass density for rho. Since I can't think of a scenario where you'd have two different species for upstream/downstream, the mass ratio is equal to the number ratio.
r""" | ||
Entropy is not conserved across a shock, since a shock is | ||
an irreversible, non-adiabatic process. This equation is based on the specific entropy | ||
of a polytropic gas before and after the shock has passed. The shock |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It wouldn't hurt to define polytropic here or somewhere (since this documentation is meant to be educational)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a good point. You can probably get way with something like...
Entropy is not conserved across a shock, since a shock is
an irreversible, non-adiabatic process. This equation is based on the specific
entropy of a polytropic gas ( :math:`p \propto \rho^\gamma`) before and after
the shock has passed. The shock is an isolated steady, perpendicular shock,
flowing through a non magnetized, polytropic gas.
p_2={"can_be_negative": True, "pass_equivalent_units": True}, | ||
c_v={"can_be_negative": False}, | ||
) | ||
def entropy_jump_polytropic( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, maybe it's worth going one further: since this function only applies to shocks described by a certain model, maybe the namespace should be more like: formulary.shocks.polytropic.entropy_jump
?
|
||
""" | ||
pressure_ratio = (p_2 / p_1).to(u.dimensionless_unscaled) | ||
density_ratio = (rho_1 / rho_2).to(u.dimensionless_unscaled) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since this only depends on the pressure and density ratios, you could potentially just take those ratios as arguments and then avoid potential confusion about units or the mass density vs. number density question I raised above.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I still think keeping the individual parameters is better, only because I think it's a more explicit signature. However, I'm open to be convinced otherwise.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with you now: the best solution is to take the individual parameters, make no requirements on their units except that they be identical, then construct the ratios (as you suggested above). That way users can use any pressure or density units they want.
) | ||
return u.Quantity(nan, unit=c_v.unit) | ||
|
||
elif ds < 0: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You could check for this earlier by checking that the density and pressure ratios are > or < than 1 as expected. The benefit to doing so would be giving better error messages (you could tell the user which of the two they switched).
@validate_quantities( | ||
rho_1={"can_be_negative": False, "pass_equivalent_units": True}, | ||
rho_2={"can_be_negative": False, "pass_equivalent_units": True}, | ||
p_1={"can_be_negative": True, "pass_equivalent_units": True}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why can the pressures be negative?
Here variables indexed by 1 and 2 are upstream (pre shock) | ||
and downstream (post shock) respectively. | ||
This function is equivalent to Eq. 4.24 in `Drake`_. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd also add here descriptions for s, p, rho, and gamma, must like you would do in a journal article.
docstrings.