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())
# 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.
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)
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 = []
# 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)
# ,(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() ##############################################
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)