openmc icon indicating copy to clipboard operation
openmc copied to clipboard

Raytrace plots

Open gridley opened this issue 2 years ago • 27 comments

Description

This PR implements 3D plotting with Phong shading. I factored out the basic ray creation from a camera into an abstract base class called RayTracePlot. Then, ProjectionPlot implements the logic for moving rays all the way through a geometry in order to wireframe cells or materials of interest and color them in an x-ray-like view. The new PhongPlot (happy to rename) lets the user specify a few materials or cells which they would like to have be opaque, with everything else in the model being transparent. By default it assumes that a light is placed at the camera's location, but the light can optionally be moved.

As an example, here is a reminder of what a ProjectionPlot looks like:

orthographic_example1

A Phong plot on a similar geometry looks kinda neat, and could certainly be a helpful tool for visualization on intricately structured stuff--especially for communicating what a model looks like to other people.

phong

You can adjust the fraction of diffuse light to give a slightly different look. By default, it uses 10% diffuse lighting, 90% lighting from the light source with single scattered isotropic scattering off surfaces.

phong_diffuse

You can move the light source location, which can make a nice dramatic effect:

phong_move_light

I was frustrated that we have to create a full Particle object just for geometric operations. As a result, I factored out the geometry state of Particle into a base class called Geometron. This comes in handy for openmc_find_cell as we no longer have to initialize the cross section caches and all that other physics cache data just to do a cell search. Similarly the Geometron is instead used for ray tracing in the plotter, now. It could also be used for the implementation of the random ray method which I hear is coming along. My last note on the Geometron is that all the geometric operations take Geometron references or pointers, not Particle. Of course, simply passing a Particle pointer works as usual. ~~This does not invoke any polymorphism, so there will be zero performance overhead as a result of this, or perhaps even performance gains since the compiler will know that only a smaller subset of the data can potentially be accessed.~~ Polymorphism is used for error handling in geometric routines. Geometrons fatal_error on erroneous leakage from the model, but Particles save the leaked ID and then the simulation continues.

~~In this direction, there was one larger change I had to make for error handling in geometry. It seems that raising an exception is the right thing to do here, with calling code defining the exception handling. Code in Particle now will resort to mark_as_lost for lost stuff, but in the plotter, you just get a plain old exception that stops the program. Previously it would just say "particle with ID=-1 leaked" or something like that. For MOC or other things like that, of course you would just want the program to exit if you leak a ray, so I hope other people like this error handling approach in the geometry now. Also, the compiler knows that exceptions happen with low frequency, so there might be a slight performance gain from the improved branch prediction in those few places where we previously had just called mark_as_lost.~~

Lastly, in the ParticleData class, I moved the comments to the setters/getters rather than on the private variables, since this is the public-facing API that people would actually want to read.

There are a few other things I want to do before merging this. It is a WIP. Of course I need to add the new plot and its options to the python API. Really not looking forward to the XML boilerplate. Also I want to factor the plot ray tracer into its own RayKernel-object. I'm thinking it'd be nice to create a ray that just has some lambdas attached to it like on_intersection_ or on_cross_surface_ to avoid repeating it in PhongPlot and ProjectionPlot. Of course this could help with parallelization and could be used in a random ray implementation. Lastly I'd like to add a 3D version of Universe.plot that automatically picks a camera position based on the bounding box size and some simple position argument like "top left" or "front left".

~~Also, I need to figure out how to rotate surface normals in transformed nested universes in order to get the direction to the light in the root universe. That's going to be a fun one.~~

Oh wait... there's one more thing. The ProjectionPlot camera rays were not uniform in pixel space, which did not create distortion effects for things that are far away, but are distorted for things up close. The old plotter would make straight surfaces appear curved, e.g:

example1

With this PR, it correctly maps pixels onto ray directions, making it look a lot better:

example1

Checklist

  • [x] I have performed a self-review of my own code
  • [x] I have run clang-format on any C++ source files (if applicable)
  • [x] I have followed the style guidelines for Python source files (if applicable)
  • [x] I have made corresponding changes to the documentation (if applicable)
  • [x] I have added tests that prove my fix is effective or that my feature works (if applicable)
  • [x] Add PhongPlot to python API
  • [x] Factor out ray tracing logic into RayTracePlot (it is duplicated right now)
  • [ ] ~~Add Universe plot3d method for easily obtained 3D visualization in ipython notebooks~~
  • [ ] ~~Plot a slice of the BEAVRS core with pins and core structure shown as solids.~~
  • [x] Make it work with rotated/translated subuniverses

gridley avatar Aug 18 '23 18:08 gridley

Just sharing some new stuff. Here's a plot of some TRISO:

image

And here's an example of shadows working correctly with the classic CSG test object:

csg_background

gridley avatar Aug 26 '23 17:08 gridley

Just made one of these plots, very nice interface and easy to use. p

shimwell avatar Aug 31 '23 15:08 shimwell

""Some files failed the formatting check! See job summary and file annotations for more info" && exit 1"

How can I look at these annotations? Huh. Thought I was running clang-format...

gridley avatar Sep 09 '23 22:09 gridley

""Some files failed the formatting check! See job summary and file annotations for more info" && exit 1"

You can see them in the run summary by clicking on the 🏠 icon in the left sidebar https://github.com/openmc-dev/openmc/actions/runs/6133354411?pr=2655

How can I look at these annotations? Huh. Thought I was running clang-format...

Are you running the same version as CI (15)? We've seen a few others get hit by that recently.

pshriwise avatar Sep 12 '23 09:09 pshriwise

We should be good for another review here, now! I removed the exception crap to just use mark_as_lost and fatal_error instead. However, we need to use a virtual here in order to retain the correct behavior: die with an error for Geometron, but save the particle info and continue for Particle.

gridley avatar Oct 05 '23 15:10 gridley

I think I still owe you a mini-PR to handle DAGMC geometry. I'll try to take care of that today. Hopefully I can review it soon.

pshriwise avatar Oct 05 '23 15:10 pshriwise

Oh sweet! OK I just realized that the mark_as_lost does actually have to be virtual to get the right behavior, and I have to move the id_ data to Geometron, but that's not really a big deal. (so gonna push that ina sec)

gridley avatar Oct 05 '23 15:10 gridley

Alright, now it should be good for review!

gridley avatar Oct 05 '23 15:10 gridley

Just sharing this nice image I made for the docs. Imagine how many voxels you'd need to create this previously! phong_triso

gridley avatar Oct 07 '23 01:10 gridley

@cfichtlscherer has some super nice stuff too. Are you able to give any sneak peeks Chris?

gridley avatar Oct 07 '23 01:10 gridley

test_evaluate_legendre is failing for me in CI. No way it's related to the recent commits... Any ideas?

gridley avatar Oct 10 '23 19:10 gridley

test_evaluate_legendre is failing for me in CI. No way it's related to the recent commits... Any ideas?

I've been seeing that too here: https://github.com/openmc-dev/openmc/actions/runs/6471480840/job/17575480291

I'll take a look soon.

pshriwise avatar Oct 10 '23 20:10 pshriwise

@cfichtlscherer has some super nice stuff too. Are you able to give any sneak peeks Chris?

Yeah I used it to plot some weapon models. I think it would be so nice to have it in the main code.

warheads_models_01102023

cfichtlscherer avatar Oct 10 '23 21:10 cfichtlscherer

wondering if metallic or surface texture or reflective surfaces would be possible

shimwell avatar Oct 20 '23 21:10 shimwell

Hey @gridley. Sorry it's taken me a while to get back to you. I talked with @jtramm about this PR and what overlap there might be with his random ray implementation. For the time being, we settled on separate implementations b/c, from what we could tell, there wouldn't be a lot of overlap aside from the definition of the ray itself (position and direction). We also identified a couple of updates here that could be of benefit. I made note of them in file comments.

One overarching note was that the introduction of the Geometron is a great contribution in and of itself. Would you be willing to break that out into a separate PR so we can get that merged more quickly? I think it would speed up review iteration and allow us to focus more on the plotting aspects of the work only.

pshriwise avatar Oct 20 '23 21:10 pshriwise

test_evaluate_legendre is failing for me in CI. No way it's related to the recent commits... Any ideas?

This has been resolved in #2729. We'll need to update this branch to get CI passing again.

pshriwise avatar Oct 20 '23 21:10 pshriwise

OK @pshriwise, just resolved any conflicts, could you give this one more review?

gridley avatar Feb 25 '24 17:02 gridley

OK @pshriwise, just resolved any conflicts, could you give this one more review?

Can do! Thanks for updating it

pshriwise avatar Feb 26 '24 21:02 pshriwise

OK, pretty sure I got all your comments addressed @pshriwise!

gridley avatar Mar 07 '24 18:03 gridley

This automatic clang format is driving me nuts. I am running clang format, but they're different versions and have some tiny whitespace differences. I've dropped some pretty unnecessary comments in the last commit where I can't figure out how to make the two versions of clang-format happy.

gridley avatar Mar 07 '24 18:03 gridley

This automatic clang format is driving me nuts. I am running clang format, but they're different versions and have some tiny whitespace differences. I've dropped some pretty unnecessary comments in the last commit where I can't figure out how to make the two versions of clang-format happy.

Yeah the C++ formatter check can be pretty frustrating sometimes, sorry. It's plagued others as well. It would be great if we could configure a bot to provide the updates as suggestions or something. I'll give that some thought.

pshriwise avatar Mar 07 '24 20:03 pshriwise