Пример #1
0
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
Пример #2
0
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')