def part_fill(self, trim=None, dt=0, ref_o=4 / 8 * np.pi, dref=np.pi / 4, edge=True, ends=True, color='k', label=None, alpha=0.8, referance='theta', loop=False, s=0, plot=False): Rin, Zin = self.R, self.Z if loop: Napp = 5 # Nappend R = np.append(self.R, self.R[:Napp]) R = np.append(self.R[-Napp:], R) Z = np.append(self.Z, self.Z[:Napp]) Z = np.append(self.Z[-Napp:], Z) R, Z = geom.rzSLine(R, Z, npoints=len(R), s=s) if isinstance(dt, (np.ndarray, list)): dt = np.append(dt, dt[:Napp]) dt = np.append(dt[-Napp:], dt) Rout, Zout = geom.offset(R, Z, dt) print('part fill') Rout, Zout = Rout[Napp:-Napp], Zout[Napp:-Napp] Rout[-1], Zout[-1] = Rout[0], Zout[0] else: R, Z = geom.rzSLine(self.R, self.Z, npoints=len(self.R), s=s) Rout, Zout = geom.offset(R, Z, dt) self.R, self.Z = Rout, Zout # update if trim is None: Lindex = [0, len(Rin)] else: Lindex = self.trim(trim) if plot: flag = 0 for i in np.arange(Lindex[0], Lindex[1] - 1): Rfill = np.array([Rin[i], Rout[i], Rout[i + 1], Rin[i + 1]]) Zfill = np.array([Zin[i], Zout[i], Zout[i + 1], Zin[i + 1]]) if flag is 0 and label is not None: flag = 1 pl.fill(Rfill, Zfill, facecolor=color, alpha=alpha, edgecolor='none', label=label) else: pl.fill(Rfill, Zfill, facecolor=color, alpha=alpha, edgecolor='none')
def add_vessel(self,vessel,npoint=80,offset=[0.12,0.2]): rvv,zvv = geom.rzSLine(vessel['r'],vessel['z'],npoint) rvv,zvv = geom.offset(rvv,zvv,offset[1]) rmin = np.min(rvv) rvv[rvv<=rmin+offset[0]] = rmin+offset[0] self.add_bound({'r':rvv,'z':zvv},'internal') # vessel self.add_bound({'r':np.min(rvv)-5e-3,'z':0},'interior') # vessel
def loop_interpolators(self, trim=[0, 1], offset=0.75, full=False): # outer loop coordinate interpolators r, z = self.x['cl']['r'], self.x['cl']['z'] self.fun = {'in': {}, 'out': {}} for side, sign in zip(['in', 'out', 'cl'], [-1, 1, 1]): # inner/outer loop offset r, z = self.x[side]['r'], self.x[side]['z'] index = self.transition_index(r, z) r = r[index['lower'] + 1:index['upper']] z = z[index['lower'] + 1:index['upper']] r, z = geom.offset(r, z, sign * offset) if full: # full loop (including nose) rmid, zmid = np.mean([r[0], r[-1]]), np.mean([z[0], z[-1]]) r = np.append(rmid, r) r = np.append(r, rmid) z = np.append(zmid, z) z = np.append(z, zmid) l = geom.length(r, z) lt = np.linspace(trim[0], trim[1], int(np.diff(trim) * len(l))) r, z = interp1d(l, r)(lt), interp1d(l, z)(lt) l = np.linspace(0, 1, len(r)) self.fun[side] = {'r': IUS(l, r), 'z': IUS(l, z)} self.fun[side]['L'] = geom.length(r, z, norm=False)[-1] self.fun[side]['dr'] = self.fun[side]['r'].derivative() self.fun[side]['dz'] = self.fun[side]['z'].derivative()
def plot_loops(self, scale=1.5, sticks=False): self.loop_ripple() ripple = self.get_ripple() #pl.plot(self.res['x'],self.res['fun'],'o',color=0.8*np.ones(3)) rpl, zpl = self.plasma_loop[:, 0], self.plasma_loop[:, 2] rr, zr = geom.offset(rpl, zpl, scale * self.ripple) color = sns.color_palette('Set2', 2) if sticks: # ripple sticks for i in range(self.nplasma): pl.plot([rpl[i], rr[i]], [zpl[i], zr[i]], color=color[0], lw=3) pl.plot(self.plasma_loop[:, 0], self.plasma_loop[:, 2], '-') #pl.plot(self.coil_loop[:,0],self.coil_loop[:,2]) x_max = np.array([ self.plasma_interp['r'](self.res['x']), self.plasma_interp['z'](self.res['x']) ]) dx = 1.5 for x in [x_max, self.LFP]: ripple = self.point([x[0], 0, x[1]], variable='ripple') pl.plot(x[0], x[1], 'o', ms=8, color=0.5 * np.ones(3), zorder=10) pl.plot([x[0] + 0.1 * dx, x[0] + 0.9 * dx], x[1] * np.ones(2), '-', lw=1, color=0.5 * np.ones(3)) pl.text(x[0] + dx, x[1], ' {:1.2f}%'.format(ripple), ha='left', va='center', color=0.5 * np.ones(3)) pl.axis('equal') pl.axis('off')
def fill(self, trim=None, dR=0, dt=0, ref_o=4 / 8 * np.pi, dref=np.pi / 4, edge=True, ends=True, color='k', label=None, alpha=0.8, referance='theta', part_fill=True, loop=False, s=0, gap=0, plot=False): dt_max = 0.1 # 2.5 if not part_fill: dt_max = dt if isinstance(dt, list): dt = self.blend(dt, ref_o=ref_o, dref=dref, referance=referance, gap=gap) dt, nt = geom.max_steps(dt, dt_max) Rin, Zin = geom.offset(self.R, self.Z, dR) # gap offset for i in range(nt): self.part_fill(trim=trim, dt=dt, ref_o=ref_o, dref=dref, edge=edge, ends=ends, color=color, label=label, alpha=alpha, referance=referance, loop=loop, s=s, plot=False) Rout, Zout = self.R, self.Z if plot: geom.polyparrot({ 'r': Rin, 'z': Zin }, { 'r': Rout, 'z': Zout }, color=color, alpha=1) # fill return Rout, Zout
def vessel_fill(self, gap=True): r, z = self.segment['blanket_fw']['r'], self.segment['blanket_fw']['z'] loop = Loop(r, z) r, z = loop.fill(dt=0.05) rb = np.append(r, r[0]) zb = np.append(z, z[0]) profile = Profile(self.setup.configuration, family='S', part='vv', npoints=400, read_write=False) shp = Shape(profile, objective='L') shp.loop.adjust_xo('upper', lb=0.6) shp.loop.adjust_xo('lower', lb=0.6) shp.loop.adjust_xo('l', lb=0.6) #shp.loop.remove_oppvar('flat') r, z = geom.rzSLine(rb, zb, 200) # sub-sample rup, zup = r[z > self.sf.Xpoint[1]], z[z > self.sf.Xpoint[1]] shp.add_bound({'r': rup, 'z': zup}, 'internal') # vessel inner bounds rd, zd = r[z < self.sf.Xpoint[1]], z[z < self.sf.Xpoint[1]] ro, zo = geom.offset(rd, zd, 0.1) # divertor offset shp.add_bound({'r': rd, 'z': zd}, 'internal') # vessel inner bounds shp.add_bound({ 'r': rd, 'z': zd - 0.25 }, 'internal') # gap below divertor #shp.plot_bounds() shp.minimise() #shp.loop.plot() x = profile.loop.draw() rin, zin = x['r'], x['z'] loop = Loop(rin, zin) r, z = loop.fill(dt=self.setup.build['VV'], ref_o=2 / 8 * np.pi, dref=np.pi / 6) shp.clear_bound() shp.add_bound({'r': r, 'z': z}, 'internal') # vessel outer bounds shp.minimise() x = profile.loop.draw() r, z = x['r'], x['z'] if 'SX' in self.setup.configuration or gap == True: vv = wrap({'r': rin, 'z': zin}, {'r': r, 'z': z}) else: vv = wrap({'r': rb, 'z': zb}, {'r': r, 'z': z}) vv.sort_z('inner', select=self.sf.Xloc) vv.sort_z('outer', select=self.sf.Xloc) self.segment['vessel_inner'] = {'r': rin, 'z': zin} self.segment['vessel_outer'] = {'r': r, 'z': z} self.segment['vessel'] = vv.fill()[1] return vv
def plot_loops(self, scale=1.5): self.get_ripple() pl.plot(self.res['x'], self.res['fun'], 'o', color=0.8 * np.ones(3)) rpl, zpl = self.plasma_loop[:, 0], self.plasma_loop[:, 2] rr, zr = geom.offset(rpl, zpl, scale * self.ripple) for i in range(self.nplasma): # ripple sticks pl.plot([rpl[i], rr[i]], [zpl[i], zr[i]], lw=1, color=0.5 * np.ones(3)) pl.plot(self.plasma_loop[:, 0], self.plasma_loop[:, 2], '-') pl.plot(self.coil_loop[:, 0], self.coil_loop[:, 2]) x = self.res['x'] pl.plot(self.plasma_interp['r'](x), self.plasma_interp['z'](x), '.', ms=10) pl.axis('equal') pl.axis('off')
def get_loops(self, x): r, z = x['r'], x['z'] wp = self.section['winding_pack'] case = self.section['case'] inboard_dt = [ case['inboard'], wp['width'] / 2, wp['width'] / 2, case['nose'] ] outboard_dt = [ case['outboard'], wp['width'] / 2, wp['width'] / 2, case['external'] ] loops = ['wp_in', 'cl', 'wp_out', 'out'] self.x['in']['r'], self.x['in']['z'] = r, z index = self.transition_index(self.x['in']['r'], self.x['in']['z']) for loop, dt_in, dt_out in zip(loops, inboard_dt, outboard_dt): dt = self.loop_dt(r, z, dt_in, dt_out, index) r, z = geom.offset(r, z, dt, close_loop=True) self.x[loop]['r'], self.x[loop]['z'] = r, z return self.x
def plot_ripple_contours(self, n=3e3, offset=-1): xlim, dx = np.zeros((3, 2)), np.zeros(3) xl = np.zeros((len(self.coil_loop), 3)) xl[:, 0], xl[:, 2] = geom.offset(self.coil_loop[:, 0], self.coil_loop[:, 2], offset) for i in range(3): xlim[i] = [np.min(xl[:, i]), np.max(xl[:, i])] dx[i] = xlim[i][1] - xlim[i][0] xlim[0][0] = self.plasma_loop[np.argmax(self.plasma_loop[:, 2]), 0] # plasma top ar = dx[0] / dx[2] nz = int(np.sqrt(n / ar)) nr = int(n / nz) r = np.linspace(xlim[0][0], xlim[0][1], nr) z = np.linspace(xlim[2][0], xlim[2][1], nz) R, Z = np.meshgrid(r, z, indexing='ij') rpl = np.zeros((nr, nz)) for i, r_ in enumerate(r): for j, z_ in enumerate(z): if geom.inloop(xl[:, 0], xl[:, 2], r_, z_): rpl[i, j] = self.point((r_, 0, z_), variable='ripple') else: rpl[i, j] = np.NaN levels = 10**(np.linspace(np.log10(0.01), np.log10(5), 7)) levels = np.round(levels, decimals=2) geom.polyfill(self.plasma_loop[:, 0], self.plasma_loop[:, 2], alpha=0.3, color=sns.color_palette('Set2', 5)[3]) self.get_ripple() # get max ripple on plasma contour rpl_max = self.res['fun'] iplasma = np.argmin(abs(np.log10(levels) - np.log10(rpl_max))) levels[iplasma] = rpl_max # select edge contour CS = pl.contour(R, Z, rpl, levels=levels, colors=[0.6 * np.ones(3)]) zc = CS.collections[iplasma] pl.setp(zc, color=[0.4 * np.ones(3)]) pl.clabel(CS, inline=1, fontsize='xx-small', fmt='%1.2f')
config = {'TF': 'NTP'} #setup = Setup(config) #sf = SF(setup.filename) #sf.get_boundary(plot=True) profile = Profile(config['TF'], family='S', part='TF') shp = Shape(profile, obj='L', nTF=18, sep={ 'r': sep['x'], 'z': sep['y'] }) # ,eqconf=config['eq'] #shp.cage.pattern(plot=True) rvv, zvv = geom.rzSLine(vv['x'], vv['y'], 60) rvv, zvv = geom.offset(rvv, zvv, 0.2) rmin = np.min(rvv) rvv[rvv <= rmin + 0.12] = rmin + 0.12 shp.add_bound({'r': rvv, 'z': zvv}, 'internal') # vessel #shp.plot_bounds() shp.minimise(ripple=True, ripple_limit=0.6) shp.update() shp.tf.fill() shp.cage.plot_contours(variable='ripple', n=2e3, loop={ 'r': vv['x'], 'z': vv['y'] })
demo.plot_ports() demo.plot_limiter() sf.contour(Nlevel=51,plot_vac=False,lw=0.5) pl.plot(sf.rbdry,sf.zbdry,color=0.75*np.ones(3),lw=1) r,z = demo.parts['Plasma']['out']['r'],demo.parts['Plasma']['out']['z'] rb.Rb,rb.Zb = geom.rzInterp(r,z) rb.trim_sol() tf.fill(alpha=0.8) #cage.plot_contours() pl.axis('equal') pl.axis('off') #pl.savefig('../../Figs/TF_ripple_{:d}.pdf'.format(nTF)) ro = np.max(demo.parts['TF_Coil']['in']['r']) r1 = np.max(demo.parts['TF_Coil']['out']['r']) offset = (r1-ro)/2 rcl,zcl = geom.offset(demo.parts['TF_Coil']['in']['r'], demo.parts['TF_Coil']['in']['z'],offset) print('shape',cage.energy()*1e-9) cage = coil_cage(nTF=nTF,rc=tf.rc,plasma={'config':config['eq']},coil={'r':rcl,'z':zcl}) print('baseline',cage.energy()*1e-9)
def get_offset(self, dr, Nsub=0): rpl, zpl = self.get_boundary() # boundary points rpl, zpl = geom.offset(rpl, zpl, dr) # offset from sep if Nsub > 0: # sub-sample rpl, zpl = geom.rzSLine(rpl, zpl, Nsub) return rpl, zpl
#sf.contour(plot_vac=True) #sf.get_legs(debug=True) rb.set_firstwall(sf.eqdsk['xlim'], sf.eqdsk['ylim']) pl.plot(rb.Rb, rb.Zb) sf.sol(dr=3e-3) rb.get_sol(plot=True) pl.plot(sf.eqdsk['xlim'], sf.eqdsk['ylim']) r = demo.parts['Vessel']['r'] # set vessel boundary z = demo.parts['Vessel']['z'] r, z = geom.offset(r, z, 0.2) # 200mm offset from vessel r, z = geom.rzSLine(r, z, npoints=20) rb.loop = geom.Loop(r, z) #sf.sol(plot=True) ''' nTF = 18 tf = TF(shape={'vessel':rb.loop,'pf':pf,'sf':sf,'fit':True, 'setup':setup,'coil_type':'S','config':config},nTF=nTF) #tf = TF(shape={'coil_type':'S','config':config,'sf':sf}) tf.coil.plot() tf.fill(text=True) tf.plot_oppvar()