def genopts(opts): title,opts = opts; getkw = mk_getkw(kw,opts,prefer_passed=True); tmpl=";;{}\n{}\n" all_opts = "".join([ genopt(k,getkw) for k in sorted(opts.keys()) ]); return tmpl.format(title,all_opts);
def genonescale(**kw): getkw = mk_getkw(kw, onescale_defaults) slen = getkw("solid_len") xlen = getkw("xlen") kw1 = sd(kw, tlim=(0.0, xlen) + (0.0, 0.0, 0.0, 0.0), sdim=(xlen - slen, xlen) + (0.0, 0.0, 0.0, 0.0)) kw1["f_1D"] = genf(**kw1) return gentargetdat(**kw1)
def manual_genboundary(bspec,**kw): kwp = sd(kw,**bspec); getkw = mk_getkw(kwp,outletdefaults,prefer_passed = True); btype = getkw("type"); lims = getkw('lim'); di = dict(); for dim,lim in zip(all_lims,lims): di[dim] = lim; if btype == 'outlet': model = getkw('model'); di['label']= getkw('label'); di['phase_velocity'] = getkw('phase_velocity'); if model == 'none': ret = outlet_none_tmpl.format(**di); elif model == 'potential': di = sd(manbounds_defs,**di); if not test(di,'connection_rank'): di['connection_rank'] =''; else: di['connection_rank'] = 'connection_rank {}'.format( getkw('connection_rank')); if not test(kwp,'voltage_measurement'): di['voltage_measurement'] = ''; else: raise NotImplementedError("haven't got to this yet..."); di['circuit'] = di['circuit']; ret = outlet_pot_tmpl.format(**di); elif model == 'laser': raise NotImplementedError("need to implement the laser..."); else: raise ValueError("unknown outlet model {}".format(model)); else: raise NotImplementedError("yeah..."); return ret;
def gendens(**kw): densityfile_tmpl = ''' type {type} data_file {targetdat} independent_variable_multiplier {imul} dependent_variable_multiplier {dmul} ''' densitypairs_tmpl = ''' type 0 data_pairs {data} end ''' getkw = mk_getkw(kw, densdefaults); speciesl = getkw('speciesl'); if test(kw,'target_density'): dens=kw['target_density']; if type(dens) == tuple: #the reason for tuple and not a general iterable #is when we pass a single scale, for example, which #we scale by fracs pass; else: if hasattr(dens, '__call__'): dens[:] = [ lambda x: frac*idensf(x) for frac,idensf in zip(fracs,dens) ]; else: dens[:] = [ frac*idens for frac,idens in zip(fracs,dens) ]; if hasattr(n_e[0],'__call__'): #invariant: txmin,txmax are in cm. x = np.linspace(kw['txmin'][0],kw['txmax'][1],20); dens[:] = [idens(x) for idens in dens]; for species,idens in zip(speciesl,dens): kw['n_' + species] = densitypairs_tmpl.format( data = idens) else: kw['dens_dat'] = getkw('dens_dat'); kw['dens_imul'] = getkw('dens_imul'); kw['dens_type'] = getkw('dens_type'); kw['fracs'] = getkw('fracs'); def copy_kw(l): if type(kw[l]) != tuple: kw[l] = (kw[l],)*len(speciesl) copy_kw('dens_dat'); copy_kw('dens_imul'); copy_kw('dens_type'); for i,species in enumerate(speciesl): kw['n_'+species] = densityfile_tmpl.format( targetdat = kw['dens_dat'][i], type = kw['dens_type'][i], imul = kw['dens_imul'][i], dmul = kw['fracs'][i]); pass; return kw;
def genf(**kw): getkw = mk_getkw(kw, datdefaults) if getkw("type") == "singlescale": tlim = mt(getkw("tlim"), m=getkw("unit")) xdim = tlim[0], tlim[1] return mkdecay(getkw("n_s"), mt(getkw("sdim"), m=getkw("unit")), xdim, getkw("expf") * getkw("unit")) else: raise NotImplementedError("Coming soon!")
def gendat(**kw): getkw=mk_getkw(kw,datdefaults); res = getkw('dat_xres'); unit=getkw('unit'); tlim = mt(getkw('tlim'),m=unit); if test(kw,'f_1D') or test(kw, 'data1D'): dim = 1; elif (test(kw,'f_2D') or test(kw, 'data2D')) and test(kw, 'tlim'): dim = 2; elif (test(kw,'f_3D') or test(kw, 'data3D')) and test(kw, 'tlim'): dim = 3; else: raise ValueError("Cannot reckon data dimensionality"); if dim == 1: if test(kw,'f_1D'): x = np.linspace(tlim[0],tlim[1],res); d = getkw('f_1D')(x); elif test(kw,'data1D'): x,d = getkw('data1D'); s = StringIO(); np.savetxt(s,np.array([x,d]).T,fmt='%.8e',); return s.getvalue(); elif dim == 2: if test(kw,'f_2D'): x = np.linspace(tlim[0],tlim[1],res); if np.isclose(tlim[2],tlim[3]): y = np.linspace(tlim[4],tlim[5],res); else: y = np.linspace(tlim[2],tlim[3],res); X,Y = np.meshgrid(x,y,indexing='ij'); d = getkw('f_2D')(X,Y); elif test(kw,'data2D'): x,y,d = getkw('data2D'); s = StringIO(); np.savetxt(s,np.array(list(d.shape)).reshape(1,-1), fmt='%i'); np.savetxt(s,np.array(x).reshape(1,-1), fmt='%.8e'); np.savetxt(s,np.array(y).reshape(1,-1), fmt='%.8e'); np.savetxt(s,np.array(d).T,fmt='%.8e',); return s.getvalue(); else: if test(kw, 'f_3d'): x = np.linspace(tlim[0],tlim[1],res); y = np.linspace(tlim[2],tlim[3],res); z = np.linspace(tlim[4],tlim[5],res); X,Y,Z = np.meshgrid(x,y,z,indexing='ij'); d = getkw('f_3d')(X,Y,Z); elif test(kw,'data3D'): x,y,z,d = getkw('data3D'); s = StringIO(); s.write("{} {} {}\n".format( d.shape[0],d.shape[1],d.shape[2])); np.savetxt(s,np.array(x).reshape(1,-1),fmt='%.8e'); np.savetxt(s,np.array(y).reshape(1,-1),fmt='%.8e'); np.savetxt(s,np.array(z).reshape(1,-1),fmt='%.8e'); for sub in np.rollaxis(d,1): np.savetxt(s,np.array(sub).T,fmt='%.8e',); return s.getvalue(); pass;
def genoptions(**kw): if test(kw,"options"): kw = sd(kw,kw['options']); #quirks getkw_outer = mk_getkw(kw,lspdefaults); kw['maximum_restart_dump_time'] = getkw_outer('restart') def genopt(k,getkw=getkw_outer,flag=False): if not flag: flag = k; i = getkw(k); if re.search("_ns$",flag): if isvalue(i): i*=1e9; else: scaletuple(i,1e9); if i is None or i is (): return ""; elif i is True: return "{} ON\n".format(flag); elif i is False: return "{} OFF\n".format(flag); elif isvalue(i): return "{} {}\n".format(flag,i); else: return "{} {} end\n".format(flag,joinspace(i)); def genopts(opts): title,opts = opts; getkw = mk_getkw(kw,opts); tmpl=";;{}\n{}\n" all_opts = "".join([ genopt(k,getkw) for k in sorted(opts.keys()) ]); return tmpl.format(title,all_opts); out=''.join([ genopts(iopts) for iopts in [restart_opts, balance_opts,] ]); out+=options_dont_touch out+=''.join([ genopts(iopts) for iopts in [kinematic_opts,dump_opts,] ]); #now we do big dumps kw['interval_ns'] = getkw_outer("dumpinterval"); kw['times_ns'] = getkw_outer("dumptimes"); kw['steps'] = getkw_outer("dumpsteps"); def gen_dumpopt(dump,opt): label = "{}_dump_{}".format(dump,opt); if test(kw, label): return genopt(label); else: return genopt(opt,flag=label); for dump in bigdumps: if not getkw_outer("dump_{}".format(dump)) : continue; out += "dump_{}s_flag ON\n".format(dump); for iopt in ['interval_ns','times_ns','steps']: out += gen_dumpopt(dump,iopt); return out;
def genf(**kw): getkw=mk_getkw(kw,datdefaults); if getkw('type') == 'singlescale': tlim = mt(getkw('tlim'),m=getkw('ux')); xdim = tlim[0], tlim[1]; return mkdecay( getkw('n_s'), mt(getkw('sdim'),m=getkw('ux')), xdim, getkw('expf')*getkw('ux')); else: raise NotImplementedError("Coming soon!");
def genonescale(**kw): getkw=mk_getkw(kw,onescale_defaults); slen = getkw("solid_len"); xlen = getkw("xlen"); kw1 = sd( kw, tlim=(0.0, xlen) + (0.0,0.0,0.0,0.0), sdim= (xlen-slen, xlen) + (0.0,0.0,0.0,0.0)); kw1['f_1D']= genf(**kw1) return gendat(**kw1);
def genf(**kw): getkw=mk_getkw(kw,datdefaults); if getkw('type') == 'singlescale': tlim = mt(getkw('tlim'),m=getkw('unit')); xdim = tlim[0], tlim[1]; return mkdecay( getkw('n_s'), mt(getkw('sdim'),m=getkw('unit')), xdim, getkw('expf')*getkw('unit')); else: raise NotImplementedError("Coming soon!");
def genregions_uniform(subdivs,**kw): ''' genregions in a uniform fashion subdivs is a list of tuples, each of which specify a range to divide along an axis. There are two options, the first is (d, split) in which d is a string representing the dimension, and split is the number of subdivions along that axis. The section option is (d, split, dmin, dmax) or (d, split, (dmin, dmax)) where dmin is the minimum along the d axis and dmax is the max. The subdivisions are cartesian multiplied (or cartesian product). ''' getkw = mk_getkw(kw, unireg_defaults); lims = mt(getkw('lim'),getkw('ux')); dims = 'xyz'; out={} for subdiv in subdivs: if len(subdiv) == 3: subdiv = subdiv[:2] + subdiv[2]; elif len(subdiv) == 2: i=dims.index(subdiv[0]) subdiv = subdiv + tuple(lims[i*2:i*2+2]) ax, split, mn, mx = subdiv; if ax not in out: out[ax]=[]; out[ax].extend(list( np.linspace(mn,mx,split+1))); for i,dim in enumerate(dims): if dim not in out: out[dim] =lims[i*2:i*2+2]; regs = [ dict(xmin=xmin,xmax=xmax, ymin=ymin,ymax=ymax, zmin=zmin,zmax=zmax,) for xmin,xmax in zip(out['x'],out['x'][1:]) for ymin,ymax in zip(out['y'],out['y'][1:]) for zmin,zmax in zip(out['z'],out['z'][1:]) ]; for i,reg in enumerate(regs): reg['i'] = i+1; if test(kw,"domains_per_region"): for reg in regs: reg['domains'] = getkw("domains_per_region"); else: ndom = getkw("domains")//len(regs); ex = getkw("domains") %len(regs); for reg in regs: reg['domains'] = ndom; regs[-1]['domains'] += ex; for reg in regs: reg['split'] = "{}SPLIT".format( getkw("region_dom_split").upper()); return regs;
def gendens(**kw): getkw = mk_getkw(kw, densdefaults); speciesl = getkw('speciesl'); outputfmt = "n_{}"; if test(kw,'target_density'): Q = kw['target_density']; fracs = getkw('fracs'); if test(kw, 'target_density_plainconst'): ret = { outputfmt.format(species) : plainconst_tmpl.format(data=Q*f) for species,f in zip(speciesl,fracs) }; kw.update(ret); return kw; if type(Q) == tuple: #the reason for tuple and not a general iterable #is when we pass a single scale, for example, which #we scale by fracs pass; else: if hasattr(Q[0], '__call__'): Q = [ lambda x: frac*iQf(x) for frac,iQf in zip(fracs,Q) ]; else: Q = [ frac*iQ for frac,iQ in zip(fracs,Q) ]; if hasattr(Q[0],'__call__'): #invariant: txmin,txmax are in cm. x = np.linspace(kw['txmin'][0],kw['txmax'][1],20); Q[:] = [iQ(x) for iQ in Q]; ret = { outputfmt.format(species) : densitypairs_tmpl.format(data = iQ) for species,iQ in zip(speciesl,Q) }; kw.update(ret) return kw; else: kw['dens_dat'] = getkw('dens_dat'); kw['dens_imul'] = getkw('dens_imul'); kw['dens_type'] = getkw('dens_type'); kw['fracs'] = getkw('fracs'); def copy_kw(l): if type(kw[l]) != tuple: kw[l] = (kw[l],)*len(speciesl) copy_kw('dens_dat'); copy_kw('dens_imul'); copy_kw('dens_type'); for i,species in enumerate(speciesl): kw['n_'+species] = densityfile_tmpl.format( targetdat = kw['dens_dat'][i], type = kw['dens_type'][i], imul = kw['dens_imul'][i], dmul = kw['fracs'][i]); return kw; pass;
def process_temp(iq): if not iq: return None if hasattr(iq, '__call__'): xres = getkw('dat_xres') x = np.linspace(kw['txmin'][0], kw['txmax'][1], xres) iq = iq(x) raise ValueError("Not implemented yet!") elif type(iq) is dict: _getkw = mk_getkw(iq, species_tempdefault) ret = densityfile_tmpl.format(targetdat=_getkw('dat'), type=_getkw('type'), imul=_getkw('imul'), dmul=_getkw('frac')) return ret
def process_temp(ifunc): if not ifunc: return None; if hasattr(ifunc, '__call__'): xres = getkw('dat_xres') x = np.linspace(kw['txmin'][0],kw['txmax'][1],xres); ifunc = ifunc(x); raise ValueError("Not implemented yet!"); elif type(ifunc) is dict: _getkw = mk_getkw(ifunc, species_tempdefault); ret = densityfile_tmpl.format( targetdat = _getkw('dat'), type = _getkw('type'), imul = _getkw('imul'), dmul = _getkw('frac')); return ret;
def gentemp(**kw): getkw = mk_getkw(kw, tempdefaults) speciesl = getkw('speciesl') otherfuncs = '' funcnum = getkw('funcnum') if test(kw, 'target_temps'): Q = kw['target_temps'] def process_temp(iq): if not iq: return None if hasattr(iq, '__call__'): xres = getkw('dat_xres') x = np.linspace(kw['txmin'][0], kw['txmax'][1], xres) iq = iq(x) raise ValueError("Not implemented yet!") elif type(iq) is dict: _getkw = mk_getkw(iq, species_tempdefault) ret = densityfile_tmpl.format(targetdat=_getkw('dat'), type=_getkw('type'), imul=_getkw('imul'), dmul=_getkw('frac')) return ret ss = [process_temp(iq) for iq in Q] else: Q = [dict()] * len(speciesl) ss = [None] * len(speciesl) for iq, species, s, e in zip(Q, speciesl, ss, getkw('thermal_energy')): cur = 'thermal_energy {}\n'.format(e) if s: otherfuncs += "function{}\n".format(funcnum) otherfuncs += s # if 'energy_flags' in iq: # energyflags = iq['energy_flags']; # else: # energyflags = getkw('energy_flags'); cur += 'spatial_function {}\n'.format(funcnum) # cur += 'energy_flags {}\n'.format( # joinspace([ # 1 if i else 0 # for i in getkw("dens_flags")])); funcnum += 1 kw['{}_thermalopts'.format(species)] = cur if otherfuncs != '': if not test(kw, 'other_funcs'): kw['other_funcs'] = '' kw['other_funcs'] += otherfuncs return kw
def gen_mov(**kw): getkw = mk_getkw(kw,mov_defaults); spec = dict(); if test(kw,'sclrq_path'): spec['sclrq_path'] = 'export PATH="{}:$PATH"\n'.format( sclrq_path); else: spec['sclrq_path'] =''; if getkw('cluster') == 'ramses': spec['sclrq_path']+='source ~/.bashrc\n'; if not test(kw,'plotI'): spec['plotI']=getkw('I')/10; if test(kw,'condafile'): spec['conda'] = kw['condafile']; else: spec['conda'] = clusters[getkw('cluster')]['condafile'] spec.update(dict( pbsbase=getkw('pbsbase'), lims=kw['clim'], n_c=getkw('n_c'))); if getkw('type')=='ni' or getkw('type')=='dq': Q,q = zip(*getkw(getkw('type')+'_species')); Q = ",".join(str(i) for i in Q); Q = "("+Q+")"; spec.update(dict( linthresh=getkw("linthresh"), quantity=Q, weights=str(q), averaging=getkw("averaging"), cmap=( getkw("cmap") if getkw('type') == 'ni' else getkw("dq_cmap")), type=getkw('type'), title="Ion Density" if getkw('type') == 'ni' else 'Charge Density', )); kw['movtmpl'] = 'movni_tmpl' elif getkw('type') == 'ne': spec['quantity'] = getkw('ne_species'); elif getkw('type') == 'rho': spec['quantity'] = getkw('ne_species'); spec['cmap'] = getkw('dq_cmap'); spec['linthresh'] = getkw('linthresh'); if test(kw, 'movtmpl'): fname = kw['movtmpl']; else: fname = 'mov{}_tmpl'.format(getkw('type')); with open(fname) as f: s=f.read(); return s.format(**spec);
def gentemp(**kw): getkw = mk_getkw(kw, tempdefaults); speciesl = getkw('speciesl'); otherfuncs = ''; funcnum = getkw('funcnum'); if test(kw,'target_temps'): Q = kw['target_temps']; def process_temp(iq): if not iq: return None; if hasattr(iq, '__call__'): xres = getkw('dat_xres') x = np.linspace(kw['txmin'][0],kw['txmax'][1],xres); iq = iq(x); raise ValueError("Not implemented yet!"); elif type(iq) is dict: _getkw = mk_getkw(iq, species_tempdefault); ret = densityfile_tmpl.format( targetdat = _getkw('dat'), type = _getkw('type'), imul = _getkw('imul'), dmul = _getkw('frac')); return ret; ss = [ process_temp(iq) for iq in Q ]; else: Q = [dict()]*len(speciesl); ss= [None] *len(speciesl); for iq,species,s,e in zip(Q,speciesl,ss,getkw('thermal_energy')): cur = 'thermal_energy {}\n'.format(e); if s: otherfuncs += "function{}\n".format(funcnum); otherfuncs += s; # if 'energy_flags' in iq: # energyflags = iq['energy_flags']; # else: # energyflags = getkw('energy_flags'); cur += 'spatial_function {}\n'.format(funcnum); # cur += 'energy_flags {}\n'.format( # joinspace([ # 1 if i else 0 # for i in getkw("dens_flags")])); funcnum += 1; kw['{}_thermalopts'.format(species)] = cur; if otherfuncs != '': if not test(kw, 'other_funcs'): kw['other_funcs'] = '' kw['other_funcs'] += otherfuncs; return kw;
def gen_mov(**kw): getkw = mk_getkw(kw, mov_defaults) spec = dict() if test(kw, 'sclrq_path'): spec['sclrq_path'] = 'export PATH="{}:$PATH"\n'.format(sclrq_path) else: spec['sclrq_path'] = '' if getkw('cluster') == 'ramses': spec['sclrq_path'] += 'source ~/.bashrc\n' if not test(kw, 'plotI'): spec['plotI'] = getkw('I') / 10 if test(kw, 'condafile'): spec['conda'] = kw['condafile'] else: spec['conda'] = clusters[getkw('cluster')]['condafile'] spec.update( dict(pbsbase=getkw('pbsbase'), lims=kw['clim'], n_c=getkw('n_c'))) if getkw('type') == 'ni' or getkw('type') == 'dq': Q, q = zip(*getkw(getkw('type') + '_species')) Q = ",".join(str(i) for i in Q) Q = "(" + Q + ")" spec.update( dict( linthresh=getkw("linthresh"), quantity=Q, weights=str(q), averaging=getkw("averaging"), cmap=(getkw("cmap") if getkw('type') == 'ni' else getkw("dq_cmap")), type=getkw('type'), title="Ion Density" if getkw('type') == 'ni' else 'Charge Density', )) kw['movtmpl'] = 'movni_tmpl' elif getkw('type') == 'ne': spec['quantity'] = getkw('ne_species') elif getkw('type') == 'rho': spec['quantity'] = getkw('rho_species') spec['cmap'] = getkw('dq_cmap') spec['linthresh'] = getkw('linthresh') if test(kw, 'movtmpl'): fname = kw['movtmpl'] else: fname = 'mov{}_tmpl'.format(getkw('type')) with open(fname) as f: s = f.read() return s.format(**spec)
def gengrids(**kw): getkw = mk_getkw(kw,grid_defs,prefer_passed = True); outgrids = ['','','']; simple_gridtmpl = ''' {dim}min {min:e} {dim}max {max:e} {dim}-cells {cells}'''; vargrid_tmpl = ''' {dim}min {min:e} {dim}max {max:e} {dim}-cells {cells} {dim}-intervals d{dim}-start {dxstart:e} {intervals} end''' vargrid_intv_tmpl = " length {length:e} for {N}"; grids = [] for dim in 'xyz': if getkw('{}cells'.format(dim)) == 0: grids.append(""); continue; vgridlabel = '{}vargrid'.format(dim); if test(kw,vgridlabel): intv = '\n'.join([ vargrid_intv_tmpl.format(length=l, N=N) for l,N in getkw(vgridlabel)]); if test(kw, 'd{}start'.format(dim)): ddimstart = getkw('d{}start'.format(dim)); else: l = getkw(vgridlabel)[0][0]; N = getkw(vgridlabel)[0][1]; ddimstart = l/N; grid = vargrid_tmpl.format( dim=dim, min=getkw('{}min'.format(dim)), max=getkw('{}max'.format(dim)), cells=getkw('{}cells'.format(dim)), dxstart=ddimstart, intervals=intv) else: grid= simple_gridtmpl.format( dim=dim, min=getkw('{}min'.format(dim)), max=getkw('{}max'.format(dim)), cells=getkw('{}cells'.format(dim))); grids.append(grid); return grids;
def genconductors(**kw): getkw=mk_getkw(kw, condb_defaults); conductorss=''; for I,conductor in enumerate(getkw('conductors')): cd = sd(condb_objdef, **conductor); coords=dict(); if test(cd,'outlet'): outlet = cd['outlet']; if outlet not in all_lims: raise ValueError('Unknown outlet "{}"'.format(outlet)); coords = outlet_coords(outlet,kw); cd['width']*=1e-4; cd['start']*=1e-4; if outlet[-2:] == 'ax': sign = 1.0; else: sign =-1.0 cd['type']= 'BLOCK'; coords[outlet] += sign*(cd['width'] + cd['start']); coords[otherside(outlet)] += sign*cd['start']; cd['from'] = (coords['xmin'],coords['ymin'],coords['zmin']); cd['to'] = (coords['xmax'],coords['ymax'],coords['zmax']); conductorss += condf_tmpl.format( i=I+1, xf=cd['from'][0],yf=cd['from'][1],zf=cd['from'][2], **cd); def mk_to(cd): '''generate the to's''' return ''.join([ condt_tmpl.format(xt=xt,yt=yt,zt=zt) for xt,yt,zt in cd['to'] ]); if cd['type'] == 'BLOCK': if type(cd['to']) == list: cd['to'] = cd['to'][0] conductorss += condt_tmpl.format( xt=cd['to'][0],yt=cd['to'][1],zt=cd['to'][2]); elif cd['type'] == 'PARALLELPIPED': conductorss += mk_to(cd); elif cd['type'] == 'TRILATERAL': conductorss += mk_to(cd); conductorss += 'sweep_direction {sweep_direction}\n'.format( **cd); else: raise ValueError( "Unknown conductor type '{}'".format(cd['type'])); return conductorss;
def gendens(**kw): getkw = mk_getkw(kw, densdefaults) speciesl = getkw('speciesl') if test(kw, 'target_density'): Q = kw['target_density'] if type(Q) == tuple: #the reason for tuple and not a general iterable #is when we pass a single scale, for example, which #we scale by fracs pass else: if hasattr(Q[0], '__call__'): Q = [lambda x: frac * iQf(x) for frac, iQf in zip(fracs, Q)] else: Q = [frac * iQ for frac, iQ in zip(fracs, Q)] if hasattr(Q[0], '__call__'): #invariant: txmin,txmax are in cm. x = np.linspace(kw['txmin'][0], kw['txmax'][1], 20) Q[:] = [iQ(x) for iQ in Q] ret = { outputfmt.format(species): densitypairs_tmpl.format(data=iQ) for species, iQ in zip(speciesl, Q) } kw.update(ret) else: kw['dens_dat'] = getkw('dens_dat') kw['dens_imul'] = getkw('dens_imul') kw['dens_type'] = getkw('dens_type') kw['fracs'] = getkw('fracs') def copy_kw(l): if type(kw[l]) != tuple: kw[l] = (kw[l], ) * len(speciesl) copy_kw('dens_dat') copy_kw('dens_imul') copy_kw('dens_type') for i, species in enumerate(speciesl): kw['n_' + species] = densityfile_tmpl.format( targetdat=kw['dens_dat'][i], type=kw['dens_type'][i], imul=kw['dens_imul'][i], dmul=kw['fracs'][i]) pass return kw
def genhash(frame,**kw): ''' Generate the hashes for the given frame for a specification given in the dictionary d returned from firsthash. Parameters: ----------- frame : frame to hash. Keywords: --------- d : hash specification generated from firsthash. new : use new hashing, which isn't really hashing. removedups: put -1 in duplicates, dims : specify dims. Supercedes the setting in `d'. dupes : array of hashes known to be dupes. ftype : type of floats. defaults to 'f'. -- old keywords from old hashing -- mins : minima of each axis avgdifs : average differences pw : powers of each axis Returns an array of the shape of the frames with hashes. ''' getkw = mk_getkw(kw,genhash_defaults,prefer_passed=True); dims = getkw('dims'); dupes= getkw('dupes'); if not getkw('new'): ip = np.array([frame['data'][l] for l in dims]).T; scaled = ((ip - getkw('mins'))/getkw('avgdiffs')).round().astype('int64'); hashes = (scaled*getkw('pw')).sum(axis=1).astype('int64'); else: hashes = np.array([ struct.pack('{}{}'.format(len(dims),getkw('ftype')), *[p[l] for l in dims]) for p in frame['data']]); if getkw('removedupes'): #marking duplicated particles if not getkw('dupes'): hashes = np.unique(hashes); else: dupei = np.in1d(hashes, getkw('dupes')); hashes[dupei] = -1 return hashes;
def genconductor_boundaries(**kw): getkw=mk_getkw(kw, condb_defaults); conductorss=''; for I,conductor in enumerate(getkw('conductors')): cd = sd(condb_objdef, **conductor); if test(cd,'from') and test(cd,'to'): cd['xmin'],cd['ymin'],cd['zmin'] = cd['from'] cd['xmax'],cd['ymax'],cd['zmax'] = cd['to'] pass; else: outlet = cd['outlet']; if outlet not in all_lims: raise ValueError('Unknown outlet "{}"'.format(outlet)); coords = outlet_coords(outlet,kw); cd['width']*=1e-4; cd['start']*=1e-4; sign = lambda outlet: 1.0 if outlet[-2:] == 'ax' else -1.0 coords[outlet] += sign(outlet)*(cd['width'] + cd['start']); coords[otherside(outlet)] += sign(outlet)*cd['start']; conductorss += condb_tmpl.format( i=I+1, **sd(cd,**coords)); return conductorss;
def gentargetdat(**kw): getkw = mk_getkw(kw, datdefaults) res = getkw("dat_xres") unit = getkw("unit") tlim = mt(getkw("tlim"), m=unit) if test(kw, "f_1D") or test(kw, "data1D"): dim = 1 elif (test(kw, "f_2D") or test(kw, "data2D")) and test(kw, "tlim"): dim = 2 elif (test(kw, "f_3D") or test(kw, "data3D")) and test(kw, "tlim"): dim = 3 else: raise ValueError("Cannot reckon data dimensionality") if dim == 1: if test(kw, "f_1D"): x = np.linspace(tlim[0], tlim[1], res) d = getkw("f_1D")(x) elif test(kw, "data1D"): x, d = getkw("data1D") s = StringIO() np.savetxt(s, np.array([x, d]).T, fmt="%.8e") return s.getvalue() elif dim == 2: if test(kw, "f_2D"): x = np.linspace(tlim[0], tlim[1], res) if np.isclose(tlim[2] - tlim[3], 0): y = np.linspace(tlim[4], tlim[5], res) else: y = np.linspace(tlim[2], tlim[3], res) X, Y = np.meshgrid(x, y, indexing="ij") d = getkw("f_2D")(X, Y) elif test(kw, "data2D"): x, y, d = getkw("data2D") s = StringIO() s.write("{} {}\n".format(d.shape[0], d.shape[1])) np.savetxt(s, np.array([x]).T, fmt="%.8e") np.savetxt(s, np.array([y]).T, fmt="%.8e") np.savetxt(s, np.array(d).T, fmt="%.8e") return s.getvalue() else: if test(kw, "f_3d"): x = np.linspace(tlim[0], tlim[1], res) y = np.linspace(tlim[2], tlim[3], res) z = np.linspace(tlim[4], tlim[5], res) X, Y, Z = np.meshgrid(x, y, z, indexing="ij") d = getkw("f_3d")(X, Y, Z) elif test(kw, "data3D"): x, y, z, d = getkw("data3D") s = StringIO() s.write("{} {} {}\n".format(d.shape[0], d.shape[1], d.shape[2])) s.write("# x\n") np.savetxt(s, np.array(x).reshape(1, -1), fmt="%.8e") s.write("# y\n") np.savetxt(s, np.array(y).reshape(1, -1), fmt="%.8e") s.write("# z\n") np.savetxt(s, np.array(z).reshape(1, -1), fmt="%.8e") s.write("# data\n") for sub in np.rollaxis(d, 1): np.savetxt(s, np.array(sub).T, fmt="%.8e") return s.getvalue() pass
def genpbs(**kw): getkw = mk_getkw(kw, defaults) domains = getkw('domains') lspexec = getkw('lspexec') cluster = getkw("cluster") clusterq = cluster if test(kw, "queue"): clusterq += "_" + kw['queue'] mycluster = clusters[clusterq] if test(kw, 'ppn'): ppn = kw['ppn'] else: ppn = mycluster['max_ppn'] nodes = int(domains / ppn) if domains % ppn > 0: nodes += 1 extra_headers = '' mpirun = mycluster['mpi'].format(domains) pre = ''' cd $PBS_O_WORKDIR ''' portions = normal_portion_tmpl.format(nodes=nodes, ppn=ppn) walltime = getkw("walltime") if walltime is inf: walltime = mycluster['max_walltime'] elif walltime > mycluster['max_walltime']: import sys sys.stderr.write("walltime exceedes allowed for {}".format(clusterq)) walltime = hours_to_walltime(walltime) if cluster == "ramses": pre = "module load openmpi-1.4.3-gnu-rpm\n\n" + pre if nodes == 1: pre = ''' D=/tmp/ngirmang.1-`mkdate`-$PBSBASE mkdir -p $D cd $PBS_O_WORKDIR cp autozipper {lspexec} {pbsbase}.lsp *.dat $D/ cd $D '''.format(lspexec=lspexec, pbsbase=pbsbase) pass else: mpirun += "-hostfile $PBS_NODEFILE" elif cluster == "garnet": if not test(kw, 'queue'): kw['queue'] = "standard_lw" if not test(kw, 'mpiprocs'): kw['mpiprocs'] = ppn portions = garnet_portion_tmpl.format(nodes=nodes, max_ppn=mycluster['max_ppn'], ppn=ppn) extra_headers = ''' #PBS -A __projectid__ #PBS -q {} '''.format(kw['queue']) if test(kw, 'autozipper'): pre += '''#autozipper ./autozipper > $PBS_O_WORKDIR/autozipper.log& ''' with open("hotwater3d_tmpl.pbs") as f: s = f.read() return s.format( nodes=nodes, mpirun_opts=mpirun, pre=pre, ppn=ppn, portions=portions, pbsbase=getkw('pbsbase'), walltime=walltime, mpirun=mpirun, extra_headers=extra_headers, lspexec=lspexec, )
def genboundaries(**kw): retboundaries = '' if test(kw,'manual_boundaries'): return '\n'.join([ manual_genboundary(bspec,**kw) for bspec in kw['manual_boundaries'] ]); laserkw = kw['laseroutlet'] if test(kw, 'laseroutlet') else dict(); laserkw = sd(kw, **laserkw); getkw = mk_getkw(laserkw,outletdefaults,prefer_passed = True); lset = set(); side_label = dict( xmin='front', xmax='back', ymin='left', ymax='right', zmin='bottom', zmax='top'); ls = []; if not test(laserkw, 'multilaser') and not (test(laserkw,'nolaser') or test(laserkw,'nolaser_outlet')): ls = [ sd(laserkw, outlet='xmin') ]; elif test(laserkw,'multilaser'): ls = kw['multilaser']; print("experimental multi-lasers"); print("if you put more than one laser on a single outlet,"); print("be sure to be using my modifications to lsp for it."); ls = kw['multilaser']; #lasers for l in ls: l = sd(laserkw, **l); lgetkw = mk_getkw(l, laserdefaults, prefer_passed = True); outlet = lgetkw('outlet'); if outlet not in all_lims: raise ValueError('Unknown outlet "{}"'.format(outlet)); lset.add(outlet); retboundaries += laser10_tmpl.format( fp = joinspace(mt(lgetkw("fp"),getkw('ux'))), components = joinspace(lgetkw("components")), phase_velocity = lgetkw('phase_velocity'), phases = joinspace(lgetkw("phases")), lasertfunc = lgetkw('lasertfunc'), laserafunc = lgetkw('laserafunc'), time_delay = lgetkw('laser_time_delay'), **outlet_coords(outlet, l) ); just_outlets = [i for i in all_lims if i not in lset]; if test(kw,'freespace'): getkwfr = mk_getkw( sd(kw,**kw['freespace']),frsp_defs,prefer_passed=True); di=dict(); di['model_type'] = getkwfr('model_type'); if di['model_type'] not in ["WAVEABC","UNIAXIAL","CFSPML"]: raise ValueError("unrecognized model_type for freespace"); if di['model_type']=="WAVEABC": di['num_of_cells'] = ""; else: di['num_of_cells'] = "number_of_cells {}".format( getkwfr('num_of_cells')); keeps = getkwfr('keep_outlets'); if keeps is None: keeps = []; just_outlets = [ i for i in just_outlets if i in keeps ]; if test(kw['freespace'],'frlim'): for dim,lim in zip(getkwfr('frlim'),all_lims): di[lim] = dim; else: dx = getkwfr('freesp_delta'); keepset = lset.union(just_outlets); for lim in all_lims: di[lim] = getkw(lim); if lim in keepset: if 'min' in lim: di[lim] -= dx; else: di[lim] += dx; di['refp'] = joinspace(getkwfr('freesp_refp')); di['label']= getkwfr('freesp_label'); retboundaries += freespace_tmpl.format(**di); #outlet boundaries which and are not removed by freespace for side in just_outlets: if laserkw[side[0]+'cells'] > 0: retboundaries += outlet_none_tmpl.format( label = side_label[side], phase_velocity=getkw('phase_velocity'), **outlet_coords(side, laserkw)); pwbtmpl=''' planewave from {xmin:e} {ymin:e} {zmin:e} to {xmax:e} {ymax:e} {zmax:e} reference_point {refp} polar_angle {polar} azimuthal_angle {azimuth} rotation_angle {rotation} frequency {freq} temporal_function {pwfunc} ''' pwbdefs = dict( polar=90, azimuth=45, rotation=-45, freq=1e3, pwfunc=3, pw_refp=[0.0,0.0,0.0], ) if test(kw, 'planewave_boundary'): di=dict(); pwkw = sd(kw,**kw['planewave_boundary']); getkwpw = mk_getkw( pwkw,pwbdefs,prefer_passed=True); if not test(pwkw, 'pwblim'): raise ValueError("This requires pwblim for now"); pwlims = getkwpw('pwblim'); for dim,lim in zip(pwlims,all_lims): di[lim] = dim; for qi in ['polar','azimuth','rotation','freq','pwfunc']: di[qi] = getkwpw(qi); di['refp'] = joinspace(getkwpw('pw_refp')); retboundaries+=pwbtmpl.format(**di); return retboundaries;
def genoptions(**kw): if test(kw, "options"): kw = sd(kw, kw['options']) #quirks getkw_outer = mk_getkw(kw, lspdefaults, prefer_passed=True) kw['maximum_restart_dump_time'] = getkw_outer('restart') def genopt(k, getkw=getkw_outer, flag=False): if not flag: flag = k i = getkw(k) if re.search("_ns$", flag): if isvalue(i): i *= 1e9 else: scaletuple(i, 1e9) if i is None or i is (): return "" elif i is True: return "{} ON\n".format(flag) elif i is False: return "{} OFF\n".format(flag) elif isvalue(i): return "{} {}\n".format(flag, i) else: return "{} {} end\n".format(flag, joinspace(i)) def genopts(opts): title, opts = opts getkw = mk_getkw(kw, opts, prefer_passed=True) tmpl = ";;{}\n{}\n" all_opts = "".join([genopt(k, getkw) for k in sorted(opts.keys())]) return tmpl.format(title, all_opts) out = ''.join([genopts(iopts) for iopts in [ restart_opts, balance_opts, ]]) out += options_dont_touch out += ''.join([genopts(iopts) for iopts in [ kinematic_opts, dump_opts, ]]) #now we do big dumps kw['interval_ns'] = getkw_outer("dumpinterval") kw['times_ns'] = getkw_outer("dumptimes") kw['steps'] = getkw_outer("dumpsteps") def gen_dumpopt(dump, opt): label = "{}_dump_{}".format(dump, opt) if test(kw, label): return genopt(label) else: return genopt(opt, flag=label) for dump in bigdumps: if not getkw_outer("dump_{}".format(dump)): continue out += "dump_{}s_flag ON\n".format(dump) for iopt in ['interval_ns', 'times_ns', 'steps']: out += gen_dumpopt(dump, iopt) return out
def angular(d, phi=None, e=None, **kw): ''' Make the angular plot. Call form 1: angular(s, phi, e, kw...) Arguments: s -- the charges. phi -- the angles of ejection. e -- energies of each charge. Call form 2 angular(d, kw...) Arguments: d -- pext data, a structured array from the lspreader. Keyword Arugments: phi -- If a string, read this array of recs as the angles. If an array, these are the angles. e -- If not None, use these as energies over d['KE'] energy_units -- Set the energy units. Options are eV, KeV, MeV, GeV, and auto. auto chooses the unit based on the max energy. energy_scale -- Set the energy scale. Not required, but you can hack it from the default due to energy_unit if you wish. toMeV -- Scale to the MeV scale from energy scale. Not required, but you can hack it from energy_unit if you wish. max_e -- Maximum energy, if 'auto', bin automatically. e_step -- Set the steps of the radius contours. min_q -- Minimum charge. max_q -- Maximum charge. angle_range -- Only bin and plot these angles. Does not affect angle binning, bins are still over (-pi,pi) angle_bins -- Set the number of angle bins. energy_bins -- Set the number of energy bins. colorbar -- If true, plot the colorbar. cmap -- use the colormap cmap. clabel -- Set the colorbar label. labels -- Set the angular labels. If not a list, if 'default', use default. If 'tdefault', use default for theta. (See defaults dict); normalize -- Subdivide charges by the bin weights. fig -- If set, use this figure, Otherwise, make a new figure. ax -- If set, use this axis. Otherwise, make a new axis. ltitle -- Make a plot on the top left. rtitle -- Make a plot on the top right. log_q -- log10 the charges. rgridopts -- pass a dictionary that sets details for the rgrid labels. Options for this dict are: angle -- angle of labels. size -- text side. color -- grid color. invert -- invert the rgrid colors. oap -- Plot this apex angle if not None as the oap collection angle. efficiency -- calculate and display the conversion efficiency in the oap angle. A dict of options passed to totalKE and laserE (I only, not E_0). See help for totalKE and laserE. F -- Multiply charges by a factor. dict_return -- Have the return value be a convenient dictionary instead of god knows what it currently is (a tuple of tuple of stuff). ''' #reckon the call form getkw = mk_getkw(kw, defaults) if type(d) == np.ndarray and len(d.dtype) > 0: structd = True e = np.copy(d['KE']) if not phi: phi = 'phi' phi = np.copy(d[phi]) s = np.abs(d['q']) * 1e6 else: structd = False if phi is None or e is None: raise ValueError("Either phi and s were not passed. See help.") s = d eunits = getkw('energy_units') if eunits == 'auto': pw = np.log10(np.max(e)) if pw < 3: eunits = 'eV' elif pw <= 5: eunits = 'KeV' elif pw <= 9: eunits = 'MeV' else: eunits = 'GeV' if test(kw, 'angle_range'): mnang, mxang = kw['angle_range'] if mxang > np.pi: good = np.logical_and(phi >= mnang, phi <= np.pi) good |= np.logical_and(phi >= -np.pi, phi <= -(mxang - np.pi)) else: good = np.logical_and(phi >= mnang, phi <= mxang) phi = phi[good] e = e[good] s = s[good] if structd: d = d[good] getunitkw = mk_getkw(kw, unit_defaults[eunits]) if test(kw, 'F'): s *= kw['F'] phi_spacing = getkw('angle_bins') E_spacing = getkw('energy_bins') e /= getunitkw('energy_scale') maxE = getunitkw('max_e') Estep = getunitkw('e_step') if maxE == 'max': maxE = np.max(e) elif maxE == 'round' or maxE == 'auto': mxe = np.max(e) tenpow = np.floor(np.log10(mxe)) mantissa = np.floor(mxe / (10**tenpow)) maxE = 10**tenpow * (int(mxe / (10**tenpow)) + 1) Estep = 10**tenpow if mantissa > 6: Estep = 6 * 10**tenpow if test(kw, 'e_step'): Estep = kw['e_step'] maxQ = getkw('max_q') minQ = getkw('min_q') if test(kw, "normalize"): s /= maxE / E_spacing * 2 * np.pi / phi_spacing s *= getunitkw('toMeV') clabel = getkw('clabel') cmap = getkw('cmap') phi_bins = np.linspace(-np.pi, np.pi, phi_spacing + 1) E_bins = np.linspace(0, maxE, E_spacing + 1) PHI, E = np.mgrid[-np.pi:np.pi:phi_spacing * 1j, 0:maxE:E_spacing * 1j] S, _, _ = np.histogram2d(phi, e, bins=(phi_bins, E_bins), weights=s) if test(kw, 'fig'): fig = kw['fig'] else: fig = plt.figure(1, facecolor=(1, 1, 1)) if test(kw, 'ax'): ax = kw['ax'] else: ax = plt.subplot(projection='polar', facecolor='white') norm = matplotlib.colors.LogNorm() if test(kw, 'log_q') else None ax.set_rmax(maxE) surf = plt.pcolormesh(PHI, E, S, norm=norm, cmap=cmap, vmin=minQ, vmax=maxQ) if test(kw, 'colorbar'): c = fig.colorbar(surf, pad=0.1) c.set_label(clabel) #making radial guides. rgrids only works for plt.polar calls #making rgrid if test(kw, 'rgridopts'): ropts = kw['rgridopts'] else: ropts = dict() getrkw = mk_getkw(ropts, rgrid_defaults) if test(ropts, 'unit'): runit = ropts['unit'] else: runit = eunits rangle = getrkw('angle') rsize = getrkw('size') gridc = getrkw('color') if test(ropts, 'invert'): c1, c2 = "w", "black" else: c1, c2 = "black", "w" full_phi = np.linspace(0.0, 2 * np.pi, 100) rlabels = np.arange(0.0, maxE, Estep)[1:] for i in rlabels: plt.plot(full_phi, np.ones(full_phi.shape) * i, c=gridc, alpha=0.9, lw=1, ls='--') ax.set_theta_zero_location('N') ax.patch.set_alpha(0.0) ax.set_facecolor('red') rlabel_str = '{} ' + runit #text outlines. _, ts = plt.rgrids(rlabels, labels=map(rlabel_str.format, rlabels), angle=rangle) for t in ts: t.set_path_effects( [pe.Stroke(linewidth=1.5, foreground=c2), pe.Normal()]) t.set_size(rsize) t.set_color(c1) if test(kw, 'oap'): oap = kw['oap'] / 2 * np.pi / 180 maxt = oap + np.pi mint = np.pi - oap maxr = maxE * .99 if test(kw, 'efficiency') and structd: defeff = dict(I=3e18, w=None, T=None, l=None, ecut=0, anglecut=None) effd = sd(defeff, **kw['efficiency']) if effd['ecut'] == 'wilks': effd['ecut'] = ( np.sqrt(1 + a0(effd['I'], l=effd['l'] * 1e2)**2 / 2.0) - 1.0) * effd['massE'] dim = effd['dim'] LE = laserE(I=effd['I'], w=effd['w'], T=effd['T'], dim=dim) KE, good = totalKE(d, ecut=effd['ecut'], anglecut=(oap / np.pi * 180, dim), return_bools=True) minr = effd['ecut'] / getunitkw('energy_scale') totalq = np.abs(d['q'][good]).sum() * 1e6 def texs(f, l=2): tenpow = int(np.floor(np.log10(f))) nfmt = "{{:0.{}f}}".format(l) + "\\cdot 10^{{{}}}" return nfmt.format(f / 10**tenpow, tenpow) fig.text(0.01, 0.04, "Efficiency:\n$\\frac{{{}J}}{{{}J}}$=${}$".format( texs(KE, l=1), texs(LE, l=1), texs(KE / LE)), fontdict=dict(fontsize=20)) fig.text(0.65, 0.05, "$Q_{{tot}}={} ${}".format( texs(totalq), "pC" if dim == "3D" else "pC/cm"), fontdict=dict(fontsize=20)) fig.text(0.6, 0.92, "I = ${}$ W/cm$^2$".format(texs(effd['I'], l=1)), fontdict=dict(fontsize=20)) else: minr = 0.12 / getunitkw('toMeV') ths = np.linspace(mint, maxt, 20) rs = np.linspace(minr, maxr, 20) mkline = lambda a, b: plt.plot( a, b, c=(0.2, 0.2, 0.2), ls='-', alpha=0.5) mkline(ths, np.ones(ths.shape) * minr) mkline(mint * np.ones(ths.shape), rs) mkline(maxt * np.ones(ths.shape), rs) if test(kw, 'labels'): if kw['labels'] == 'default': labels = defaults['labels'] elif kw['labels'] == 'tdefault': labels = defaults['tlabels'] else: labels = kw['labels'] ax.set_xticks(np.pi / 180 * np.linspace(0, 360, len(labels), endpoint=False)) ax.set_xticklabels(labels) if test(kw, 'ltitle'): if len(kw['ltitle']) <= 4: ax.set_title(kw['ltitle'], loc='left', fontdict={'fontsize': 24}) else: ax.text(np.pi / 4 + 0.145, maxE + Estep * 2.4, kw['ltitle'], fontdict={'fontsize': 24}) if test(kw, 'rtitle'): if '\n' in kw['rtitle']: fig.text(0.60, 0.875, kw['rtitle'], fontdict={'fontsize': 22}) else: plt.title(kw['rtitle'], loc='right', fontdict={'fontsize': 22}) if test(kw, 'dict_return'): return dict( surf=surf, ax=ax, fig=fig, phi_bins=phi_bins, E_bins=E_bins, phi=phi, e=e, s=s, eunits=eunits, ) else: return (surf, ax, fig, (phi_bins, E_bins), (phi, e, s))
def genopts(opts): title, opts = opts getkw = mk_getkw(kw, opts, prefer_passed=True) tmpl = ";;{}\n{}\n" all_opts = "".join([genopt(k, getkw) for k in sorted(opts.keys())]) return tmpl.format(title, all_opts)
def genpext(**kw): def getkw(l,scale=None): if test(kw, l): ret = kw[l] else: ret = pext_defaults[l]; if scale: return [scale*i for i in ret]; return ret; tmpl=''' ; extract{i} species {species} direction {direction} maximum_number 1000000000 start_time {start_time} stop_time {stop_time} at {position} ''' lims = list(getkw('lim',scale=getkw('ux'))); lims[0] = [lims[0],0,0]; lims[1] = [lims[1],0,0]; lims[2] = [0,lims[2],0]; lims[3] = [0,lims[3],0]; lims[4] = [0,0,lims[4]]; lims[5] = [0,0,lims[5]]; dirs = ['X','X','Y','Y','Z','Z']; planes = list(zip(dirs,lims)); if kw['zcells'] == 0: del planes[4:6]; if kw['ycells'] == 0: del planes[2:4]; def formatsp(sp,i): return [ dict(i=i+j+1, species=sp, direction=d, start_time=getkw('start_time'), stop_time =getkw('stop_time'), position =joinspace(lim)) for j,(d,lim) in enumerate(planes)]; pextplanes = [ tmpl.format(**d) for i,sp in enumerate(getkw('species')) for d in formatsp(sp,len(planes)*i)]; ret = joinspace(pextplanes); if test(kw, 'extrapexts'): ppl = len(pextplanes); expext_def = dict( species=10, direction='X', start_time=0, stop_time=1, position=(0.0,0.0,0.0), ); expexts = []; for p in getkw('extrapexts'): if test(p,'species') and p['species'] != 'all': expexts.append(p); elif test(p,'species') and type(p['species']) != str: expexts += [ sd(p, species = sp) for sp in p['species']]; else: expexts += [ sd(p, species = sp) for sp in getkw('species') ]; for i,ep in enumerate(expexts): pgetkw = mk_getkw(p, expext_def, prefer_passed = True); ret+=tmpl.format( i=ppl+i+1, species = pgetkw('species'), direction = pgetkw('direction'), start_time = pgetkw('start_time'), stop_time = pgetkw('stop_time'), position = joinspace(pgetkw('position')),); return ret;
def gensim(**kw): getkw = mk_getkw(kw,defaults); pbsbase=getkw("pbsbase"); files = ["sine700points.dat"]; if test(kw, "autozipper"): files.append('zipper'); files.append('loopscript'); # # target creation # if test(kw,'singlescale'): if type(getkw('fp')) != tuple: fpx = get_roundfpx(kw); if getkw('fp') != 'nc': fpx += getkw('fp'); kw['fp'] = (fpx,0.0,0.0); tlim = getkw('tlim') kw['xlen'] = tlim[1]-tlim[0]; dens = genonescale(**kw); kw['dens_dat'] = "{}um.dat".format(getkw('expf')); files.append((kw['dens_dat'], dens)); elif test(kw, 'scale_with_min'): #this involves a single scale where we #pick the min. We figure out the longitudinal #dimensions ourselves if not test(kw,'long_res') and not test(kw,'long_resd'): raise ValueError( "you must supply a longitudinal resolution for scale_with_min"); long_margin = getkw('long_margin'); expf,n_s,n_min,slen=getkw('expf','n_s','n_min','solid_len'); pp_len = expf*np.log(n_s/n_min); if test(kw,'roundup_pp'): pp_len = np.ceil(pp_len); elif test(kw,'roundup_ten_pp'): pp_len = np.ceil(pp_len/10) * 10; if type(getkw('fp')) != tuple: fpx = get_roundfpx(kw); if getkw('fp') != 'nc': fpx += getkw('fp'); kw['fp'] = (fpx,0.0,0.0); kw['lim'] = list(getkw('lim')); kw['tlim'] = list(getkw('tlim')); kw['res'] = list(getkw('res')); kw['tlim'][0] = -pp_len; kw['tlim'][1] = slen; kw['lim'][0] = kw['tlim'][0] - long_margin[0]; kw['lim'][1] = kw['tlim'][1] + long_margin[1]; xlen = kw['lim'][1] - kw['lim'][0]; if test(kw, 'long_res'): kw['res'][0] = xlen * kw['long_res'] elif test(kw, 'long_resd'): kw['res'][0] = int(np.round(xlen / (getkw('l')*1e6 / kw['long_resd']))); kw['timestep'] = getkw('timestep'); if xlen*1e-6/kw['res'][0] < c*kw['timestep']: print("adapting timestep..."); kw['timestep'] = xlen*1e-6/kw['res'][0]; dens = genonescale(xlen=kw['tlim'][1]-kw['tlim'][0], **kw); kw['dens_dat'] = "{:0.2f}um.dat".format(getkw('expf')); files.append((kw['dens_dat'], dens)); print("from scale_with_min, generated dimensions:"); print(take(kw,['expf','res','tlim','lim','timestep'])) #elif test(kw,'shelf'): # if type(getkw('fp')) != tuple: # tlim = getkw('tlim'); # kw['xlen'] = tlim[1]-tlim[0]; # if test(kw, 'slen'): # if getkw('fp') != 'nc': # fpx += getkw('fp'); # kw['fp'] = (fpx,0.0,0.0); elif (test(kw,'externalf_1D') and test(kw, 'f_1D')) or (test(kw,'externalf_2D') and test(kw, 'f_2D')): if not test(kw, 'dats'): kw['dats']=[]; tlim = getkw('tlim'); if not test(kw, 'new_externalf'): kwp = sd(kw, tlim=(0, tlim[1]-tlim[0], 0, tlim[3]-tlim[2], 0, 0), unit=1e-4); else: kwp = sd(kw, unit=1e-4); if not test(kw, 'dens_dat'): kw['dens_dat'] = "watercolumn.dat"; kw['dats'] += [(kw['dens_dat'], kwp)]; if test(kw, 'dats'): files.extend([ (fname, gendat(**sd(kw,**dat))) for fname,dat in kw['dats'] ]); # # movies # movs = takef(kw,['movne','movni','movdq','movrho','movE','movB','movS']); #yes really. tyf = lambda s: re.search(r"mov(\w+)",s).group(1); movs = { tyf(k) : movs[k] for k in movs if movs[k]}; for movtype in sorted(movs.keys()): sname ='mov'+movtype; movd={}; if type(kw[sname]) == dict: movd = sd(kw,**kw[sname]); if not test(movd,'n_c'): movd['n_c'] = nc(kw['l']); movd['type'] = movtype; movstr=gen_mov(**movd); #adding it to pbs if not test(kw, "concurrents") or kw['concurrents'] is None: kw['concurrents'] = [(sname,'./'+sname)]; else: kw['concurrents'] += [(sname,'./'+sname)]; files.append((sname,movstr,0o755) ); if test(kw,'angular'): #adding it to pbs if test(kw, "concurrents") and kw['concurrents'] is not None: kw['concurrents'] += [('genangular','./genangular')]; else: kw['concurrents'] = [('genangular','./genangular')]; files.append('genangular'); # #special subdivisions # if test(kw, "splittime"): totaltime = getkw("totaltime"); # Structure of splittime # [ (totaltime, dict) ] # Each tuple represents a slice of the restarts # totaltime is supposed to be the end of that time slice. # The dict is what enters subdiv. # # This does very little, it just overloads totaltime and # sets each `lspexec` of the restarts to r. It also adds a `pre` # that copies the restart files, facilitated by the "setrestart" # script. # # We read the last totaltime over the passed keyword. st = getkw("splittime"); kw['subdivs'] = []; for i,(itime, id) in enumerate(st): if id is None: id = {}; igetkw = mk_getkw( sd(kw,**id), defaults ); if i == 0: si = ''; else: si = '_{}'.format(i); kw['subdivs'].append( sd(id, totaltime=itime, lspexec =igetkw("lspexec")+" -r ", dump_restart_flag=True, pbsbase=pbsbase+si,)); subdivs = getkw("subdivs"); if len(subdivs) == 0: subdivs = [kw]; for subdiv in subdivs: if not subdiv: subdiv=dict(); ikw = sd(kw,**subdiv); igetkw = mk_getkw(ikw, defaults); pbses = igetkw('pbses'); ipbsbase = igetkw('pbsbase'); lsp=genlsp(**ikw); files.append((ipbsbase+".lsp", lsp)); if pbses is None: files.append((ipbsbase+".pbs",genpbs(**ikw))) else: if pbses == "defaults": pbses = mk_hpcmp_pbses( **ikw); for pbs in pbses: files.append( (pbs['pbsname']+".pbs", genpbs(**sd(ikw,**pbs))) ); if test(kw,'extra_files'): files.extend(kw['extra_files']); dir=getkw('dir'); if dir == True: dir = pbsbase; output(dir=dir,files=files);
def genoutlets(**kw): outlet_tmpl=''' ;{label} outlet from {xmin:e} {ymin:e} {zmin:e} to {xmax:e} {ymax:e} {zmax:e} phase_velocity 1.0 drive_model NONE'''; laser10_tmpl=''' ;laser outlet from {xmin:e} {ymin:e} {zmin:e} to {xmax:e} {ymax:e} {zmax:e} phase_velocity 1.0 drive_model LASER reference_point {fp} components {components} phases {phases} temporal_function {lasertfunc} analytic_function {laserafunc} time_delay {time_delay} ''' retoutlets = '' laserkw = kw['laseroutlet'] if test(kw, 'laseroutlet') else dict(); laserkw = sd(kw, **laserkw); getkw = mk_getkw(laserkw,outletdefaults,prefer_passed = True); lset = set(); side_label = dict( xmin='front', xmax='back', ymin='left', ymax='right', zmin='bottom', zmax='top'); ls = []; if not test(laserkw, 'multilaser') and not test(laserkw,'nolaser'): ls = [ sd(laserkw, outlet='xmin') ]; elif test(laserkw,'multilaser'): ls = kw['multilaser']; print("experimental multi-lasers"); print("if you put more than one laser on a single outlet,"); print("be sure to be using my modifications to lsp for it."); ls = kw['multilaser']; #lasers for l in ls: l = sd(laserkw, **l); lgetkw = mk_getkw(l, laserdefaults, prefer_passed = True); outlet = lgetkw('outlet'); if outlet not in all_lims: raise ValueError('Unknown outlet "{}"'.format(outlet)); lset.add(outlet); retoutlets += laser10_tmpl.format( fp = joinspace(scaletuple(lgetkw("fp"))), components = joinspace(lgetkw("components")), phases = joinspace(lgetkw("phases")), lasertfunc = lgetkw('lasertfunc'), laserafunc = lgetkw('laserafunc'), time_delay = lgetkw('laser_time_delay'), **outlet_coords(outlet, l) ); #outlet boundaries for side in [i for i in all_lims if i not in lset] : if laserkw[side[0]+'cells'] > 0: retoutlets += outlet_tmpl.format( label = side_label[side], **outlet_coords(side, laserkw)); return retoutlets;
def genpbs(**kw): getkw = mk_getkw(kw,pbsdefaults); domains=getkw('domains'); lspexec=getkw('lspexec'); pbsbase=getkw('pbsbase'); label = getkw('label'); email = getkw('email'); if not label: label = pbsbase; cluster = getkw("cluster"); clusterq = cluster; concurrents = getkw('concurrents'); if not concurrents: concurrents=[]; if 'autozipper' not in kw or kw['autozipper']: concurrents = [ ('zipper','./zipper -a >$PBS_O_WORKDIR') ]+concurrents movne=False; if test(kw,"queue"): clusterq += "_"+kw['queue']; mycluster = clusters[clusterq]; if test(kw,'ppn'): ppn = kw['ppn']; else: ppn = mycluster['max_ppn']; nodes=int(domains/ppn); if domains%ppn > 0: nodes+=1; mpiformat = mycluster['mpi'] extra_headers=''; pre = ''' cd "$PBS_O_WORKDIR" '''; portions = normal_portion_tmpl.format( nodes=nodes,ppn=ppn); walltime = getkw("walltime"); if walltime is inf: walltime = mycluster['max_walltime'] elif walltime > mycluster['max_walltime']: import sys sys.stderr.write("walltime exceedes allowed for {}".format( clusterq)); walltime = hours_to_walltime(walltime); post='' # # server quirks # if cluster == "ramses": if nodes == 1: pre += ''' D={ramses_rundir} mkdir -p $D cd "$PBS_O_WORKDIR" cp {lspexec} {pbsbase}.lsp *.dat $D/ '''.format(lspexec=lspexec, ramses_rundir=getkw('ramses_rundir'), pbsbase=pbsbase); for concurrent in concurrents: pre+='cp {} $D/\n'.format(concurrent[0]); if len(concurrents) > 0: pre+='cp loopscript $D/\n'; pre+='cd $D\n' pre = "module load openmpi-1.4.3-gnu-rpm\n\n"+pre; if dodcluster(cluster): if test(kw,'mpiprocs') and kw['mpiprocs'] != ppn: mpiformat = 'aprun -n {{}} -N {}'.format( kw['mpiprocs']) nodes=int(domains/kw['mpiprocs']); if domains%kw['mpiprocs'] > 0: nodes+=1; else: kw['mpiprocs'] = ppn; portions = garnet_portion_tmpl.format( nodes=nodes, ppn=ppn, mpiprocs=kw['mpiprocs']); extra_headers="#PBS -A __projectid__\n#PBS -q {}\n".format( kw['queue']); if test(kw, "mkrundir"): pre += ( 'export RUNDIR="${{PBS_JOBNAME}}_${{PBS_JOBID}}"\n' 'mkdir -p $RUNDIR' 'rcp {lspexec} {pbsbase}.lsp *.dat $RUNDIR' 'cd $RUNDIR' ); if cluster == "garnet": #truncate name because life sucks label = label[:14]; if not test(kw,'queue'): kw['queue']="standard_lw"; #handling conncurrent scripts if not dodcluster(cluster): for concurrent in concurrents: script = concurrent[0] pre+='''#{script} ./loopscript {script} &> $PBS_O_WORKDIR/{script}.log& {script}_PID=$! '''.format(script=script); post+="kill ${script}_PID\n".format(script=script); if len(concurrent)>1: post+="{}\n".format(concurrent[1]); mpirun = mpiformat.format(domains); #finally outputting with open("hotwater3d_tmpl.pbs") as f: s=f.read(); return s.format( label=label, nodes=nodes, mpirun_opts=mpirun, pre=pre, post=post, ppn=ppn, portions=portions, email=email, pbsbase=getkw('pbsbase'), walltime=walltime, mpirun=mpirun, extra_headers=extra_headers, lspexec=lspexec,);
def angular(d, phi=None, e=None, **kw): ''' Make the angular plot. Call form 1: angular(s, phi, e, kw...) Arguments: s -- the charges. phi -- the angles of ejection. e -- energies of each charge. Call form 2 angular(d, kw...) Arguments: d -- pext data, a structured array from the lspreader. Keyword Arugments: phi -- If a string, read this array of recs as the angles. If an array, these are the angles. e -- If not None, use these as energies over d['KE'] energy_units -- Set the energy units. Options are eV, KeV, MeV, GeV, and auto. auto chooses the unit based on the max energy. energy_scale -- Set the energy scale. Not required, but you can hack it from the default due to energy_unit if you wish. toMeV -- Scale to the MeV scale from energy scale. Not required, but you can hack it from energy_unit if you wish. max_e -- Maximum energy, if 'auto', bin automatically. e_step -- Set the steps of the radius contours. min_q -- Minimum charge. max_q -- Maximum charge. angle_range -- Only bin and plot these angles. Does not affect angle binning, bins are still over (-pi,pi) angle_bins -- Set the number of angle bins. energy_bins -- Set the number of energy bins. colorbar -- If true, plot the colorbar. cmap -- use the colormap cmap. clabel -- Set the colorbar label. labels -- Set the angular labels. If not a list, if 'default', use default. If 'tdefault', use default for theta. (See defaults dict); normalize -- Subdivide charges by the bin weights. fig -- If set, use this figure, Otherwise, make a new figure. ax -- If set, use this axis. Otherwise, make a new axis. ltitle -- Make a plot on the top left. rtitle -- Make a plot on the top right. log_q -- log10 the charges. rgridopts -- pass a dictionary that sets details for the rgrid labels. Options for this dict are: angle -- angle of labels. size -- text side. color -- grid color. invert -- invert the rgrid colors. oap -- Plot this apex angle if not None as the oap collection angle. efficiency -- calculate and display the conversion efficiency in the oap angle. A dict of options passed to totalKE and laserE (I only, not E_0). See help for totalKE and laserE. F -- Multiply charges by a factor. dict_return -- Have the return value be a convenient dictionary instead of god knows what it currently is (a tuple of tuple of stuff). ''' #reckon the call form getkw = mk_getkw(kw,defaults); if type(d) == np.ndarray and len(d.dtype) > 0: structd = True; e = np.copy(d['KE']); if not phi: phi = 'phi'; phi = np.copy(d[phi]); s = np.abs(d['q'])*1e6; else: structd = False; if phi is None or e is None: raise ValueError( "Either phi and s were not passed. See help."); s = d; eunits = getkw('energy_units'); if eunits == 'auto': pw = np.log10(np.max(e)) if pw < 3: eunits = 'eV'; elif pw <= 5: eunits = 'KeV'; elif pw <= 9: eunits = 'MeV'; else: eunits = 'GeV'; if test(kw,'angle_range'): mnang,mxang = kw['angle_range']; if mxang > np.pi: good = np.logical_and(phi >= mnang, phi <= np.pi); good|= np.logical_and(phi >= -np.pi, phi <= -(mxang-np.pi)); else: good = np.logical_and(phi >= mnang, phi <= mxang); phi = phi[good]; e = e[good]; s = s[good]; if structd: d = d[good]; getunitkw = mk_getkw(kw,unit_defaults[eunits]); if test(kw, 'F'): s*=kw['F']; phi_spacing = getkw('angle_bins'); E_spacing = getkw('energy_bins'); e /= getunitkw('energy_scale'); maxE = getunitkw('max_e'); Estep = getunitkw('e_step'); if maxE == 'max': maxE = np.max(e); elif maxE == 'round' or maxE == 'auto': mxe = np.max(e); tenpow = np.floor(np.log10(mxe)) mantissa = np.floor(mxe/(10**tenpow)); maxE = 10**tenpow * (int(mxe/(10**tenpow))+1) Estep = 10**tenpow; if mantissa > 6: Estep = 6*10**tenpow; if test(kw,'e_step'): Estep = kw['e_step']; maxQ = getkw('max_q'); minQ = getkw('min_q'); if test(kw,"normalize"): s /= maxE/E_spacing*2*np.pi/phi_spacing; s *= getunitkw('toMeV'); clabel = getkw('clabel'); cmap = getkw('cmap'); phi_bins = np.linspace(-np.pi,np.pi,phi_spacing+1); E_bins = np.linspace(0, maxE, E_spacing+1); PHI,E = np.mgrid[ -np.pi : np.pi : phi_spacing*1j, 0 : maxE : E_spacing*1j]; S,_,_ = np.histogram2d(phi,e,bins=(phi_bins,E_bins),weights=s); if test(kw,'fig'): fig = kw['fig'] else: fig = plt.figure(1,facecolor=(1,1,1)); if test(kw,'ax'): ax = kw['ax'] else: ax = plt.subplot(projection='polar',facecolor='white'); norm = matplotlib.colors.LogNorm() if test(kw,'log_q') else None; ax.set_rmax(maxE); surf=plt.pcolormesh( PHI,E,S,norm=norm,cmap=cmap, vmin=minQ,vmax=maxQ); if test(kw,'colorbar'): c=fig.colorbar(surf,pad=0.1); c.set_label(clabel); #making radial guides. rgrids only works for plt.polar calls #making rgrid if test(kw, 'rgridopts'): ropts = kw['rgridopts']; else: ropts = dict(); getrkw = mk_getkw(ropts,rgrid_defaults); if test(ropts, 'unit'): runit = ropts['unit']; else: runit = eunits; rangle=getrkw('angle'); rsize =getrkw('size'); gridc =getrkw('color'); if test(ropts, 'invert'): c1,c2 = "w","black"; else: c1,c2 = "black","w"; full_phi = np.linspace(0.0,2*np.pi,100); rlabels = np.arange(0.0,maxE,Estep)[1:]; for i in rlabels: plt.plot(full_phi,np.ones(full_phi.shape)*i, c=gridc, alpha=0.9, lw=1, ls='--'); ax.set_theta_zero_location('N'); ax.patch.set_alpha(0.0); ax.set_facecolor('red'); rlabel_str = '{} ' + runit; #text outlines. _,ts=plt.rgrids(rlabels, labels=map(rlabel_str.format,rlabels), angle=rangle); for t in ts: t.set_path_effects([ pe.Stroke(linewidth=1.5, foreground=c2), pe.Normal() ]); t.set_size(rsize); t.set_color(c1); if test(kw,'oap'): oap = kw['oap']/2 * np.pi/180; maxt = oap+np.pi; mint = np.pi-oap; maxr = maxE*.99; if test(kw, 'efficiency') and structd: defeff = dict( I=3e18,w=None,T=None,l=None, ecut=0, anglecut=None); effd=sd(defeff,**kw['efficiency']); if effd['ecut'] == 'wilks': effd['ecut'] = ( np.sqrt(1+a0(effd['I'],l=effd['l']*1e2)**2/2.0) - 1.0 )*effd['massE']; dim = effd['dim']; LE=laserE(I=effd['I'],w=effd['w'],T=effd['T'],dim=dim); KE,good=totalKE( d, ecut=effd['ecut'], anglecut=(oap/np.pi*180,dim), return_bools=True) minr = effd['ecut'] / getunitkw('energy_scale'); totalq = np.abs(d['q'][good]).sum()*1e6; def texs(f,l=2): tenpow=int(np.floor(np.log10(f))); nfmt = "{{:0.{}f}}".format(l) + "\\cdot 10^{{{}}}" return nfmt.format(f/10**tenpow,tenpow); fig.text( 0.01,0.04, "Efficiency:\n$\\frac{{{}J}}{{{}J}}$=${}$".format( texs(KE,l=1),texs(LE,l=1),texs(KE/LE)), fontdict=dict(fontsize=20)); fig.text( 0.65,0.05, "$Q_{{tot}}={} ${}".format( texs(totalq), "pC" if dim == "3D" else "pC/cm"), fontdict=dict(fontsize=20)); fig.text( 0.6,0.92, "I = ${}$ W/cm$^2$".format( texs(effd['I'],l=1)), fontdict=dict(fontsize=20)); else: minr = 0.12/getunitkw('toMeV') ths=np.linspace(mint, maxt, 20); rs =np.linspace(minr, maxr, 20); mkline = lambda a,b: plt.plot(a,b,c=(0.2,0.2,0.2),ls='-',alpha=0.5); mkline(ths, np.ones(ths.shape)*minr) mkline(mint*np.ones(ths.shape), rs); mkline(maxt*np.ones(ths.shape), rs); if test(kw,'labels'): if kw['labels'] == 'default': labels = defaults['labels']; elif kw['labels'] == 'tdefault': labels = defaults['tlabels']; else: labels= kw['labels']; ax.set_xticks(np.pi/180*np.linspace(0,360,len(labels),endpoint=False)); ax.set_xticklabels(labels); if test(kw,'ltitle'): if len(kw['ltitle']) <= 4: ax.set_title(kw['ltitle'],loc='left',fontdict={'fontsize':24}); else: ax.text(np.pi/4+0.145,maxE+Estep*2.4,kw['ltitle'],fontdict={'fontsize':24}); if test(kw,'rtitle'): if '\n' in kw['rtitle']: fig.text(0.60,0.875,kw['rtitle'],fontdict={'fontsize':22}); else: plt.title(kw['rtitle'],loc='right',fontdict={'fontsize':22}); if test(kw, 'dict_return'): return dict( surf=surf, ax=ax, fig=fig, phi_bins=phi_bins, E_bins=E_bins, phi=phi, e=e, s=s, eunits=eunits, ); else: return (surf, ax, fig, (phi_bins, E_bins), (phi,e,s));
def genoutlets(**kw): outlet_tmpl = ''' ;{side} outlet from {xf:e} {yf:e} {zf:e} to {xt:e} {yt:e} {zt:e} phase_velocity 1.0 drive_model NONE''' laser10_tmpl = ''' ;laser outlet from {xf:e} {yf:e} {zf:e} to {xt:e} {yt:e} {zt:e} phase_velocity 1.0 drive_model LASER reference_point {fp} components {components} phases {phases} temporal_function {lasertfunc} analytic_function {laserafunc} time_delay {time_delay} ''' retoutlets = '' laserkw = kw['laseroutlet'] if test(kw, 'laseroutlet') else dict() laserkw = sd(kw, **laserkw) getkw = mk_getkw(laserkw, outletdefaults, prefer_passed=True) if not test(laserkw, 'nolaser'): retoutlets += laser10_tmpl.format( xf=kw['xmin'], xt=kw['xmin'], yf=kw['ymin'], yt=kw['ymax'], zf=kw['zmin'], zt=kw['zmax'], fp=joinspace(scaletuple(getkw("fp"))), components=joinspace(getkw("components")), phases=joinspace(getkw("phases")), lasertfunc=getkw('lasertfunc'), laserafunc=getkw('laserafunc'), time_delay=getkw('laser_time_delay'), ) else: retoutlets += outlet_tmpl.format( side='front', xf=kw['xmin'], xt=kw['xmin'], yf=kw['ymin'], yt=kw['ymax'], zf=kw['zmin'], zt=kw['zmax'], ) retoutlets += outlet_tmpl.format( side='back', xf=kw['xmax'], xt=kw['xmax'], yf=kw['ymin'], yt=kw['ymax'], zf=kw['zmin'], zt=kw['zmax'], ) if kw['ycells'] > 0: retoutlets += outlet_tmpl.format( side='left', xf=kw['xmin'], xt=kw['xmax'], yf=kw['ymin'], yt=kw['ymin'], zf=kw['zmin'], zt=kw['zmax'], ) retoutlets += outlet_tmpl.format( side='right', xf=kw['xmin'], xt=kw['xmax'], yf=kw['ymax'], yt=kw['ymax'], zf=kw['zmin'], zt=kw['zmax'], ) if kw['zcells'] > 0: retoutlets += outlet_tmpl.format( side='bottom', xf=kw['xmin'], xt=kw['xmax'], yf=kw['ymin'], yt=kw['ymax'], zf=kw['zmin'], zt=kw['zmin'], ) retoutlets += outlet_tmpl.format( side='top', xf=kw['xmin'], xt=kw['xmax'], yf=kw['ymin'], yt=kw['ymax'], zf=kw['zmax'], zt=kw['zmax'], ) return retoutlets
def gendat(**kw): getkw=mk_getkw(kw,datdefaults); xres = getkw('dat_xres'); yres=zres=xres; if test(kw,'dat_yres'): yres = kw['dat_yres']; if test(kw,'dat_zres'): zres = kw['dat_zres']; unit=getkw('ux'); tlim = mt(getkw('tlim'),m=unit); fmt = getkw('datfmt'); if test(kw,'f_1D') or test(kw, 'data1D'): dim = 1; elif (test(kw,'f_2D') or test(kw, 'data2D')) and test(kw, 'tlim'): dim = 2; elif (test(kw,'f_3D') or test(kw, 'data3D')) and test(kw, 'tlim'): dim = 3; else: raise ValueError("Cannot reckon data dimensionality"); if dim == 1: if test(kw,'f_1D'): x = np.linspace(tlim[0],tlim[1],xres); d = getkw('f_1D')(x); elif test(kw,'data1D'): x,d = getkw('data1D'); s = BytesIO(); np.savetxt(s,np.array([x,d]).T,fmt=fmt,); return s.getvalue(); elif dim == 2: if test(kw,'f_2D'): x = np.linspace(tlim[0],tlim[1],xres); if np.isclose(tlim[2],tlim[3]): y = np.linspace(tlim[4],tlim[5],yres); else: y = np.linspace(tlim[2],tlim[3],yres); X,Y = np.meshgrid(x,y,indexing='ij'); d = getkw('f_2D')(X,Y); elif test(kw,'data2D'): x,y,d = getkw('data2D'); s = BytesIO(); np.savetxt(s,np.array(list(d.shape)).reshape(1,-1), fmt='%i'); np.savetxt(s,np.array(x).reshape(1,-1), fmt=fmt); np.savetxt(s,np.array(y).reshape(1,-1), fmt=fmt); np.savetxt(s,np.array(d).T,fmt=fmt,); return s.getvalue(); else: s = BytesIO(); if test(kw, 'f_3D'): X,Y,Z = np.mgrid[ tlim[0]:tlim[1]:xres*1j, tlim[2]:tlim[3]:yres*1j, tlim[4]:tlim[5]:zres*1j]; d = getkw('f_3D')(X,Y,Z); np.savetxt(s,np.array(list(d.shape)).reshape(1,-1), fmt='%i'); np.savetxt(s,X[:,0,0].reshape(1,-1),fmt=fmt); np.savetxt(s,Y[0,:,0].reshape(1,-1),fmt=fmt); np.savetxt(s,Z[0,0,:].reshape(1,-1),fmt=fmt); del X,Y,Z; elif test(kw,'data3D'): x,y,z,d = getkw('data3D'); np.savetxt(s,np.array(list(d.shape)).reshape(1,-1), fmt='%i'); np.savetxt(s,np.array(x).reshape(1,-1),fmt=fmt); np.savetxt(s,np.array(y).reshape(1,-1),fmt=fmt); np.savetxt(s,np.array(z).reshape(1,-1),fmt=fmt); #manual is probably best. zl = d.shape[-1]; for i in range(zl): np.savetxt(s,np.array(d[:,:,i]).T,fmt=fmt); return s.getvalue(); pass;
def trajectories(ret,trajs,**kw): ''' Draw trajectories on a pc. I will provide better documentation later. For hints on valid keyword names, look at lspplot.pc.trajdefaults Arguments: ret -- dict returned from pc. trajs -- trajectories in the form created from lspreader's pmovie scheme. Keyword Arguments: coords -- coordinates to plot as1l2 list of field names no_resize -- avoid resizing the axekms which happens if the trajectories fall outside of the current axes. lw -- line width of traj color -- color of traj cmap -- colormap of traj color_quantity -- a truly crazy thing. Color quantities by either 1) a particular quantity 2) a function. If this is a str, assume 1). Otherwise let the color of the traj be color_quantity(itr) where itr is a row in trajs. If none, just plot a line. scale -- scale the coordinates. simple -- simple scatter. flip -- flip instead of rotate. Mimics behavior before version 0.0.12. Returns: None. ''' import matplotlib.pyplot as plt; getkw=mk_getkw(kw, trajdefaults); xl,yl = getkw("coords"); xs,ys = getkw("scale"); if test(kw,'flip') or test(ret,'flip'): xl,yl = yl,xl; # yes, unneeded, but clearer. xs,ys = ys,xs; else: xl,yl = yl,xl; xs,ys =-ys,xs; if not test(kw, "no_resize"): xlim, ylim = ret['axes'].get_xlim(), ret['axes'].get_ylim(); alpha = getkw('alpha'); af = alpha; if alpha is None: af = lambda itr: None; elif type(alpha) == float: af = lambda itr: alpha; def nonnan(x): if x is not None: x = x.ravel(); return x[np.isfinite(x)]; if test(kw,'color_quantity'): cf = getkw('color_quantity'); if type(cf) == str: cf = lambda itr: itr[cf]; def _plotit(itr): x=nonnan(itr[xl])*xs; y=nonnan(itr[yl])*ys; x, y=x[s], y[s]; ret['axes'].scatter( x, y, c=nonnan(cf(itr)), marker=getkw('marker'), lw=getkw('lw'), s=getkw('size'), #this is disabled pending further study #alpha=nonnan(af(itr)), cmap=getkw('cmap')); plotit = _plotit; else: #this must be plot for just alpha def _plotit(itr): x=nonnan(itr[xl])*xs; y=nonnan(itr[yl])*ys; ret['axes'].plot( x, y, lw=getkw('lw'), alpha=af(itr), c=getkw('color'),); plotit = _plotit; if test(kw, 'simple'): plotit(trajs); else: for itr in trajs: if np.any(np.isnan(itr[xl])): print("skipping nan"); continue; plotit(itr); if not test(kw, "no_resize"): ret['axes'].set_xlim(xlim); ret['axes'].set_ylim(ylim);
def genobjects(**kw): getkw=mk_getkw(kw, condb_defaults); ux = getkw('ux'); objss=''; for I,objspec in enumerate(getkw('objects')): coords=dict(); #objd = sd(condb_defaults, **kw); objd = sd(condb_objdef, **kw); objd = sd(objd, **objspec); objd['i'] = I + 1; if test(objspec,'outlet'): outlet = objd['outlet']; if outlet not in all_lims: raise ValueError('Unknown outlet "{}"'.format(outlet)); coords = outlet_coords(outlet,kw); objd['width']*=ux; objd['start']*=ux; if outlet[-2:] == 'ax': sign = 1.0; else: sign =-1.0 objd['type']= 'BLOCK'; coords[outlet] += sign*(objd['width'] + objd['start']); coords[otherside(outlet)] += sign*objd['start']; objd['crossstart']*=ux; otherdims = [i for i in 'xyz' if i != outlet[:-3]]; for dim in otherdims: if getkw('{}cells'.format(dim)) > 0: coords['{}min'.format(dim)] += objd['crossstart']; coords['{}max'.format(dim)] -= objd['crossstart']; objd['from'] = (coords['xmin'],coords['ymin'],coords['zmin']); objd['to'] = (coords['xmax'],coords['ymax'],coords['zmax']); #objss += condf_tmpl.format( # i=I+1, # condon=objd['condon'], # xf=objd['from'][0],yf=objd['from'][1],zf=objd['from'][2], # **objd); def mk_to(objd): '''generate the to's''' return ''.join([ condt_tmpl.format(xt=xt,yt=yt,zt=zt) for xt,yt,zt in objd['to'] ]); frms = ['BLOCK', 'PARALLELPIPED', 'TRILATERAL']; if objd['type'] == 'SOLID': objss += obj_solid_tmpl.format(**objd); elif objd['type'] in frms: objss += condf_tmpl.format( xf=objd['from'][0],yf=objd['from'][1],zf=objd['from'][2], **objd); objd = sd(condb_objdef, **objd); if objd['type'] == 'BLOCK': if type(objd['to']) != list: objd['to'] = [objd['to']]; objss += mk_to(objd); if objd['type'] == 'TRILATERAL': objss += 'sweep_direction {sweep_direction}\n'.format( **objd); elif objd['type'] == 'CONE': objd = sd(obj_cone_defs, **objd); coordtokeysl(objd, 'base', '{}b'); coordtokeysl(objd, 'apex', '{}ap'); coordtokeysl(objd, 'edge', '{}ed'); objss += obj_cone_tmpl.format(**objd); elif objd['type'] == 'CYLINDER' or objd['type'] == 'TORUS': objd = sd(obj_cyl_defs, **objd); objd['axis'],objd['pitch'] = objd['axis_pitch']; objd['azaxis'],objd['azpitch'] = objd['azimuthal_axis_pitch']; objd['start_angle'],objd['sweep_angle'] = objd['azimuth_range']; if objd['type'] == 'CYLINDER': coordtokeysl(objd, 'base', '{}b'); objss += obj_cyl_tmpl.format(**objd); elif objd['type'] == 'TORUS': objd = sd(obj_torus_defs,**objd); coordtokeysl(objd, 'center', '{}c'); objss += obj_torus_tmpl.format(**objd); else: raise Exception("WTFdiosjf03y2q8qencdq"); else: raise ValueError( "Unknown object type '{}'".format(objd['type'])); pass #end for return objss;
def genpbs(**kw): getkw = mk_getkw(kw, pbsdefaults) domains = getkw('domains') lspexec = getkw('lspexec') pbsbase = getkw('pbsbase') label = getkw('label') if not label: label = pbsbase cluster = getkw("cluster") clusterq = cluster concurrents = getkw('concurrents') if not concurrents: concurrents = [] if 'autozipper' not in kw or kw['autozipper']: concurrents = [('zipper', './zipper -a >$PBS_O_WORKDIR')] + concurrents movne = False if test(kw, "queue"): clusterq += "_" + kw['queue'] mycluster = clusters[clusterq] if test(kw, 'ppn'): ppn = kw['ppn'] else: ppn = mycluster['max_ppn'] nodes = int(domains / ppn) if domains % ppn > 0: nodes += 1 mpiformat = mycluster['mpi'] extra_headers = '' pre = ''' cd "$PBS_O_WORKDIR" ''' portions = normal_portion_tmpl.format(nodes=nodes, ppn=ppn) walltime = getkw("walltime") if walltime is inf: walltime = mycluster['max_walltime'] elif walltime > mycluster['max_walltime']: import sys sys.stderr.write("walltime exceedes allowed for {}".format(clusterq)) walltime = hours_to_walltime(walltime) post = '' # # server quirks # if cluster == "ramses": if nodes == 1: pre += ''' D=/tmp/ngirmang.1-`mkdate`-$PBSBASE mkdir -p $D cd "$PBS_O_WORKDIR" cp {lspexec} {pbsbase}.lsp *.dat $D/ '''.format(lspexec=lspexec, pbsbase=pbsbase) for concurrent in concurrents: pre += 'cp {} $D/\n'.format(concurrent[0]) if len(concurrents) > 0: pre += 'cp loopscript $D/\n' pre += 'cd $D\n' pre = "module load openmpi-1.4.3-gnu-rpm\n\n" + pre if dodcluster(cluster): if test(kw, 'mpiprocs') and kw['mpiprocs'] != ppn: mpiformat = 'aprun -n {{}} -N {}'.format(kw['mpiprocs']) nodes = int(domains / kw['mpiprocs']) if domains % kw['mpiprocs'] > 0: nodes += 1 else: kw['mpiprocs'] = ppn portions = garnet_portion_tmpl.format(nodes=nodes, ppn=ppn, mpiprocs=kw['mpiprocs']) extra_headers = "#PBS -A __projectid__\n#PBS -q {}\n".format( kw['queue']) if test(kw, "mkrundir"): pre += ('export RUNDIR="${{PBS_JOBNAME}}_${{PBS_JOBID}}"\n' 'mkdir -p $RUNDIR' 'rcp {lspexec} {pbsbase}.lsp *.dat $RUNDIR' 'cd $RUNDIR') if cluster == "garnet": #truncate name because life sucks label = label[:14] if not test(kw, 'queue'): kw['queue'] = "standard_lw" #handling conncurrent scripts if not dodcluster(cluster): for concurrent in concurrents: script = concurrent[0] pre += '''#{script} ./loopscript {script} &> $PBS_O_WORKDIR/{script}.log& {script}_PID=$! '''.format(script=script) post += "kill ${script}_PID\n".format(script=script) if len(concurrent) > 1: post += "{}\n".format(concurrent[1]) mpirun = mpiformat.format(domains) #finally outputting with open("hotwater3d_tmpl.pbs") as f: s = f.read() return s.format( label=label, nodes=nodes, mpirun_opts=mpirun, pre=pre, post=post, ppn=ppn, portions=portions, pbsbase=getkw('pbsbase'), walltime=walltime, mpirun=mpirun, extra_headers=extra_headers, lspexec=lspexec, )