def test_toroidal_flux_is_constant(self): """ this test ensures that the toroidal flux does not change, regardless of the cross section (varphi = constant) across which it is computed """ s = get_exact_surface() coils, currents, ma = get_ncsx_data() stellarator = CoilCollection(coils, currents, 3, True) bs_tf = BiotSavart(stellarator.coils, stellarator.currents) gamma = s.gamma() num_phi = gamma.shape[0] tf_list = np.zeros((num_phi, )) for idx in range(num_phi): tf = ToroidalFlux(s, bs_tf, idx=idx) tf_list[idx] = tf.J() mean_tf = np.mean(tf_list) max_err = np.max(np.abs(mean_tf - tf_list)) / mean_tf assert max_err < 1e-2
s.fit_to_curve(ma, 0.10, flip_theta=True) iota = -0.4 tf = ToroidalFlux(s, bs_tf) ar = Area(s) ar_target = ar.J() boozer_surface = BoozerSurface(bs, s, ar, ar_target) # compute surface first using LBFGS, this will just be a rough initial guess res = boozer_surface.minimize_boozer_penalty_constraints_LBFGS(tol=1e-10, maxiter=300, constraint_weight=100., iota=iota, G=G0) print(f"After LBFGS: iota={res['iota']:.3f}, tf={tf.J():.3f}, area={s.area():.3f}, ||residual||={np.linalg.norm(boozer_surface_residual(s, res['iota'], res['G'], bs, derivatives=0)):.3e}") if "DISPLAY" in os.environ: s.plot() # now drive the residual down using a specialised least squares algorithm res = boozer_surface.minimize_boozer_penalty_constraints_ls(tol=1e-10, maxiter=100, constraint_weight=100., iota=res['iota'], G=res['G'], method='manual') print(f"After Lev-Mar: iota={res['iota']:.3f}, tf={tf.J():.3f}, area={s.area():.3f}, ||residual||={np.linalg.norm(boozer_surface_residual(s, res['iota'], res['G'], bs, derivatives=0)):.3e}") if "DISPLAY" in os.environ: s.plot() # change the label of the surface to toroidal flux and aim for a surface with triple the flux print('Now aim for a larger surface') tf_target = 3 * tf.J() boozer_surface = BoozerSurface(bs, s, tf, tf_target) res = boozer_surface.minimize_boozer_penalty_constraints_ls(tol=1e-10, maxiter=100, constraint_weight=100., iota=res['iota'], G=res['G'], method='manual') print(f"After Lev-Mar: iota={res['iota']:.3f}, tf={tf.J():.3f}, area={s.area():.3f}, ||residual||={np.linalg.norm(boozer_surface_residual(s, res['iota'], res['G'], bs, derivatives=0)):.3e}") if "DISPLAY" in os.environ: s.plot()
res = qfm_surface.minimize_qfm_penalty_constraints_LBFGS( tol=1e-12, maxiter=1000, constraint_weight=constraint_weight) print( f"||vol constraint||={0.5*(s.volume()-vol_target)**2:.8e}, ||residual||={np.linalg.norm(qfm.J()):.8e}" ) res = qfm_surface.minimize_qfm_exact_constraints_SLSQP(tol=1e-12, maxiter=1000) print( f"||vol constraint||={0.5*(s.volume()-vol_target)**2:.8e}, ||residual||={np.linalg.norm(qfm.J()):.8e}" ) # Now optimize at fixed toroidal flux tf = ToroidalFlux(s, bs_tf) tf_target = tf.J() qfm_surface = QfmSurface(bs, s, tf, tf_target) res = qfm_surface.minimize_qfm_penalty_constraints_LBFGS( tol=1e-12, maxiter=1000, constraint_weight=constraint_weight) print( f"||tf constraint||={0.5*(s.volume()-vol_target)**2:.8e}, ||residual||={np.linalg.norm(qfm.J()):.8e}" ) res = qfm_surface.minimize_qfm_exact_constraints_SLSQP(tol=1e-12, maxiter=1000) print( f"||tf constraint||={0.5*(tf.J()-tf_target)**2:.8e}, ||residual||={np.linalg.norm(qfm.J()):.8e}" ) # Check that volume is not changed