Esempio n. 1
0
    def test_get_dofs(self):
        """
        Test that we can convert the degrees of freedom into a 1D vector
        """

        # First try an axisymmetric surface for simplicity:
        s = SurfaceRZFourier()
        s.rc[0, 0] = 1.3
        s.rc[1, 0] = 0.4
        s.zs[0, 0] = 0.3
        s.zs[1, 0] = 0.2
        dofs = s.get_dofs()
        self.assertEqual(dofs.shape, (3, ))
        self.assertAlmostEqual(dofs[0], 1.3)
        self.assertAlmostEqual(dofs[1], 0.4)
        self.assertAlmostEqual(dofs[2], 0.2)

        # Now try a nonaxisymmetric shape:
        s = SurfaceRZFourier(mpol=3, ntor=1)
        s.rc[:, :] = [[100, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]]
        s.zs[:, :] = [[101, 102, 13], [14, 15, 16], [17, 18, 19], [20, 21, 22]]
        dofs = s.get_dofs()
        self.assertEqual(dofs.shape, (21, ))
        for j in range(21):
            self.assertAlmostEqual(dofs[j], j + 2)
Esempio n. 2
0
def get_surface(surfacetype, stellsym, phis=None, thetas=None):
    np.random.seed(2)
    mpol = 4
    ntor = 3
    nfp = 2
    phis = phis if phis is not None else np.linspace(0, 1, 31, endpoint=False)
    thetas = thetas if thetas is not None else np.linspace(
        0, 1, 31, endpoint=False)
    if surfacetype == "SurfaceRZFourier":
        from simsopt.geo.surfacerzfourier import SurfaceRZFourier
        s = SurfaceRZFourier(nfp=nfp,
                             stellsym=stellsym,
                             mpol=mpol,
                             ntor=ntor,
                             quadpoints_phi=phis,
                             quadpoints_theta=thetas)
        s.set_dofs(s.get_dofs() * 0.)
        s.rc[0, ntor + 0] = 1
        s.rc[1, ntor + 0] = 0.3
        s.zs[1, ntor + 0] = 0.3
    elif surfacetype == "SurfaceXYZFourier":
        from simsopt.geo.surfacexyzfourier import SurfaceXYZFourier
        s = SurfaceXYZFourier(nfp=nfp,
                              stellsym=stellsym,
                              mpol=mpol,
                              ntor=ntor,
                              quadpoints_phi=phis,
                              quadpoints_theta=thetas)
        s.set_dofs(s.get_dofs() * 0.)
        s.xc[0, ntor + 1] = 1.
        s.xc[1, ntor + 1] = 0.1
        s.ys[0, ntor + 1] = 1.
        s.ys[1, ntor + 1] = 0.1
        s.zs[1, ntor] = 0.1
    elif surfacetype == "SurfaceXYZTensorFourier":
        from simsopt.geo.surfacexyztensorfourier import SurfaceXYZTensorFourier
        s = SurfaceXYZTensorFourier(nfp=nfp,
                                    stellsym=stellsym,
                                    mpol=mpol,
                                    ntor=ntor,
                                    quadpoints_phi=phis,
                                    quadpoints_theta=thetas)
        s.set_dofs(s.get_dofs() * 0.)
        s.x[0, 0] = 1.0
        s.x[1, 0] = 0.1
        s.z[mpol + 1, 0] = 0.1
    else:
        assert False

    dofs = np.asarray(s.get_dofs())
    np.random.seed(2)
    rand_scale = 0.01
    s.set_dofs(dofs +
               rand_scale * np.random.rand(len(dofs)).reshape(dofs.shape))
    return s
Esempio n. 3
0
    def test_surface_sampling(self):
        np.random.seed(1)
        nquadpoints = int(4e2)
        surface = SurfaceRZFourier(nfp=1, stellsym=True, mpol=1, ntor=0, quadpoints_phi=nquadpoints, quadpoints_theta=nquadpoints)
        dofs = surface.get_dofs()
        dofs[0] = 1
        dofs[1] = 0.8
        surface.set_dofs(dofs)
        n = np.linalg.norm(surface.normal(), axis=2)
        print(np.min(n), np.max(n))

        start = int(0.2*nquadpoints)
        stop = int(0.5*nquadpoints)

        from scipy.integrate import simpson
        quadpoints_phi = surface.quadpoints_phi
        quadpoints_theta = surface.quadpoints_theta
        lineintegrals = [simpson(y=n[i, start:stop], x=quadpoints_theta[start:stop]) for i in range(start, stop)]
        area_of_subset = simpson(y=lineintegrals, x=quadpoints_phi[start:stop])
        total_area = surface.area()
        print("area_of_subset/total_area", area_of_subset/total_area)

        nsamples = int(1e6)
        xyz, idxs = draw_uniform_on_surface(surface, nsamples, safetyfactor=10)
        samples_in_range = np.sum((idxs[0] >= start) * (idxs[0] < stop)*(idxs[1] >= start) * (idxs[1] < stop))
        print("samples_in_range/nsamples", samples_in_range/nsamples)
        print("fraction of samples if uniform", (stop-start)**2/(nquadpoints**2))
        assert abs(samples_in_range/nsamples - area_of_subset/total_area) < 1e-2
Esempio n. 4
0
    def test_change_resolution(self):
        """
        Check that we can change mpol and ntor.
        """
        for mpol in [1, 2]:
            for ntor in [0, 1]:
                s = SurfaceRZFourier(mpol=mpol, ntor=ntor)
                n = len(s.get_dofs())
                s.set_dofs((np.random.rand(n) - 0.5) * 0.01)
                s.set_rc(0, 0, 1.0)
                s.set_rc(1, 0, 0.1)
                s.set_zs(1, 0, 0.13)
                v1 = s.volume()
                a1 = s.area()

                s.change_resolution(mpol + 1, ntor)
                s.recalculate = True
                v2 = s.volume()
                a2 = s.area()
                self.assertAlmostEqual(v1, v2)
                self.assertAlmostEqual(a1, a2)

                s.change_resolution(mpol, ntor + 1)
                s.recalculate = True
                v2 = s.volume()
                a2 = s.area()
                self.assertAlmostEqual(v1, v2)
                self.assertAlmostEqual(a1, a2)

                s.change_resolution(mpol + 1, ntor + 1)
                s.recalculate = True
                v2 = s.volume()
                a2 = s.area()
                self.assertAlmostEqual(v1, v2)
                self.assertAlmostEqual(a1, a2)
Esempio n. 5
0
 def test_convert_back(self):
     """
     If we start with a SurfaceRZFourier, convert to Garabedian, and
     convert back to SurfaceFourier, we should get back what we
     started with.
     """
     for mpol in range(1, 4):
         for ntor in range(5):
             for nfp in range(1, 4):
                 sf1 = SurfaceRZFourier(nfp=nfp, mpol=mpol, ntor=ntor)
                 # Set all dofs to random numbers in [-2, 2]:
                 sf1.set_dofs(
                     (np.random.rand(len(sf1.get_dofs())) - 0.5) * 4)
                 sg = sf1.to_Garabedian()
                 sf2 = sg.to_RZFourier()
                 np.testing.assert_allclose(sf1.rc, sf2.rc)
                 np.testing.assert_allclose(sf1.zs, sf2.zs)
Esempio n. 6
0
    def test_derivatives(self):
        """
        Check the automatic differentiation for area and volume.
        """
        for mpol in range(1, 3):
            for ntor in range(2):
                for nfp in range(1, 4):
                    s = SurfaceRZFourier(nfp=nfp, mpol=mpol, ntor=ntor)
                    x0 = s.get_dofs()
                    x = np.random.rand(len(x0)) - 0.5
                    x[0] = np.random.rand() + 2
                    # This surface will probably self-intersect, but I
                    # don't think this actually matters here.
                    s.set_dofs(x)

                    dofs = Dofs([s.area, s.volume])
                    jac = dofs.jac()
                    fd_jac = dofs.fd_jac()
                    print('difference for surface test_derivatives:',
                          jac - fd_jac)
                    np.testing.assert_allclose(jac,
                                               fd_jac,
                                               rtol=1e-4,
                                               atol=1e-4)