|
The Open FUSION Toolkit 1.0.0-beta6
Modeling tools for plasma and fusion research and engineering
|
In this example we demonstrate how to run a time-domain simulation with current diagnostics for a simple ThinCurr model of a cylinder.
To load the ThinCurr python module we need to tell python where to the module is located. This can be done either through the PYTHONPATH environment variable or within a script using sys.path.append() as below, where we look for the environement variable OFT_ROOTPATH to provide the path to where the OpenFUSIONToolkit is installed (/Applications/OFT for binaries on macOS).
We now create a OFT_env instance for execution using two threads and a ThinCurr instance that utilizes that execution environment.
Once created, we setup the model from an existing HDF5 and XML mesh definition using setup_model(). For this model we have defined current jumpers using additional nodesets, which must be identified using the jumper_start argument. Here we use python-style reverse array indexing to indicate the jumpers start at the last entry in the nodeset list.
Finally, we initialize I/O for this model using setup_io() to enable output of plotting files for 3D visualization in VisIt, Paraview, or using pyvista below.
#----------------------------------------------
Open FUSION Toolkit Initialized
Development branch: v1_beta6
Revision id: 681e857
Parallelization Info:
# of MPI tasks = 1
# of NUMA nodes = 1
# of OpenMP threads = 2
Fortran input file = /var/folders/52/n5qxh27n4w19qxzqygz2btbw0000gn/T/oft_64877/oftpyin
XML input file = none
Integer Precisions = 4 8
Float Precisions = 4 8 16
Complex Precisions = 4 8
LA backend = native
#----------------------------------------------
Creating thin-wall model
Orientation depth = 895
Loading V(t) driver coils
Loading I(t) driver coils
# of points = 795
# of edges = 2259
# of cells = 1464
# of holes = 1
# of Vcoils = 0
# of closures = 0
# of Icoils = 1
Building holes
Loading region resistivity:
1 1.2570E-05
Unlike in ThinCurr Python Example: Time-domain simulation of a cylinder we are not definining any magnetic sensors. However, we must still call compute_Msensor() to setup the jumpers. During this time the orientation of positive current for each jumper is saved to a jumpers_orient.dat file in the current directory.
Setting jumper information:
1 -4.981645644143631E-02 -9.987583895355365E-01 -0.000000000000000E+00
Building element->sensor inductance matrix
Building coil->sensor inductance matrix
With the model setup, we can now compute the self-inductance and resistivity matrices. A numpy version of the self-inductance matrix will be stored at tw_plate.Lmat. By default the resistivity matrix is not moved to python as it is sparse and converting to dense representation would require an increase in memory. These matrices correspond to the \(\textrm{L}\) and \(\textrm{R}\) matrices for the physical system
\(\textrm{L} \frac{\partial I}{\partial t} + \textrm{R} I = V\)
Building coil<->element inductance matrices
Time = 0s
Building coil<->coil inductance matrix
Building element<->element self inductance matrix
Time = 1s
Building resistivity matrix
With the model fully defined we can now use run_td() to perform a time-domain simulation. In this case we simulate 80 ms using a timestep of 0.2 ms (400 steps). We also specify using a direct solver for the time-advance (direct=True) and set the current in the single I-coil defined in the XML input file as a function of time (coil_currs), where the first column specifies time points in ascending order and the remaining columns specify coil currents at each time point.
Starting simulation Starting factorization Inverting real matrix Time = 1.2357999999999999E-002 Timestep 10 2.00000009E-03 3.21358885E-03 1 Timestep 20 4.00000019E-03 6.27122633E-03 1 Timestep 30 6.00000005E-03 9.10636503E-03 1 Timestep 40 8.00000038E-03 1.17357541E-02 1 Timestep 50 9.99999978E-03 1.41745238E-02 1 Timestep 60 1.20000001E-02 1.64365564E-02 1 Timestep 70 1.40000004E-02 1.85346715E-02 1 Timestep 80 1.60000008E-02 2.04807445E-02 1 Timestep 90 1.79999992E-02 2.22857799E-02 1 Timestep 100 1.99999996E-02 2.38748975E-02 1 Timestep 110 2.19999999E-02 2.22232491E-02 1 Timestep 120 2.40000002E-02 2.06126291E-02 1 Timestep 130 2.60000005E-02 1.91188417E-02 1 Timestep 140 2.80000009E-02 1.77332275E-02 1 Timestep 150 2.99999993E-02 1.64479148E-02 1 Timestep 160 3.20000015E-02 1.52556524E-02 1 Timestep 170 3.40000018E-02 1.41497208E-02 1 Timestep 180 3.59999985E-02 1.31238885E-02 1 Timestep 190 3.79999988E-02 1.21723702E-02 1 Timestep 200 3.99999991E-02 1.12897959E-02 1 Timestep 210 4.19999994E-02 1.04711801E-02 1 Timestep 220 4.39999998E-02 9.71189607E-03 1 Timestep 230 4.60000001E-02 9.00765043E-03 1 Timestep 240 4.80000004E-02 8.35445710E-03 1 Timestep 250 5.00000007E-02 7.74862012E-03 1 Timestep 260 5.20000011E-02 7.18670804E-03 1 Timestep 270 5.40000014E-02 6.66553853E-03 1 Timestep 280 5.60000017E-02 6.18215930E-03 1 Timestep 290 5.79999983E-02 5.73383039E-03 1 Timestep 300 5.99999987E-02 5.31801209E-03 1 Timestep 310 6.19999990E-02 4.93234675E-03 1 Timestep 320 6.40000030E-02 4.57464904E-03 1 Timestep 330 6.59999996E-02 4.24289098E-03 1 Timestep 340 6.80000037E-02 3.93519131E-03 1 Timestep 350 7.00000003E-02 3.64980591E-03 1 Timestep 360 7.19999969E-02 3.38511681E-03 1 Timestep 370 7.40000010E-02 3.13962274E-03 1 Timestep 380 7.59999976E-02 2.91193230E-03 1 Timestep 390 7.80000016E-02 2.70075398E-03 1 Timestep 400 7.99999982E-02 2.50489078E-03 1
We can now plot the signals from the current jumper as a function of time. During the time-domain run this information is stored in OFT's binary history file format, which can be read using the histfile class. This class stores the resulting signals in a Python dict-like representation.
OFT History file: jumpers.hist
Number of fields = 3
Number of entries = 401
Fields:
time: Simulation time [s] (d1)
JUMPER_0001: No description (d1)
HOLE_0001: No description (d1)
After completing the simulation we can generate plot files using tw_torus.plot_td(). Plot files are saved at a fixed timestep interval, specified by the nplot argument to run_td() with a default value of 10.
Once all fields have been saved for plotting tw_torus.build_XDMF() to generate the XDMF descriptor files for plotting with VisIt of Paraview. This method also returns a XDMF_plot_file object, which can be used to read and interact with plot data in Python (see below).
Post-processing simulation
Removing old Xdmf files
Removed 43 files
Creating output files: oft_xdmf.XXXX.h5
Found Group: thincurr
Found Mesh: icoils
# of blocks: 1
Found Mesh: smesh
# of blocks: 1
For demonstration purposes we now plot the the solution at the end of the driven phase using pyvista. We now use the plot_data object to generate a 3D plot of the current at t=2.E-2. For more information on the basic steps in this block see ThinCurr Python Example: Compute eigenstates in a plate