예제 #1
0
    def test_run(self):
        """
        Try running SPEC and reading in the output.
        """
        filename = os.path.join(TEST_DIR, '1DOF_Garabedian.sp')

        for new_mpol in [2, 3]:
            for new_ntor in [2, 3]:
                s = Spec(filename)
                print('new_mpol: {}, new_ntor: {}'.format(new_mpol, new_ntor))
                s.inputlist.mpol = new_mpol
                s.inputlist.ntor = new_ntor
                s.run()

                self.assertAlmostEqual(s.volume(), 0.001973920880217874, places=4)

                self.assertAlmostEqual(s.results.output.helicity, 0.435225, places=3)

                self.assertAlmostEqual(s.iota(), 0.544176, places=3)
예제 #2
0
    def test_integrated_stellopt_scenarios_1dof(self):
        """
        This script implements the "1DOF_circularCrossSection_varyR0_targetVolume"
        example from
        https://github.com/landreman/stellopt_scenarios

        This optimization problem has one independent variable, representing
        the mean major radius. The problem also has one objective: the plasma
        volume. There is not actually any need to run an equilibrium code like
        SPEC since the objective function can be computed directly from the
        boundary shape. But this problem is a fast way to test the
        optimization infrastructure with SPEC.

        Details of the optimum and a plot of the objective function landscape
        can be found here:
        https://github.com/landreman/stellopt_scenarios/tree/master/1DOF_circularCrossSection_varyR0_targetVolume
        """
        for grad in [True, False]:
            # Start with a default surface.
            equil = Spec()
            surf = equil.boundary

            # Set the initial boundary shape. Here is one way to do it:
            surf.set('rc(0,0)', 1.0)
            # Here is another syntax that works:
            surf.set_rc(0, 1, 0.1)
            surf.set_zs(0, 1, 0.1)

            surf.set_rc(1, 0, 0.1)
            surf.set_zs(1, 0, 0.1)

            surf.set_rc(1, 1, 0)
            surf.set_zs(1, 1, 0)

            # SPEC parameters are all fixed by default, while surface
            # parameters are all non-fixed by default. You can choose
            # which parameters are optimized by setting their 'fixed'
            # attributes.
            surf.all_fixed()
            surf.set_fixed('rc(0,0)', False)

            # Turn off Poincare plots and use low resolution, for speed:
            equil.inputlist.nptrj[0] = 0
            equil.inputlist.lrad[0] = 2

            # Each Target is then equipped with a shift and weight, to become a
            # term in a least-squares objective function
            desired_volume = 0.15
            term1 = (equil.volume, desired_volume, 1)

            # A list of terms are combined to form a nonlinear-least-squares
            # problem.
            prob = LeastSquaresProblem([term1])

            # Check that the problem was set up correctly:
            self.assertEqual(len(prob.dofs.names), 1)
            self.assertEqual(prob.dofs.names[0][:7], 'rc(0,0)')
            np.testing.assert_allclose(prob.x, [1.0])
            self.assertEqual(prob.dofs.all_owners, [equil, surf])
            self.assertEqual(prob.dofs.dof_owners, [surf])

            # Solve the minimization problem:
            least_squares_serial_solve(prob, grad=grad)

            self.assertAlmostEqual(surf.get_rc(0, 0), 0.7599088773175, places=5)
            self.assertAlmostEqual(equil.volume(), 0.15, places=6)
            self.assertAlmostEqual(surf.volume(), 0.15, places=6)
            self.assertLess(np.abs(prob.objective()), 1.0e-15)
예제 #3
0
    def test_integrated_stellopt_scenarios_2dof(self):
        """
        This script implements the "2DOF_vmecOnly_targetIotaAndVolume" example from
        https://github.com/landreman/stellopt_scenarios

        This optimization problem has two independent variables, representing
        the helical shape of the magnetic axis. The problem also has two
        objectives: the plasma volume and the rotational transform on the
        magnetic axis.

        The resolution in this example (i.e. ns, mpol, and ntor) is somewhat
        lower than in the stellopt_scenarios version of the example, just so
        this example runs fast.

        Details of the optimum and a plot of the objective function landscape
        can be found here:
        https://github.com/landreman/stellopt_scenarios/tree/master/2DOF_vmecOnly_targetIotaAndVolume
        """
        filename = os.path.join(TEST_DIR, '2DOF_targetIotaAndVolume.sp')

        # Initialize SPEC from an input file
        equil = Spec(filename)
        surf = equil.boundary

        # VMEC parameters are all fixed by default, while surface parameters are all non-fixed by default.
        # You can choose which parameters are optimized by setting their 'fixed' attributes.
        surf.all_fixed()
        surf.set_fixed('rc(1,1)', False)
        surf.set_fixed('zs(1,1)', False)

        # Each Target is then equipped with a shift and weight, to become a
        # term in a least-squares objective function.  A list of terms are
        # combined to form a nonlinear-least-squares problem.
        desired_volume = 0.15
        volume_weight = 1
        term1 = (equil.volume, desired_volume, volume_weight)

        desired_iota = -0.41
        iota_weight = 1
        term2 = (equil.iota, desired_iota, iota_weight)

        prob = LeastSquaresProblem([term1, term2])

        # Solve the minimization problem:
        least_squares_serial_solve(prob)

        # The tests here are based on values from the VMEC version in
        # https://github.com/landreman/stellopt_scenarios/tree/master/2DOF_vmecOnly_targetIotaAndVolume
        # Due to this and the fact that we don't yet have iota on axis from SPEC, the tolerances are wide.
        """
        assert np.abs(surf.get_rc(1, 1) - 0.0313066948) < 0.001
        assert np.abs(surf.get_zs(1, 1) - (-0.031232391)) < 0.001
        assert np.abs(equil.volume() - 0.178091) < 0.001
        assert np.abs(surf.volume()  - 0.178091) < 0.001
        assert np.abs(equil.iota() - (-0.4114567)) < 0.001
        assert (prob.objective() - 7.912501330E-04) < 0.2e-4
        """
        self.assertAlmostEqual(surf.get_rc(1, 1), 0.0313066948, places=3)
        self.assertAlmostEqual(surf.get_zs(1, 1), -0.031232391, places=3)
        self.assertAlmostEqual(equil.volume(), 0.178091, places=3)
        self.assertAlmostEqual(surf.volume(), 0.178091, places=3)
        self.assertAlmostEqual(equil.iota(), -0.4114567, places=3)
        self.assertAlmostEqual(prob.objective(), 7.912501330E-04, places=3)