def trim(self, Rloop, Zloop, R, Z): Rloop, Zloop = geom.order(Rloop, Zloop) L = geom.length(R, Z) index = np.append(np.diff(L) != 0, True) R, Z = R[index], Z[index] # remove duplicates nRloop, nZloop, Rloop, Zloop = geom.normal(Rloop, Zloop) Rin, Zin = np.array([]), np.array([]) for r, z in zip(R, Z): i = np.argmin((r - Rloop)**2 + (z - Zloop)**2) dr = [Rloop[i] - r, Zloop[i] - z] dn = [nRloop[i], nZloop[i]] if np.dot(dr, dn) > 0: Rin, Zin = np.append(Rin, r), np.append(Zin, z) i = np.argmin((Rin[-1] - R)**2 + (Zin[-1] - Z)**2) Rin, Zin = R[:i + 2], Z[:i + 2] # extend past target i = np.argmin( (Rin[-1] - R)**2 + (Zin[-1] - Z)**2) # sol crossing bndry jo = np.argmin((R[i] - Rloop)**2 + (Z[i] - Zloop)**2) j = np.array([jo, jo + 1]) s = np.array([R[i], Z[i]]) ds = np.array([R[i] - R[i - 1], Z[i] - Z[i - 1]]) b = np.array([Rloop[j[0]], Zloop[j[0]]]) bstep, db = self.get_bstep(s, ds, b, Rloop, Zloop, j) if bstep < 0: j = np.array([jo - 1, jo]) # switch target pannel bstep, db = self.get_bstep(s, ds, b, Rloop, Zloop, j) step = np.cross(b - s, db) / np.cross(ds, db) intersect = s + step * ds # predict - correct if step < 0: # step back Rin, Zin = Rin[:-1], Zin[:-1] Rin, Zin = np.append(Rin, intersect[0]), np.append(Zin, intersect[1]) return Rin, Zin, db
def sort_z(self, loop, select='lower'): r, z = self.get_segment(loop) r, z = geom.order(r, z, anti=True) # order points if select == 'lower': imin = np.argmin(z) # locate minimum r = np.append(r[imin:], r[:imin]) # sort z = np.append(z[imin:], z[:imin]) else: imax = np.argmax(z) # locate minimum r = np.append(r[imax:], r[:imax]) # sort z = np.append(z[imax:], z[:imax]) self.set_segment(loop, r, z)
def add_bound(self, sf): rpl, zpl = sf.get_offset(self.config['dr'], Nsub=self.config['Nsub']) self.shp.add_bound({ 'r': rpl, 'z': zpl }, 'internal') # vessel inner bounds Xpoint = sf.Xpoint_array[:, 0] # select lower self.shp.add_bound( { 'r': Xpoint[0] + 0.12 * sf.shape['a'], 'z': Xpoint[1] }, 'internal') self.shp.add_bound( { 'r': Xpoint[0], 'z': Xpoint[1] - 0.01 * sf.shape['a'] }, 'internal') if self.config['flux_fit']: # add flux boundary points sf.get_LFP() # get low feild point rflux, zflux = sf.first_wall_psi(psi_n=self.config['psi_n'], trim=False)[:2] rflux, zflux = sf.midplane_loop(rflux, zflux) rflux, zflux = geom.order(rflux, zflux) istop = next((i for i in range(len(zflux)) if zflux[i] < sf.LFPz), -1) rflux, zflux = rflux[:istop], zflux[:istop] dL = np.diff(geom.length(rflux, zflux)) if np.max(dL) > 3*np.median(dL) or \ np.argmax(zflux) == len(zflux)-1: wtxt = '\n\nOpen feild line detected\n' wtxt += 'disabling flux fit for ' wtxt += '{:1.1f}% psi_n \n'.format(1e2 * self.config['psi_n']) wtxt += 'configuration: ' + sf.filename + '\n' warn(wtxt) else: # add flux_fit bounds rflux, zflux = geom.rzSLine(rflux, zflux, int(self.config['Nsub'] / 2)) self.shp.add_bound({'r': rflux, 'z': zflux}, 'internal')
def blanket_thickness(self, Nt=100, plot=False): bl, loop = {}, {} # read blanket for side in ['in', 'out']: bl[side], c = {}, {} for x in ['r', 'z']: c[x] = self.parts['Blanket'][side][x] r, z = geom.order(c['r'], c['z'], anti=True) r, z, l = geom.unique(r, z) # remove repeats bl[side]['r'], bl[side]['z'] = r, z loop[side] = {'r': IUS(l, r), 'z': IUS(l, z)} # interpolator def thickness(L, Lo, loop, norm): r = loop['in']['r'](Lo) + L[0] * norm['nr'](Lo) z = loop['in']['z'](Lo) + L[0] * norm['nz'](Lo) err = (r-loop['out']['r'](L[1]))**2+\ (z-loop['out']['z'](L[1]))**2 return err r, z = geom.unique(bl['in']['r'], bl['in']['z'])[:2] # remove repeats nr, nz, r, z = geom.normal(r, z) l = geom.length(r, z) norm = {'nr': IUS(l, nr), 'nz': IUS(l, nz)} # interpolator dt, Lo = np.zeros(Nt), np.linspace(0, 1, Nt) for i, lo in enumerate(Lo): L = minimize(thickness, [0, lo], method='L-BFGS-B', bounds=([0, 5], [0, 1]), args=(lo, loop, norm)).x dt[i] = np.sqrt((loop['in']['r'](lo) - loop['out']['r'](L[1]))**2 + (loop['in']['z'](lo) - loop['out']['z'](L[1]))**2) dt[i] = L[0] dt = savgol_filter(dt, 7, 2) # filter if plot: pl.plot(Lo, dt) return [np.min(dt), np.max(dt)]
def draw(self, npoints=250): x = self.profile.loop.draw(npoints=npoints) r, z = x['r'], x['z'] r, z = geom.order(r, z, anti=True) return r, z