Skip to content
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

split MagnetSet and MagnetCoil #182

Merged
merged 15 commits into from
Jan 31, 2025
Merged

Conversation

Edgar-21
Copy link
Contributor

@Edgar-21 Edgar-21 commented Dec 27, 2024

Round 2 at splitting this class to add the custom geometry functionality while preserving all the other features. After being away from this for a bit I realized I wanted to do it differently than in #173 and it was easier just to start fresh.

MagnetSet() is the parent class, and MagnetSetFromFilaments and MagnetSetFromGeometry inherit from it. MagnetSetFromFilaments is functionally the same as the current MagnetSet class. MagnetSetFromGeometry enables use of existing CAD files with the typical parastell workflows. Both classes have tested to work with DAGMC model generation and with the radial distance utilities.

MagnetSetFromGeometry has no need for MagnetCoil objects, so a new object, Filament, has been introduced which contains the functionality needed for radial distance finding with both MagnetSetFromFilaments and MagnetSetFromGeometry.

Kind of a big diff but to get the tests passing many little things needed to be tweaked. There is very little new code here, mostly just moving around existing pieces.

Addresses #174

@Edgar-21 Edgar-21 marked this pull request as ready for review December 27, 2024 20:24
Copy link
Collaborator

@connoramoreno connoramoreno left a comment

Choose a reason for hiding this comment

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

Here are some initial thoughts - we can discuss these further if you disagree. This branch will also need to be rebased onto main.


self.volume_ids = list(range(first_vol_id, last_vol_id + 1))
Arguments:
coils_file (str): path to coil filament data file.
Copy link
Collaborator

Choose a reason for hiding this comment

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

The reason for including coils_file as an argument for MagnetSetFromGeometry is that it is helpful when used in conjunction with the radial distance utility. It may be better just to modify the radial distance utility or have users create a custom workflow using the radial distance functions, since coils_file isn't used for any of the methods of MagnetSetFromGeometry.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I agree, I'll tackle updating rdu to work with both subclasses in an upcoming PR, I've created an issue and assigned myself here #186

Comment on lines 362 to 365
geometry_file (str): filename of the existing coil geometry. Can be of
the types supported by cubit_io.import_geom_to_cubit()
working_dir (str): path to directory in which existing geometry
is saved.
Copy link
Collaborator

Choose a reason for hiding this comment

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

Would it make sense to combine these two arguments? Just a relative path can be supplied.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yeah seems like a good plan

Comment on lines 370 to 375
start_line (int): starting line index for data in filament data file
(defaults to 3).
sample_mod (int): sampling modifier for filament points (defaults to
1). For a user-defined value n, every nth point will be sampled.
scale (float): a scaling factor between the units of the point-locus
data and [cm] (defaults to m2cm = 100).
Copy link
Collaborator

Choose a reason for hiding this comment

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

We can probably remove these optional arguments. If we want to include the ability to scale the geometry still, we should instead have a method to rescale.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yes, with removing the filament data from this subclass that makes sense

@@ -18,10 +18,6 @@ class MagnetSet(object):

Arguments:
coils_file (str): path to coil filament data file.
Copy link
Collaborator

Choose a reason for hiding this comment

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

See comments on MagnetSetFromGeometry class about removing this as an argument. Same goes for the optional attributes.

Comment on lines 66 to 70
def _instantiate_filaments(self):
"""Extracts filament coordinate data from input data file and
instantiates Filament class objects.
(Internal function not intended to be called externally)
"""
Copy link
Collaborator

Choose a reason for hiding this comment

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

This function and those below that have to do with coil data/filament objects should be moved to the MagnetSetFromFilaments class

Comment on lines 287 to 293
def _cut_magnets(self):
"""Cuts the magnets at the planes defining the toriodal extent.
(Internal function not intended to be called externally)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Would this not also be useful for imported geometries?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm assuming that people who bring their own cad will have it in state where it matches their geometry, or will have the means to do that.

Copy link
Collaborator

@connoramoreno connoramoreno left a comment

Choose a reason for hiding this comment

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

Just a quick thing on Cubit syntax for newer versions. We can (potentially) submit an additional review after Friday's meeting.

@@ -155,9 +172,27 @@ def export_dagmc_cubit(
cubit.cmd("mesh surface all")

export_path = Path(export_dir) / Path(filename).with_suffix(".h5m")
cubit.cmd(f'export dagmc "{export_path}" overwrite')
cubit.cmd(f'export cf_dagmc "{export_path}" overwrite')
Copy link
Collaborator

Choose a reason for hiding this comment

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

In more recent versions of Cubit, such as 2024.8+ which we now support, DAGMC export syntax was changed. Native cubit DAGMC faceting now has the syntax export dagmc

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I suppose I can upgrade, this has now been reverted

parastell/magnet_coils.py Outdated Show resolved Hide resolved
@connoramoreno
Copy link
Collaborator

connoramoreno commented Jan 24, 2025

@gonuke, Edgar and I discussed the software design of the code changes in magnet_coils.py and we'd like your input on best practices/pythonicity. I'm mostly on board with the changes Edgar is introducing here but I'm hesitant to approve this PR with the current implementation of the parent class, MagnetSet. Specifically, MagnetSet is not functional as a stand-alone class. Although it's a parent class, it relies on member variables, including self.geometry_file and self.working_dir in the import_geom_cubit method, being set by one of the child classes. Is that okay? I'm unsure what "proper" code design is here.

@gonuke
Copy link
Member

gonuke commented Jan 24, 2025

@gonuke, Edgar and I discussed the software design of the code changes in magnet_coils.py and we'd like your input on best practices/pythonicity. I'm mostly on board with the changes Edgar is introducing here but I'm hesitant to approve this PR with the current implementation of the parent class, MagnetSet. Specifically, MagnetSet is not functional as a stand-alone class. Although it's a parent class, it relies on member variables, including self.geometry_file and self.working_dir in the import_geom_cubit method, being set by one of the child classes. Is that okay? I'm unsure what "proper" code design is here.

In general, this is a common pattern. For example, in C++, it's common to have a parent class that defines a common API (i.e. a set of functions) but define those function in the parent class to be explicitly undefined so that it's never legal to define an object from that parent class.

I'll take a closer look at this specific implementation to see if I have any thoughts, though.

@Edgar-21 Edgar-21 force-pushed the magnets_from_custom_geometry branch from 32e8675 to def847b Compare January 27, 2025 18:10
Copy link
Collaborator

@connoramoreno connoramoreno left a comment

Choose a reason for hiding this comment

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

This is looking pretty good to me now, thanks @Edgar-21. I'll hold off on approving/merging until Paul gives his thoughts on our software design discussion

Comment on lines +10 to +24
files_to_remove = [
"magnet_set.step",
"magnet_mesh.exo",
"magnet_mesh.h5m",
"stellarator.log",
"step_import.log",
"single_coil.step",
]


def remove_files():
for file in files_to_remove:
if Path(file).exists():
Path.unlink(file)

Copy link
Collaborator

Choose a reason for hiding this comment

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

Nice

Copy link
Collaborator

Choose a reason for hiding this comment

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

I'd like to change all of the tests to use this routine. I think a separate PR would be most appropriate for that though.

Copy link
Member

@gonuke gonuke left a comment

Choose a reason for hiding this comment

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

I think the code looks OK. It's a little hard to track all the changes because many of them are just a reorganization of existing code that are hard to compare because of how they have moved in the file. It seems OK to me.

I have one minor request on the organization of the

.gitignore Show resolved Hide resolved
@Edgar-21 Edgar-21 force-pushed the magnets_from_custom_geometry branch from def847b to 0fa2477 Compare January 29, 2025 23:10
@Edgar-21
Copy link
Contributor Author

rebased, and made a few changes to get things working with the new cad to dagmc methods. I've added a method to InvesselBuild() and MagnetSet() that adds the geometry to a cad_to_dagmc instance, rather than getting the cad solids from each class and combining them in Stellarator.build_cad_to_dagmc_model()

Copy link
Collaborator

@connoramoreno connoramoreno left a comment

Choose a reason for hiding this comment

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

A comment about code structure, almost done!

parastell/parastell.py Outdated Show resolved Hide resolved
Copy link
Collaborator

@connoramoreno connoramoreno left a comment

Choose a reason for hiding this comment

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

Looks great! Thanks for this upgrade @Edgar-21

@connoramoreno
Copy link
Collaborator

Just need @gonuke to approve before we can merge.

Copy link
Member

@gonuke gonuke left a comment

Choose a reason for hiding this comment

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

Thanks @Edgar-21

@connoramoreno connoramoreno merged commit 552801c into main Jan 31, 2025
3 checks passed
@Edgar-21 Edgar-21 deleted the magnets_from_custom_geometry branch February 3, 2025 18:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants