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
shp = Shape(profile, obj='L', eqconf=config['eq'], load=True) # ,nTF=18 rvv, zvv = geom.rzSLine(rb.segment['vessel']['r'], rb.segment['vessel']['z'], 31) rvv, zvv = geom.offset(rvv, zvv, 0.2) rmin = np.min(rvv) rvv[rvv <= rmin + 0.12] = rmin + 0.12 shp.loop.xo['r1'] = { 'value': 4.486, 'lb': np.min(rvv), 'ub': 8 } # inner radius shp.loop.xo['upper'] = {'value': 0.33, 'lb': 0.5, 'ub': 1} shp.loop.xo['lower'] = {'value': 0.33, 'lb': 0.5, 'ub': 1} shp.add_bound({'r': rvv, 'z': zvv}, 'internal') # vessel shp.plot_bounds() shp.minimise() #shp.loop.plot() tf = TF(profile, sf=sf) tf.fill() demo = DEMO() #demo.fill_part('Blanket') #demo.fill_part('Vessel') #demo.plot_limiter() ''' rb.vessel() rb.trim_sol() profile = Profile(config['TF'],family='S',part='TF')