@@ -28,7 +28,7 @@ tensor is the identity matrix), but this can be changed by specifying
2828the metric tensor components.
2929
3030Integer quantities such as ``nx `` can be numbers (like “260”), or
31- expressions (like “256 + 2\* MXG”).
31+ expressions (like “256 + 2\* MXG”).
3232A common use is to make ``x `` and ``z `` dimensions have the same
3333number of points, when ``x `` has ``mxg `` boundary cells on each
3434boundary but ``z `` does not (since it is usually periodic):
@@ -37,14 +37,14 @@ boundary but ``z`` does not (since it is usually periodic):
3737
3838 [mesh]
3939 nx = nz + 2*mxg # X grid size
40- nz = 256 # Z grid size
41- mxg = 2
40+ nz = 256 # Z grid size
41+ mxg = 2
4242
4343
4444 Note that the order of the defintion within a section isn't important,
4545variables can be used before they are defined. All variables are first
4646read, and only processed if they are used.
47-
47+
4848Expressions are always calculated in floating point; When expressions
4949are used to set integer quantities (such as the number of grid
5050points), the expressions are calculated in floating point and then
@@ -60,7 +60,7 @@ the ``round`` function:
6060 nx = 256.4 # Error!
6161 nx = round(256.4) # ok
6262
63-
63+
6464 Real (floating-point) values can also be expressions, allowing quite
6565complicated analytic inputs. For example in the example ``test-griddata ``:
6666
@@ -158,7 +158,9 @@ Cartesian.
158158You can read additional quantities from the grid and make them available in
159159expressions in the input file by listing them in the ``input:grid_variables ``
160160section, with the key being the name in the grid file (``mesh:file ``) and the
161- value being the type (one of ``field3d ``, ``field2d ``, ``boutreal ``):
161+ value being the type (one of ``field3d ``, ``field2d ``, ``boutreal ``). Variables
162+ read in this way are made available under a ``gridvar: `` namespace to avoid
163+ collisions with other input variables:
162164
163165.. code-block :: cfg
164166
@@ -168,7 +170,7 @@ value being the type (one of ``field3d``, ``field2d``, ``boutreal``):
168170 scale = boutreal
169171
170172 [mesh]
171- B = (scale / rho) * cos(theta)
173+ B = (gridvar: scale / gridvar: rho) * cos(gridvar: theta)
172174
173175 This section describes how to generate inputs for tokamak equilibria. If
174176you’re not interested in tokamaks then you can skip to the next section.
@@ -219,7 +221,7 @@ From EFIT files
219221A separate tool (in python) called `Hypnotoad <https://github.com/boutproject/hypnotoad >`_
220222has been developed to create BOUT++ input files from R-Z equilibria. This can read EFIT ’g’
221223(geqdsk) files, find flux surfaces, and calculate metric
222- coefficients.
224+ coefficients.
223225
224226From GRIDUE files
225227--------------
@@ -281,7 +283,7 @@ As in the above code, creating an output file consists of the following steps:
281283
2822841. Define a magnetic field
2832852. Define the grid points. This can be broken down into:
284-
286+
285287 a) Define 2D "poloidal" grids
286288 b) Form a 3D grid by putting 2D grids together along the Y direction
287289
@@ -307,9 +309,9 @@ In this case with 10 points in y (second argument to ``rectangular_grid(nx,ny,nz
307309the y locations are :math: `\left (0.5 , 1.5 , 2.5 , \ldots , 9.5 \right )`.
308310
309311At each of these y locations ``rectangular_grid `` defines a rectangular 2D poloidal grid in
310- the X-Z coordinates, by default with a length of 1 in each direction and centred on :math: `x=0 ,z=0 `.
312+ the X-Z coordinates, by default with a length of 1 in each direction and centred on :math: `x=0 ,z=0 `.
311313These 2D poloidal grids are then put together into a 3D ``Grid ``. This process can be customised
312- by separating step 2 (the ``rectangular_grid `` call) into stages 2a) and 2b).
314+ by separating step 2 (the ``rectangular_grid `` call) into stages 2a) and 2b).
313315For example, to create a periodic rectangular grid we could use the following::
314316
315317 import numpy as np
@@ -333,7 +335,7 @@ input file (this is in ``examples/zoidberg/tokamak.py``)::
333335
334336 import numpy as np
335337 import zoidberg
336-
338+
337339 field = zoidberg.field.GEQDSK("g014220.00200") # Read magnetic field
338340
339341 grid = zoidberg.grid.rectangular_grid(100, 10, 100,
@@ -345,13 +347,13 @@ input file (this is in ``examples/zoidberg/tokamak.py``)::
345347
346348 # Create the forward and backward maps
347349 maps = zoidberg.make_maps(grid, field)
348-
350+
349351 # Save to file
350352 zoidberg.write_maps(grid, field, maps, gridfile="grid.fci.nc")
351353
352354 # Plot grid points and the points they map to in the forward direction
353355 zoidberg.plot.plot_forward_map(grid, maps)
354-
356+
355357In the last example only one poloidal grid was created (a ``RectangularPoloidalGrid ``)
356358and then re-used for each y slice. We can instead define a different grid for each y
357359position. For example, to define a grid which expands along y (for some reason) we could do::
@@ -387,10 +389,10 @@ One way to create this grid is to define the grid points manually e.g.::
387389 r,theta = np.meshgrid(np.linspace(1,2,10),
388390 np.linspace(0,2*np.pi, 10),
389391 indexing="ij")
390-
392+
391393 R = r * np.sin(theta)
392394 Z = r * np.cos(theta)
393-
395+
394396 poloidal_grid = zoidberg.poloidal_grid.StructuredPoloidalGrid(R,Z)
395397
396398For more complicated shapes than circles, Zoidberg comes with an
@@ -402,21 +404,21 @@ outer boundaries::
402404 inner = zoidberg.rzline.shaped_line(R0=3.0, a=0.5,
403405 elong=1.0, triang=0.0, indent=1.0,
404406 n=50)
405-
407+
406408 outer = zoidberg.rzline.shaped_line(R0=2.8, a=1.5,
407409 elong=1.0, triang=0.0, indent=0.2,
408410 n=50)
409-
411+
410412 poloidal_grid = zoidberg.poloidal_grid.grid_elliptic(inner, outer,
411413 100, 100, show=True)
412414
413415which should produce the figure below:
414416
415417.. figure :: ../figs/zoidberg/elliptic_grid.png
416418 :name: elliptic
417- :alt:
419+ :alt:
418420 :scale: 50
419-
421+
420422 A grid produced by ``grid_elliptic `` from shaped inner and outer lines
421423
422424
@@ -440,14 +442,14 @@ flux surface.
440442At the moment this will not work correctly for slab geometries, but expects
441443closed flux surfaces such as in a stellarator or tokamak. A simple test case
442444is a straight stellarator::
443-
445+
444446 import zoidberg
445447 field = zoidberg.field.StraightStellarator(I_coil=0.4, yperiod=10)
446448
447449By default ``StraightStellarator `` calculates the magnetic field due to four coils which spiral around
448450the axis at a distance :math: `r=0.8 ` in a classical stellarator configuration. The ``yperiod ``
449451argument is the period in y after which the coils return to their starting locations.
450-
452+
451453To visualise the Poincare plot for this stellarator field, pass the ``MagneticField `` object
452454to ``zoidberg.plot.plot_poincare ``, together with start location(s) and periodicity information::
453455
@@ -459,14 +461,14 @@ which should produce the following figure:
459461 :name: poincare
460462 :alt: Points on four oval shaped flux surfaces in x-z at three locations along the y direction
461463 :scale: 50
462-
464+
463465 Poincare map of straight stellarator showing a single flux
464466 surface. Each colour corresponds to a different x-z plane
465- in the y direction.
466-
467+ in the y direction.
468+
467469The inputs here are the starting location :math: `\left (x,z\right ) = \left (0.4 , 0.0 \right )`,
468470and the periodicity in the y direction (10.0). By default this will
469- integrate from this given starting location 40 times (``revs `` option) around the y domain (0 to 10).
471+ integrate from this given starting location 40 times (``revs `` option) around the y domain (0 to 10).
470472
471473To create an ``RZline `` from these Poincare plots we need a
472474list of points in order around the line. Since the points
@@ -476,14 +478,14 @@ this is a `known hard problem <https://en.wikipedia.org/wiki/Travelling_salesman
476478but fortunately in this case the nearest neighbour algorithm seems to be quite robust provided there are enough points.
477479
478480An example of calculating a Poincare plot on a single y slice (y=0) and producing an ``RZline `` is::
479-
481+
480482 from zoidberg.fieldtracer import trace_poincare
481483 rzcoord, ycoords = trace_poincare(field, 0.4, 0.0, 10.0,
482484 y_slices=[0])
483-
485+
484486 R = rzcoord[:,0,0]
485487 Z = rzcoord[:,0,1]
486-
488+
487489 line = zoidberg.rzline.line_from_points(R, Z)
488490
489491 line.plot()
@@ -495,7 +497,7 @@ approximation to the flux surface, increase the number of points by setting the
495497(y revolutions) in the ``trace_poincare `` call.
496498
497499In general the points along this line are not evenly
498- distributed, but tend to cluster together in some regions and have large gaps in others.
500+ distributed, but tend to cluster together in some regions and have large gaps in others.
499501The elliptic grid generator places grid points on the boundaries
500502which are uniform in the index of the ``RZline `` it is given.
501503Passing a very uneven set of points will therefore result in
@@ -509,7 +511,7 @@ to create a grid file for a straight stellarator.
509511
510512Sections below now describe each part of Zoidberg in more detail. Further documentation
511513of the API can be found in the docstrings and unit tests.
512-
514+
513515Magnetic fields
514516~~~~~~~~~~~~~~~
515517
@@ -518,12 +520,12 @@ Magnetic fields can be defined in either cylindrical or Cartesian coordinates:
518520
519521* In Cartesian coordinates all (x,y,z) directions have the same units of length
520522* In cylindrical coordinates the y coordinate is assumed to be an angle, so that
521- the distance in y is given by :math: `ds = R dy` where :math: `R` is the major radius.
523+ the distance in y is given by :math: `ds = R dy` where :math: `R` is the major radius.
522524
523525Which coordinate is used is controlled by the ``Rfunc `` method, which should return the
524526major radius if using a cylindrical coordinate system.
525- Should return ``None `` for a Cartesian coordinate system (the default).
526-
527+ Should return ``None `` for a Cartesian coordinate system (the default).
528+
527529Several implementations inherit from ``MagneticField ``, and provide:
528530``Bxfunc ``, ``Byfunc ``, ``Bzfunc `` which give the components of the magnetic field in
529531the x,y and z directions respectively. These should be in the same units (e.g. Tesla) for
@@ -550,14 +552,14 @@ and has a given major radius (default 1)::
550552 field = zoidberg.field.CurvedSlab()
551553
552554Note that this uses a large aspect-ratio approximation, so the major radius
553- is constant across the domain (independent of x).
554-
555+ is constant across the domain (independent of x).
556+
555557Straight stellarator
556558++++++++++++++++++++
557559
558560This is generated by four coils with alternating currents arranged
559561on the edge of a circle, which spiral around the axis::
560-
562+
561563 import zoidberg
562564 field = zoidberg.field.StraightStellarator()
563565
@@ -588,7 +590,7 @@ Plotting the magnetic field
588590~~~~~~~~~~~~~~~~~~~~~~~~~~~
589591
590592Routines to plot the magnetic field are in ``zoidberg.plot ``. They include Poincare plots
591- and 3D field line plots.
593+ and 3D field line plots.
592594
593595For example, to make a Poincare plot from a MAST equilibrium::
594596
@@ -634,7 +636,7 @@ To create a rectangular grid, pass the number of points and lengths in the x and
634636to ``RectangularPoloidalGrid ``::
635637
636638 import zoidberg
637-
639+
638640 rect = zoidberg.poloidal_grid.RectangularPoloidalGrid( nx, nz, Lx, Lz )
639641
640642By default the middle of the rectangle is at :math: `\left (R,Z\right ) = \left (0 ,0 \right )`
@@ -649,7 +651,7 @@ To create the structured curvilinear grids inner and outer lines are needed
649651with the following formula:
650652
651653.. math ::
652-
654+
653655 R = R_0 - b + \left (a + b \cos \left (\theta \right )\cos \left (\theta + \delta \sin \left (\theta \right )\right )\right )
654656
655657 Z = \left (1 + \epsilon \right )a\sin \left (\theta \right )
0 commit comments