Example #1
0
def test_readwrite():
    """Test reading/writing to a file round-trip"""
    tokamak = freegs.machine.MAST_sym()
    eq = freegs.Equilibrium(
        tokamak=tokamak,
        Rmin=0.1,
        Rmax=2.0,
        Zmin=-1.0,
        Zmax=1.0,
        nx=17,
        ny=17,
        boundary=freegs.boundary.freeBoundaryHagenow,
    )
    profiles = freegs.jtor.ConstrainPaxisIp(1e4, 1e6, 2.0)

    # Note here the X-point locations and isoflux locations are not the same.
    # The result will be an unbalanced double null configuration, where the
    # X-points are on different flux surfaces.
    xpoints = [(1.1, -0.6), (1.1, 0.8)]
    isoflux = [(1.1, -0.6, 1.1, 0.6)]
    constrain = freegs.control.constrain(xpoints=xpoints, isoflux=isoflux)

    freegs.solve(eq, profiles, constrain, maxits=25, atol=1e-3, rtol=1e-1)

    memory_file = io.BytesIO()

    with freegs.OutputFile(memory_file, "w") as f:
        f.write_equilibrium(eq)

    with freegs.OutputFile(memory_file, "r") as f:
        read_eq = f.read_equilibrium()

    assert tokamak == read_eq.tokamak
    assert allclose(eq.psi(), read_eq.psi())
Example #2
0
# Specify locations of the X-points
# to use to constrain coil currents

xpoints = [(1.1, -0.6),   # (R,Z) locations of X-points
           (1.1, 0.6)]

isoflux = [(1.1,-0.6, 1.1,0.6), # (R1,Z1, R2,Z2) pair of locations
           (1.7, 0.0, 0.84, 0.0)]

constrain = freegs.control.constrain(xpoints=xpoints, isoflux=isoflux, gamma = 1e-17)

#########################################
# Nonlinear solve

freegs.solve(eq,          # The equilibrium to adjust
             profiles,    # The toroidal current profile function
             constrain)   # Constraint function to set coil currents


            
# Currents in the coils
tokamak.printCurrents()

# Forces on the coils
eq.printForces()

############################
# Optimise
# Minimise the maximum force on the coils, while avoiding intersection of the LCFS and walls
# by modifying the radius of the P2U and P2L coils.
Example #3
0
import freegs
from freegs import geqdsk
from freegs.equilibrium import refine
from freegs.plotting import plotEquilibrium

# Reading MAST equilibrium, up-down symmetric coils
tokamak = freegs.machine.MAST()

#with open("g014220.00200") as f:
with open("mast.geqdsk") as f:
  eq = geqdsk.read(f, tokamak, show=True)

# Increase resolution by a factor of 2
eq2 = refine(eq)

# Re-solve, keeping the same control points and profiles
freegs.solve(eq2, eq._profiles, eq.control, rtol=1e-6)

# Save to G-EQDSK
with open("mast-highres.geqdsk", "w") as f:
  geqdsk.write(eq2, f)

plotEquilibrium(eq2)

Example #4
0
    1e3,  # Plasma pressure on axis [Pascals]
    2e5,  # Plasma current [Amps]
    2.0)  # Vacuum f=R*Bt

xpoints = [
    (1.1, -0.6),  # (R,Z) locations of X-points
    (1.1, 0.8)
]

isoflux = [(1.1, -0.6, 1.1, 0.6)]  # (R1,Z1, R2,Z2) pair of locations

constrain = freegs.control.constrain(xpoints=xpoints, isoflux=isoflux)

freegs.solve(
    eq,  # The equilibrium to adjust
    profiles,  # The toroidal current profile function
    constrain,
    rtol=rtol)

############################################
# Now have initial solution

resolutions = [eq.R.shape[0]]
psivals = [eq.psiRZ(*location)]
brvals = [eq.Br(*location)]
volumevals = [eq.plasmaVolume()]
coilcurrents = [eq.tokamak["P1L"].current]

# List of l2 and l∞ norms
l2vals = []
linfvals = []
Example #5
0
# Plasma equilibrium (Grad-Shafranov) solver
import freegs

# Boundary conditions
import freegs.boundary as boundary

profiles = freegs.jtor.ConstrainPaxisIp(
    1e4,  # Plasma pressure on axis [Pascals]
    1e6,  # Plasma current [Amps]
    1.0)  # fvac = R*Bt

eq = freegs.Equilibrium(Rmin=0.1,
                        Rmax=2.0,
                        Zmin=-1.0,
                        Zmax=1.0,
                        nx=65,
                        ny=65,
                        boundary=boundary.fixedBoundary)

# Nonlinear solver for Grad-Shafranov equation
freegs.solve(
    eq,  # The equilibrium to adjust
    profiles)  # The toroidal current profile function

print("Done!")

# Plot equilibrium
from freegs.plotting import plotEquilibrium

plotEquilibrium(eq)
Example #6
0
    #           ,(0.7,-1.1, 1.5,-1.9)  # Lower X-point, lower outer leg
    #           ,(0.7,1.1,  1.5, 1.9)  # Upper X-point, upper outer leg
]

constrain = freegs.control.constrain(xpoints=xpoints,
                                     gamma=1e-12,
                                     isoflux=isoflux)

constrain(eq)

#########################################
# Nonlinear solve

freegs.solve(
    eq,  # The equilibrium to adjust
    profiles,  # The plasma profiles
    constrain,  # Plasma control constraints
    show=True)  # Shows results at each nonlinear iteration

# eq now contains the solution

print("Done!")

print("Plasma current: %e Amps" % (eq.plasmaCurrent()))
print("Pressure on axis: %e Pascals" % (eq.pressure(0.0)))
print("Plasma poloidal beta: %e" % (eq.poloidalBeta()))
print("Plasma volume: %e m^3" % (eq.plasmaVolume()))

eq.tokamak.printCurrents()

##############################################
Example #7
0
boundaries = [("A", 0.1, 2.0, -1.0, 1.0), ("B", 0.5, 1.75, -0.8, 1.1)]

for n in resolutions:
    for bndry_name, Rmin, Rmax, Zmin, Zmax in boundaries:
        # Re-create objects so no state is retained between runs

        tokamak = freegs.machine.TestTokamak()

        eq = freegs.Equilibrium(
            tokamak=tokamak,
            Rmin=Rmin,
            Rmax=Rmax,  # Radial domain
            Zmin=Zmin,
            Zmax=Zmax,  # Height range
            nx=n,
            ny=n)  # Number of grid points

        freegs.solve(
            eq,  # The equilibrium to adjust
            profiles,  # The toroidal current profile function
            constrain,  # Constraint function to set coil currents
            rtol=1e-6,
            show=False)

        # Save solution for later analysis
        with open("test-02-" + bndry_name + "-" + str(n) + ".pkl", "wb") as f:
            pickle.dump(n, f)
            pickle.dump((bndry_name, Rmin, Rmax, Zmin, Zmax), f)
            pickle.dump(eq, f)