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)
def test_2dof_surface_opt(self): """ Optimize the minor radius and elongation of an axisymmetric torus to obtain a desired volume and area. """ for solver in solvers: desired_volume = 0.6 desired_area = 8.0 # Start with a default surface, which is axisymmetric with major # radius 1 and minor radius 0.1. surf = SurfaceRZFourier(quadpoints_phi=62, quadpoints_theta=63) # Set initial surface shape. It helps to make zs(1,0) larger # than rc(1,0) since there are two solutions to this # optimization problem, and for testing we want to find one # rather than the other. surf.set_zs(1, 0, 0.2) # Parameters are all non-fixed by default, meaning they will be # optimized. You can choose to exclude any subset of the variables # from the space of independent variables by setting their 'fixed' # property to True. surf.set_fixed('rc(0,0)') # Each function you want in the objective function 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. prob = LeastSquaresProblem([(surf.volume, desired_volume, 1), (surf.area, desired_area, 1)]) # Verify the state vector and names are what we expect np.testing.assert_allclose(prob.x, [0.1, 0.2]) self.assertEqual(prob.dofs.names[0][:28], 'rc(1,0) of SurfaceRZFourier ') self.assertEqual(prob.dofs.names[1][:28], 'zs(1,0) of SurfaceRZFourier ') # Solve the minimization problem: solver(prob) # Check results self.assertAlmostEqual(surf.get_rc(0, 0), 1.0, places=13) self.assertAlmostEqual(surf.get_rc(1, 0), 0.10962565115956417, places=13) self.assertAlmostEqual(surf.get_zs(0, 0), 0.0, places=13) self.assertAlmostEqual(surf.get_zs(1, 0), 0.27727411213693337, places=13) self.assertAlmostEqual(surf.volume(), desired_volume, places=8) self.assertAlmostEqual(surf.area(), desired_area, places=8) self.assertLess(np.abs(prob.objective()), 1.0e-15)
def test_area_volume(self): """ Test the calculation of area and volume for an axisymmetric surface """ s = SurfaceRZFourier() s.rc[0, 0] = 1.3 s.rc[1, 0] = 0.4 s.zs[1, 0] = 0.2 true_area = 15.827322032265993 true_volume = 2.0528777154265874 self.assertAlmostEqual(s.area(), true_area, places=4) self.assertAlmostEqual(s.volume(), true_volume, places=3)
desired_area = 8.0 # Start with a default surface, which is axisymmetric with major # radius 1 and minor radius 0.1. surf = SurfaceRZFourier() # Parameters are all non-fixed by default, meaning they will be # optimized. You can choose to exclude any subset of the variables # from the space of independent variables by setting their 'fixed' # property to True. surf.set_fixed('rc(0,0)') # Each target function is then equipped with a shift and weight, to # become a term in a least-squares objective function term1 = (surf.volume, desired_volume, 1) term2 = (surf.area, desired_area, 1) # A list of terms are combined to form a nonlinear-least-squares # problem. prob = LeastSquaresProblem([term1, term2]) # Solve the minimization problem: least_squares_serial_solve(prob) print("At the optimum,") print(" rc(m=1,n=0) = ", surf.get_rc(1, 0)) print(" zs(m=1,n=0) = ", surf.get_zs(1, 0)) print(" volume = ", surf.volume()) print(" area = ", surf.area()) print(" objective function = ", prob.objective())