Skip to content

Add a Material class#3096

Open
JaydenR2305 wants to merge 4 commits intoPlasmaPy:mainfrom
JaydenR2305:material-class
Open

Add a Material class#3096
JaydenR2305 wants to merge 4 commits intoPlasmaPy:mainfrom
JaydenR2305:material-class

Conversation

@JaydenR2305
Copy link
Member

In this PR, I outline a consistent structure for stopping and ranging (STAR) data by defining MaterialSTARData. I then use this definition to create an interface for users to create compounds using the Material class. This is critical to my PR implementing Moliere scattering (#2748) to ensure that we provide support for users who wish to scatter through a compound

@JaydenR2305 JaydenR2305 requested a review from a team as a code owner August 18, 2025 18:17
@JaydenR2305 JaydenR2305 requested review from ejohnson-96 and removed request for a team August 18, 2025 18:17
@github-actions
Copy link

Thank you for submitting this pull request (PR)! ✨

Below are checks that are being run for this PR. Click on the name of a check to learn why it didn't pass. ✅ Don't worry if something broke! We break stuff all the time. 😅

PlasmaPy's contributor guide has pages on:

Tip

📚 For a documentation preview, click on docs/readthedocs.org:plasmapy below. For cryptic documentation errors, see the documentation troubleshooting guide.

Tip

🧹 Automatically fix most pre-commit.ci failures by commenting pre-commit.ci autofix below. For other failures, please see the pre-commit troubleshooting guide.

We thank you once again! 🌌

@github-actions github-actions bot added plasmapy.plasma Related to the plasmapy.plasma subpackage python Pull requests that update Python code labels Aug 18, 2025
@JaydenR2305
Copy link
Member Author

JaydenR2305 commented Aug 18, 2025

@namurphy What do you think about the structure of Material? The plasma module is a little old so I just wanted to get your take on defining a class meant for solid materials alongside the older plasma class

@JaydenR2305 JaydenR2305 requested a review from namurphy as a code owner August 19, 2025 14:18
@github-actions github-actions bot added docs PlasmaPy Docs at http://docs.plasmapy.org CI Related to continuous integration static type checking feature For new functionality, excluding breaking changes labels Aug 19, 2025
@codecov
Copy link

codecov bot commented Aug 19, 2025

Codecov Report

❌ Patch coverage is 43.93939% with 37 lines in your changes missing coverage. Please review.
✅ Project coverage is 94.95%. Comparing base (6899c30) to head (ab7e43f).
⚠️ Report is 48 commits behind head on main.

Files with missing lines Patch % Lines
src/plasmapy/plasma/material.py 43.07% 37 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3096      +/-   ##
==========================================
- Coverage   95.48%   94.95%   -0.53%     
==========================================
  Files         108      109       +1     
  Lines        9869     9935      +66     
  Branches     1501     1507       +6     
==========================================
+ Hits         9423     9434      +11     
- Misses        255      304      +49     
- Partials      191      197       +6     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@JaydenR2305
Copy link
Member Author

@pheuer Thoughts on this?

An array of the atomic numbers of the elements making up the compound.
Does not have any units.

fractional_weights : `~astropy.units.Quantity`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's much better to have these be the number fractions. When you read a chemical formula, that's what you have available, e.g. C2H4, = C:2, H:4. Calculating the weight fractions in the code is then easy using the atomic masses.

An array of the atomic weights of the elements in the compound in units
convertible to atomic mass units.

Z : `~astropy.units.Quantity`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If A is the atomic number, then Z is usually the ionization state in a plasma. But this is a solid, so I think you only need A. In the Moliere scattering then, "z" is "A".

The density of the material in units convertible to kilograms per cubic
meter.

name : str, optional
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I suggested this but now IDK if we really need the name attribute



class MaterialSTARData(TypedDict):
"""Type definition for formatting data related to beam-target interactions."""
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In theory these are redundant - once you know the stopping power, you could calculate the others. Not saying the class has to do that, but it could in theory.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it should be possible for some of these to be None - what if all you have, and all you need, is stopping power data?

name : str, optional
The name of the material.

STAR_data : `~plasmapy.plasma.material.MaterialSTARData`, optional
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't really like the idea of providing this as an iterable of this class in the case of different particles. How about storing this internally as a nested dict, something like d['proton']['stopping_power'], then creating methods like add_stopping_power(particle, energy_axis, data) to populate it, creating the interpolators as you go?

stopping_power: u.Quantity[
u.MeV * u.cm**2 / u.g
] # Units of energy per areal density
CSDA_range: u.Quantity[u.cm]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How is CSDA range different than projected range? I thought all the projected range data was using the CDSA approximation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CI Related to continuous integration docs PlasmaPy Docs at http://docs.plasmapy.org feature For new functionality, excluding breaking changes plasmapy.plasma Related to the plasmapy.plasma subpackage python Pull requests that update Python code static type checking

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants