The Pleiades Code¶
The Pleiades code is designed for computing axisymmetric magnetic fields from combinations of electromagnets and permanent magnets with a focus on modeling plasma physics experiments. The project originated at the Wisconsin Plasma Physics Laboratory during experiments on the novel confinement device known as the Big Red Ball. Pleiades is written entirely in Python for now and is intended to be an easily accessible toolkit for computing and visualizing magnetic confinement geometries and data simultaneously.
Aside from simple computations of magnetic fields, there is a plasma MHD equilibrium solver incorporated into the package as well, which has been used to generate magnetic mirror equilibria and input files suitable for being run with the GENRAY and CQL3D codes for the design of the new Wisconsin HTS Axisymmetric Mirror (WHAM) and its eventual upgrade to a neutron source (WHAM-NS).
The Pleiades code is available on github. Any and all feedback and contributions are welcome!
Contents¶
Quick Install Guide¶
To install the Pleiades code. Simply clone the github repository and install with pip
. An
example for how to do this on linux is shown below.
Installing on Linux¶
git clone https://github.com/eepeterson/pleiades
cd pleiades
pip install -e .
Examples¶
Here are some (1 right now) example Jupyter Notebooks for showing users how to get started with the Pleiades package.
General Usage¶
Introduction¶
Introduction to Coil Sets, Devices, and Fields¶
The purpose of this tutorial is to develop familiarity with the fundamental objects we will need to create, manipulate, and analyze magnetic configurations.¶
The four objectives of this tutorial are enumerated below:¶
- Create coil sets and transform them through translations and rotations.
- Create suitable meshes and use them to create Green's functions for flux and magnetic field components
- Learn how to combine sets of coils into a Device object
- Understand and plot the results of goals 1, 2, and 3
Just like any other python notebook we start with importing standard libraries as well as our project's specific functionality
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
from pleiades import RectangularCoil
Now we will create an instance of the RectangularCoil
class as it is by far the most common coil set used for building electromagnets for plasma physics or fusion experiments. We create a RectangularCoil
by specifying at a minimum the centroid (r0, z0)
of the regular array of current filaments in cylindrical coordinates and with SI units.
rc1 = RectangularCoil(1, .5, nr=10, nz=10, dr=.01, dz=.01)
print(rc1)
We can learn the basic properties of a coil set just by printing it, but to see what other attributes it has let's print some of those as well.
print(f'Centroid: {rc1.centroid}, Units: m')
print(f'Cross-sectional area: {rc1.area}, Units: m$^2$')
print(f'Current per filament: {rc1.current}, Units: A')
print(f'Total current: {rc1.total_current}, Units: A')
print(f'Current density: {rc1.current_density}, Units: A/m$^2$')
Now we will try our hand at plotting some of this data as well as the visulaizations. to access the fields like psi, B_R, and B_Z we simply call their attributes from the brb object as shown below.
from pleiades import RectMesh
mesh = RectMesh(rmin=0, rmax=3, zmin=0, zmax=3)
rc1.mesh = mesh
rc1.psi()
fig, ax = plt.subplots()
rc1.plot(ax, color='k')
ax.contour(mesh.R, mesh.Z, rc1.psi().reshape(mesh.R.shape), 51)
ax.set_xlim(0, 3)
ax.set_ylim(0, 3)
ax.set_aspect(1)
ax.set_xlabel('R (m)')
ax.set_ylabel('Z (m)')
plt.show()
fig, ax = plt.subplots()
rc1.plot(ax, color='k')
ax.contour(mesh.R, mesh.Z, rc1.psi().reshape(mesh.R.shape), 11)
ax.set_xlim(.9, 1.1)
ax.set_ylim(.4, .6)
ax.set_aspect(1)
ax.set_xlabel('R (m)')
ax.set_ylabel('Z (m)')
plt.show()
Big Red Ball (BRB) Basic Usage¶
The Big Red Ball (BRB) Basic Functionality¶
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
from pleiades import RectMesh
from pleiades.configurations import BRB
brb = BRB()
brb.hh_s.current = 50
brb.hh_n.current = 50
mesh = RectMesh(rmin=0, rmax=3, zmin=-2, zmax=2, nr=101, nz=101)
brb.mesh = mesh
fig, ax = plt.subplots(figsize=(4,6))
brb.plot(ax)
ax.set_xlim(0, 3)
ax.set_ylim(-2, 2)
ax.set_aspect(1)
ax.set_xlabel('R (m)')
ax.set_ylabel('Z (m)')
plt.show()
Wisconsin HTS Axisymmetric Mirror (WHAM) Basic Usage¶
import numpy as np
import os
import matplotlib.pyplot as plt
from matplotlib import ticker
from matplotlib.collections import PatchCollection
import matplotlib.colors as colors
from pleiades import RectMesh, compute_equilibrium, write_eqdsk
from pleiades.configurations import WHAM
from pleiades.analysis import get_gpsi, locs_to_vals, get_fieldlines
# create the WHAM device
wham = WHAM()
# choose values for HTS mirror coils and central cell coils
wham.hts1.current = 160000
wham.hts2.current = 160000
wham.cc1.current = 60000
wham.cc2.current = 60000
mesh = RectMesh(rmin=0, rmax=0.75, zmin=-1, zmax=1, nr=76, nz=201)
R, Z = mesh.R, mesh.Z
# set the brb grid (does all greens functions calculations right here)
wham.mesh = mesh
# get desired field quantities from brb object and view coilset
B = np.sqrt(wham.BR()**2 + wham.BZ()**2).reshape(R.shape)
BR = wham.BR().reshape(R.shape)
BZ = wham.BZ().reshape(R.shape)
psi = wham.psi().reshape(R.shape)
psi_lim = locs_to_vals(R, Z, psi, [(1.25, 0)])[0]
psi_space = np.linspace(0, psi_lim, 11)
bspace = np.logspace(-3, 1, 41)
# Plotting Section
fig, ax = plt.subplots()
cf = ax.contourf(Z, R, BZ, bspace, cmap="rainbow", locator=ticker.LogLocator(), extend='min')
ax.contour(Z, R, psi, 21, colors="k", linewidths=0.5)
fig.colorbar(cf)
ax.set_xlim(-1., 1.)
ax.set_ylim(0, 0.75)
ax.set_xlabel("Z (m)")
ax.set_ylabel("R (m)")
ax.set_aspect(1)
plt.show()
# Zoomed in Plotting Section
fig,ax = plt.subplots()
cf = ax.contourf(Z,R,B,bspace,cmap="rainbow",locator=ticker.LogLocator(), extend='min')
ax.contour(Z,R,psi,21,colors="k", linewidths=0.5)
fig.colorbar(cf)
ax.set_xlim(-1., 1.)
ax.set_ylim(0, 0.75)
ax.set_xlabel("Z (m)")
ax.set_ylabel("R (m)")
ax.set_aspect(1)
plt.show()
Now lets look at an equilibrium... A few parameters are important here: namely the plasma limiting radius, a, the peak pressure, P0, the exponent of the pressure profile, alpha, and the plasma beta at the origin with respect to the vacuum field. Once we build the pressure function and get the Green's function for plasma currents on the grid we are ready to run compute_equilibrium and write out an eqdsk. When this cell is run you should see the iteration number and error print to the screen and the error should decrease to a small value below 1E-10 by default to know the computation has converged.
# setup pressure profile and compute P0 for a given desired initial beta
a = .5
alpha = 2.0
beta0 = .1
B0 = locs_to_vals(R,Z,B,[(0,0)])[0]
P0 = beta0*B0**2/(2*4*np.pi*1E-7)
print("pressure ", P0)
# build pressure function of cylindrical radius
Pfunc = lambda x: P0*(1-(x/a)**2)**alpha if x < a else 0
# get greens function for plasma currents
gplas = get_gpsi(R,Z)
# compute equilibrium
psieq,plas_currents,pfit = compute_equilibrium(R,Z,Pfunc,psi,gplas,maxiter=400,plotit=False)
write_eqdsk(R,Z,psi,plas_currents,"wham_eqdsk.txt","WHAM_Mirror Equilib")
P = pfit(psi.flatten()).reshape(psi.shape)
jphi = plas_currents/((R[0,1]-R[0,0])*(Z[1,0]-Z[0,0]))
Below we will plot some flux lines as well as the diamagnetic current density j_phi in A/m^2 in the colormap. We've also included a demonstration of tracing field lines which can be used to interpolate values along a field line for stability calculations as well as flux surface averaging.
fig,ax = plt.subplots()
cf = ax.contourf(R,Z,jphi,101)
cs = ax.contour(R,Z,psieq,psi_space,colors="k")
for clev in psi_space[1:]:
flpts = get_fieldlines(cs,clev,start_coord=(0.05,.98),end_coord=(0.05,-0.98),clockwise=True)
ax.plot(flpts[:,0],flpts[:,1],"bo")
ax.plot(flpts[0,0],flpts[0,1],"go")
ax.plot(flpts[-1,0],flpts[-1,1],"ro")
ax.set_xlabel("R (m)")
ax.set_ylabel("Z (m)")
cbar = fig.colorbar(cf)
cbar.set_label("J_phi (A/m^2)")
plt.show()
Here let's plot a slice of B along the axis of symmetry.
#### Plotting
# plot slice of B as function of Z at R=0
ridx = np.abs(R[0,:]).argmin()
plt.plot(Z[:,ridx],B[:,ridx])
plt.xlabel("Z @ R=0 (m)")
plt.ylabel("B (T)")
plt.show()
Equilibrium Solver Basics¶
Welcome to Pleiades! the python package for Plasma Experiment Iteratively Advanced Design and Simulation¶
The goal of this package is to make designing magnetic confinement experiments simple, intuitive and fast for the purpose of interfacing with advanced plasma physics codes like NIMROD, GENRAY, and CQL3D and optimization of design considerations.¶
This notebook is broken after the core functionality was reworked¶
There are 4 main sections to the code base that focus on the fundamental stages of experimental design. They are as follows:¶
- An object oriented coil design architecture with built in Green's functions for axisymmetric field calculations and incorporated visulization
- A simple MHD equilibrium solver
- Preliminary stability calculations (m=1 flute mode and m=\inf ballooning) for magnetic mirrors
- Integrated IO module for generating input files to other codes like eqdsks for GENRAY and CQL3D
This example notebook demonstrates how to use an existing experiment known as the Big Red Ball (BRB) located at the Wisconsin Plasma Physics Laboratory (WIPPL) and add an additional coil set to produce a non-paraxial magnetic mirror. A vacuum field geometry is selected and an equilibrium is computed for a given pressure profile. Finally an eqdsk compatible with GENRAY and CQL3D is generated. There are plots and explanations along the way to help you get your feet wet!¶
Necessary import section is shown below. Pleiades is designed to be compatible with an out-of-the-box installation of Anaconda2/3 and the primary dependencies are numpy/scipy and matplotlib. If part of this notebook doesn't work for you please let us know and we will try to get a fix in place as soon as possible!
import numpy as np
import os
import matplotlib.pyplot as plt
from matplotlib import ticker
from matplotlib.collections import PatchCollection
import matplotlib.colors as colors
from pleiades import RectMesh, compute_equilibrium, write_eqdsk
from pleiades.configurations import BRB
from pleiades.analysis import get_gpsi, locs_to_vals, get_fieldlines
Now we will start by creating our Experiment which is done by instantiating an object of the BRB class. We will add an extra coil set, set some coil current values and create a grid in the R-Z plane for the ensuing computations.
# create the BRB object
brb = BRB()
# choose values for TREX HH coil (2kA) and current in mirror coils to (100kA) and assign them
hh_cur = 200
mir_cur = 100000
brb.hh_n.current = hh_cur
brb.hh_s.current = hh_cur
brb.ltrx_n.currents = mir_cur
brb.ltrx_s.currents = mir_cur
# turn off current in ltrx coils and in the vessel magnets so they don't mess with the flux plot
# also hide the visualization for the ltrx coils with brb.ltrx.patch_mask
#brb.vessel_mags.currents = [0,0,0]
# build the grid for field computation - creates a structured R-Z grid from R=[0,1] with 101 points and Z=[-.5,5] with 151 points
mesh = RectMesh(rmin=0, rmax=2, zmin=-2, zmax=2, nr=201, nz=201)
R, Z = mesh.R, mesh.Z
# set the brb grid (does all greens functions calculations right here)
brb.mesh = mesh
Here we will force the shape of the limiting flux surface by specifying the flux line through the mirror throat at (R,Z) = (0.08m,0.5m) to also pass through the point (R,Z) = (0.6m,0.0m). The mirror coil current is fixed and the TREX coil current is solved in order to enforce this criterion.
# force psi_lim through rlim1,zlim1 and rlim2,zlim2
#rlim1,zlim1 = 0.08,0.5
#rlim2,zlim2 = 0.6,0.0
#r1idx,z1idx = np.abs(R[0,:]-rlim1).argmin(), np.abs(Z[:,0]-zlim1).argmin()
#r2idx,z2idx = np.abs(R[0,:]-rlim2).argmin(), np.abs(Z[:,0]-zlim2).argmin()
#gm1,gm2 = np.sum(brb.mirrors.gpsi,axis=-1).reshape(R.shape)[z1idx,r1idx], np.sum(brb.mirrors.gpsi,axis=-1).reshape(R.shape)[z2idx,r2idx]
#gc1,gc2 = np.sum(brb.trex.gpsi,axis=-1).reshape(R.shape)[z1idx,r1idx], np.sum(brb.trex.gpsi,axis=-1).reshape(R.shape)[z2idx,r2idx]
#gp1,gp2 = 0, 0
#iplas = 0
#new_trex_cur = -((gm1-gm2)*brb.mirrors.currents[0] + (gp1-gp2)*iplas)/(gc1 - gc2)
#print(new_trex_cur)
#brb.trex.currents = [new_trex_cur,new_trex_cur]
Now we will try our hand at plotting some of this data as well as the visulaizations. to access the fields like psi, B_R, and B_Z we simply call their attributes from the brb object as shown below.
# get desired field quantities from brb object and view coilset
B = np.sqrt(brb.BR()**2 + brb.BZ()**2).reshape(R.shape)
BR = brb.BR().reshape(R.shape)
BZ = brb.BZ().reshape(R.shape)
psi = brb.psi().reshape(R.shape)
psi_lim = locs_to_vals(R, Z, psi, [(1.25, 0)])[0]
psi_space = np.linspace(0, psi_lim, 11)
# Plotting Section
fig, ax = plt.subplots()
cf = ax.contourf(R, Z, B, 101, cmap="rainbow", locator=ticker.LogLocator())
ax.contour(R, Z, psi, 51, colors="k")
plt.colorbar(cf)
ax.set_xlim(0, 2.5)
ax.set_ylim(-1.75, 1.75)
ax.set_xlabel("R (m)")
ax.set_ylabel("Z (m)")
ax.set_aspect(1)
plt.show()
# Zoomed in Plotting Section
fig,ax = plt.subplots()
cf = ax.contourf(R,Z,B,101,cmap="rainbow",locator=ticker.LogLocator())
ax.contour(R,Z,psi,51,colors="k")
plt.colorbar(cf)
ax.set_xlim(0,1.2)
ax.set_ylim(-.6,.6)
ax.set_xlabel("R (m)")
ax.set_ylabel("Z (m)")
ax.set_aspect(1)
plt.show()
Now lets look at an equilibrium... A few parameters are important here: namely the plasma limiting radius, a, the peak pressure, P0, the exponent of the pressure profile, alpha, and the plasma beta at the origin with respect to the vacuum field. Once we build the pressure function and get the Green's function for plasma currents on the grid we are ready to run compute_equilibrium and write out an eqdsk. When this cell is run you should see the iteration number and error print to the screen and the error should decrease to a small value below 1E-10 by default to know the computation has converged.
# setup pressure profile and compute P0 for a given desired initial beta
a = .6
alpha = 2.0
beta0 = .1
B0 = locs_to_vals(R,Z,B,[(0,0)])[0]
P0 = beta0*B0**2/(2*4*np.pi*1E-7)
print("pressure ", P0)
# build pressure function of cylindrical radius
Pfunc = lambda x: P0*(1-(x/a)**2)**alpha if x < a else 0
# get greens function for plasma currents
gplas = get_gpsi(R,Z)
# compute equilibrium
psieq,plas_currents,pfit = compute_equilibrium(R,Z,Pfunc,psi,gplas,maxiter=400,plotit=False)
write_eqdsk(R,Z,psi,plas_currents,"mfnpeqdsk1.txt","MFNP_Mirror Equilib")
P = pfit(psi.flatten()).reshape(psi.shape)
jphi = plas_currents/((R[0,1]-R[0,0])*(Z[1,0]-Z[0,0]))
Below we will plot some flux lines as well as the diamagnetic current density j_phi in A/m^2 in the colormap. We've also included a demonstration of tracing field lines which can be used to interpolate values along a field line for stability calculations as well as flux surface averaging.
fig,ax = plt.subplots()
cf = ax.contourf(R,Z,jphi,101)
cs = ax.contour(R,Z,psieq,psi_space,colors="k")
for clev in psi_space[1:]:
flpts = get_fieldlines(cs,clev,start_coord=(0.05,.5),end_coord=(0.05,-0.5),clockwise=True)
ax.plot(flpts[:,0],flpts[:,1],"bo")
ax.plot(flpts[0,0],flpts[0,1],"go")
ax.plot(flpts[-1,0],flpts[-1,1],"ro")
ax.set_xlabel("R (m)")
ax.set_xlabel("Z (m)")
cbar = fig.colorbar(cf)
cbar.set_label("J_phi (A/m^2)")
plt.show()
Here let's plot a slice of B along the axis of symmetry.
#### Plotting
# plot slice of B as function of Z at R=0
ridx = np.abs(R[0,:]).argmin()
plt.plot(Z[:,ridx],B[:,ridx])
plt.xlabel("Z @ R=0 (m)")
plt.ylabel("B (T)")
plt.show()
Now let's look at how the flux lines change with finite plasma beta. the black lines are the vacuum field lines and green are the equilibrium field line values for the given beta and pressure profile. The red line shows the limiting flux surface.
# plot up close flux lines and J_phi
fig,ax = plt.subplots(figsize=(10,8))
#cf = ax.contourf(R,Z,B,101,cmap="rainbow",locator=ticker.LogLocator(),zorder=0)
cf = ax.contourf(R,Z,jphi,101,zorder=0)
cs = ax.contour(R,Z,psi,51,colors='k',zorder=1)
cs1 = ax.contour(R,Z,psieq,51,colors='g',zorder=1)
cs = ax.contour(R,Z,psieq,(psi_lim,),colors='r',zorder=1)
cbar = fig.colorbar(cf)
cbar.set_label("J_phi (A/m^2)",fontsize=16)
ax.set_xlim(0,1.0)
ax.set_ylabel("Z (m)")
ax.set_xlabel("R (m)")
ax.set_ylim(-.5,.5)
ax.set_aspect('equal')
ax.add_collection(PatchCollection(brb.patches,match_original=True))
plt.show()
Python API¶
This page contains documentation on the Python modules, classes, and functions that comprise the pleiades package.
Modules
pleiades
– Basic Functionality¶
Building Magnetic Configurations¶
pleiades.RectangularCoil |
A rectangular cross section coil in the R-Z plane |
pleiades.Device |
A container for a full configuration of magnets for an experiment |
pleiades.CurrentFilamentSet |
Set of locations that have the same current value. |
pleiades.FieldsOperator |
Mixin class for computing fields on meshes |
pleiades.compute_greens |
Compute axisymmetric Green’s functions for magnetic fields |
Building Meshes¶
pleiades.Mesh |
A mesh in the R-Z plane for calculating magnetic fields and flux. |
pleiades.RectMesh |
A regular linearly spaced 2D R-Z mesh. |
pleiades.PointsMesh |
An unstructured mesh specified by two lists of coordinate points. |
pleiades.RChord |
A 1D chord of cylindrical radii at fixed height z. |
pleiades.ZChord |
A 1D chord of Z values at fixed cylindrical radius. |
pleiades.SphericalRChord |
A 1D chord of spherical radius at fixed polar angle theta. |
pleiades.ThetaChord |
A 1D chord of polar angles at fixed spherical radius r. |
WIPPL Magnetic Configurations¶
pleiades.configurations.BRB |
The Device object representing the Big Red Ball at UW-Madison. |
pleiades.configurations.PCX_magCage |
|
pleiades.configurations.PCX_HH |
Computing Equilibria¶
pleiades.compute_equilibrium |
Compute jxB=gradP equilibrium for given P as function of R |
pleiades.mirror_equilibrium |
Compute jxB=gradP equilibrium for given P as function of psi/psi_lim given by P(psi) = p0*(1-(psi/psi_lim)**alpha1)**alpha2 |
IO Functionality¶
pleiades.write_eqdsk |
pleiades.configurations
– Existing Experimental Facility Models¶
WIPPL Magnetic Configurations¶
pleiades.configurations.BRB |
The Device object representing the Big Red Ball at UW-Madison. |
pleiades.configurations.PCX_magCage |
|
pleiades.configurations.PCX_HH |
pleiades.analysis
– Analysis Functions¶
Mathematical Functions¶
pleiades.analysis.get_gpsi |
Plotting Helper Functions¶
pleiades.analysis.get_mirror_patches |
Get mirror image patches across desired axis. |
pleiades.analysis.scale_patches |
scale patches by desired factor. |
pleiades.analysis.transpose_patches |
Transpose patches (reflect across line y=x). |
Interpolation Helper Functions¶
pleiades.analysis.contour_points |
|
pleiades.analysis.reflect_and_hstack |
Reflect and concatenate grid and quantities in args to plot both half planes (rho>=0 and rho<=0). |
pleiades.analysis.regular_grid |
|
pleiades.analysis.poly_fit |
|
pleiades.analysis.transform_to_rtheta |
Transform Rho Z grid and rho,z components of vector field to polar coordinates |
pleiades.analysis.transform_to_rhoz |
Transform R Theta grid and r theta components of vector field to cylindrical coordinates |
pleiades.analysis.locs_to_vals |
Picks values of field Q at desired coordinates. |
pleiades.analysis.locs_to_vals_griddata |
Picks values of field Q at desired coordinates. |
pleiades.analysis.locs_to_vals1D |
Picks values of field Q at desired coordinates. |
Fieldline Analysis Functions¶
pleiades.analysis.get_fieldlines |
Return coordinates for segments comprising a flux surface (Nx2 array). |
pleiades.analysis.parse_segment |
|
pleiades.analysis.get_fieldline_distance |
Return cumulative field line distance vector |
pleiades.analysis.interp |
interpolate quantity Q on Rho, Z grid onto flpoints (Nx2 array of x,y pairs). |
pleiades.analysis.flux_surface_avg |
Compute flux surface average of quantity Q or return dVdpsi (dl_B) |
pleiades.analysis.diff_central |
Miscellaneous Helper Functions¶
pleiades.analysis.get_deltapsi |
Returns contribution to psi from fast ion currents. |
pleiades.analysis.get_concave_hull |
Gallery¶
This section will be filled in later with example plots of experiments as well as plots for publications that used Pleiades
Publications¶
Used Pleiades in Analysis¶
- Ethan E. Peterson, Douglass A. Endrizzi, Matthew Beidler, Kyle J. Bunkers, Michael Clark, Jan Egedal, Ken Flanagan, Karsten J. McCollam, Jason Milhone, Joseph Olson, Carl R. Sovinec, Roger Waleffe, John Wallace, and Cary B. Forest, “A laboratory model for the Parker spiral and magnetized stellar winds,” Nature Physics, 15, 1095–1100 (2019).
Resources and Reference Material¶
Below is a collection of resources for specific computing and software development resources we’ve curated in an attempt to provide a quick reference page for anybody starting out on a project like this.
Linux¶
Just for reference, the Linux Kernel Documentation uses Read the Docs to host their official documentation. So, if it’s good enough for the kernel developers, it’s good enough for us.
The Bash Reference Manual is super helpful for learning how to write bash scripts for manipulating files, running programs, and in general for executing things on the commandline.
The Linux Filesystem Hierarchy Standard is a helpful reference for how files are organized and common conventional uses of each directory. Understanding the purpose of the handful of directories under the root directory can go a long way towards helping you get comfortable with Linux and give you more control over your system. Also, because what the hell is …AppDataRoaming
Python¶
Python is the most popular programming language and is still growing. There are many reasons for this including general purpose capabilites as well as visualization toolkits and scientific computing libraries that are all user-friendly (more or less). The current supported version of Python is Python 3 as Python 2 support was ended in January 2020.
Scientific Computing with Python¶
The recommended Python distribution for scientific computing and data analysis is Anaconda 3 as it provides a very simple way to access many of most popular packages like numpy, scipy, pandas, matplotlib, scikit-learn and tensorflow. In addition many third-party packages are available for install through the conda package manager, including OpenMC.
Data Visualization¶
Git and Software Development¶
Git is a powerful tool for software development and version control for projects of all sizes, big or small. There are a number of helpful tutorials out there on how to use git,
Often times using git at the command line can be daunting for beginners. However, having a good understanding of proper git workflows can go a long way towards easing that anxiety. A very helpful reference that clearly explains a good git workflow including branching, merging, and releases can be found here
Program Design¶
License Agreement¶
MIT License
Copyright (c) 2020 Ethan Peterson
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.