Пример #1
0
 def __init__(self, config, family='S', nTF=16, obj='L'):
     self.nTF = nTF
     self.config = config
     datadir = trim_dir('../../Data')
     file = 'salome_input'  #  config #  +'_{}{}{}'.format(family,nTF,obj)
     self.filename = datadir + '/' + file + '.json'
     self.profile = Profile(config['TF'],
                            family=family,
                            load=True,
                            part='TF',
                            nTF=nTF,
                            obj=obj,
                            npoints=250)
     setup = Setup(config['eq'])
     self.sf = SF(setup.filename)
     self.tf = TF(self.profile, sf=self.sf)
     self.pf = PF(self.sf.eqdsk)
     self.PF_support()  # calculate PF support seats
     self.CS_support()  # calculate CS support seats
     self.Gravity_support()
     self.cage = coil_cage(nTF=nTF,
                           rc=self.tf.rc,
                           ny=3,
                           plasma={'config': config['eq']},
                           coil=self.tf.x['cl'])
     self.eq = EQ(self.sf,
                  self.pf,
                  dCoil=0.5,
                  sigma=0,
                  boundary=self.sf.get_sep(expand=0.5),
                  n=1e3)
     self.eq.plasma()
     self.ff = force_feild(self.pf.index, self.pf.coil, self.eq.coil,
                           self.eq.plasma_coil)
Пример #2
0
 def __init__(self, sf, setup, npoints=500):
     self.setup = setup
     self.sf = sf
     self.npoints = npoints
     self.dataname = setup.configuration
     self.datadir = trim_dir('../../../Data/')
     self.segment = {}  # store section segments (divertor,fw,blanket...)
Пример #3
0
 def __init__(self, file, directory='../../Data/'):
     directory = trim_dir(directory)
     self.file = directory + file + '.pkl'
     self.data = {
         'rb': None,
         'sf': None,
         'eq': None,
         'cc': None,
         'inv': None,
         'ax': None,
         'pf': None
     }
     self.data = od(sorted(self.data.items(), key=lambda x: x[0]))
     self.inmemory = False
Пример #4
0
 def __init__(self,
              name,
              family='S',
              part='TF',
              npoints=200,
              symetric=False,
              read_write=True,
              **kwargs):
     self.npoints = npoints
     self.name = name
     self.part = part
     self.read_write = read_write
     self.initalise_loop(family, npoints,
                         symetric=symetric)  # initalize loop object
     data_dir = trim_dir('../../Data/')
     self.dataname = data_dir + self.name + '_{}.pkl'.format(part)
     self.nTF = kwargs.get('nTF', 'unset')
     self.obj = kwargs.get('obj', 'L')
     self.read_loop_dict()
Пример #5
0
    def ansys(self, plot=False, nl=250, nr=5, ny=5):
        datadir = trim_dir('../../Data/')
        filename = datadir + 'TFload_{:d}'.format(self.nTF)
        ans = table(filename)
        ans.f.write('! loading tables for {:d}TF coil concept\n'.format(
            self.nTF))
        ans.f.write('! loop length parameterized from 0-1\n')
        ans.f.write('! loop starts at the inboard midplane\n')
        ans.f.write('! loop progresses in the anti-clockwise direction\n')
        ans.f.write('! tables defined with cylindrical coordinate system\n')
        ans.f.write(
            '! body applied to nodes of winding-pack in cartisean system x,y,z\n'
        )
        ans.f.write(
            '! winding-pack must be labled as named-selection \'wp\'\n')
        ans.f.write('\nlocal,11,1,{:1.9f},0,{:1.9f},0,90,0'\
                    .format(self.sf.mo[0],self.sf.mo[1]))
        ans.f.write('  ! define local cylindrical coordinate system\n')
        ans.f.write('csys,0  ! restore to cartesian\n')

        ans.f.write('\n! per-TF PF coil forces (Fr,Fz) [N]\n')
        ans.f.write('! order as numbered in plots\n')
        F = self.ff.get_force()['F']
        ans.load('F_coil', 1e6 * F / self.nTF)
        ans.write_array()

        apdlstr = '''
        nPF = 4
        *do,i,1,nPF
          F,c%i-1%,Fz,1e6*F_coil(i,2)
        *enddo
        F,cs,Fz,1e6*F_coil(i+1,2)
        '''
        ans.f.write('\n/nopr  ! suppress large table output\n')

        self.tf.loop_interpolators(offset=0,
                                   full=True)  # construct TF interpolators
        TFloop = self.tf.fun['cl']

        ngrid = {'nr': 20, 'nt': 150}  #  coordinate interpolation grid
        ndata = {
            'nl': nl,
            'nr': nr,
            'ny': ny
        }  #  coordinate interpolation grid
        l = np.linspace(0, 1, 250)  # calculate grid extent
        xin, zin = self.tf.fun['in']['r'](l), self.tf.fun['in']['z'](l)
        rin = np.sqrt((xin - self.sf.mo[0])**2 + (zin - self.sf.mo[1])**2)
        rmin = np.min(rin)  # minimum radius
        xout, zout = self.tf.fun['out']['r'](l), self.tf.fun['out']['z'](l)
        rout = np.sqrt((xout - self.sf.mo[0])**2, (zout - self.sf.mo[1])**2)
        rmax = np.max(rout)  # maximum radius

        radius = np.linspace(rmin, rmax, ngrid['nr'])
        theta = np.linspace(-np.pi, np.pi, ngrid['nt'])
        l_map = np.zeros((ngrid['nr'], ngrid['nt']))
        dr_map = np.zeros((ngrid['nr'], ngrid['nt']))
        for i in range(ngrid['nr']):
            for j in range(ngrid['nt']):
                x = self.sf.mo[0] + radius[i] * np.cos(theta[j])
                z = self.sf.mo[1] + radius[i] * np.sin(theta[j])
                L = minimize_scalar(OCC.OIS_placment,
                                    method='bounded',
                                    args=(TFloop, (x, z)),
                                    bounds=[0, 1]).x
                xl, zl = TFloop['r'](L), TFloop['z'](L)
                l_map[i, j] = L
                dr_map[i,j] = np.sqrt((x-xl)**2+(z-zl)**2)*\
                np.sign(np.dot([x-xl,z-zl],[x-self.sf.mo[0],z-self.sf.mo[1]]))

        width = self.tf.section['winding_pack']['width']
        depth = self.tf.section['winding_pack']['depth']
        cross_section = width * depth
        l_data = np.linspace(0, 1, ndata['nl'])
        if ndata['nr'] > 1:
            dr_data = np.linspace(-width / 2, width / 2, ndata['nr'])
        else:
            dr_data = np.array([0])
        if ndata['ny'] > 1:
            dy_data = np.linspace(-depth / 2, depth / 2, ndata['ny'])
        else:
            dy_data = np.array([0])
        Fbody = {}
        for var in ['x', 'y', 'z']:
            Fbody[var] = np.zeros((ndata['nl'], ndata['nr'], ndata['ny']))

        self.tf.loop_interpolators(offset=0, full=True)  # centreline
        Jturn = self.cage.Iturn / cross_section  # current density magnitude
        for i, l in enumerate(l_data):
            iter_str = '\rcalculating TF body force:'
            iter_str += 'segment {:d} of {:d}'.format(i, ndata['nl'])
            sys.stdout.write(iter_str)
            sys.stdout.flush()
            xo = self.tf.fun['cl']['r'](l)
            zo = self.tf.fun['cl']['z'](l)
            dxo = self.tf.fun['cl']['dr'](l)
            dzo = self.tf.fun['cl']['dz'](l)
            that = np.array([dxo, 0, dzo])
            that /= np.linalg.norm(that)
            J = Jturn * that  # current density vector
            nhat = np.array([that[2], 0, -that[0]])
            for j, dr in enumerate(dr_data):
                for k, dy in enumerate(dy_data):
                    point = np.array([xo, dy, zo]) + dr * nhat
                    Fb = self.ff.topple(point,
                                        J,
                                        self.cage,
                                        self.eq.Bpoint,
                                        method='BS')  # body force
                    for m, var in enumerate(['x', 'y', 'z']):  # store
                        Fbody[var][i, j, k] = Fb[m]
                    if plot:
                        Fvec = 1e-8 * Fb  #/np.linalg.norm(Fb)
                        #Fvec = that
                        pl.arrow(point[0],
                                 point[2],
                                 Fvec[0],
                                 Fvec[2],
                                 head_width=0.3,
                                 head_length=0.6)
                        pl.plot(point[0],
                                point[2],
                                'o',
                                color=0.15 * np.ones(3),
                                ms=3)
        print('\n',
              np.sum(Fbody['x'][:-1, :, :]) * 1e-9,
              np.sum(Fbody['y'][:-1, :, :]) * 1e-9,
              np.sum(Fbody['z'][:-1, :, :]) * 1e-9)

        ans.f.write('\n! parametric coil length, fn(theta)\n')
        ans.load('l_map', l_map, [radius, theta])
        ans.write(['radus', 'theta'])
        ans.f.write('\n! parametric coil offset, fn(theta)\n')
        ans.load('dr_map', dr_map, [radius, theta])
        ans.write(['radus', 'theta'])
        for var in ['x', 'y', 'z']:
            ans.f.write(
                '\n! winding-pack body force, Fbody_{} [N/m3]\n'.format(var))
            ans.load('Fbody_{}'.format(var), Fbody[var],
                     [l_data, dr_data, dy_data])
            ans.write(['l_map', 'dr_map', 'offset'])
        ans.f.write('/gopr  ! enable output\n')

        apdlstr = '''
        pi = 4*atan(1)
        csys,11  ! switch to cylindrical coordinate system
        esel,s,elem,,wp  ! select winding pack (requires named selection 'wp')
        *get,nel,elem,0,count
        *vget,el_sel,elem,,esel  ! selection mask
        *vget,el_id,elem,,elist  ! winding pack selection array
        *vget,el_vol,elem,,geom  ! element volume
        *vget,el_radius,elem,,cent,x  ! element radius
        *vget,el_theta,elem,,cent,y  ! element theta
        *vget,el_offset,elem,,cent,z  ! element axial offset
        *voper,el_theta,el_theta,mult,pi/180  ! convert to radians
        csys,0  ! return coordinate system
        
        ! compress selections
        *dim,el_v,array,nel
        *dim,el_r,array,nel
        *dim,el_t,array,nel
        *dim,el_o,array,nel
        *dim,el_l,array,nel
        *dim,el_dr,array,nel
        
        *vmask,el_sel
        *vfun,el_v,comp,el_vol  ! volume
        *vmask,el_sel
        *vfun,el_r,comp,el_radius  ! radius
        *vmask,el_sel
        *vfun,el_t,comp,el_theta  ! theta
        *vmask,el_sel
        *vfun,el_o,comp,el_offset  ! offset
        *vitrp,el_l,l_map,el_r,el_t  ! interpolate l_map table
        *vitrp,el_dr,dr_map,el_r,el_t !  interpolate dr_map table
        
        xyz = 'x','y','z'  ! axes
        fcum,add  ! accumulate nodal forces
        *do,i,1,nel  ! apply forces to loads
          esel,s,elem,,el_id(i)
          nsle  ! select nodes attached to element
          nsel,r,node,,wp  ! ensure all nodes from winding pack
          *get,nnd,node,0,count  ! count nodes
          *do,j,1,3  ! Fx,Fy,Fz - all nodes attached to element
              F,all,F%xyz(j)%,Fbody_%xyz(j)%(el_l(i),el_dr(i),el_o(i))*el_v(i)/nnd
          *enddo
        *enddo
        allsel  
        '''
        ans.f.write(apdlstr)
        ans.close()
Пример #6
0
        font='sans-serif',
        palette='Set2',
        font_scale=7 / 8,
        rc=rc)
color = sns.color_palette('Set2', 5)

config, setup = select(base={'TF': 'dtt', 'eq': 'DEMO_FW_SOF'}, nTF=18)
sf = SF(setup.filename)
pf = PF(sf.eqdsk)
pf.plot(coils=pf.coil, label=True, plasma=False, current=True)
levels = sf.contour(plot_vac=False)
rb = RB(setup, sf)
rb.firstwall(plot=True, debug=False, color=color[1])
rb.trim_sol()

filename = trim_dir('../../Data/') + 'CATIA_FW.xlsx'
wb = load_workbook(filename=filename, read_only=True, data_only=True)
ws = wb[wb.get_sheet_names()[0]]

FW = {}
for col, var in zip([5, 6], ['r', 'z']):
    row = ws.columns[col]
    FW[var] = np.zeros(len(row) - 1)
    for i, r in enumerate(row[1:]):
        try:
            FW[var][i] = 1e-3 * float(r.value)  # m
        except:
            break
r, z = geom.pointloop(FW['r'], FW['z'], ref='min')
pl.plot(r[:-1], z[:-1])
'''
Пример #7
0
from OCC import UnitsAPI
UnitsAPI.unitsapi_SetCurrentUnit('LENGTH', 'meter')
from amigo.IO import trim_dir

sys.path.insert(0, r'D:/Code/Nova/nova/TF/geom')


def add_line(point):
    p = []
    for i in range(2):
        p.append(gp_Pnt(point[i]['r'], 0, point[i]['z']))
    edge = BRepBuilderAPI_MakeEdge(p[0], p[1]).Edge()
    return edge


datadir = trim_dir('../../../Data/')
with open(datadir + 'occ_input.json', 'r') as f:
    data = json.load(f)
loop, cs, pf, nTF = data['p'], data['section'], data['pf'], data['nTF']
color = data['color']
PFsupport, CSsupport = data['PFsupport'], data['CSsupport']
Gsupport, OISsupport = data['Gsupport'], data['OISsupport']

w = []
for segment in loop:
    Pnt = TColgp_Array1OfPnt(1, 4)
    for i in range(4):
        point = segment['p{:d}'.format(i)]
        Pnt.SetValue(i + 1, gp_Pnt(point['r'], 0, point['z']))
    curve = Geom_BezierCurve(Pnt)
    w.append(BRepBuilderAPI_MakeEdge(curve.GetHandle()).Edge())
Пример #8
0
    def eqwrite(self, pf, CREATE=False, prefix='Nova', config=''):
        if len(config) > 0:
            name = prefix + '_' + config
        else:
            name = prefix
        if CREATE:  # save with create units (Webber/loop, negated Iplasma)
            name = 'CREATE_format_' + name
            norm = 2 * np.pi  # reformat: webber/loop
            Ip_dir = -1  # reformat: reverse plasma current
            psi_offset = self.get_Xpsi()[0]  # reformat: boundary psi=0
        else:
            norm, Ip_dir, psi_offset = 1, 1, 0  # no change
        nc, rc, zc, drc, dzc, Ic = pf.unpack_coils()[:-1]
        psi_ff = np.linspace(0, 1, self.nr)
        pad = np.zeros(self.nr)
        eq = {
            'name': name,
            'nx': self.nr,
            'ny': self.nz,  # Number of horizontal and vertical points
            'r': self.r,
            'z': self.z,  # Location of the grid-points
            'rdim': self.r[-1] - self.r[0],  # Size of the domain in meters
            'zdim': self.z[-1] - self.z[0],  # Size of the domain in meters
            'rcentr':
            self.eqdsk['rcentr'],  # Reference vacuum toroidal field (m, T)
            'bcentr':
            self.eqdsk['bcentr'],  # Reference vacuum toroidal field (m, T)
            'rgrid1': self.r[0],  # R of left side of domain
            'zmid': self.z[0] +
            (self.z[-1] - self.z[0]) / 2,  # Z at the middle of the domain
            'rmagx': self.Mpoint[0],  # Location of magnetic axis
            'zmagx': self.Mpoint[1],  # Location of magnetic axis
            'simagx':
            float(self.Mpsi) * norm,  # Poloidal flux at the axis (Weber / rad)
            'sibdry':
            self.Xpsi * norm,  # Poloidal flux at plasma boundary (Weber / rad)
            'cpasma': self.eqdsk['cpasma'] * Ip_dir,
            'psi': (np.transpose(self.psi).reshape((-1, )) - psi_offset) *
            norm,  # Poloidal flux in Weber/rad on grid points
            'fpol': self.Fpsi(
                psi_ff),  # Poloidal current function on uniform flux grid
            'ffprim': self.b_scale * self.FFprime(psi_ff) /
            norm,  # "FF'(psi) in (mT)^2/(Weber/rad) on uniform flux grid"
            'pprime': self.b_scale * self.Pprime(psi_ff) /
            norm,  # "P'(psi) in (N/m2)/(Weber/rad) on uniform flux grid"
            'pressure': pad,  # Plasma pressure in N/m^2 on uniform flux grid
            'qpsi': pad,  # q values on uniform flux grid
            'nbdry': self.nbdry,
            'rbdry': self.rbdry,
            'zbdry': self.zbdry,  # Plasma boundary
            'nlim': self.nlim,
            'xlim': self.xlim,
            'ylim': self.ylim,  # first wall
            'ncoil': nc,
            'rc': rc,
            'zc': zc,
            'drc': drc,
            'dzc': dzc,
            'Ic': Ic
        }  # coils

        eqdir = trim_dir('../../eqdsk')
        filename = eqdir + '/' + config + '.eqdsk'
        print('writing eqdsk', filename)
        nova.geqdsk.write(filename, eq)