def test_pfv(self): """check the computation of p from a given v """ femp, stokesmatsc, rhsd = \ dnsps.get_sysmats(problem='cylinderwake', N=self.N, Re=self.Re, scheme=self.scheme, mergerhs=True) Mc, Ac = stokesmatsc['M'], stokesmatsc['A'] BTc, Bc = stokesmatsc['JT'], stokesmatsc['J'] print(Bc.shape) invinds = femp['invinds'] fv, fp = rhsd['fv'], rhsd['fp'] print(np.linalg.norm(fv), np.linalg.norm(fp)) inivdict = dict(A=Ac, J=Bc, JT=BTc, M=Mc, ppin=self.ppin, fv=fv, fp=fp, return_vp=True, V=femp['V'], clearprvdata=True, invinds=invinds, diribcs=femp['diribcs']) vp_init = snu.solve_steadystate_nse(**inivdict) NV = Bc.shape[1] pfv = snu.get_pfromv(v=vp_init[0], V=femp['V'], M=Mc, A=Ac, J=Bc, fv=fv, invinds=femp['invinds'], diribcs=femp['diribcs']) self.assertTrue(np.allclose(pfv, vp_init[1]))
def getthecoeffs(N=None, Re=None, scheme='CR', inivp='Stokes', inifemp=None): femp, stokesmatsc, rhsmomcont \ = dnsps.get_sysmats(problem='cylinderwake', N=N, Re=Re, scheme=scheme, mergerhs=True) fp = rhsmomcont['fp'] fv = rhsmomcont['fv'] # stokesmatsc.update(rhsmomcont) J, MP = stokesmatsc['J'], stokesmatsc['MP'] NV, NP = J.T.shape # Nv = J.shape[1] # Mpfac = spsla.splu(MP) if inivp is 'Stokes': inivp = lau.solve_sadpnt_smw(amat=stokesmatsc['A'], jmat=J, jmatT=-J.T, rhsv=fv, rhsp=fp) iniv = inivp[:NV] inip = snu.get_pfromv(v=iniv, V=femp['V'], M=stokesmatsc['M'], A=stokesmatsc['A'], J=J, fv=fv, fp=fp, diribcs=femp['diribcs'], invinds=femp['invinds']) else: inv, inp = dts.expand_vp_dolfunc(vp=inivp, **inifemp) # interpolate on new mesh and extract the invinds getconvvec = getconvvecfun(**femp) return dict(A=stokesmatsc['A'], M=stokesmatsc['M'], J=J, JT=J.T, MP=MP, fp=fp, fv=fv, getconvvec=getconvvec, iniv=iniv, inip=inip, V=femp['V'], Q=femp['Q'], invinds=femp['invinds'], diribcs=femp['diribcs'], ppin=femp['ppin'], femp=femp)
def testit(problem='drivencavity', N=None, nu=None, Re=None, Nts=1e3, ParaviewOutput=False, tE=1.0, scheme=None): nnewtsteps = 9 # n nwtn stps for vel comp vel_nwtn_tol = 1e-14 tips = dict(t0=0.0, tE=tE, Nts=Nts) femp, stokesmatsc, rhsd = dnsps.get_sysmats(problem=problem, N=N, Re=Re, nu=nu, scheme=scheme, mergerhs=True) proutdir = 'results/' ddir = 'data/' data_prfx = problem + '_N{0}_Re{1}_Nts{2}_tE{3}'.\ format(N, femp['Re'], Nts, tE) soldict = stokesmatsc # containing A, J, JT soldict.update(femp) # adding V, Q, invinds, diribcs soldict.update(tips) # adding time integration params soldict.update(rhsd) soldict.update(N=N, nu=nu, vel_nwtn_stps=nnewtsteps, vel_nwtn_tol=vel_nwtn_tol, start_ssstokes=True, get_datastring=None, data_prfx=ddir+data_prfx, paraviewoutput=ParaviewOutput, vel_pcrd_stps=1, clearprvdata=True, vfileprfx=proutdir+'vel_{0}_'.format(scheme), pfileprfx=proutdir+'p_{0}_'.format(scheme)) soldict.update(krylovdict) # if we wanna use an iterative solver snu.solve_nse(**soldict)
def testit(problem='drivencavity', N=None, nu=1e-2, Re=None, Nts=1e3, ParaviewOutput=False, tE=1.0): vel_nwtn_tol = 1e-14 tips = dict(t0=0.0, tE=tE, Nts=Nts) femp, stokesmatsc, rhsd = \ dnsps.get_sysmats(problem='cylinderwake', N=N, Re=Re, mergerhs=True) soldict = stokesmatsc # containing A, J, JT soldict.update(femp) # adding V, Q, invinds, diribcs soldict.update(rhsd) # adding fvc, fpr soldict.update(tips) # adding time integration params nnewtsteps = 8 # n nwtn stps for vel comp soldict.update(N=N, nu=nu, vel_nwtn_stps=nnewtsteps, vel_nwtn_tol=vel_nwtn_tol, start_ssstokes=True, data_prfx=ddir + problem, paraviewoutput=False, clearprvdata=True) snu.solve_nse(**soldict) nnewtsteps = 1 # n nwtn stps for vel comp soldict.update(N=N, nu=nu, vel_nwtn_stps=nnewtsteps, vel_nwtn_tol=vel_nwtn_tol, start_ssstokes=True, data_prfx=ddir + problem, clearprvdata=True, return_dictofvelstrs=True) csd = snu.solve_nse(**soldict) print('1, 2, check, check') nnewtsteps = 7 # n nwtn stps for vel comp soldict.update(N=N, nu=nu, vel_nwtn_stps=nnewtsteps, vel_nwtn_tol=vel_nwtn_tol, start_ssstokes=True, data_prfx=ddir + problem, clearprvdata=False, lin_vel_point=csd, vel_pcrd_stps=0, return_dictofvelstrs=True) soldict.update(krylovdict) # if we wanna use an iterative solver snu.solve_nse(**soldict)
def testit(problem='cylinderwake', N=2, nu=None, Re=1e2, Nts=1e3 + 1, ParaviewOutput=False, tE=1.0, scheme=None, zerocontrol=False): nnewtsteps = 9 # n nwtn stps for vel comp vel_nwtn_tol = 1e-14 tips = dict(t0=0.0, tE=tE, Nts=Nts) femp, stokesmatsc, rhsd_vfrc, rhsd_stbc \ = dnsps.get_sysmats(problem=problem, Re=Re, meshparams=dict(refinement_level=N), bccontrol=True, nu=nu, scheme=scheme) proutdir = 'results/' ddir = 'data/' data_prfx = problem + '_N{0}_Re{1}_Nts{2}_tE{3}'.\ format(N, femp['Re'], Nts, tE) dolfin.plot(femp['mesh']) palpha = 1e-5 stokesmatsc['A'] = stokesmatsc['A'] + 1. / palpha * stokesmatsc['Arob'] if zerocontrol: Brob = 0. * 1. / palpha * stokesmatsc['Brob'] else: Brob = 1. / palpha * stokesmatsc['Brob'] def fv_tmdp(time=0, v=None, **kw): return np.sin(time) * (Brob[:, :1] - Brob[:, 1:]), None soldict = stokesmatsc # containing A, J, JT soldict.update(femp) # adding V, Q, invinds, diribcs soldict.update(tips) # adding time integration params soldict.update( fv=rhsd_stbc['fv'] + rhsd_vfrc['fvc'], fp=rhsd_stbc['fp'] + rhsd_vfrc['fpr'], N=N, nu=nu, vel_nwtn_stps=nnewtsteps, # comp_nonl_semexp=True, treat_nonl_explct=False, vel_nwtn_tol=vel_nwtn_tol, fv_tmdp=fv_tmdp, start_ssstokes=True, get_datastring=None, data_prfx=ddir + data_prfx, paraviewoutput=ParaviewOutput, vel_pcrd_stps=1, clearprvdata=True, vfileprfx=proutdir + 'vel_{0}_'.format(scheme), pfileprfx=proutdir + 'p_{0}_'.format(scheme)) snu.solve_nse(**soldict)
def testit(problem='drivencavity', N=None, nu=1e-2, Re=None, Nts=1e3, ParaviewOutput=False, tE=1.0): vel_nwtn_tol = 1e-14 tips = dict(t0=0.0, tE=tE, Nts=Nts) femp, stokesmatsc, rhsd_vfrc, \ rhsd_stbc, data_prfx, ddir, proutdir \ = dnsps.get_sysmats(problem=problem, N=N, nu=nu) soldict = stokesmatsc # containing A, J, JT soldict.update(femp) # adding V, Q, invinds, diribcs soldict.update(rhsd_vfrc) # adding fvc, fpr soldict.update(tips) # adding time integration params nnewtsteps = 8 # n nwtn stps for vel comp soldict.update(fv_stbc=rhsd_stbc['fv'], fp_stbc=rhsd_stbc['fp'], N=N, nu=nu, vel_nwtn_stps=nnewtsteps, vel_nwtn_tol=vel_nwtn_tol, start_ssstokes=True, data_prfx=ddir+data_prfx, paraviewoutput=False, clearprvdata=True) snu.solve_nse(**soldict) nnewtsteps = 1 # n nwtn stps for vel comp soldict.update(fv_stbc=rhsd_stbc['fv'], fp_stbc=rhsd_stbc['fp'], N=N, nu=nu, vel_nwtn_stps=nnewtsteps, vel_nwtn_tol=vel_nwtn_tol, start_ssstokes=True, data_prfx=ddir+data_prfx, clearprvdata=True, return_dictofvelstrs=True) csd = snu.solve_nse(**soldict) print '1, 2, check, check' nnewtsteps = 7 # n nwtn stps for vel comp csd = soldict.update(fv_stbc=rhsd_stbc['fv'], fp_stbc=rhsd_stbc['fp'], N=N, nu=nu, vel_nwtn_stps=nnewtsteps, vel_nwtn_tol=vel_nwtn_tol, start_ssstokes=True, data_prfx=ddir+data_prfx, clearprvdata=False, lin_vel_point=csd, vel_pcrd_stps=0, return_dictofvelstrs=True) soldict.update(krylovdict) # if we wanna use an iterative solver snu.solve_nse(**soldict)
def testit(problem='drivencavity', N=None, nu=1e-2, Re=None, t0=0.0, tE=1.0, Nts=1e2 + 1, ParaviewOutput=False, scheme='TH'): femp, stokesmatsc, rhsd = \ dnsps.get_sysmats(problem='gen_bccont', Re=Re, bccontrol=False, scheme=scheme, mergerhs=True, meshparams=dict(strtomeshfile=meshfile, strtophysicalregions=physregs, strtobcsobs=geodata)) ddir = 'data/' data_prfx = problem + '{4}_N{0}_Re{1}_Nts{2}_tE{3}'.\ format(N, femp['Re'], Nts, tE, scheme) # setting some parameters if Re is not None: nu = femp['charlen'] / Re tips = dict(t0=t0, tE=tE, Nts=Nts) try: os.chdir(ddir) except OSError: raise Warning('need "' + ddir + '" subdir for storing the data') os.chdir('..') soldict = stokesmatsc # containing A, J, JT soldict.update(femp) # adding V, Q, invinds, diribcs soldict.update(tips) # adding time integration params soldict.update(fv=rhsd['fv'], fp=rhsd['fp'], N=N, nu=nu, start_ssstokes=True, get_datastring=None, treat_nonl_explct=True, dbcinds=femp['dbcinds'], dbcvals=femp['dbcvals'], data_prfx=ddir + data_prfx, paraviewoutput=ParaviewOutput, vfileprfx=proutdir + 'vel_', pfileprfx=proutdir + 'p_') # # compute the uncontrolled steady state Navier-Stokes solution # # v_ss_nse, list_norm_nwtnupd = snu.solve_steadystate_nse(**soldict) snu.solve_nse(**soldict) print('for plots check \nparaview ' + proutdir + 'vel___timestep.pvd') print('or \nparaview ' + proutdir + 'p___timestep.pvd')
def comptorque(rotval, thingdict=None, returnitall=False): def rotcont(t, vel=None, p=None, memory={}): return rotval, memory rotcondict = {} dircntdict = dict(diricontbcinds=[femp['mvwbcinds']], diricontbcvals=[femp['mvwbcvals']], diricontfuncs=[rotcont], diricontfuncmems=[rotcondict]) soldict.update(dircntdict) soldict.update(dict(vel_start_nwtn=thingdict['vel_start_nwtn'])) if ininu is not None and thingdict['vel_start_nwtn'] is None: inifemp, inistokesmatsc, inirhsd = \ dnsps.get_sysmats(problem=problem, nu=ininu, bccontrol=False, charvel=charvel, scheme=scheme, mergerhs=True, meshparams=meshparams) soldict.update(inistokesmatsc) soldict.update(inifemp) soldict.update(fv=inirhsd['fv'], fp=inirhsd['fp']) vp_ss_nse = snu.solve_steadystate_nse(**soldict) soldict.update(dict(vel_start_nwtn=vp_ss_nse[0])) soldict.update(stokesmatsc) soldict.update(femp) soldict.update(fv=rhsd['fv'], fp=rhsd['fp']) vp_ss_nse = snu.solve_steadystate_nse(**soldict) thingdict.update(dict(vel_start_nwtn=vp_ss_nse[0])) if returnitall: vfun, pfun = dts.\ expand_vp_dolfunc(vc=vp_ss_nse[0], pc=vp_ss_nse[1], V=femp['V'], Q=femp['Q']) # lift, drag = getld.evaliftdragforce(u=vfun, p=pfun) drag = steady_state_res(vfun, pfun, phi=pox) lift = steady_state_res(vfun, pfun, phi=poy) # phionex = phione.sub(0) trqe = steady_state_res(vfun, pfun, phi=phitwo) # trqe = getld.evatorqueSphere2D(u=vfun, p=pfun) a_1 = dolfin.Point(0.15, 0.2) a_2 = dolfin.Point(0.25, 0.2) pdiff = rho * pfun(a_2) - rho * pfun(a_1) return trqe, lift, drag, pdiff else: vfun, pfun = dts.\ expand_vp_dolfunc(vc=vp_ss_nse[0], pc=vp_ss_nse[1], V=femp['V'], Q=femp['Q']) # trqe = getld.evatorqueSphere2D(u=vfun, p=pfun) trqe = steady_state_res(vfun, pfun, phi=phitwo) print('omeg: {0:.3e} -- trqe: {1:.3e}'.format(rotval, trqe)) return np.abs(trqe)
def testit(problem='cylinderwake', N=2, nu=None, Re=1e2, Nts=1e3+1, ParaviewOutput=False, tE=1.0, scheme=None, zerocontrol=False): nnewtsteps = 9 # n nwtn stps for vel comp vel_nwtn_tol = 1e-14 tips = dict(t0=0.0, tE=tE, Nts=Nts) femp, stokesmatsc, rhsd_vfrc, rhsd_stbc \ = dnsps.get_sysmats(problem=problem, Re=Re, meshparams=dict(refinement_level=N), bccontrol=True, nu=nu, scheme=scheme) proutdir = 'results/' ddir = 'data/' data_prfx = problem + '_N{0}_Re{1}_Nts{2}_tE{3}'.\ format(N, femp['Re'], Nts, tE) dolfin.plot(femp['mesh']) palpha = 1e-5 stokesmatsc['A'] = stokesmatsc['A'] + 1./palpha*stokesmatsc['Arob'] if zerocontrol: Brob = 0.*1./palpha*stokesmatsc['Brob'] else: Brob = 1./palpha*stokesmatsc['Brob'] def fv_tmdp(time=0, v=None, **kw): return np.sin(time)*(Brob[:, :1] - Brob[:, 1:]), None soldict = stokesmatsc # containing A, J, JT soldict.update(femp) # adding V, Q, invinds, diribcs soldict.update(tips) # adding time integration params soldict.update(fv=rhsd_stbc['fv']+rhsd_vfrc['fvc'], fp=rhsd_stbc['fp']+rhsd_vfrc['fpr'], N=N, nu=nu, vel_nwtn_stps=nnewtsteps, # comp_nonl_semexp=True, treat_nonl_explct=True, vel_nwtn_tol=vel_nwtn_tol, fv_tmdp=fv_tmdp, start_ssstokes=True, get_datastring=None, data_prfx=ddir+data_prfx, paraviewoutput=ParaviewOutput, vel_pcrd_stps=1, clearprvdata=True, vfileprfx=proutdir+'vel_{0}_'.format(scheme), pfileprfx=proutdir+'p_{0}_'.format(scheme)) snu.solve_nse(**soldict)
def testit(problem='drivencavity', N=None, nu=1e-2, Re=None, nonltrt=None, t0=0.0, tE=1.0, Nts=1e2 + 1, ParaviewOutput=False, scheme='TH'): femp, stokesmatsc, rhsd = \ dnsps.get_sysmats(problem=problem, Re=Re, nu=nu, scheme=scheme, meshparams=dict(refinement_level=N), mergerhs=True) proutdir = 'results/' dolfin.plot(femp['V'].mesh()) # setting some parameters if Re is not None: nu = femp['charlen'] / Re tips = dict(t0=t0, tE=tE, Nts=Nts) soldict = stokesmatsc # containing A, J, JT soldict.update(femp) # adding V, Q, invinds, diribcs soldict.update(tips) # adding time integration params soldict.update(fv=rhsd['fv'], fp=rhsd['fp'], N=N, nu=nu, start_ssstokes=True, treat_nonl_explct=nonltrt, no_data_caching=True, paraviewoutput=ParaviewOutput, vfileprfx=proutdir + 'vel_expnl_', pfileprfx=proutdir + 'p_expnl') soldict.update(krylovdict) # if we wanna use an iterative solver # # compute the uncontrolled steady state Navier-Stokes solution # # vp_ss_nse = snu.solve_steadystate_nse(**soldict) # soldict.update(dict(start_ssstokes=True)) snu.solve_nse(**soldict)
def testit(problem='cylinderwake', N=None, nu=None, Re=None, nnwtnstps=9, npcrdstps=5, palpha=1e-5): vel_nwtn_tol = 1e-14 # prefix for data files data_prfx = problem # dir to store data ddir = 'data/' # paraview output ParaviewOutput = True proutdir = 'results/' femp, stokesmatsc, rhsd = dnsps.get_sysmats(problem=problem, N=N, Re=Re, nu=nu, scheme='TH', mergerhs=True, bccontrol=True) proutdir = 'results/' ddir = 'data/' import scipy.sparse.linalg as spsla print 'get expmats: ||A|| = {0}'.format(spsla.norm(stokesmatsc['A'])) print 'get expmats: ||Arob|| = {0}'.format(spsla.norm(stokesmatsc['Arob'])) stokesmatsc['A'] = stokesmatsc['A'] + 1./palpha*stokesmatsc['Arob'] b_mat = 0.*1./palpha*stokesmatsc['Brob'] brhs = 1.5*b_mat[:, :1] - 1.5*b_mat[:, 1:] soldict = stokesmatsc # containing A, J, JT soldict.update(femp) # adding V, Q, invinds, diribcs soldict.update(fv=rhsd['fv']+brhs, fp=rhsd['fp'], N=N, nu=nu, vel_nwtn_stps=nnwtnstps, vel_pcrd_stps=npcrdstps, vel_nwtn_tol=vel_nwtn_tol, ddir=ddir, get_datastring=None, clearprvdata=True, data_prfx=data_prfx, paraviewoutput=ParaviewOutput, vfileprfx=proutdir+'vel_', pfileprfx=proutdir+'p_') # # compute the uncontrolled steady state Navier-Stokes solution # v_ss_nse, list_norm_nwtnupd = snu.solve_steadystate_nse(**soldict)
def testit(problem='drivencavity', N=None, nu=1e-2, Re=None, nonltrt=None, t0=0.0, tE=1.0, Nts=1e2+1, ParaviewOutput=False, scheme='TH'): femp, stokesmatsc, rhsd = \ dnsps.get_sysmats(problem=problem, Re=Re, nu=nu, scheme=scheme, meshparams=dict(refinement_level=N), mergerhs=True) proutdir = 'results/' ddir = 'data/' data_prfx = problem + '{4}_N{0}_Re{1}_Nts{2}_tE{3}'.\ format(N, femp['Re'], Nts, tE, scheme) dolfin.plot(femp['V'].mesh()) # setting some parameters if Re is not None: nu = femp['charlen']/Re tips = dict(t0=t0, tE=tE, Nts=Nts) try: os.chdir(ddir) except OSError: raise Warning('need "' + ddir + '" subdir for storing the data') os.chdir('..') soldict = stokesmatsc # containing A, J, JT soldict.update(femp) # adding V, Q, invinds, diribcs soldict.update(tips) # adding time integration params soldict.update(fv=rhsd['fv'], fp=rhsd['fp'], N=N, nu=nu, start_ssstokes=True, get_datastring=None, treat_nonl_explct=nonltrt, data_prfx=ddir+data_prfx, paraviewoutput=ParaviewOutput, vfileprfx=proutdir+'vel_expnl_', pfileprfx=proutdir+'p_expnl') soldict.update(krylovdict) # if we wanna use an iterative solver # # compute the uncontrolled steady state Navier-Stokes solution # # v_ss_nse, list_norm_nwtnupd = snu.solve_steadystate_nse(**soldict) snu.solve_nse(**soldict)
def test_pfv(self): """check the computation of p from a given v """ femp, stokesmatsc, rhsd = \ dnsps.get_sysmats(problem='cylinderwake', meshparams=dict(refinement_level=self.N), Re=self.Re, scheme=self.scheme, mergerhs=True) Mc, Ac = stokesmatsc['M'], stokesmatsc['A'] BTc, Bc = stokesmatsc['JT'], stokesmatsc['J'] print(Bc.shape) invinds = femp['invinds'] fv, fp = rhsd['fv'], rhsd['fp'] print(np.linalg.norm(fv), np.linalg.norm(fp)) inivdict = dict(A=Ac, J=Bc, JT=BTc, M=Mc, ppin=self.ppin, fv=fv, fp=fp, return_vp=True, V=femp['V'], clearprvdata=True, invinds=invinds, diribcs=femp['diribcs']) vp_init = snu.solve_steadystate_nse(**inivdict) dbcinds, dbcvals = dts.unroll_dlfn_dbcs(femp['diribcs']) pfv = snu.get_pfromv(v=vp_init[0][invinds], V=femp['V'], M=Mc, A=Ac, J=Bc, fv=fv, invinds=femp['invinds'], dbcinds=dbcinds, dbcvals=dbcvals) self.assertTrue(np.allclose(pfv, vp_init[1]))
def testit(problem='drivencavity', N=None, nu=1e-2, Re=None, Nts=1e3, ParaviewOutput=False, tE=1.0): nnewtsteps = 4 # n nwtn stps for vel comp npcrdsteps = 0 # n picard steps vel_nwtn_tol = 1e-14 tips = dict(t0=0.0, tE=tE, Nts=Nts) femp, stokesmatsc, rhsd_vfrc, rhsd_stbc \ = dnsps.get_sysmats(problem=problem, N=N, nu=nu) proutdir = 'results/' ddir = 'data/' data_prfx = problem + '_N{0}_Re{1}_Nts{2}_tE{3}'.\ format(N, femp['Re'], Nts, tE) soldict = stokesmatsc # containing A, J, JT soldict.update(femp) # adding V, Q, invinds, diribcs soldict.update(tips) # adding time integration params soldict.update(fv=rhsd_stbc['fv']+rhsd_vfrc['fvc'], fp=rhsd_stbc['fp']+rhsd_vfrc['fpr'], N=N, nu=nu, vel_nwtn_stps=nnewtsteps, vel_pcrd_stps=npcrdsteps, vel_nwtn_tol=vel_nwtn_tol, start_ssstokes=True, get_datastring=None, data_prfx=ddir+data_prfx, paraviewoutput=ParaviewOutput, clearprvdata=True, comp_nonl_semexp=True, vfileprfx=proutdir+'vel_', pfileprfx=proutdir+'p_') soldict.update(krylovdict) # if we wanna use an iterative solver snu.solve_nse(**soldict) print(len(krylovdict['krpslvprms']['convstatsl']))
def testit(problem=None, nu=None, ininu=None, charvel=None, meshlvl=1, rho=1., ParaviewOutput=False, scheme='TH'): meshfile = 'mesh/karman2D-rotcyl_lvl{0}.xml.gz'.format(meshlvl) physregs = 'mesh/karman2D-rotcyl_lvl{0}_facet_region.xml.gz'.\ format(meshlvl) meshparams = dict(strtomeshfile=meshfile, strtophysicalregions=physregs, strtobcsobs=geodata) femp, stokesmatsc, rhsd = \ dnsps.get_sysmats(problem=problem, nu=nu, bccontrol=False, charvel=charvel, scheme=scheme, mergerhs=True, meshparams=meshparams) soldict = {} soldict.update(stokesmatsc) # containing A, J, JT soldict.update(femp) # adding V, Q, invinds, diribcs ddir = 'data/' data_prfx = problem + '{2}_mesh{0}_Re{1}'.\ format(meshlvl, femp['Re'], scheme) soldict.update(fv=rhsd['fv'], fp=rhsd['fp'], N=meshlvl, nu=nu, verbose=True, vel_pcrd_stps=0, vel_nwtn_tol=1e-10, vel_nwtn_stps=10, return_vp=True, get_datastring=None, dbcinds=femp['dbcinds'], dbcvals=femp['dbcvals'], data_prfx=ddir + data_prfx, paraviewoutput=ParaviewOutput, vfileprfx=proutdir + 'vel_', pfileprfx=proutdir + 'p_') L = femp['charlen'] # characteristic length phionevec = np.zeros((femp['V'].dim(), 1)) phionevec[femp['mvwbcinds'], :] = 1. phione = dolfin.Function(femp['V']) phione.vector().set_local(phionevec) pickx = dolfin.as_matrix([[1., 0.], [0., 0.]]) picky = dolfin.as_matrix([[0., 0.], [0., 1.]]) pox = pickx * phione poy = picky * phione phitwovec = np.zeros((femp['V'].dim(), 1)) phitwovec[femp['mvwbcinds'], 0] = femp['mvwbcvals'] phitwo = dolfin.Function(femp['V']) phitwo.vector().set_local(phitwovec) if ParaviewOutput: phifile = dolfin.File('results/phione.pvd') phifile << phitwo # getld = dnsps.LiftDragSurfForce(V=femp['V'], nu=nu, # phione=phione, phitwo=phitwo, # outflowds=femp['outflowds'], # ldds=femp['liftdragds']) steady_state_res = \ get_steady_state_res(V=femp['V'], gradvsymmtrc=True, outflowds=femp['outflowds'], nu=nu) def comptorque(rotval, thingdict=None, returnitall=False): def rotcont(t, vel=None, p=None, memory={}): return rotval, memory rotcondict = {} dircntdict = dict(diricontbcinds=[femp['mvwbcinds']], diricontbcvals=[femp['mvwbcvals']], diricontfuncs=[rotcont], diricontfuncmems=[rotcondict]) soldict.update(dircntdict) soldict.update(dict(vel_start_nwtn=thingdict['vel_start_nwtn'])) if ininu is not None and thingdict['vel_start_nwtn'] is None: inifemp, inistokesmatsc, inirhsd = \ dnsps.get_sysmats(problem=problem, nu=ininu, bccontrol=False, charvel=charvel, scheme=scheme, mergerhs=True, meshparams=meshparams) soldict.update(inistokesmatsc) soldict.update(inifemp) soldict.update(fv=inirhsd['fv'], fp=inirhsd['fp']) vp_ss_nse = snu.solve_steadystate_nse(**soldict) soldict.update(dict(vel_start_nwtn=vp_ss_nse[0])) soldict.update(stokesmatsc) soldict.update(femp) soldict.update(fv=rhsd['fv'], fp=rhsd['fp']) vp_ss_nse = snu.solve_steadystate_nse(**soldict) thingdict.update(dict(vel_start_nwtn=vp_ss_nse[0])) if returnitall: vfun, pfun = dts.\ expand_vp_dolfunc(vc=vp_ss_nse[0], pc=vp_ss_nse[1], V=femp['V'], Q=femp['Q']) # lift, drag = getld.evaliftdragforce(u=vfun, p=pfun) drag = steady_state_res(vfun, pfun, phi=pox) lift = steady_state_res(vfun, pfun, phi=poy) # phionex = phione.sub(0) trqe = steady_state_res(vfun, pfun, phi=phitwo) # trqe = getld.evatorqueSphere2D(u=vfun, p=pfun) a_1 = dolfin.Point(0.15, 0.2) a_2 = dolfin.Point(0.25, 0.2) pdiff = rho * pfun(a_2) - rho * pfun(a_1) return trqe, lift, drag, pdiff else: vfun, pfun = dts.\ expand_vp_dolfunc(vc=vp_ss_nse[0], pc=vp_ss_nse[1], V=femp['V'], Q=femp['Q']) # trqe = getld.evatorqueSphere2D(u=vfun, p=pfun) trqe = steady_state_res(vfun, pfun, phi=phitwo) print('omeg: {0:.3e} -- trqe: {1:.3e}'.format(rotval, trqe)) return np.abs(trqe) Um = charvel thingdict = dict(vel_start_nwtn=None) testrot = 0. trqe, lift, drag, pdif = comptorque(testrot, thingdict, returnitall=True) print('\n\n# ## Nonrotating Cylinder ') cdclfac = 2. / (rho * L * Um**2) trqefac = 4 / (Um**2 * rho * L**2) print('Cl: {0:.9f}'.format(cdclfac * lift)) print('Cd: {0:.9f}'.format(cdclfac * drag)) print('Ct: {0:.5e}'.format(trqefac * trqe)) print('Delta P: {0:.9f}'.format(pdif)) if charvel == 0.2: print('\n cp. values from Schaefer/Turek as in') print('www.featflow.de/en/benchmarks/cfdbenchmarking/flow/' + 'dfg_benchmark1_re20.html:') print('Cl: {0:.8f}'.format(0.010618948146)) print('Cd: {0:.8f}'.format(5.57953523384)) print('Delta P: {0:.8f}'.format(0.11752016697)) print('\n\n# ## Rotating Cylinder -- optimizing rotation for zero torque') tinfo = {} with dou.Timer(timerinfo=tinfo): res = sco.minimize_scalar(comptorque, args=(thingdict), options={'maxiter': 80}, tol=1e-13) trqe, lift, drag, pdiff = comptorque(res['x'], thingdict, returnitall=True) print('\n# ## Rotating Cylinder -- optimized rotation for zero torque') print('omega*: {0:.8f}'.format(res['x'] * L / (2 * Um))) print('Cl: {0:.8f}'.format(cdclfac * lift)) print('Cd: {0:.8f}'.format(cdclfac * drag)) print('Ct: {0:.4e}'.format(trqefac * trqe)) print('Delta P: {0:.8f}'.format(pdif)) if charvel == 0.2: print('\n cp. values from Richter et. al') print('omega*: {0}'.format(0.00126293)) print('Cl: {0}'.format(0.0047141)) print('Cd: {0}'.format(5.579558)) print('Delta P: {0}'.format(0.117520))
def comp_exp_nsmats( problemname="drivencavity", N=10, Re=1e2, nu=None, linear_system=False, refree=False, bccontrol=False, palpha=None, use_old_data=False, mddir="pathtodatastorage", ): """compute and export the system matrices for Navier-Stokes equations Parameters --- refree : boolean, optional whether to use `Re=1` (so that the `Re` number can be applied later by scaling the corresponding matrices, defaults to `False` linear_system : boolean, optional whether to compute/return the linearized system, defaults to `False` bccontrol : boolean, optional whether to model boundary control at the cylinder via penalized robin boundary conditions, defaults to `False` palpha : float, optional penalization parameter for the boundary control, defaults to `None`, `palpha` is mandatory for `linear_system` """ if refree: Re = 1 print "For the Reynoldsnumber free mats, we set Re=1" if problemname == "drivencavity" and bccontrol: raise NotImplementedError("boundary control for the driven cavity" + " is not implemented yet") if linear_system and bccontrol and palpha is None: raise UserWarning("For the linear system a" + " value for `palpha` is needed") if not linear_system and bccontrol: raise NotImplementedError("Nonlinear system with boundary control" + " is not implemented yet") femp, stokesmatsc, rhsd_vfrc, rhsd_stbc = dnsps.get_sysmats(problem=problemname, bccontrol=bccontrol, N=N, Re=Re) if linear_system and bccontrol: Arob = stokesmatsc["A"] + 1.0 / palpha * stokesmatsc["Arob"] Brob = 1.0 / palpha * stokesmatsc["Brob"] elif linear_system: Brob = 0 invinds = femp["invinds"] A, J = stokesmatsc["A"], stokesmatsc["J"] fvc, fpc = rhsd_vfrc["fvc"], rhsd_vfrc["fpr"] fv_stbc, fp_stbc = rhsd_stbc["fv"], rhsd_stbc["fp"] invinds = femp["invinds"] NV = invinds.shape[0] data_prfx = problemname + "__N{0}Re{1}".format(N, Re) if bccontrol: data_prfx = data_prfx + "_penarob" soldict = stokesmatsc # containing A, J, JT soldict.update(femp) # adding V, Q, invinds, diribcs soldict.update(rhsd_vfrc) # adding fvc, fpr fv = rhsd_vfrc["fvc"] + rhsd_stbc["fv"] fp = rhsd_vfrc["fpr"] + rhsd_stbc["fp"] # print 'get expmats: ||fv|| = {0}'.format(np.linalg.norm(fv)) # print 'get expmats: ||fp|| = {0}'.format(np.linalg.norm(fp)) # import scipy.sparse.linalg as spsla # print 'get expmats: ||A|| = {0}'.format(spsla.norm(A)) # print 'get expmats: ||Arob|| = {0}'.format(spsla.norm(Arob)) # print 'get expmats: ||A|| = {0}'.format(spsla.norm(stokesmatsc['A'])) # raise Warning('TODO: debug') soldict.update( fv=fv, fp=fp, N=N, nu=nu, clearprvdata=~use_old_data, get_datastring=None, data_prfx=ddir + data_prfx + "_stst", paraviewoutput=False, ) if bccontrol and linear_system: soldict.update(A=Arob) # compute the uncontrolled steady state Navier-Stokes solution vp_ss_nse, list_norm_nwtnupd = snu.solve_steadystate_nse(return_vp=True, **soldict) v_ss_nse, p_ss_nse = vp_ss_nse[:NV], vp_ss_nse[NV:] # specify in what spatial direction Bu changes. The remaining is constant if problemname == "drivencavity": uspacedep = 0 elif problemname == "cylinderwake": uspacedep = 1 # # Control mats # contsetupstr = problemname + "__NV{0}NU{1}NY{2}".format(NV, NU, NY) # get the control and observation operators try: b_mat = dou.load_spa(ddir + contsetupstr + "__b_mat") u_masmat = dou.load_spa(ddir + contsetupstr + "__u_masmat") print "loaded `b_mat`" except IOError: print "computing `b_mat`..." b_mat, u_masmat = cou.get_inp_opa(cdcoo=femp["cdcoo"], V=femp["V"], NU=NU, xcomp=uspacedep) dou.save_spa(b_mat, ddir + contsetupstr + "__b_mat") dou.save_spa(u_masmat, ddir + contsetupstr + "__u_masmat") try: mc_mat = dou.load_spa(ddir + contsetupstr + "__mc_mat") y_masmat = dou.load_spa(ddir + contsetupstr + "__y_masmat") print "loaded `c_mat`" except IOError: print "computing `c_mat`..." mc_mat, y_masmat = cou.get_mout_opa(odcoo=femp["odcoo"], V=femp["V"], NY=NY) dou.save_spa(mc_mat, ddir + contsetupstr + "__mc_mat") dou.save_spa(y_masmat, ddir + contsetupstr + "__y_masmat") # restrict the operators to the inner nodes mc_mat = mc_mat[:, invinds][:, :] b_mat = b_mat[invinds, :][:, :] c_mat = lau.apply_massinv(y_masmat, mc_mat, output="sparse") # TODO: right choice of norms for y # and necessity of regularization here # by now, we go on number save # the pressure observation mean over a small domain if problemname == "cylinderwake": podcoo = dict(xmin=0.6, xmax=0.64, ymin=0.18, ymax=0.22) elif problemname == "drivencavity": podcoo = dict(xmin=0.45, xmax=0.55, ymin=0.7, ymax=0.8) else: podcoo = femp["odcoo"] # description of the control and observation domains dmd = femp["cdcoo"] xmin, xmax, ymin, ymax = dmd["xmin"], dmd["xmax"], dmd["ymin"], dmd["ymax"] velcondomstr = "vel control domain: [{0}, {1}]x[{2}, {3}]\n".format(xmin, xmax, ymin, ymax) dmd = femp["odcoo"] xmin, xmax, ymin, ymax = dmd["xmin"], dmd["xmax"], dmd["ymin"], dmd["ymax"] velobsdomstr = "vel observation domain: [{0}, {1}]x[{2}, {3}]\n".format(xmin, xmax, ymin, ymax) dmd = podcoo xmin, xmax, ymin, ymax = dmd["xmin"], dmd["xmax"], dmd["ymin"], dmd["ymax"] pobsdomstr = "pressure observation domain: [{0}, {1}]x[{2}, {3}]\n".format(xmin, xmax, ymin, ymax) pcmat = cou.get_pavrg_onsubd(odcoo=podcoo, Q=femp["Q"], ppin=None) cdatstr = snu.get_datastr_snu(time=None, meshp=N, nu=nu, Nts=None) (coors, xinds, yinds, corfunvec) = dts.get_dof_coors(femp["V"], invinds=invinds) ctrl_visu_str = ( " the (distributed) control setup is as follows \n" + " B maps into the domain of control -" + velcondomstr + " the first half of the columns" + "actuate in x-direction, the second in y direction \n" + " Cv measures averaged velocities in the domain of observation" + velobsdomstr + " Cp measures the averaged pressure" + " in the domain of pressure observation: " + pobsdomstr + " the first components are in x, the last in y-direction \n\n" + " Visualization: \n\n" + " `coors` -- array of (x,y) coordinates in " + " the same order as v[xinds] or v[yinds] \n" + " `xinds`, `yinds` -- indices of x and y components" + " of v = [vx, vy] -- note that indexing starts with 0\n" + " for testing use corfunvec wich is the interpolant of\n" + " f(x,y) = [x, y] on the grid \n\n" + "Created in `get_exp_nsmats.py` " + "(see https://github.com/highlando/dolfin_navier_scipy) at\n" + datetime.datetime.now().strftime("%I:%M%p on %B %d, %Y") ) if bccontrol and problemname == "cylinderwake" and linear_system: ctrl_visu_str = ( "the boundary control is realized via penalized robin \n" + "boundary conditions, cf. e.g. [Hou/Ravindran `98], \n" + "with predefined shape functions for the cylinder wake \n" + "and the penalization parameter `palpha`={0}." ).format(palpha) + ctrl_visu_str if linear_system: convc_mat, rhs_con, rhsv_conbc = snu.get_v_conv_conts( prev_v=v_ss_nse, invinds=invinds, V=femp["V"], diribcs=femp["diribcs"] ) # TODO: omg if bccontrol: f_mat = -Arob - convc_mat else: f_mat = -stokesmatsc["A"] - convc_mat infostr = ( "These are the coefficient matrices of the linearized " + "Navier-Stokes Equations \n for the " + problemname + " to be used as \n\n" + " $M \\dot v = Av + J^Tp + Bu$ and $Jv = 0$ \n\n" + " the Reynoldsnumber is computed as L/nu \n" + " Note this is the reduced system for the velocity update\n" + " caused by the control, i.e., no boundary conditions\n" + " or inhomogeneities here. To get the actual flow, superpose \n" + " the steadystate velocity solution `v_ss_nse` \n\n" + ctrl_visu_str ) matstr = (mddir + problemname + "__mats_N{0}_Re{1}").format(NV, Re) if bccontrol: matstr = matstr + "__penarob_palpha{0}".format(palpha) scipy.io.savemat( matstr, dict( A=f_mat, M=stokesmatsc["M"], nu=femp["nu"], Re=femp["Re"], J=stokesmatsc["J"], B=b_mat, C=c_mat, Cp=pcmat, Brob=Brob, v_ss_nse=v_ss_nse, info=infostr, contsetupstr=contsetupstr, datastr=cdatstr, coors=coors, xinds=xinds, yinds=yinds, corfunvec=corfunvec, ), ) print ("matrices saved to " + matstr) elif refree: hstr = ddir + problemname + "_N{0}_hmat".format(N) try: hmat = dou.load_spa(hstr) print "loaded `hmat`" except IOError: print "assembling hmat ..." hmat = dts.ass_convmat_asmatquad(W=femp["V"], invindsw=invinds) dou.save_spa(hmat, hstr) zerv = np.zeros((NV, 1)) bc_conv, bc_rhs_conv, rhsbc_convbc = snu.get_v_conv_conts( prev_v=zerv, V=femp["V"], invinds=invinds, diribcs=femp["diribcs"], Picard=False ) # diff_mat = stokesmatsc['A'] # bcconv_mat = bc_conv # fv_bcdiff = fv_stbc # fv_bcconv = - bc_rhs_conv fv = fvc fp = fpc # fp_bc = fp_stbc infostr = ( "These are the coefficient matrices of the quadratic " + "formulation of the Navier-Stokes Equations \n for the " + problemname + " to be used as \n\n" + " $M \\dot v + Av + H*kron(v,v) + J^Tp = Bu + fv$ \n" + " and $Jv = fp$ \n\n" + " the Reynoldsnumber is computed as L/nu \n" + " note that `A` contains the diffusion and the linear term \n" + " that comes from the dirichlet boundary values \n" + " as initial value one can use the provided steady state \n" + " Stokes solution \n" + " see https://github.com/highlando/dolfin_navier_scipy/blob/" + " master/tests/solve_nse_quadraticterm.py for appl example\n" + ctrl_visu_str ) scipy.io.savemat( mddir + problemname + "quadform__mats_N{0}_Re{1}".format(NV, Re), dict( A=f_mat, M=stokesmatsc["M"], H=-hmat, fv=fv, fp=fp, nu=femp["nu"], Re=femp["Re"], J=stokesmatsc["J"], B=b_mat, Cv=c_mat, Cp=pcmat, info=infostr, # ss_stokes=old_v, contsetupstr=contsetupstr, datastr=cdatstr, coors=coors, xinds=xinds, yinds=yinds, corfunvec=corfunvec, ), ) else: hstr = ddir + problemname + "_N{0}_hmat".format(N) try: hmat = dou.load_spa(hstr) print "loaded `hmat`" except IOError: print "assembling hmat ..." hmat = dts.ass_convmat_asmatquad(W=femp["V"], invindsw=invinds) dou.save_spa(hmat, hstr) zerv = np.zeros((NV, 1)) bc_conv, bc_rhs_conv, rhsbc_convbc = snu.get_v_conv_conts( prev_v=zerv, V=femp["V"], invinds=invinds, diribcs=femp["diribcs"], Picard=False ) f_mat = -stokesmatsc["A"] - bc_conv l_mat = -bc_conv fv = fv_stbc + fvc - bc_rhs_conv fp = fp_stbc + fpc vp_stokes = lau.solve_sadpnt_smw(amat=A, jmat=J, rhsv=fv_stbc + fvc, rhsp=fp_stbc + fpc) old_v = vp_stokes[:NV] p_stokes = -vp_stokes[NV:] # the pressure was flipped for symmetry infostr = ( "These are the coefficient matrices of the quadratic " + "formulation of the Navier-Stokes Equations \n for the " + problemname + " to be used as \n\n" + " $M \\dot v = Av + H*kron(v,v) + J^Tp + Bu + fv$ \n" + " and $Jv = fp$ \n\n" + " the Reynoldsnumber is computed as L/nu \n" + " note that `A` contains the diffusion and the linear term `L`\n" + " that comes from the dirichlet boundary values \n" + " for linearizations it might be necessary to consider `A-L` \n" + " as initial value one can use the provided steady state \n" + " Stokes solution \n" + " see https://github.com/highlando/dolfin_navier_scipy/blob/" + " master/tests/solve_nse_quadraticterm.py for appl example\n" + ctrl_visu_str ) scipy.io.savemat( mddir + problemname + "quadform__mats_N{0}_Re{1}".format(NV, Re), dict( A=f_mat, M=stokesmatsc["M"], H=-hmat, fv=fv, fp=fp, L=l_mat, nu=femp["nu"], Re=femp["Re"], J=stokesmatsc["J"], B=b_mat, Cv=c_mat, Cp=pcmat, info=infostr, p_ss_stokes=p_stokes, p_ss_nse=p_ss_nse, v_ss_stokes=old_v, v_ss_nse=v_ss_nse, contsetupstr=contsetupstr, datastr=cdatstr, coors=coors, xinds=xinds, yinds=yinds, corfunvec=corfunvec, ), )
nwtn_myadi_dict = dict(adi_max_steps=350, adi_newZ_reltol=1e-7, nwtn_max_steps=30, nwtn_upd_reltol=1e-9, nwtn_upd_abstol=1e-7, ms=[-30.0, -20.0, -10.0, -5.0, -3.0, -1.0], verbose=True, full_upd_norm_check=False, check_lyap_res=False) nwtn_pyadi_dict = dict(verbose=True, maxit=45, aditol=1e-8, nwtn_res2_tol=4e-8, linesearch=True) femp, stokesmatsc, rhsd_vfrc, rhsd_stbc \ = dnsps.get_sysmats(problem=problemname, N=N, Re=Re, bccontrol=bccontrol, scheme='TH') invinds, NV = femp['invinds'], len(femp['invinds']) stokesmatsc['A'] = stokesmatsc['A'] + 1./palpha*stokesmatsc['Arob'] b_mat = 1./palpha*stokesmatsc['Brob'] b_mat_reg = lau.app_prj_via_sadpnt(amat=stokesmatsc['M'], jmat=stokesmatsc['J'], rhsv=b_mat, transposedprj=True) contsetupstr = 'NV{0}_bcc_NY{1}_palpha{2}'.format(NV, NY, palpha) shortcontsetupstr = '{0}{1}{2}'.format(NV, NY, np.int(np.log2(palpha))) fdstr = ddir + problemname + '_Re{0}_gamma{1}_'.format(Re, gamma) + \ contsetupstr + prbstr
def testit(problem=None, nu=None, charvel=None, Re=None, meshlvl=1, rho=1., t0=0.0, tE=1.0, Nts=1e2+1, ParaviewOutput=False, scheme='TH'): meshfile = 'mesh/karman2D-rotcyl_lvl{0}.xml.gz'.format(meshlvl) physregs = 'mesh/karman2D-rotcyl_lvl{0}_facet_region.xml.gz'.\ format(meshlvl) femp, stokesmatsc, rhsd = \ dnsps.get_sysmats(problem='cylinder_rot', nu=nu, bccontrol=False, charvel=charvel, scheme=scheme, mergerhs=True, meshparams=dict(strtomeshfile=meshfile, strtophysicalregions=physregs, strtobcsobs=geodata)) ddir = 'data/' data_prfx = problem + '{4}_mesh{0}_Re{1}_Nts{2}_tE{3}'.\ format(meshlvl, femp['Re'], Nts, tE, scheme) tips = dict(t0=t0, tE=tE, Nts=Nts) # ## Parameters for the benchmark values Um = charvel # (we alread scale the inflow parabola accordingly) L = femp['charlen'] # characteristic length NP, NV = stokesmatsc['J'].shape print('NV + NP : {0} + {1} = {2}'.format(NV, NP, NV+NP)) def rotcont(t, vel): return 0. dircntdict = dict(diricontbcinds=[femp['mvwbcinds']], diricontbcvals=[femp['mvwbcvals']], diricontfuncs=[rotcont]) soldict = stokesmatsc # containing A, J, JT soldict.update(femp) # adding V, Q, invinds, diribcs soldict.update(tips) # adding time integration params soldict.update(dircntdict) soldict.update(fv=rhsd['fv'], fp=rhsd['fp'], N=meshlvl, nu=nu, # start_ssstokes=True, verbose=True, return_vp=True, iniv=0*rhsd['fv'], get_datastring=None, comp_nonl_semexp=True, dbcinds=femp['dbcinds'], dbcvals=femp['dbcvals'], data_prfx=ddir+data_prfx, paraviewoutput=ParaviewOutput, vfileprfx=proutdir+'vel_', pfileprfx=proutdir+'p_') # # compute the uncontrolled steady state Navier-Stokes solution # vp_ss_nse = snu.solve_steadystate_nse(**soldict) vss, dynpss = dts.expand_vp_dolfunc(vc=vp_ss_nse[0], pc=vp_ss_nse[1], **femp) realpss = rho*dynpss # Um**2*rho*dynpss realvss = vss # Um*vss getld = dnsps.LiftDragSurfForce(V=femp['V'], nu=nu, ldds=femp['liftdragds']) clift, cdrag = getld.evaliftdragforce(u=realvss, p=realpss) cdclfac = 2./(rho*L*Um**2) print('Cl: {0}'.format(cdclfac*clift)) print('Cd: {0}'.format(cdclfac*cdrag)) import dolfin a_1 = dolfin.Point(0.15, 0.2) a_2 = dolfin.Point(0.25, 0.2) pdiff = realpss(a_1) - realpss(a_2) print('Delta P: {0}'.format(pdiff)) print('\n values from Schaefer/Turek as in') print('www.featflow.de/en/benchmarks/cfdbenchmarking/flow/' + 'dfg_benchmark1_re20.html:') print('Cl: {0}'.format(0.010618948146)) print('Cd: {0}'.format(5.57953523384)) print('Delta P: {0}'.format(0.11752016697))
def solve_euler_timedep(method=1, Omega=8, tE=None, Prec=None, N=40, NtsList=None, LinaTol=None, MaxIter=None, UsePreTStps=None, SaveTStps=None, SaveIniVal=None, scheme='TH', nu=0, Re=None, inikryupd=None, tolcor=False, prob=None): """system to solve du\dt + (u*D)u + grad p = fv div u = fp """ methdict = { 1: 'HalfExpEulSmaMin', 2: 'HalfExpEulInd2'} # instantiate object containing mesh, V, Q, rhs, velbcs, invinds # set nu=0 for Euler flow if prob == 'cyl': femp, stokesmatsc, rhsd_vfrc, rhsd_stbc \ = dnsps.get_sysmats(problem='cylinderwake', N=N, Re=Re, scheme=scheme) Mc, Ac = stokesmatsc['M'], stokesmatsc['A'] MPa = stokesmatsc['MP'] BTc, Bc = stokesmatsc['JT'], stokesmatsc['J'] Ba = stokesmatsc['Jfull'] # bcinds, bcvals = femp['bcinds'], femp['bcvals'] fvbc, fpbc = rhsd_stbc['fv'], rhsd_stbc['fp'] inivdict = dict(A=Ac, J=Bc, JT=BTc, M=Mc, ppin=None, V=femp['V'], Q=femp['Q'], fv=fvbc, fp=fpbc, vel_pcrd_stps=0, vel_nwtn_stps=0, return_vp=True, diribcs=femp['diribcs'], invinds=femp['invinds']) dimredsys = Bc.shape[1] + Bc.shape[0] vp_init = snu.solve_steadystate_nse(**inivdict)[0] PrP = FempToProbParams(N, omega=Omega, femp=femp, pdof=None) PrP.Pdof = None # No p pinning for outflow flow print 'Nv, Np -- w/o boundary nodes', BTc.shape else: if Re is not None: nu = 1./Re PrP = ProbParams(N, omega=Omega, nu=nu, scheme=scheme) # get system matrices as np.arrays smts = dts.get_stokessysmats(PrP.V, PrP.Q, nu=nu) rhsvecs = dts.setget_rhs(PrP.V, PrP.Q, PrP.fv, PrP.fp) # Ma, Aa, BTa, Ba = smts['A'], smts['JT'], smts['J'] # MPa = smts['MP'] # Ma, Aa, BTa, Ba, MPa = dtn.get_sysNSmats(PrP.V, PrP.Q, nu=nu) # fv, fp = rhsvecs['fv'], rhsvecs['fp'] # fv, fp = dtn.setget_rhs(PrP.V, PrP.Q, PrP.fv, PrP.fp) print 'Nv, Np -- w/ boundary nodes', smts['BTa'].shape # condense the system by resolving the boundary values # (Mc, Ac, BTc, Bc, fvbc, fpbc, bcinds, bcvals, # invinds) = dtn.condense_sysmatsbybcs(Ma, Aa, BTa, Ba, smts.update(rhsvecs) smtsc = dts.condense_sysmatsbybcs(smts, PrP.velbcs) Mc, Ac, BTc, Bc = smtsc['Mc'], smtsc['Ac'], smtsc['BTc'], smtsc['Bc'] fvbc, fpbc = smtsc['fvbc'], smtsc['fpbc'] # invinds print 'Nv, Np -- w/o boundary nodes', BTc.shape PrP.Pdof = 0 # Thats how the smamin is constructed dimredsys = Bc.shape[0] + Bc.shape[1] # TODO: this should sol(0) vp_init = np.zeros((dimredsys, 1)) # instantiate the Time Int Parameters TsP = TimestepParams(methdict[method], N, scheme=scheme) if NtsList is not None: TsP.Ntslist = NtsList if LinaTol is not None: TsP.linatol = LinaTol if MaxIter is not None: TsP.MaxIter = MaxIter if tE is not None: TsP.tE = tE if Omega is not None: TsP.Omega = Omega if SaveTStps is not None: TsP.SaveTStps = SaveTStps if UsePreTStps is not None: TsP.UsePreTStps = UsePreTStps if SaveIniVal is not None: TsP.SaveIniVal = SaveIniVal if inikryupd is not None: TsP.inikryupd = inikryupd TsP.TolCorB = tolcor print 'Mesh parameter N = %d' % N print 'Time interval [%d,%1.2f]' % (TsP.t0, TsP.tE) print 'Omega = %d' % TsP.Omega print 'You have chosen %s for time integration' % methdict[method] print 'The tolerance for the linear solver is %e' % TsP.linatol print 'tolcor -- controlling the abs residuals -- is ', tolcor if method == 1: # Rearrange the matrices and rhs # from smamin_utils import col_columns_atend from scipy.io import loadmat if prob == 'cyl' and scheme == 'CR': if N == 0: cricell = 758 elif N == 1: cricell = 1498 elif N == 2: cricell = 2386 elif N == 3: cricell = 4843 else: raise NotImplementedError() # TODO: this is hard coded... # dptatnb = dolfin.Point(2.2, 0.2) # cricell = smt.get_cellid_nexttopoint(PrP.mesh, dptatnb) elif prob == 'cyl': raise NotImplementedError() else: cricell = None MSmeCL, ASmeCL, BSme, B2Inds, B2BoolInv, B2BI = smt.\ get_smamin_rearrangement(N, PrP, M=Mc, A=Ac, B=Bc, crinicell=cricell, addnedgeat=cricell, scheme=scheme, fullB=Ba) FvbcSme = np.vstack([fvbc[~B2BoolInv, ], fvbc[B2BoolInv, ]]) FpbcSme = fpbc # inivalue dname = 'IniValSmaMinN%s' % N try: IniV = loadmat(dname) qqpq_init = IniV['qqpq_old'] vp_init = None except IOError: qqpq_init = None # Output try: os.chdir('json') except OSError: raise Warning('need "json" subdirectory for storing the data') os.chdir('..') if TsP.ParaviewOutput: os.chdir('results/') for fname in glob.glob(TsP.method + scheme + '*'): os.remove(fname) os.chdir('..') # ## Time stepping ## # for i, CurNTs in enumerate(TsP.Ntslist): TsP.Nts = CurNTs if method == 2: tis.halfexp_euler_nseind2(Mc, MPa, Ac, BTc, Bc, fvbc, fpbc, PrP, TsP, vp_init=vp_init) elif method == 1: tis.halfexp_euler_smarminex(MSmeCL, ASmeCL, BSme, MPa, FvbcSme, FpbcSme, B2BoolInv, PrP, TsP, qqpq_init=qqpq_init, vp_init=vp_init) # Output only in first iteration! TsP.ParaviewOutput = False save_simu(TsP, PrP) return
fh = logging.FileHandler('log.interpoltest') fh.setLevel(logging.DEBUG) formatter = \ logging.Formatter('%(name)s - %(levelname)s - %(message)s') # logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') fh.setFormatter(formatter) logger.addHandler(fh) problemname = 'cylinderwake' N = 2 Nref = 3 Re = 10 femp, stokesmatsc, rhsd = dnsps.get_sysmats(problem=problemname, N=N, Re=Re, mergerhs=True) soldict = stokesmatsc # containing A, J, JT soldict.update(femp) # adding V, Q, invinds, diribcs soldict.update(rhsd) # adding the discrete rhs v_ss_nse, list_norm_nwtnupd = snu.solve_steadystate_nse(N=N, **soldict) vwbc = dts.append_bcs_vec(v_ss_nse, **femp) vwbcf, _ = dts.expand_vp_dolfunc(vc=vwbc, V=femp['V']) fempref, stokesmatsc, rhsd = dnsps.get_sysmats(problem=problemname, N=Nref, Re=Re, mergerhs=True) Vref = fempref['V'] class ExtFunZero(dolfin.Expression):
def get_curmeshdict(problem=None, N=None, Re=None, nu=None, scheme=None, onlymesh=False, smaminex=False): """ Parameters --- smaminex : boolean, optional whether compute return the rearranged matrices needed for the index-1 formulation with minimal extension [Altmann, Heiland 2015], defaults to `False` """ if onlymesh: femp = dnsps.get_sysmats(problem=problem, N=N, scheme=scheme, onlymesh=True) return femp else: femp, stokesmatsc, rhsd = dnsps.\ get_sysmats(problem=problem, N=N, Re=Re, nu=nu, scheme=scheme, mergerhs=True) M, A, J = stokesmatsc['M'], stokesmatsc['A'], stokesmatsc['J'] V, Q = femp['V'], femp['Q'] invinds, diribcs = femp['invinds'], femp['diribcs'] nu = femp['nu'] if nu is None else nu fv, fp = rhsd['fv'], rhsd['fp'] cmd = dict(M=M, A=A, J=J, V=V, Q=Q, invinds=invinds, diribcs=diribcs, fv=fv, fp=fp, N=N, Re=femp['Re']) logger.debug('in `get_curmeshdict`: ' + 'problem={0}, scheme={1}, Re={2}, nu={3}, ppin={4}'. format(problem, scheme, Re, nu, femp['ppin'])) if smaminex: cricelldict = {0: 758, 1: 1498, 2: 2386, 3: 4843, 4: 6993} # TODO: this is hardcoded for the FEniCS cylinder meshes if problem == 'cylinderwake' and scheme == 'CR': try: cricell = cricelldict[N] except KeyError(): raise NotImplementedError() else: raise NotImplementedError() MSmeCL, ASmeCL, BSme, B2Inds, B2BoolInv, B2BI = smt.\ get_smamin_rearrangement(N, None, M=M, A=A, B=J, V=V, Q=Q, nu=nu, mesh=femp['mesh'], crinicell=cricell, addnedgeat=cricell, Pdof=femp['ppin'], scheme=scheme, invinds=invinds, fullB=stokesmatsc['Jfull']) FvbcSme = np.vstack([fv[~B2BoolInv, ], fv[B2BoolInv, ]]) def sortitback(q1=None, q2=None): vc = np.zeros((fv.size, 1)) vc[~B2BoolInv, ] = q1.reshape((q1.size, 1)) vc[B2BoolInv, ] = q2.reshape((q2.size, 1)) return vc def sortitthere(vc, getitstacked=False): q1 = vc[~B2BoolInv, ] q2 = vc[B2BoolInv, ] if getitstacked: return np.vstack([q1, q2]) else: return q1, q2 cmd.update(dict(ASme=ASmeCL, JSme=BSme, MSme=MSmeCL, fvSme=FvbcSme, smmxqq2vel=sortitback, npc=BSme.shape[0], vel2smmxqq=sortitthere)) return cmd
def testit(problem=None, nu=None, charvel=None, Re=None, meshlvl=1, gradvsymmtrc=True, rho=1., ParaviewOutput=False, scheme='TH'): meshfile = 'mesh/karman2D-rotcyl_lvl{0}.xml.gz'.format(meshlvl) physregs = 'mesh/karman2D-rotcyl_lvl{0}_facet_region.xml.gz'.\ format(meshlvl) femp, stokesmatsc, rhsd = \ dnsps.get_sysmats(problem=problem, nu=nu, charvel=charvel, gradvsymmtrc=gradvsymmtrc, scheme=scheme, mergerhs=True, meshparams=dict(strtomeshfile=meshfile, movingwallcntrl=False, strtophysicalregions=physregs, strtobcsobs=geodata)) ddir = 'data/' data_prfx = problem + '{2}_mesh{0}_Re{1}'.format(meshlvl, femp['Re'], scheme) # ## Parameters for the benchmark values Um = charvel # (we alread scale the inflow parabola accordingly) L = femp['charlen'] # characteristic length NP, NV = stokesmatsc['J'].shape print('NV + NP : {0} + {1} = {2}'.format(NV, NP, NV + NP)) soldict = stokesmatsc # containing A, J, JT # soldict.update(femp) # adding V, Q, invinds, diribcs soldict.update(invinds=femp['invinds'], V=femp['V'], Q=femp['Q']) soldict.update(fv=rhsd['fv'], fp=rhsd['fp'], N=meshlvl, nu=nu, verbose=True, return_vp=True, get_datastring=None, dbcinds=femp['dbcinds'], dbcvals=femp['dbcvals'], data_prfx=ddir + data_prfx, paraviewoutput=ParaviewOutput, vfileprfx=proutdir + 'vel_', pfileprfx=proutdir + 'p_') # # compute the uncontrolled steady state Navier-Stokes solution # vp_ss_nse = snu.solve_steadystate_nse(**soldict) vss, dynpss = dts.expand_vp_dolfunc(vc=vp_ss_nse[0], pc=vp_ss_nse[1], **femp) steady_state_res = \ get_steady_state_res(V=femp['V'], gradvsymmtrc=True, outflowds=femp['outflowds'], nu=nu) res = steady_state_res(vss, rho * dynpss) auxvec = np.zeros((femp['V'].dim(), )) invinds = femp['invinds'] auxvec[invinds] = res.get_local()[invinds] print('two norm of the res: {0}'.format(np.linalg.norm(auxvec))) phionevec = np.zeros((femp['V'].dim(), 1)) phionevec[femp['ldsbcinds'], :] = 1. phione = dolfin.Function(femp['V']) phione.vector().set_local(phionevec) pickx = dolfin.as_matrix([[1., 0.], [0., 0.]]) picky = dolfin.as_matrix([[0., 0.], [0., 1.]]) pox = pickx * phione poy = picky * phione drag = steady_state_res(vss, rho * dynpss, phi=pox) lift = steady_state_res(vss, rho * dynpss, phi=poy) cdclfac = 2. / (rho * L * Um**2) print('Computed via testing the residual: ') print('Cl: {0}'.format(cdclfac * lift)) print('Cd: {0}'.format(cdclfac * drag)) phionevec = np.zeros((femp['V'].dim(), 1)) phionevec[femp['ldsbcinds'], :] = 1. phione = dolfin.Function(femp['V']) phione.vector().set_local(phionevec) # phionex = phione.sub(0) print('Computed via `dnsps.LiftDragSurfForce`:') realpss = rho * dynpss # Um**2*rho*dynpss realvss = vss # Um*vss getld = dnsps.LiftDragSurfForce(V=femp['V'], nu=nu, ldds=femp['liftdragds'], outflowds=femp['outflowds'], phione=phione) clift, cdrag = getld.evaliftdragforce(u=realvss, p=realpss) print('Cl: {0}'.format(cdclfac * clift)) print('Cd: {0}'.format(cdclfac * cdrag)) a_1 = dolfin.Point(0.15, 0.2) a_2 = dolfin.Point(0.25, 0.2) pdiff = realpss(a_1) - realpss(a_2) print('Delta P: {0}'.format(pdiff)) print('\n values from Schaefer/Turek as in') print('www.featflow.de/en/benchmarks/cfdbenchmarking/flow/' + 'dfg_benchmark1_re20.html:') print('Cl: {0}'.format(0.010618948146)) print('Cd: {0}'.format(5.57953523384)) print('Delta P: {0}'.format(0.11752016697))
def gopod(problemname='drivencavity', N=10, Re=1e2, t0=0.0, tE=1.0, Nts=11, NU=3, NY=3, paraoutput=True, multiproc=False, krylov=None, krpslvprms={}, krplsprms={}): """Main routine for LQGBT Parameters ---------- problemname : string, optional what problem to be solved, 'cylinderwake' or 'drivencavity' N : int, optional parameter for the dimension of the space discretization Re : real, optional Reynolds number, defaults to `1e2` t0, tE, Nts : real, real, int, optional starting and endpoint of the considered time interval, number of time instancses, default to `0.0, 1.0, 11` NU, NY : int, optional dimensions of components of in and output space (will double because there are two components), default to `3, 3` krylov : {None, 'gmres'}, optional whether or not to use an iterative solver, defaults to `None` krpslvprms : dictionary, optional to specify parameters of the linear solver for use in Krypy, e.g., * initial guess * tolerance * number of iterations defaults to `None` krplsprms : dictionary, optional parameters to define the linear system like *preconditioner """ femp, stokesmatsc, rhsd_vfrc, rhsd_stbc, data_prfx, ddir, proutdir = \ dnsps.get_sysmats(problem=problemname, N=N, Re=Re) # specify in what spatial direction Bu changes. The remaining is constant uspacedep = femp['uspacedep'] # output ddir = 'data/' try: os.chdir(ddir) except OSError: raise Warning('need "' + ddir + '" subdir for storing the data') os.chdir('..') data_prfx = ddir + data_prfx # casting some parameters NV = len(femp['invinds']) # contsetupstr = 'NV{0}NU{1}NY{2}alphau{3}'.format(NV, NU, NY, alphau) contsetupstr = 'NV{0}NU{1}NY{2}Re{3}'.format(NV, NU, NY, Re) soldict = stokesmatsc # containing A, J, JT soldict.update(femp) # adding V, Q, invinds, diribcs soldict.update(rhsd_vfrc) # adding fvc, fpr soldict.update(fv_stbc=rhsd_stbc['fv'], fp_stbc=rhsd_stbc['fp'], N=N, nu=femp['nu'], data_prfx=data_prfx) soldict.update(paraviewoutput=paraoutput) soldict.update(krylov=krylov, krplsprms=krplsprms, krpslvprms=krpslvprms) # # Prepare for control # # get the control and observation operators try: b_mat = dou.load_spa(ddir + contsetupstr + '__b_mat') u_masmat = dou.load_spa(ddir + contsetupstr + '__u_masmat') print 'loaded `b_mat`' except IOError: print 'computing `b_mat`...' b_mat, u_masmat = cou.get_inp_opa(cdcoo=femp['cdcoo'], V=femp['V'], NU=NU, xcomp=uspacedep) dou.save_spa(b_mat, ddir + contsetupstr + '__b_mat') dou.save_spa(u_masmat, ddir + contsetupstr + '__u_masmat') try: mc_mat = dou.load_spa(ddir + contsetupstr + '__mc_mat') y_masmat = dou.load_spa(ddir + contsetupstr + '__y_masmat') print 'loaded `c_mat`' except IOError: print 'computing `c_mat`...' mc_mat, y_masmat = cou.get_mout_opa(odcoo=femp['odcoo'], V=femp['V'], NY=NY) dou.save_spa(mc_mat, ddir + contsetupstr + '__mc_mat') dou.save_spa(y_masmat, ddir + contsetupstr + '__y_masmat') # restrict the operators to the inner nodes invinds = femp['invinds'] mc_mat = mc_mat[:, invinds][:, :] b_mat = b_mat[invinds, :][:, :] # tb_mat = 1./np.sqrt(alphau) # setup the system for the correction # # # compute the uncontrolled steady state Stokes solution # v_ss_stokes, list_norm_nwtnupd = \ snu.solve_steadystate_nse(vel_pcrd_stps=0, vel_nwtn_stps=0, clearprvdata=True, **soldict) tmesh = np.linspace(t0, tE, Nts) soldict.update(trange=tmesh, iniv=v_ss_stokes, lin_vel_point=v_ss_stokes, clearprvdata=True, vel_nwtn_stps=1, return_dictofvelstrs=False, paraviewoutput=True, vfileprfx='results/fullvel', pfileprfx='results/fullp') convc_mat_n, rhs_con_n, rhsv_conbc_n = \ snu.get_v_conv_conts(prev_v=v_ss_stokes, invinds=invinds, V=femp['V'], diribcs=femp['diribcs'], Picard=False) convc_mat_z, rhs_con_z, rhsv_conbc_z = \ snu.get_v_conv_conts(prev_v=0*v_ss_stokes, invinds=invinds, V=femp['V'], diribcs=femp['diribcs'], Picard=False) vellist = snu.solve_nse(return_as_list=True, **soldict) velar = np.array(vellist)[:, :, 0].T rhsv = soldict['fv_stbc'] + soldict['fvc'] + rhsv_conbc_n + rhs_con_n rhsp = soldict['fp_stbc'] + soldict['fpr'] # print 'fvstbc', np.linalg.norm(soldict['fv_stbc']) # print 'fvc', np.linalg.norm(soldict['fvc']) # print 'rhsvconbc', np.linalg.norm(rhsv_conbc_n) # print 'rhscon', np.linalg.norm(rhs_con_n) print 'velarshape :', velar.shape checkreturns = False if checkreturns: inivel = velar[:, 0:1] ylist = snu.solve_nse(A=soldict['A']+convc_mat_n-convc_mat_z, M=soldict['M'], J=soldict['J'], fvc=rhsv, fpr=rhsp, iniv=inivel, fv_stbc=0*rhsv - rhsv_conbc_z - rhs_con_z, fp_stbc=0*rhsp, lin_vel_point=0*inivel, trange=tmesh, V=femp['V'], Q=femp['Q'], invinds=femp['invinds'], diribcs=femp['diribcs'], N=soldict['N'], nu=soldict['nu'], vel_nwtn_stps=1, return_as_list=True) velarcheck = np.array(ylist)[:, :, 0].T print np.linalg.norm(velarcheck - velar) # print np.linalg.norm(velarcheck[:, 1] - velar[:, 1]) return (soldict['M'], soldict['A']+convc_mat_n, velar, rhsv, b_mat, tmesh, soldict['J'])
import dolfin_navier_scipy.problem_setups as dnsps import dolfin_navier_scipy.stokes_navier_utils as snu import numpy as np N, Re, scheme, ppin = 2, 50, 'TH', None femp, stokesmatsc, rhsd_vfrc, \ rhsd_stbc, data_prfx, ddir, proutdir \ = dnsps.get_sysmats(problem='cylinderwake', N=N, Re=Re, scheme=scheme) Mc, Ac = stokesmatsc['M'], stokesmatsc['A'] BTc, Bc = stokesmatsc['JT'], stokesmatsc['J'] print Bc.shape invinds = femp['invinds'] fv, fp = rhsd_stbc['fv'], rhsd_stbc['fp'] inivdict = dict(A=Ac, J=Bc, JT=BTc, M=Mc, ppin=ppin, fv=fv, fp=fp, return_vp=True, V=femp['V'], invinds=invinds, diribcs=femp['diribcs']) vp_init = snu.solve_steadystate_nse(**inivdict)[0] NV = Bc.shape[1] pfv = snu.get_pfromv(v=vp_init[:NV, :], V=femp['V'], M=Mc, A=Ac, J=Bc, fv=fv, invinds=femp['invinds'], diribcs=femp['diribcs']) print invinds.shape print Bc.shape print pfv.shape print vp_init.shape
def twod_simu(nu=None, charvel=None, rho=1., rhosolid=10., meshparams=None, inirot=None, inivfun=None, t0=0.0, tE=.1, Nts=1e2+1, start_steadystate=False, ininu=None, plotplease=False, proutdir='paraviewplots/', return_final_vp=False, ParaviewOutput=False, scheme='TH'): femp, stokesmatsc, rhsd = \ dnsps.get_sysmats(problem='gen_bccont', nu=nu, bccontrol=False, charvel=charvel, scheme=scheme, mergerhs=True, meshparams=meshparams) # dnsps.get_sysmats(problem='cylinder_rot', nu=nu, bccontrol=False, # charvel=charvel, scheme=scheme, mergerhs=True, # meshparams=meshparams) tips = dict(t0=t0, tE=tE, Nts=Nts) NP, NV = stokesmatsc['J'].shape print('NV + NP : {0} + {1} = {2}'.format(NV, NP, NV+NP)) # function of ones at the lift/drag boundary phionevec = np.zeros((femp['V'].dim(), 1)) phionevec[femp['mvwbcinds'], :] = 1. phione = dolfin.Function(femp['V']) phione.vector().set_local(phionevec) pickx = dolfin.as_matrix([[1., 0.], [0., 0.]]) picky = dolfin.as_matrix([[0., 0.], [0., 1.]]) pox = pickx*phione poy = picky*phione # function of the tangential vector at the lift/drag boundary phitwovec = np.zeros((femp['V'].dim(), 1)) phitwovec[femp['mvwbcinds'], 0] = femp['mvwbcvals'] phitwo = dolfin.Function(femp['V']) phitwo.vector().set_local(phitwovec) # getld = dnsps.LiftDragSurfForce(V=femp['V'], nu=nu, # phione=phione, phitwo=phitwo, # outflowds=femp['outflowds'], # ldds=femp['liftdragds']) # L = femp['charlen'] # characteristic length = 2*Radius a_1 = dolfin.Point(0.15, 0.2) a_2 = dolfin.Point(0.25, 0.2) reschkdict = dict(V=femp['V'], gradvsymmtrc=True, outflowds=femp['outflowds'], nu=nu) euleres = get_imex_res(explscheme='eule', **reschkdict) heunres = get_imex_res(explscheme='heun', **reschkdict) abtwres = get_imex_res(explscheme='abtw', **reschkdict) # ststres = get_steady_state_res(**reschkdict) def record_ldt(t, vel=None, p=None, memory={}, mode='abtwo'): rotval = 0. if mode == 'stokes': memory.update(dict(lastt=t)) return rotval, memory if mode == 'init': memory.update(dict(lastt=t)) return rotval, memory vfun, pfun = dts.expand_vp_dolfunc(vc=vel, pc=p, **femp) if mode == 'heunpred' or mode == 'heuncorr': curdt = t - memory['lastt'] if mode == 'heunpred': memory.update(dict(lastv=vel)) pass elif mode == 'heuncorr': lvfun = dts.expand_vp_dolfunc(vc=memory['lastv'], **femp)[0] trqe = euleres(vfun, pfun, curdt, lastvel=lvfun, phi=phitwo) lift = euleres(vfun, pfun, curdt, lastvel=lvfun, phi=poy) drag = euleres(vfun, pfun, curdt, lastvel=lvfun, phi=pox) memory.update(dict(lastt=t, lastdt=curdt, heunpred=vel)) memory['trqs'].append(trqe) memory['lfts'].append(lift) memory['drgs'].append(drag) memory['tims'].append(t) elif mode == 'abtwo': lvfun = dts.expand_vp_dolfunc(vc=memory['lastv'], **femp)[0] curdt = t - memory['lastt'] try: ovfn = dts.expand_vp_dolfunc(vc=memory['lastlastv'], **femp)[0] modres = abtwres except KeyError: # no lastlastv yet -- we can check the Heun res ovfn = dts.expand_vp_dolfunc(vc=memory['heunpred'], **femp)[0] modres = heunres trqe = modres(vfun, pfun, curdt, lastvel=lvfun, othervel=ovfn, phi=phitwo) lift = modres(vfun, pfun, curdt, lastvel=lvfun, othervel=ovfn, phi=poy) drag = modres(vfun, pfun, curdt, lastvel=lvfun, othervel=ovfn, phi=pox) memory.update(dict(lastlastv=np.copy(memory['lastv']))) memory.update(dict(lastv=vel)) memory['trqs'].append(trqe) memory['lfts'].append(lift) memory['drgs'].append(drag) memory['tims'].append(t) memory.update(dict(lastt=t, lastdt=curdt)) deltap = pfun(a_1) - pfun(a_2) memory['dtps'].append(deltap) return rotval, memory rotcondict = dict(lastt=None, trqs=[], omegs=[], lfts=[], drgs=[], dtps=[], tims=[], lastdt=None) dircntdict = dict(diricontbcinds=[femp['mvwbcinds']], diricontbcvals=[femp['mvwbcvals']], diricontfuncs=[record_ldt], diricontfuncmems=[rotcondict]) soldict = {} soldict.update(stokesmatsc) # containing A, J, JT soldict.update(femp) # adding V, Q, invinds, diribcs soldict.update(tips) # adding time integration params soldict.update(dircntdict) soldict.update(fv=rhsd['fv'], fp=rhsd['fp'], verbose=True, vel_pcrd_stps=5, return_vp=True, treat_nonl_explct=True, no_data_caching=True, return_final_vp=return_final_vp, dbcinds=femp['dbcinds'], dbcvals=femp['dbcvals'], paraviewoutput=ParaviewOutput, vfileprfx=proutdir+'vel_', pfileprfx=proutdir+'p_') # if inivfun is None: if start_steadystate: if ininu is not None: inifemp, inistokesmatsc, inirhsd = \ dnsps.get_sysmats(problem='cylinder_rot', nu=ininu, bccontrol=False, charvel=charvel, scheme=scheme, mergerhs=True, meshparams=meshparams) soldict.update(inistokesmatsc) soldict.update(inifemp) soldict.update(fv=inirhsd['fv'], fp=inirhsd['fp']) vp_ss_nse = snu.solve_steadystate_nse(**soldict) soldict.update(dict(vel_start_nwtn=vp_ss_nse[0])) soldict.update(stokesmatsc) soldict.update(femp) soldict.update(fv=rhsd['fv'], fp=rhsd['fp']) soldict.update(vel_nwtn_tol=1e-3) vp_ss_nse = snu.solve_steadystate_nse(**soldict) soldict.update(dict(iniv=vp_ss_nse[0])) else: soldict.update(start_ssstokes=True) else: inivvec = (inivfun.vector().get_local()).reshape((femp['V'].dim(), 1)) soldict.update(dict(iniv=inivvec)) finalvp = snu.solve_nse(**soldict) if ParaviewOutput: print('for plots check \nparaview ' + proutdir + 'vel___timestep.pvd') print('or \nparaview ' + proutdir + 'p___timestep.pvd') resdict = rotcondict nnz = 2*stokesmatsc['J'].nnz + stokesmatsc['A'].nnz resdict.update(dict(nvnp=[NV, NP], nnz=nnz)) if return_final_vp: return rotcondict, finalvp return rotcondict
import dolfin_navier_scipy.problem_setups as dnsps import dolfin_navier_scipy.stokes_navier_utils as snu import numpy as np N, Re, scheme, ppin = 2, 50, 'TH', None femp, stokesmatsc, rhsd = \ dnsps.get_sysmats(problem='cylinderwake', Re=Re, scheme=scheme, mergerhs=True, meshparams=dict(refinement_level=N)) Mc, Ac = stokesmatsc['M'], stokesmatsc['A'] BTc, Bc = stokesmatsc['JT'], stokesmatsc['J'] invinds = femp['invinds'] fv, fp = rhsd['fv'], rhsd['fp'] inivdict = dict(A=Ac, J=Bc, JT=BTc, M=Mc, ppin=ppin, fv=fv, fp=fp, return_vp=True, V=femp['V'], invinds=invinds, diribcs=femp['diribcs']) # ## Solve the steady-state NSE vp_steadystate = snu.solve_steadystate_nse(**inivdict) NV = Bc.shape[1] # ## Test: recompute the p from the v pfv = snu.get_pfromv(v=vp_steadystate[0], V=femp['V'], M=Mc, A=Ac, J=Bc, fv=fv, invinds=femp['invinds'], diribcs=femp['diribcs']) print('Number of inner velocity nodes: {0}'.format(invinds.shape))
import dolfin import dolfin_navier_scipy.problem_setups as dnsps N = 10 mesh = dolfin.UnitSquareMesh(N, N) edgepoint = dolfin.Point(1., 1.) aaa = mesh.bounding_box_tree().compute_first_entity_collision(edgepoint) femp, stokesmatsc, rhsd_vfrc, rhsd_stbc \ = dnsps.get_sysmats(problem='cylinderwake', N=4, Re=2, scheme='CR') mesh = femp['mesh'] edgepoint = dolfin.Point(2.5, .2) aaac = mesh.bounding_box_tree().compute_first_entity_collision(edgepoint) print 'Cell id at boundary: ', aaac dolfin.plot(mesh) dolfin.interactive(True)
def comp_exp_nsmats(problemname='drivencavity', N=10, Re=1e2, nu=None, linear_system=False, refree=False, bccontrol=False, palpha=None, use_old_data=False, mddir='pathtodatastorage'): """compute and export the system matrices for Navier-Stokes equations Parameters --- refree : boolean, optional whether to use `Re=1` (so that the `Re` number can be applied later by scaling the corresponding matrices, defaults to `False` linear_system : boolean, optional whether to compute/return the linearized system, defaults to `False` bccontrol : boolean, optional whether to model boundary control at the cylinder via penalized robin boundary conditions, defaults to `False` palpha : float, optional penalization parameter for the boundary control, defaults to `None`, `palpha` is mandatory for `linear_system` """ if refree: Re = 1 print 'For the Reynoldsnumber free mats, we set Re=1' if problemname == 'drivencavity' and bccontrol: raise NotImplementedError('boundary control for the driven cavity' + ' is not implemented yet') if linear_system and bccontrol and palpha is None: raise UserWarning('For the linear system a' + ' value for `palpha` is needed') if not linear_system and bccontrol: raise NotImplementedError('Nonlinear system with boundary control' + ' is not implemented yet') femp, stokesmatsc, rhsd_vfrc, rhsd_stbc = \ dnsps.get_sysmats(problem=problemname, bccontrol=bccontrol, N=N, Re=Re) if linear_system and bccontrol: Arob = stokesmatsc['A'] + 1. / palpha * stokesmatsc['Arob'] Brob = 1. / palpha * stokesmatsc['Brob'] elif linear_system: Brob = 0 invinds = femp['invinds'] A, J = stokesmatsc['A'], stokesmatsc['J'] fvc, fpc = rhsd_vfrc['fvc'], rhsd_vfrc['fpr'] fv_stbc, fp_stbc = rhsd_stbc['fv'], rhsd_stbc['fp'] invinds = femp['invinds'] NV = invinds.shape[0] data_prfx = problemname + '__N{0}Re{1}'.format(N, Re) if bccontrol: data_prfx = data_prfx + '_penarob' soldict = stokesmatsc # containing A, J, JT soldict.update(femp) # adding V, Q, invinds, diribcs soldict.update(rhsd_vfrc) # adding fvc, fpr fv = rhsd_vfrc['fvc'] + rhsd_stbc['fv'] fp = rhsd_vfrc['fpr'] + rhsd_stbc['fp'] # print 'get expmats: ||fv|| = {0}'.format(np.linalg.norm(fv)) # print 'get expmats: ||fp|| = {0}'.format(np.linalg.norm(fp)) # import scipy.sparse.linalg as spsla # print 'get expmats: ||A|| = {0}'.format(spsla.norm(A)) # print 'get expmats: ||Arob|| = {0}'.format(spsla.norm(Arob)) # print 'get expmats: ||A|| = {0}'.format(spsla.norm(stokesmatsc['A'])) # raise Warning('TODO: debug') soldict.update(fv=fv, fp=fp, N=N, nu=nu, clearprvdata=~use_old_data, get_datastring=None, data_prfx=ddir + data_prfx + '_stst', paraviewoutput=False) if bccontrol and linear_system: soldict.update(A=Arob) # compute the uncontrolled steady state Navier-Stokes solution vp_ss_nse, list_norm_nwtnupd = snu.solve_steadystate_nse(return_vp=True, **soldict) v_ss_nse, p_ss_nse = vp_ss_nse[:NV], vp_ss_nse[NV:] # specify in what spatial direction Bu changes. The remaining is constant if problemname == 'drivencavity': uspacedep = 0 elif problemname == 'cylinderwake': uspacedep = 1 # # Control mats # contsetupstr = problemname + '__NV{0}NU{1}NY{2}'.format(NV, NU, NY) # get the control and observation operators try: b_mat = dou.load_spa(ddir + contsetupstr + '__b_mat') u_masmat = dou.load_spa(ddir + contsetupstr + '__u_masmat') print 'loaded `b_mat`' except IOError: print 'computing `b_mat`...' b_mat, u_masmat = cou.get_inp_opa(cdcoo=femp['cdcoo'], V=femp['V'], NU=NU, xcomp=uspacedep) dou.save_spa(b_mat, ddir + contsetupstr + '__b_mat') dou.save_spa(u_masmat, ddir + contsetupstr + '__u_masmat') try: mc_mat = dou.load_spa(ddir + contsetupstr + '__mc_mat') y_masmat = dou.load_spa(ddir + contsetupstr + '__y_masmat') print 'loaded `c_mat`' except IOError: print 'computing `c_mat`...' mc_mat, y_masmat = cou.get_mout_opa(odcoo=femp['odcoo'], V=femp['V'], NY=NY) dou.save_spa(mc_mat, ddir + contsetupstr + '__mc_mat') dou.save_spa(y_masmat, ddir + contsetupstr + '__y_masmat') # restrict the operators to the inner nodes mc_mat = mc_mat[:, invinds][:, :] b_mat = b_mat[invinds, :][:, :] c_mat = lau.apply_massinv(y_masmat, mc_mat, output='sparse') # TODO: right choice of norms for y # and necessity of regularization here # by now, we go on number save # the pressure observation mean over a small domain if problemname == 'cylinderwake': podcoo = dict(xmin=0.6, xmax=0.64, ymin=0.18, ymax=0.22) elif problemname == 'drivencavity': podcoo = dict(xmin=0.45, xmax=0.55, ymin=0.7, ymax=0.8) else: podcoo = femp['odcoo'] # description of the control and observation domains dmd = femp['cdcoo'] xmin, xmax, ymin, ymax = dmd['xmin'], dmd['xmax'], dmd['ymin'], dmd['ymax'] velcondomstr = 'vel control domain: [{0}, {1}]x[{2}, {3}]\n'.\ format(xmin, xmax, ymin, ymax) dmd = femp['odcoo'] xmin, xmax, ymin, ymax = dmd['xmin'], dmd['xmax'], dmd['ymin'], dmd['ymax'] velobsdomstr = 'vel observation domain: [{0}, {1}]x[{2}, {3}]\n'.\ format(xmin, xmax, ymin, ymax) dmd = podcoo xmin, xmax, ymin, ymax = dmd['xmin'], dmd['xmax'], dmd['ymin'], dmd['ymax'] pobsdomstr = 'pressure observation domain: [{0}, {1}]x[{2}, {3}]\n'.\ format(xmin, xmax, ymin, ymax) pcmat = cou.get_pavrg_onsubd(odcoo=podcoo, Q=femp['Q'], ppin=None) cdatstr = snu.get_datastr_snu(time=None, meshp=N, nu=nu, Nts=None) (coors, xinds, yinds, corfunvec) = dts.get_dof_coors(femp['V'], invinds=invinds) ctrl_visu_str = \ ' the (distributed) control setup is as follows \n' +\ ' B maps into the domain of control -' +\ velcondomstr +\ ' the first half of the columns' +\ 'actuate in x-direction, the second in y direction \n' +\ ' Cv measures averaged velocities in the domain of observation' +\ velobsdomstr +\ ' Cp measures the averaged pressure' +\ ' in the domain of pressure observation: ' +\ pobsdomstr +\ ' the first components are in x, the last in y-direction \n\n' +\ ' Visualization: \n\n' +\ ' `coors` -- array of (x,y) coordinates in ' +\ ' the same order as v[xinds] or v[yinds] \n' +\ ' `xinds`, `yinds` -- indices of x and y components' +\ ' of v = [vx, vy] -- note that indexing starts with 0\n' +\ ' for testing use corfunvec wich is the interpolant of\n' +\ ' f(x,y) = [x, y] on the grid \n\n' +\ 'Created in `get_exp_nsmats.py` ' +\ '(see https://github.com/highlando/dolfin_navier_scipy) at\n' +\ datetime.datetime.now().strftime("%I:%M%p on %B %d, %Y") if bccontrol and problemname == 'cylinderwake' and linear_system: ctrl_visu_str = \ ('the boundary control is realized via penalized robin \n' + 'boundary conditions, cf. e.g. [Hou/Ravindran `98], \n' + 'with predefined shape functions for the cylinder wake \n' + 'and the penalization parameter `palpha`={0}.').format(palpha) +\ ctrl_visu_str if linear_system: convc_mat, rhs_con, rhsv_conbc = \ snu.get_v_conv_conts(prev_v=v_ss_nse, invinds=invinds, V=femp['V'], diribcs=femp['diribcs']) # TODO: omg if bccontrol: f_mat = -Arob - convc_mat else: f_mat = -stokesmatsc['A'] - convc_mat infostr = 'These are the coefficient matrices of the linearized ' +\ 'Navier-Stokes Equations \n for the ' +\ problemname + ' to be used as \n\n' +\ ' $M \\dot v = Av + J^Tp + Bu$ and $Jv = 0$ \n\n' +\ ' the Reynoldsnumber is computed as L/nu \n' +\ ' Note this is the reduced system for the velocity update\n' +\ ' caused by the control, i.e., no boundary conditions\n' +\ ' or inhomogeneities here. To get the actual flow, superpose \n' +\ ' the steadystate velocity solution `v_ss_nse` \n\n' +\ ctrl_visu_str matstr = (mddir + problemname + '__mats_N{0}_Re{1}').format(NV, Re) if bccontrol: matstr = matstr + '__penarob_palpha{0}'.format(palpha) scipy.io.savemat( matstr, dict(A=f_mat, M=stokesmatsc['M'], nu=femp['nu'], Re=femp['Re'], J=stokesmatsc['J'], B=b_mat, C=c_mat, Cp=pcmat, Brob=Brob, v_ss_nse=v_ss_nse, info=infostr, contsetupstr=contsetupstr, datastr=cdatstr, coors=coors, xinds=xinds, yinds=yinds, corfunvec=corfunvec)) print('matrices saved to ' + matstr) elif refree: hstr = ddir + problemname + '_N{0}_hmat'.format(N) try: hmat = dou.load_spa(hstr) print 'loaded `hmat`' except IOError: print 'assembling hmat ...' hmat = dts.ass_convmat_asmatquad(W=femp['V'], invindsw=invinds) dou.save_spa(hmat, hstr) zerv = np.zeros((NV, 1)) bc_conv, bc_rhs_conv, rhsbc_convbc = \ snu.get_v_conv_conts(prev_v=zerv, V=femp['V'], invinds=invinds, diribcs=femp['diribcs'], Picard=False) # diff_mat = stokesmatsc['A'] # bcconv_mat = bc_conv # fv_bcdiff = fv_stbc # fv_bcconv = - bc_rhs_conv fv = fvc fp = fpc # fp_bc = fp_stbc infostr = 'These are the coefficient matrices of the quadratic ' +\ 'formulation of the Navier-Stokes Equations \n for the ' +\ problemname + ' to be used as \n\n' +\ ' $M \\dot v + Av + H*kron(v,v) + J^Tp = Bu + fv$ \n' +\ ' and $Jv = fp$ \n\n' +\ ' the Reynoldsnumber is computed as L/nu \n' +\ ' note that `A` contains the diffusion and the linear term \n' +\ ' that comes from the dirichlet boundary values \n' +\ ' as initial value one can use the provided steady state \n' +\ ' Stokes solution \n' +\ ' see https://github.com/highlando/dolfin_navier_scipy/blob/' +\ ' master/tests/solve_nse_quadraticterm.py for appl example\n' +\ ctrl_visu_str scipy.io.savemat( mddir + problemname + 'quadform__mats_N{0}_Re{1}'.format(NV, Re), dict( A=f_mat, M=stokesmatsc['M'], H=-hmat, fv=fv, fp=fp, nu=femp['nu'], Re=femp['Re'], J=stokesmatsc['J'], B=b_mat, Cv=c_mat, Cp=pcmat, info=infostr, # ss_stokes=old_v, contsetupstr=contsetupstr, datastr=cdatstr, coors=coors, xinds=xinds, yinds=yinds, corfunvec=corfunvec)) else: hstr = ddir + problemname + '_N{0}_hmat'.format(N) try: hmat = dou.load_spa(hstr) print 'loaded `hmat`' except IOError: print 'assembling hmat ...' hmat = dts.ass_convmat_asmatquad(W=femp['V'], invindsw=invinds) dou.save_spa(hmat, hstr) zerv = np.zeros((NV, 1)) bc_conv, bc_rhs_conv, rhsbc_convbc = \ snu.get_v_conv_conts(prev_v=zerv, V=femp['V'], invinds=invinds, diribcs=femp['diribcs'], Picard=False) f_mat = -stokesmatsc['A'] - bc_conv l_mat = -bc_conv fv = fv_stbc + fvc - bc_rhs_conv fp = fp_stbc + fpc vp_stokes = lau.solve_sadpnt_smw(amat=A, jmat=J, rhsv=fv_stbc + fvc, rhsp=fp_stbc + fpc) old_v = vp_stokes[:NV] p_stokes = -vp_stokes[NV:] # the pressure was flipped for symmetry infostr = 'These are the coefficient matrices of the quadratic ' +\ 'formulation of the Navier-Stokes Equations \n for the ' +\ problemname + ' to be used as \n\n' +\ ' $M \\dot v = Av + H*kron(v,v) + J^Tp + Bu + fv$ \n' +\ ' and $Jv = fp$ \n\n' +\ ' the Reynoldsnumber is computed as L/nu \n' +\ ' note that `A` contains the diffusion and the linear term `L`\n' +\ ' that comes from the dirichlet boundary values \n' +\ ' for linearizations it might be necessary to consider `A-L` \n' +\ ' as initial value one can use the provided steady state \n' +\ ' Stokes solution \n' +\ ' see https://github.com/highlando/dolfin_navier_scipy/blob/' +\ ' master/tests/solve_nse_quadraticterm.py for appl example\n' +\ ctrl_visu_str scipy.io.savemat( mddir + problemname + 'quadform__mats_N{0}_Re{1}'.format(NV, Re), dict(A=f_mat, M=stokesmatsc['M'], H=-hmat, fv=fv, fp=fp, L=l_mat, nu=femp['nu'], Re=femp['Re'], J=stokesmatsc['J'], B=b_mat, Cv=c_mat, Cp=pcmat, info=infostr, p_ss_stokes=p_stokes, p_ss_nse=p_ss_nse, v_ss_stokes=old_v, v_ss_nse=v_ss_nse, contsetupstr=contsetupstr, datastr=cdatstr, coors=coors, xinds=xinds, yinds=yinds, corfunvec=corfunvec))
def test_residuals(self): femp, stokesmatsc, rhsd = \ dnsps.get_sysmats(problem=self.problem, nu=self.nu, bccontrol=False, charvel=self.charvel, scheme=self.scheme, mergerhs=True, meshparams=self.meshparams) # setting some parameters t0 = 0.0 tE = .1 Nts = 2 tips = dict(t0=t0, tE=tE, Nts=Nts) soldict = stokesmatsc # containing A, J, JT soldict.update(femp) # adding V, Q, invinds, diribcs soldict.update(tips) # adding time integration params soldict.update(fv=rhsd['fv'], fp=rhsd['fp'], treat_nonl_explct=True, return_vp_dict=True, no_data_caching=True, start_ssstokes=True) vpdct = snu.solve_nse(**soldict) M, A, JT = stokesmatsc['M'], stokesmatsc['A'], stokesmatsc['JT'] fv = rhsd['fv'] V, invinds = femp['V'], femp['invinds'] dt = (tE - t0) / Nts tm = (tE - t0) / 2 reschkdict = dict(V=V, nu=self.nu, gradvsymmtrc=True, outflowds=femp['outflowds']) euleres = get_imex_res(explscheme='eule', **reschkdict) heunres = get_imex_res(explscheme='heun', **reschkdict) crnires = get_imex_res(explscheme='abtw', **reschkdict) # the initial value inivwbcs = vpdct[t0]['v'] iniv = inivwbcs[invinds] iniconvvec = dts.get_convvec(V=V, u0_vec=inivwbcs, invinds=invinds) inivelfun = dts.expand_vp_dolfunc(vc=inivwbcs, **femp)[0] # the Heun prediction step cneevwbcs = vpdct[(tm, 'heunpred')]['v'] cneev = cneevwbcs[invinds] cneep = vpdct[(tm, 'heunpred')]['p'] # the Heun step cnhevwbcs = vpdct[tm]['v'] cnhev = cnhevwbcs[invinds] cnhep = vpdct[tm]['p'] hpconvvec = dts.get_convvec(V=V, u0_vec=cneevwbcs, invinds=invinds) hpvelfun = dts.expand_vp_dolfunc(vc=cneevwbcs, **femp)[0] # the AB2 step cnabvwbcs = vpdct[tE]['v'] cnabv = cnabvwbcs[invinds] cnabp = vpdct[tE]['p'] hcconvvec = dts.get_convvec(V=V, u0_vec=cnhevwbcs, invinds=invinds) hcvelfun = dts.expand_vp_dolfunc(vc=cnhevwbcs, **femp)[0] print('Heun-Prediction: one step of Euler') resvec = (1. / dt * M * (cneev - iniv) + .5 * A * (iniv + cneev) + iniconvvec - JT * cneep - fv) hpscres = np.linalg.norm(resvec) print('Scipy residual: ', hpscres) curv, curp = dts.expand_vp_dolfunc(vc=cneevwbcs, pc=cneep, **femp) res = euleres(curv, curp, dt, lastvel=inivelfun) hpfnres = np.linalg.norm(res.get_local()[invinds]) print('dolfin residua: ', hpfnres) self.assertTrue(np.allclose(hpfnres, 0.)) self.assertTrue(np.allclose(hpscres, 0.)) print('\nHeun-Step:') heunrhs = M * iniv - .5 * dt * \ (A * iniv + iniconvvec + hpconvvec) + dt * fv matvp = M * cnhev + .5 * dt * A * cnhev - dt * JT * cnhep hcscres = np.linalg.norm(matvp - heunrhs) print('Scipy residual: ', hcscres) # import ipdb; ipdb.set_trace() curv, curp = dts.expand_vp_dolfunc(vc=cnhevwbcs, pc=cnhep, **femp) heunres = heunres(curv, curp, dt, lastvel=inivelfun, othervel=hpvelfun) hcfnres = np.linalg.norm(heunres.get_local()[invinds]) print('dolfin residua: ', hcfnres) self.assertTrue(np.allclose(hcfnres, 0.)) self.assertTrue(np.allclose(hcscres, 0.)) print('\nAB2-Step:') abtrhs = M * cnhev - .5 * dt * \ (A * cnhev + -iniconvvec + 3. * hcconvvec) + dt * fv matvp = M * cnabv + .5 * dt * A * cnabv - dt * JT * cnabp abscres = np.linalg.norm(matvp - abtrhs) print('Scipy residual: ', abscres) # import ipdb; ipdb.set_trace() curv, curp = dts.expand_vp_dolfunc(vc=cnabvwbcs, pc=cnabp, **femp) crnires = crnires(curv, curp, dt, lastvel=hcvelfun, othervel=inivelfun) abfnres = np.linalg.norm(crnires.get_local()[invinds]) print('dolfin residua: ', abfnres) self.assertTrue(np.allclose(abfnres, 0.)) self.assertTrue(np.allclose(abscres, 0.))
def lqgbt(problemname='drivencavity', N=10, Re=1e2, plain_bt=False, use_ric_ini=None, t0=0.0, tE=1.0, Nts=11, NU=3, NY=3, bccontrol=True, palpha=1e-5, paraoutput=True, trunc_lqgbtcv=1e-6, nwtn_adi_dict=None, comp_freqresp=False, comp_stepresp='nonlinear', closed_loop=False, multiproc=False, perturbpara=1e-3): """Main routine for LQGBT Parameters ---------- problemname : string, optional what problem to be solved, 'cylinderwake' or 'drivencavity' N : int, optional parameter for the dimension of the space discretization Re : real, optional Reynolds number, defaults to `1e2` plain_bt : boolean, optional whether to try simple *balanced truncation*, defaults to False use_ric_ini : real, optional use the solution with this Re number as stabilizing initial guess, defaults to `None` t0, tE, Nts : real, real, int, optional starting and endpoint of the considered time interval, number of time instancses, default to `0.0, 1.0, 11` bccontrol : boolean, optional whether to apply boundary control via penalized robin conditions, defaults to `False` NU, NY : int, optional dimensions of components of in and output space (will double because there are two components), default to `3, 3` comp_freqresp : boolean, optional whether to compute and compare the frequency responses, defaults to `False` comp_stepresp : {'nonlinear', False, None} whether to compute and compare the step responses | if False -> no step response | if == 'nonlinear' -> compare linear reduced to nonlinear full model | else -> linear reduced versus linear full model defaults to `False` trunc_lqgbtcv : real, optional threshold at what the lqgbt characteristiv values are truncated, defaults to `1e-6` closed_loop : {'full_state_fb', 'red_output_fb', False, None} how to do the closed loop simulation: | if False -> no simulation | if == 'full_state_fb' -> full state feedback | if == 'red_output_fb' -> reduced output feedback | else -> no control is applied defaults to `False` """ typprb = 'BT' if plain_bt else 'LQG-BT' print '\n ### We solve the {0} problem for the {1} at Re={2} ###\n'.\ format(typprb, problemname, Re) if nwtn_adi_dict is not None: nap = nwtn_adi_dict else: nap = nwtn_adi_params()['nwtn_adi_dict'] # output ddir = 'data/' try: os.chdir(ddir) except OSError: raise Warning('need "' + ddir + '" subdir for storing the data') os.chdir('..') # stokesmats = dts.get_stokessysmats(femp['V'], femp['Q'], nu) # rhsd_vf = dts.setget_rhs(femp['V'], femp['Q'], # femp['fv'], femp['fp'], t=0) # # remove the freedom in the pressure # stokesmats['J'] = stokesmats['J'][:-1, :][:, :] # stokesmats['JT'] = stokesmats['JT'][:, :-1][:, :] # rhsd_vf['fp'] = rhsd_vf['fp'][:-1, :] # # reduce the matrices by resolving the BCs # (stokesmatsc, # rhsd_stbc, # invinds, # bcinds, # bcvals) = dts.condense_sysmatsbybcs(stokesmats, # femp['diribcs']) # # pressure freedom and dirichlet reduced rhs # rhsd_vfrc = dict(fpr=rhsd_vf['fp'], fvc=rhsd_vf['fv'][invinds, ]) # # add the info on boundary and inner nodes # bcdata = {'bcinds': bcinds, # 'bcvals': bcvals, # 'invinds': invinds} # femp.update(bcdata) femp, stokesmatsc, rhsd_vfrc, rhsd_stbc \ = dnsps.get_sysmats(problem=problemname, N=N, Re=Re, bccontrol=bccontrol, scheme='TH') nu = femp['charlen']/Re # specify in what spatial direction Bu changes. The remaining is constant uspacedep = femp['uspacedep'] # casting some parameters invinds, NV = femp['invinds'], len(femp['invinds']) prbstr = '_bt' if plain_bt else '_lqgbt' # contsetupstr = 'NV{0}NU{1}NY{2}alphau{3}'.format(NV, NU, NY, alphau) if bccontrol: import scipy.sparse as sps contsetupstr = 'NV{0}_bcc_NY{1}'.format(NV, NY) stokesmatsc['A'] = stokesmatsc['A'] + 1./palpha*stokesmatsc['Arob'] b_mat = 1./palpha*stokesmatsc['Brob'] u_masmat = sps.eye(b_mat.shape[1], format='csr') else: contsetupstr = 'NV{0}NU{1}NY{2}'.format(NV, NU, NY) def get_fdstr(Re): return ddir + problemname + '_Re{0}_'.format(Re) + \ contsetupstr + prbstr fdstr = get_fdstr(Re) soldict = stokesmatsc # containing A, J, JT soldict.update(femp) # adding V, Q, invinds, diribcs # soldict.update(rhsd_vfrc) # adding fvc, fpr soldict.update(fv=rhsd_stbc['fv']+rhsd_vfrc['fvc'], fp=rhsd_stbc['fp']+rhsd_vfrc['fpr'], N=N, nu=nu, data_prfx=fdstr) # # Prepare for control # # get the control and observation operators if not bccontrol: try: b_mat = dou.load_spa(ddir + contsetupstr + '__b_mat') u_masmat = dou.load_spa(ddir + contsetupstr + '__u_masmat') print 'loaded `b_mat`' except IOError: print 'computing `b_mat`...' b_mat, u_masmat = cou.get_inp_opa(cdcoo=femp['cdcoo'], V=femp['V'], NU=NU, xcomp=uspacedep) dou.save_spa(b_mat, ddir + contsetupstr + '__b_mat') dou.save_spa(u_masmat, ddir + contsetupstr + '__u_masmat') b_mat = b_mat[invinds, :][:, :] # tb_mat = 1./np.sqrt(alphau) try: mc_mat = dou.load_spa(ddir + contsetupstr + '__mc_mat') y_masmat = dou.load_spa(ddir + contsetupstr + '__y_masmat') print 'loaded `c_mat`' except IOError: print 'computing `c_mat`...' mc_mat, y_masmat = cou.get_mout_opa(odcoo=femp['odcoo'], V=femp['V'], NY=NY) dou.save_spa(mc_mat, ddir + contsetupstr + '__mc_mat') dou.save_spa(y_masmat, ddir + contsetupstr + '__y_masmat') c_mat = lau.apply_massinv(y_masmat, mc_mat, output='sparse') # restrict the operators to the inner nodes mc_mat = mc_mat[:, invinds][:, :] c_mat = c_mat[:, invinds][:, :] c_mat_reg = lau.app_prj_via_sadpnt(amat=stokesmatsc['M'], jmat=stokesmatsc['J'], rhsv=c_mat.T, transposedprj=True).T # c_mat_reg = np.array(c_mat.todense()) # TODO: right choice of norms for y # and necessity of regularization here # by now, we go on number save # # setup the system for the correction # # # compute the uncontrolled steady state Stokes solution # v_ss_nse, list_norm_nwtnupd = snu.solve_steadystate_nse(**soldict) (convc_mat, rhs_con, rhsv_conbc) = snu.get_v_conv_conts(prev_v=v_ss_nse, invinds=invinds, V=femp['V'], diribcs=femp['diribcs']) f_mat = - stokesmatsc['A'] - convc_mat mmat = stokesmatsc['M'] # ssv_rhs = rhsv_conbc + rhsv_conbc + rhsd_vfrc['fvc'] + rhsd_stbc['fv'] if plain_bt: get_gramians = pru.solve_proj_lyap_stein else: get_gramians = pru.proj_alg_ric_newtonadi truncstr = '__lqgbtcv{0}'.format(trunc_lqgbtcv) try: tl = dou.load_npa(fdstr + '__tl' + truncstr) tr = dou.load_npa(fdstr + '__tr' + truncstr) print 'loaded the left and right transformations: \n' + \ fdstr + '__tl/__tr' + truncstr except IOError: print 'computing the left and right transformations' + \ ' and saving to: \n' + fdstr + '__tl/__tr' + truncstr try: zwc = dou.load_npa(fdstr + '__zwc') zwo = dou.load_npa(fdstr + '__zwo') print 'loaded factor of the Gramians: \n\t' + \ fdstr + '__zwc/__zwo' except IOError: zinic, zinio = None, None if use_ric_ini is not None: fdstr = get_fdstr(use_ric_ini) try: zinic = dou.load_npa(fdstr + '__zwc') zinio = dou.load_npa(fdstr + '__zwo') print 'Initialize Newton ADI by zwc/zwo from ' + fdstr except IOError: raise UserWarning('No initial guess with Re={0}'. format(use_ric_ini)) fdstr = get_fdstr(Re) print 'computing factors of Gramians: \n\t' + \ fdstr + '__zwc/__zwo' def compobsg(): try: zwo = dou.load_npa(fdstr + '__zwo') print 'at least __zwo is there' except IOError: zwo = get_gramians(mmat=mmat.T, amat=f_mat.T, jmat=stokesmatsc['J'], bmat=c_mat_reg.T, wmat=b_mat, nwtn_adi_dict=nap, z0=zinio)['zfac'] dou.save_npa(zwo, fdstr + '__zwo') def compcong(): try: zwc = dou.load_npa(fdstr + '__zwc') print 'at least __zwc is there' except IOError: zwc = get_gramians(mmat=mmat, amat=f_mat, jmat=stokesmatsc['J'], bmat=b_mat, wmat=c_mat_reg.T, nwtn_adi_dict=nap, z0=zinic)['zfac'] dou.save_npa(zwc, fdstr + '__zwc') if multiproc: print '\n ### multithread start - ' +\ 'output might be intermangled' p1 = multiprocessing.Process(target=compobsg) p2 = multiprocessing.Process(target=compcong) p1.start() p2.start() p1.join() p2.join() print '### multithread end' else: compobsg() compcong() zwc = dou.load_npa(fdstr + '__zwc') zwo = dou.load_npa(fdstr + '__zwo') print 'computing the left and right transformations' + \ ' and saving to:\n' + fdstr + '__tr/__tl' + truncstr tl, tr = btu.\ compute_lrbt_transfos(zfc=zwc, zfo=zwo, mmat=stokesmatsc['M'], trunck={'threshh': trunc_lqgbtcv}) dou.save_npa(tl, fdstr + '__tl' + truncstr) dou.save_npa(tr, fdstr + '__tr' + truncstr) print 'NV = {0}, NP = {2}, k = {1}'.\ format(tl.shape[0], tl.shape[1], stokesmatsc['J'].shape[0]) if comp_freqresp: btu.compare_freqresp(mmat=stokesmatsc['M'], amat=f_mat, jmat=stokesmatsc['J'], bmat=b_mat, cmat=c_mat, tr=tr, tl=tl, plot=True, datastr=fdstr + '__tl' + truncstr) if comp_stepresp is not False: if comp_stepresp == 'nonlinear': stp_rsp_nwtn = 3 stp_rsp_dtpr = 'nonl_stepresp_' else: stp_rsp_nwtn = 1 stp_rsp_dtpr = 'stepresp_' def fullstepresp_lnse(bcol=None, trange=None, ini_vel=None, cmat=None, soldict=None): soldict.update(fv_stbc=rhsd_stbc['fv']+bcol, vel_nwtn_stps=stp_rsp_nwtn, trange=trange, iniv=ini_vel, lin_vel_point=ini_vel, clearprvdata=True, data_prfx=stp_rsp_dtpr, return_dictofvelstrs=True) dictofvelstrs = snu.solve_nse(**soldict) return cou.extract_output(strdict=dictofvelstrs, tmesh=trange, c_mat=cmat, load_data=dou.load_npa) # differences in the initial vector # print np.dot(c_mat_reg, v_ss_nse) # print np.dot(np.dot(c_mat_reg, tr), # np.dot(tl.T, stokesmatsc['M']*v_ss_nse)) jsonstr = fdstr + stp_rsp_dtpr + '_Nred{0}_t0tENts{1}{2}{3}.json'.\ format(tl.shape[1], t0, tE, Nts) btu.compare_stepresp(tmesh=np.linspace(t0, tE, Nts), a_mat=f_mat, c_mat=c_mat_reg, b_mat=b_mat, m_mat=stokesmatsc['M'], tr=tr, tl=tl, iniv=v_ss_nse, # ss_rhs=ssv_rhs, fullresp=fullstepresp_lnse, fsr_soldict=soldict, plot=True, jsonstr=jsonstr) # compute the regulated system trange = np.linspace(t0, tE, Nts) if closed_loop is False: return elif closed_loop == 'full_state_fb': zwc = dou.load_npa(fdstr + '__zwc') zwo = dou.load_npa(fdstr + '__zwo') mtxtb = pru.get_mTzzTtb(stokesmatsc['M'].T, zwc, b_mat) def fv_tmdp_fullstatefb(time=None, curvel=None, linv=None, tb_mat=None, tbxm_mat=None, **kw): """realizes a full state static feedback as a function that can be passed to a solution routine for the unsteady Navier-Stokes equations Parameters ---------- time : real current time curvel : (N,1) nparray current velocity linv : (N,1) nparray linearization point for the linear model tb_mat : (N,K) nparray input matrix containing the input weighting tbxm_mat : (N,K) nparray `tb_mat * gain * mass` Returns ------- actua : (N,1) nparray current contribution to the right-hand side , : dictionary dummy `{}` for consistency """ actua = -lau.comp_uvz_spdns(tb_mat, tbxm_mat, curvel-linv) # actua = 0*curvel print '\nnorm of deviation', np.linalg.norm(curvel-linv) # print 'norm of actuation {0}'.format(np.linalg.norm(actua)) return actua, {} tmdp_fsfb_dict = dict(linv=v_ss_nse, tb_mat=b_mat, tbxm_mat=mtxtb.T) fv_tmdp = fv_tmdp_fullstatefb fv_tmdp_params = tmdp_fsfb_dict fv_tmdp_memory = None elif closed_loop == 'red_output_fb': try: xok = dou.load_npa(fdstr+truncstr+'__xok') xck = dou.load_npa(fdstr+truncstr+'__xck') ak_mat = dou.load_npa(fdstr+truncstr+'__ak_mat') ck_mat = dou.load_npa(fdstr+truncstr+'__ck_mat') bk_mat = dou.load_npa(fdstr+truncstr+'__bk_mat') except IOError: print 'couldn"t load the red system - compute it' zwc = dou.load_npa(fdstr + '__zwc') zwo = dou.load_npa(fdstr + '__zwo') ak_mat = np.dot(tl.T, f_mat*tr) ck_mat = lau.mm_dnssps(c_mat_reg, tr) bk_mat = lau.mm_dnssps(tl.T, b_mat) tltm, trtm = tl.T*stokesmatsc['M'], tr.T*stokesmatsc['M'] xok = np.dot(np.dot(tltm, zwo), np.dot(zwo.T, tltm.T)) xck = np.dot(np.dot(trtm, zwc), np.dot(zwc.T, trtm.T)) dou.save_npa(xok, fdstr+truncstr+'__xok') dou.save_npa(xck, fdstr+truncstr+'__xck') dou.save_npa(ak_mat, fdstr+truncstr+'__ak_mat') dou.save_npa(ck_mat, fdstr+truncstr+'__ck_mat') dou.save_npa(bk_mat, fdstr+truncstr+'__bk_mat') obs_bk = np.dot(xok, ck_mat.T) DT = (tE - t0)/(Nts-1) sysmatk_inv = np.linalg.inv(np.eye(ak_mat.shape[1]) - DT*(ak_mat - np.dot(np.dot(xok, ck_mat.T), ck_mat) - np.dot(bk_mat, np.dot(bk_mat.T, xck)))) def fv_tmdp_redoutpfb(time=None, curvel=None, memory=None, linvel=None, ipsysk_mat_inv=None, obs_bk=None, cts=None, b_mat=None, c_mat=None, xck=None, bk_mat=None, **kw): """realizes a reduced static output feedback as a function that can be passed to a solution routine for the unsteady Navier-Stokes equations For convinience the Parameters ---------- time : real current time curvel : (N,1) nparray current velocity. For consistency, the full state is taken as input. However, internally, we only use the observation `y = c_mat*curvel` memory : dictionary contains values from previous call, in particular the previous state estimate linvel : (N,1) nparray linearization point for the linear model ipsysk_mat_inv : (K,K) nparray inverse of the system matrix that defines the update of the state estimate obs_bk : (K,NU) nparray input matrix in the observer cts : real time step length b_mat : (N,NU) sparse matrix input matrix of the full system c_mat=None, c_mat : (NY,N) sparse matrix output matrix of the full system xck : (K,K) nparray reduced solution of the CARE bk_mat : (K,NU) nparray reduced input matrix Returns ------- actua : (N,1) nparray the current actuation memory : dictionary to be passed back in the next timestep """ xk_old = memory['xk_old'] buk = cts*np.dot(obs_bk, lau.mm_dnssps(c_mat, (curvel-linvel))) xk_old = np.dot(ipsysk_mat_inv, xk_old + buk) # cts*np.dot(obs_bk, # lau.mm_dnssps(c_mat, (curvel-linvel)))) memory['xk_old'] = xk_old actua = -lau.mm_dnssps(b_mat, np.dot(bk_mat.T, np.dot(xck, xk_old))) print '\nnorm of deviation', np.linalg.norm(curvel-linvel) print 'norm of actuation {0}'.format(np.linalg.norm(actua)) return actua, memory fv_rofb_dict = dict(cts=DT, linvel=v_ss_nse, b_mat=b_mat, c_mat=c_mat_reg, obs_bk=obs_bk, bk_mat=bk_mat, ipsysk_mat_inv=sysmatk_inv, xck=xck) fv_tmdp = fv_tmdp_redoutpfb fv_tmdp_params = fv_rofb_dict fv_tmdp_memory = dict(xk_old=np.zeros((tl.shape[1], 1))) else: fv_tmdp = None fv_tmdp_params = {} fv_tmdp_memory = {} perturbini = perturbpara*np.ones((NV, 1)) reg_pertubini = lau.app_prj_via_sadpnt(amat=stokesmatsc['M'], jmat=stokesmatsc['J'], rhsv=perturbini) soldict.update(fv_stbc=rhsd_stbc['fv'], trange=trange, iniv=v_ss_nse + reg_pertubini, lin_vel_point=None, clearprvdata=True, data_prfx=fdstr + truncstr, fv_tmdp=fv_tmdp, comp_nonl_semexp=True, fv_tmdp_params=fv_tmdp_params, fv_tmdp_memory=fv_tmdp_memory, return_dictofvelstrs=True) outstr = truncstr + '{0}'.format(closed_loop) \ + 't0{0}tE{1}Nts{2}N{3}Re{4}'.format(t0, tE, Nts, N, Re) if paraoutput: soldict.update(paraviewoutput=True, vfileprfx='results/vel_'+outstr, pfileprfx='results/p_'+outstr) dictofvelstrs = snu.solve_nse(**soldict) yscomplist = cou.extract_output(strdict=dictofvelstrs, tmesh=trange, c_mat=c_mat, load_data=dou.load_npa) dou.save_output_json(dict(tmesh=trange.tolist(), outsig=yscomplist), fstring=fdstr + truncstr + '{0}'.format(closed_loop) + 't0{0}tE{1}Nts{2}'.format(t0, tE, Nts) + 'inipert{0}'.format(perturbpara)) dou.plot_outp_sig(tmesh=trange, outsig=yscomplist)
import dolfin_navier_scipy.problem_setups as dnsps import dolfin_navier_scipy.stokes_navier_utils as snu import dolfin_navier_scipy.dolfin_to_sparrays as dts import numpy as np N, Re, scheme, ppin = 2, 50, 'TH', None femp, stokesmatsc, rhsd = \ dnsps.get_sysmats(problem='cylinderwake', Re=Re, scheme=scheme, mergerhs=True, meshparams=dict(refinement_level=N)) Mc, Ac = stokesmatsc['M'], stokesmatsc['A'] BTc, Bc = stokesmatsc['JT'], stokesmatsc['J'] invinds = femp['invinds'] fv, fp = rhsd['fv'], rhsd['fp'] inivdict = dict(A=Ac, J=Bc, JT=BTc, M=Mc, ppin=ppin, fv=fv, fp=fp, return_vp=True, V=femp['V'], invinds=invinds, diribcs=femp['diribcs']) # ## Solve the steady-state NSE vp_steadystate = snu.solve_steadystate_nse(**inivdict)