Exemplo n.º 1
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
Exemplo n.º 2
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)
Exemplo n.º 3
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)
Exemplo n.º 4
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
Exemplo n.º 5
0
    def test_set_dofs(self):
        """
        Test that we can set the shape from a 1D vector
        """

        # First try an axisymmetric surface for simplicity:
        s = SurfaceRZFourier()
        s.set_dofs([2.9, -1.1, 0.7])
        self.assertAlmostEqual(s.rc[0, 0], 2.9)
        self.assertAlmostEqual(s.rc[1, 0], -1.1)
        self.assertAlmostEqual(s.zs[1, 0], 0.7)

        # Now try a nonaxisymmetric shape:
        s = SurfaceRZFourier(mpol=3, ntor=1)
        s.set_dofs(np.array(list(range(21))) + 1)
        self.assertAlmostEqual(s.rc[0, 0], 0)
        self.assertAlmostEqual(s.rc[0, 1], 1)
        self.assertAlmostEqual(s.rc[0, 2], 2)
        self.assertAlmostEqual(s.rc[1, 0], 3)
        self.assertAlmostEqual(s.rc[1, 1], 4)
        self.assertAlmostEqual(s.rc[1, 2], 5)
        self.assertAlmostEqual(s.rc[2, 0], 6)
        self.assertAlmostEqual(s.rc[2, 1], 7)
        self.assertAlmostEqual(s.rc[2, 2], 8)
        self.assertAlmostEqual(s.rc[3, 0], 9)
        self.assertAlmostEqual(s.rc[3, 1], 10)
        self.assertAlmostEqual(s.rc[3, 2], 11)

        self.assertAlmostEqual(s.zs[0, 0], 0)
        self.assertAlmostEqual(s.zs[0, 1], 0)
        self.assertAlmostEqual(s.zs[0, 2], 12)
        self.assertAlmostEqual(s.zs[1, 0], 13)
        self.assertAlmostEqual(s.zs[1, 1], 14)
        self.assertAlmostEqual(s.zs[1, 2], 15)
        self.assertAlmostEqual(s.zs[2, 0], 16)
        self.assertAlmostEqual(s.zs[2, 1], 17)
        self.assertAlmostEqual(s.zs[2, 2], 18)
        self.assertAlmostEqual(s.zs[3, 0], 19)
        self.assertAlmostEqual(s.zs[3, 1], 20)
        self.assertAlmostEqual(s.zs[3, 2], 21)
Exemplo 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)