Repository navigation
Conversation
Pynite being my previous attempt at a python plasma simulation code.
|
Hello @SolarDrew! Thanks for updating the PR.
Comment last updated on August 13, 2017 at 13:34 Hours UTC |
| def density(self, density: u.kg/u.m**3): | ||
| """Sets the simulation's density profile to the specified array. | ||
| Other arrays which depend on the density values, such as the kinetic pressure, | ||
| are then redefined automatically. |
There was a problem hiding this comment.
That's clever, I like it!
|
|
||
| assert density.shape == self.grid_size, \ | ||
| 'Specified density array shape does not match simulation grid.' | ||
| self._density = density |
There was a problem hiding this comment.
Doesn't the previous necessitate self._pressure = self.pressure() after this line here?
There was a problem hiding this comment.
I think it doesn't, but because the comment is wrong rather than the implementation.
Change pressure to energy, fix grid inconsistancies and pep8ify
Mostly for the purposes of keeping the pep8 bot happy
StanczakDominik
left a comment
There was a problem hiding this comment.
Had a brief look to stay up-to-date on what you're doing here. It looks pretty awesome!
| import astropy.units as u | ||
|
|
||
| mu0 = np.pi * 4.0e-7 * (u.newton / (u.amp**2)) | ||
| from astropy.utils.console import ProgressBar |
There was a problem hiding this comment.
Right, because of course astropy would have a built-in progress bar for all things astronomical.
There was a problem hiding this comment.
Yeah, astropy is amazing :D
| self._magnetic_field = np.zeros((3, *self.domain_shape)) * u.T | ||
|
|
||
| # Connect a simulation object for simulating | ||
| self.simulation_physics = MHDSimulation() |
There was a problem hiding this comment.
Love that you're keeping this generic!
| raise ValueError("Either max_time or max_its must be set.") | ||
|
|
||
| if np.isinf(max_time): | ||
| pb = ProgressBar(max_its) |
There was a problem hiding this comment.
Perhaps we could raise a warning here if both max_time and max_its are set?
There was a problem hiding this comment.
Good idea. But the question then becomes how to procede in a predictable way if there are two possible end 'times'. Stop at whichever one is sooner I suppose, but I feel like that's going to lead to unexpected behaviour if users aren't careful, so maybe raising an exception would be better. I'm happy to be convinced otherwise though.
There was a problem hiding this comment.
Sure, an exception does make more sense than a warning.
|
|
||
| # Collect equations into a nice easy-to-use list | ||
| # self.equations = [self._ddt_density, self._ddt_momentum, | ||
| # self._ddt_energy, self._ddt_magfield] |
There was a problem hiding this comment.
Thanks :) I found in the earlier version of this code that it's an easy and generalisable way to get at the functions you need.
So that it can get at the plasma variables, grid size, etc.
Also associated things
|
|
||
|
|
||
| class MHDSimulation(): | ||
| """Physics class for magnetohydrodynamics. |
|
|
||
| mu0 = np.pi * 4.0e-7 * (u.newton / (u.amp**2)) | ||
|
|
||
| class Plasma(): |
There was a problem hiding this comment.
You don't need the () in Python 3.
There was a problem hiding this comment.
But it looks so strange without them....
|
Update: so before NAM I managed to get some of the hyperviscosity implemented and running. With this in place, I've managed to run the Riemann shock tube test and the output looks like this: So there are still definitely some issues that need fixing, mostly with stability, but it's getting there. |
|
I haven't looked into this much, but sympy.utilities.codegen is probably useful (for some definition of useful). There was a tutorial on automatic code generation with SymPy at SciPy 2017. (These are what I mentioned in our last telecon.) In the intermediate future we may also wish to have some finite element modeling capabilities in here too, such as with packages like FEniCS. This could be really helpful with non-trivial geometry like tokamaks with non-circular cross sections. |
Used for allowing the viscous tensor to interact with things
To more easily see if/when calculations are going wrong
Turns out this was breaking the tests because it should have been using just the dx value for the appropriate axis. Didn't show up in 1D examples.
Was previously default 5/3, now set to match the example I'm trying to replicate
| dot = np.array([sum([vec[i] * tensor[i, 0, ...] for i in dims]), | ||
| sum([vec[i] * tensor[i, 1, ...] for i in dims]), | ||
| sum([vec[i] * tensor[i, 2, ...] for i in dims])]) \ | ||
| * vec.unit * tensor.unit |
There was a problem hiding this comment.
Perhaps, if speed is an issue, this part could be optimized somehow. Two possibilities that come to mind are some crazy numpy broadcasting tricks (I'm not saying I see how to do this just yet, though!) and JITting this part via Numba.
Numba doesn't play nice with Coveragepy, though. 😞
There was a problem hiding this comment.
Yeah, I feel like this could be speeded up by doing it the 'proper' numpy way. At the moment most of the viscous tensor stuff is still a bit fluid (boom boom) because I don't really fully understand and I haven't figured out how to do it with broadcasting. Premature optimisation, right...?
There was a problem hiding this comment.
Of course! Still, let's keep it in mind for later :)
I think I might have done something like this with numpy.einsum or whatever. I'll try to figure out how to do this via broadcasting a bit later.
There was a problem hiding this comment.
Definitely :) Cool, thanks :D
| t0 = datetime.datetime.now() | ||
| for maxt in np.arange(0, 0.21, 0.02): | ||
| print('- Running Simulation... ', end='') | ||
| riemann.simulate(max_time=maxt*u.s) |
There was a problem hiding this comment.
As I see it, we're running all pictures from 0 to t where t increases in the arange, right? Perhaps it would be easier on the computation to rewrite simulation to avoid that - go from 0 to t_1, take a snapshot.
In all likelihood this is something you've already thought of, but I just thought I'd raise it out in the open if anyone wants to hack away at implementing that.
There was a problem hiding this comment.
Huh, this is outdated now. Okay, git trees are magic.
There was a problem hiding this comment.
Yep, they are :P You're right, in the long term I'd like to have the Simulation object itself be able to save a snapshot so you don't need this sort of thing, but I haven't got around to it yet so I'm still using this hack.
| riemann.simulate(max_time=maxt*u.s) | ||
| print("Simulation complete") | ||
|
|
||
| fig, ax = plt.subplots(2, 2) |
There was a problem hiding this comment.
I always liked doing it like this:
fig, ((density_ax, velocity_ax), (energy_ax, pressure_ax)) = plt.subplots...
There was a problem hiding this comment.
Yeah, this is a bit nicer. Good call, thanks.
02e758d to
749a6bd
Compare
|
Sorry @SolarDrew, I think it's time to mark this one as stale. 😉 |
|
😭 Fair enough. Some day I'll come back to this and make it work! |


Closes #7 and provides a simple-to-use interface for setting up and running simulations. What's here at the moment is based largely on a similar previous project, which can be found here, but I'm happy to deviate from it based on input from others.
Below are some snapshots of density from a demo 2D simulation with a plasma blob initally in the middle and diffusing outwards. It's technically solving the MHD equations but with B = 0. As you can see, I'm getting some instabilities even without magnetic field, and the less said about the boundary conditions the better.
Also speed is obviously an issue at the moment.