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
class main_chamber(object): def __init__(self, name, **kwargs): self.name = name self.set_filename(**kwargs) self.initalise_loop() def initalise_loop(self): self.profile = Profile(self.filename, family='S', part='chamber', npoints=200) self.shp = Shape(self.profile, objective='L') self.set_bounds() def set_bounds(self): self.shp.loop.adjust_xo('upper', lb=0.7) self.shp.loop.adjust_xo('top', lb=0.05, ub=0.75) self.shp.loop.adjust_xo('lower', lb=0.7) self.shp.loop.adjust_xo('bottom', lb=0.05, ub=0.75) self.shp.loop.adjust_xo('l', lb=0.8, ub=1.5) self.shp.loop.adjust_xo('tilt', lb=-25, ub=25) #self.shp.loop.remove_oppvar('flat') #self.shp.loop.remove_oppvar('tilt') def date(self, verbose=True): today = datetime.date.today().strftime('%Y_%m_%d') if verbose: print(today) return today def set_filename(self, update=False, **kwargs): today = self.date(verbose=False) if update: # use today's date date_str = today else: date_str = kwargs.get('date', today) self.filename = '{}_{}'.format(date_str, self.name) # chamber name def generate(self, eq_names, dr=0.225, psi_n=1.07, flux_fit=False, symetric=False, plot=False): self.set_filename(update=True) # update date in filename self.profile.loop.reset_oppvar(symetric) # reset loop oppvar self.set_bounds() self.config = { 'dr': dr, 'psi_n': psi_n, 'flux_fit': flux_fit, 'Nsub': 100 } self.config['eqdsk'] = [] sf_list = self.load_sf(eq_names) for sf in sf_list: # convert input to list self.add_bound(sf) self.shp.add_interior(r_gap=0.001) # add internal bound self.shp.minimise() self.write() # append config data to loop pickle if plot: self.plot_chamber() def load_sf(self, eq_names): sf_dict, sf_list = OrderedDict(), [] for configuration in eq_names: sf = SF(Setup(configuration).filename) sf_dict[configuration] = sf.filename.split('/')[-1] sf_list.append(sf) self.config['eqdsk'] = sf_dict return sf_list def write(self): # overwrite loop_dict + add extra chamber fields with open(self.profile.dataname, 'wb') as output: pickle.dump(self.profile.loop_dict, output, -1) pickle.dump(self.config, output, -1) pickle.dump(self.shp.bound, output, -1) # boundary points pickle.dump(self.shp.bindex, output, -1) # boundary index def load_data(self, plot=False): try: with open(self.profile.dataname, 'rb') as input: self.profile.loop_dict = pickle.load(input) self.config = pickle.load(input) self.shp.bound = pickle.load(input) self.shp.bindex = pickle.load(input) except: print(self.profile.dataname) errtxt = 'boundary information not found' raise ValueError(errtxt) if plot: self.plot_chamber() def plot_chamber(self): self.shp.loop.plot() self.shp.plot_bounds() r, z = self.draw() pl.plot(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 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
#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'] }) #plot_oppvar(shp.loop.xo,shp.loop.oppvar)