Hello Daniel,

Thank you for the paper and the script - I am afraid it will take me some
time though, its impressive and long work !!

Regarding the equations, I think I was not clear enough in my previous
explanations, I apologize.
In substance, I have 4 variables : ro, roU, roV and roE. They are density,
velocity along X, velocity along Y and energy.
I also have 4 differential equations :

dro/dt + nabla.(ro*[U,V]) = 0
droU/dt + nabla.(roU*[U,V]) = -dp / dx
droV/dt + nabla.(roV*[U,V]) = -dp / dy
droE/dt + nabla.(roE*[U,V]) = - d(p*(roU/ro))/dx - d(p*(roV/ro))/dy

As you can see, they are written with a fifth variable, p, for pressure,
that is related to the others by :

p = (gamma-1.0)*roE - 0.5*(gamma-1.0)*(roU**2 + roV**2)/ro

this is what I call the equation of state, it is not differential it is
just algebraic.

I wager the differential equations above are not the most complex you have
seen or implemented in FiPy, and I think I succeeded, although of course,
since the whole thing does not work, I cannot be sure. But then I am stuck
with that non-differential equation that I would have to solve with the
four differential (?) to close the system …

Can you see what I am stuck with ?
Also, could you please elaborate on the last paragraph of your previous
e-mail ? « If you do include … » I am not sure I get why you speak of
linearization and relaxation ?

I attach the latest version of my non-working script ..

Thanks for the help

Best,

Thibault


2017-05-17 17:06 GMT+02:00 Daniel Wheeler <daniel.wheel...@gmail.com>:

> Hi Thibault,
>
> The paper and your attempts at solving it are very impressive, nice
> work. I'm not sure I understand the issue with the equation of state /
> 2D issue though. Is it that you want to couple in the equation of
> state with the other equations instead of solving explicitly?
>
> Here is a link for some work I did with FiPy quite a long time ago,
>
>     https://gist.github.com/wd15/c28ab796cb3d9781482b01fb67a7ec2d
>
> It resulted in a publication, see https://arxiv.org/pdf/1006.4881.pdf.
> In that work, everything is being solved in one matrix, see
>
> https://gist.github.com/wd15/c28ab796cb3d9781482b01fb67a7ec
> 2d#file-input-py-L245
>
> Look at,
>
> https://gist.github.com/wd15/c28ab796cb3d9781482b01fb67a7ec
> 2d#file-input-py-L286
>
> That particular equation is like an equation of state (it has no
> transient term). The point is that with the use of
> ImplicitSourceTerm's, you can include an equation of state implicitly.
> I'm not sure whether this is your issue or not, but it might be
> related. The above set of equations are dissipative, which yours are
> not, but also, I wasn't concerned with resolving the shocks
> numerically so a Roe solver wasn't used. Also, this work was done
> before FiPy had coupled solutions.
>
> If you do include the equation of state in the matrix, then think
> carefully about how you linearize the "roU" and "roV" terms. Also, as
> the equation of state is like an immediate update, it might be
> necessary to relax the updates a bit during the non-linear iteration
> cycle.
>
> Cheers,
>
> Daniel
>
>
>
> On Mon, May 15, 2017 at 11:46 AM, Thibault Bridel-Bertomeu
> <thibault.bridellel...@gmail.com> wrote:
> > Hello Daniel,
> >
> > Thanks for the answer
> >
> > An implementation of the Roe scheme would certainly go a long way in
> > simplifying the resolution of hyperbolic equations but I think FiPy
> already
> > has was it takes to do that - terms wise.
> > I know of CLAWPACK yes, but I really would like to see if FiPy can handle
> > fluid dynamics equations. I work at CERFACS, a lab in France centered
> around
> > the use of Computational Fluid Dynamics for academic and industrial
> purpose,
> > and although we do have a production code, I would like to let my
> colleagues
> > know about FiPy because I think it has the potential to be a great
> > first-approach solver for simple to mildly complex problems.
> >
> > I actually already succeeded in solving (and validating with the known
> Sod
> > shock tube test case) the 1D compressible Euler equations (script
> attached
> > with an exact solver for reference).
> > But then in 1D, things are pretty easy - equation wise.
> > If you have time to check the code, can you tell me if you see any kind
> of
> > mis-use of FiPy ? Are there any lines you would have written differently
> ?
> >
> > In 2D everything becomes harder and I can’t get it right - although I
> > suspect it is because I don’t know FiPy very well yet.
> > If you don’t mind, I have a couple questions to try and make it work.
> >
> > 1/ I do not get how to include the resolution of an equation of state in
> the
> > system of differential equations. I wrote a stub of code (attached,
> called
> > 7-covo2D.py) in which I solve for (rho, rhoU, rhoV, rhoE) as usual. An
> easy
> > way to write the Euler equations however is to include a notion of
> pressure,
> > which is related to the unknown by an equation of state (it is not a
> > differential equation though) - see for instance
> > http://bender.astro.sunysb.edu/hydro_by_example/compressible/Euler.pdf.
> > Because of this, I have to inject the EoS directly into the equations and
> > try and make do with that, but the Finite Volume method is not designed
> to
> > have the fluxes computed like I do in the script, so naturally everything
> > crashes or gives nonsensical results.
> > Do you see a possibility in FiPy to solve 4 differential equations and 1
> > algebraic equation (the EoS) in a coupled manner ?
> >
> > 2/ If it is not possible to include the equation of state in the system,
> how
> > would you take the -dp/dx and the -dp/dy from the momentum equations
> (with p
> > expanded as a function of rhoE, rhoU and rhoV) into account ?
> >
> > Thank you very much for your help,
> >
> > Best regards,
> >
> > Thibault
> >
> >
> >
> > 2017-05-15 15:38 GMT+02:00 Daniel Wheeler <daniel.wheel...@gmail.com>:
> >>
> >> Hi Thibault,
> >>
> >> I started down the road of implementing a Riemann solver in FiPy, see
> >>
> >>
> >> https://github.com/usnistgov/fipy/blob/riemann/fipy/terms/
> baseRoeConvectionTerm.py
> >>
> >> Unfortunately, I never completed and merged this work. You might want
> >> to look into CLAWPACK for a code to better handle compressible flow.
> >>
> >> I've given a few answers about this in the past as well, see
> >>
> >>    - http://git.net/ml/python-fipy/2012-02/msg00024.html
> >>
> >>    -
> >> http://fipy.nist.narkive.com/A0gJrSl2/semilinear-wave-equation-in-fipy
> >>
> >>    -
> >> http://fipy.nist.narkive.com/YVZTRM0G/1d-coupled-fluid-
> equations-in-fipy
> >>
> >> Cheers,
> >>
> >> Daniel
> >>
> >> On Sun, May 14, 2017 at 9:33 AM, Thibault Bridel-Bertomeu
> >> <thibault.bridellel...@gmail.com> wrote:
> >> > Good afternoon,
> >> >
> >> > I was wondering if anyone had ever tried implementing the compressible
> >> > euler
> >> > equations in FiPy ?
> >> > I have been trying for a while now but even in 1D I can’t get a proper
> >> > shock
> >> > tube solution.
> >> >
> >> > If anyone has ever tried, I would be infinitely grateful if they were
> to
> >> > share their knowledge !!
> >> >
> >> > Thank you very much,
> >> >
> >> > T. BRIDEL-BERTOMEU
> >> >
> >> >
> >> >
> >> > _______________________________________________
> >> > fipy mailing list
> >> > fipy@nist.gov
> >> > http://www.ctcms.nist.gov/fipy
> >> >   [ NIST internal ONLY: https://email.nist.gov/mailman/listinfo/fipy
> ]
> >> >
> >>
> >>
> >>
> >> --
> >> Daniel Wheeler
> >>
> >> _______________________________________________
> >> fipy mailing list
> >> fipy@nist.gov
> >> http://www.ctcms.nist.gov/fipy
> >>   [ NIST internal ONLY: https://email.nist.gov/mailman/listinfo/fipy ]
> >
> >
> >
> > _______________________________________________
> > fipy mailing list
> > fipy@nist.gov
> > http://www.ctcms.nist.gov/fipy
> >   [ NIST internal ONLY: https://email.nist.gov/mailman/listinfo/fipy ]
> >
>
>
>
> --
> Daniel Wheeler
>
> _______________________________________________
> fipy mailing list
> fipy@nist.gov
> http://www.ctcms.nist.gov/fipy
>   [ NIST internal ONLY: https://email.nist.gov/mailman/listinfo/fipy ]
>
#!/usr/bin/env python

import fipy
from fipy import numerix
from fipy import parallel
import numpy as np

#==============================

nx = 128
ny = 128

# dx = 0.1
# dy = 0.1

# Lx = nx*dx
# Ly = ny*dy

Lx = 0.1
Ly = 0.1

dx = Lx / nx
dy = Ly / ny

mesh = fipy.PeriodicGrid2D(nx=nx, ny=ny, dx=dx, dy=dy)
X, Y = mesh.cellCenters
x, y = mesh.faceCenters
if parallel.procID == 0:
	print Y
	print y

#==============================

gamma = 1.4
gm1 = gamma - 1.0
Cv = 717.875
Cp = gamma * Cv
Rgas = Cp - Cv

#==============================

ro = fipy.CellVariable(mesh=mesh, name="ro", hasOld=True)
roU = fipy.CellVariable(mesh=mesh, name="roU", hasOld=True)
roV = fipy.CellVariable(mesh=mesh, name="roV", hasOld=True)
roE = fipy.CellVariable(mesh=mesh, name="roE", hasOld=True)
p = fipy.CellVariable(mesh=mesh, name="p")#, hasOld=True)

X0 = 0.05
Y0 = 0.05
beta = 5.0
Rsq = (X-X0)**2 + (Y-Y0)**2
Rc = 0.005

pinf = 1.0
roinf = 1.0
uinf = 1.0
vinf = 0.0

# ro_init = (pinf/roinf + gm1*beta**2/(8*gamma*numerix.pi**2)*numerix.exp((1.0-Rsq)/Rc**2))**(1/gm1)
# roU_init = ro_init * (uinf - beta*numerix.exp(0.5*(1-Rsq))*0.5/numerix.pi)
# roV_init = ro_init * (vinf + beta*numerix.exp(0.5*(1-Rsq))*0.5/numerix.pi)
# press_init = ro_init**gamma
# roE_init = press_init / gm1 + 0.5 * ro_init * ( roU_init**2 + roV_init**2 ) / ro_init**2

U_init = uinf - beta/(2*np.pi)*numerix.exp(-0.5*Rsq/Rc**2)*(Y-Y0)/Rc
V_init = vinf + beta/(2*np.pi)*numerix.exp(-0.5*Rsq/Rc**2)*(X-X0)/Rc
temp_init = 1.0 - gm1*beta**2/(8*gamma*np.pi**2)*numerix.exp(-Rsq/Rc**2)
ro_init = temp_init**(1.0/gm1)
press_init = ro_init**gamma
roE_init = press_init / gm1 + 0.5 * ro_init * (U_init**2 + V_init**2)

ro.setValue( ro_init )
roU.setValue( ro_init * U_init )
roV.setValue( ro_init * V_init )
roE.setValue( roE_init )
p.setValue( press_init )

# X0 = 0.05
# Y0 = 0.05
# Gamma = 34.7279426399
# Rc = 0.005
# cut = 8.0

# press_inf = 100000
# Ma_inf = 0.0 #0.5
# temp_inf = 300.0
# alpha_inf = 0.0
# beta_inf = 0.0

# ro_inf = press_inf / (Rgas * temp_inf)
# c_inf = numerix.sqrt(gamma * press_inf / ro_inf)
# unorm_inf = c_inf * Ma_inf
# U_inf = unorm_inf * numerix.cos(alpha_inf*numerix.pi/180.0) * numerix.cos(beta_inf*numerix.pi/180.0)
# V_inf = unorm_inf * numerix.sin(beta_inf*numerix.pi/180.0)
# roE_inf = press_inf / gm1 + 0.5 * ro_inf * unorm_inf**2

# Rsq = (X - X0)**2 + (Y-Y0)**2
# expon = numerix.exp(-0.5*Rsq/Rc**2)
# U_init = U_inf - (Y-Y0) / Rc * Gamma * expon
# V_init = V_inf + (X-X0) / Rc * Gamma * expon
# temp_init = temp_inf - 0.5 * (Gamma * Gamma) * numerix.exp(-Rsq / Rc**2) / Cp
# ro_init = ro_inf * (temp_init / temp_inf)**(1.0/gm1)
# pres_init = ro_init * Rgas * temp_init
# roE_init = pres_init / gm1 + 0.5*(U_init**2 + V_init**2)*ro_init

# ro.setValue( ro_init*(np.sqrt(Rsq)<=Rc*cut)+ro_inf*(np.sqrt(Rsq)>Rc*cut) )
# roU.setValue( ro_init*U_init*(np.sqrt(Rsq)<=Rc*cut)+ro_inf*U_inf*(np.sqrt(Rsq)>Rc*cut) )
# roV.setValue( ro_init*V_init*(np.sqrt(Rsq)<=Rc*cut)+ro_inf*V_inf*(np.sqrt(Rsq)>Rc*cut) )
# roE.setValue( roE_init*(np.sqrt(Rsq)<=Rc*cut)+roE_inf*(np.sqrt(Rsq)>Rc*cut) )
# p.setValue( pres_init*(np.sqrt(Rsq)<=Rc*cut)+press_inf*(np.sqrt(Rsq)>Rc*cut) )

ro_init = fipy.CellVariable(mesh=mesh, value=ro_init)

if parallel.procID == 0:
	vi2D = fipy.Viewer(vars=p) #(ro,roU,roV,roE,p))
	vi2D.plot()
# raw_input("Initialization. Press <return> to continue ...")

#==============================

umax = max(max(U_init), max(V_init))
CFL = 0.75
dx = numerix.sqrt(min(mesh.cellVolumes))
dt = dx * CFL / umax

if parallel.procID == 0:
	print "Timestep for CFL=%.2f, t=%.8fs"%(CFL, dt)

#==============================

coeffConv = fipy.CellVariable(mesh=mesh, rank=1)
coeffConv[0] = roU/ro
coeffConv[1] = roV/ro

# coeffConvMinus = fipy.CellVariable(mesh=mesh, rank=1)
# coeffConvMinus[0] = -roV/ro
# coeffConvMinus[1] = roU/ro

# coeffConvSquare = fipy.CellVariable(mesh=mesh, rank=1)
# coeffConvSquare[0] = roU**2/ro**2
# coeffConvSquare[1] = roU*roV/ro**2

# coeffConvSquareBis = fipy.CellVariable(mesh=mesh, rank=1)
# coeffConvSquareBis[0] = roU*roV/ro**2
# coeffConvSquareBis[1] = roV**2/ro**2

#----

eqnC = fipy.TransientTerm(var=ro) + \
	   fipy.ExponentialConvectionTerm(coeff=coeffConv.faceValue, var=ro) == 0.0

#----

eqnMx = fipy.TransientTerm(var=roU) + \
	    fipy.ExponentialConvectionTerm(coeff=coeffConv.faceValue, var=roU) == \
	    - p.grad.dot([1., 0.])
	    # gm1*fipy.ExponentialConvectionTerm(var=(roE-0.5*(roU**2+rov**2)/ro)) == 0.0
	    # (1.0-0.5*gm1)*fipy.ExponentialConvectionTerm(coeff=coeffConv.faceValue, var=roU) + \
	    # gm1*roE.grad.dot([1., 0.]) + \
	    # 0.5*gm1*fipy.ExponentialConvectionTerm(coeff=coeffConvMinus.faceValue, var=roV) == 0.0

#----

eqnMy = fipy.TransientTerm(var=roV) + \
		fipy.ExponentialConvectionTerm(coeff=coeffConv.faceValue, var=roV) == \
	    - p.grad.dot([0., 1.])
	    # (1.0-0.5*gm1)*fipy.ExponentialConvectionTerm(coeff=coeffConv.faceValue, var=roV) + \
	    # gm1*roE.grad.dot([0., 1.]) - \
	    # 0.5*gm1*fipy.ExponentialConvectionTerm(coeff=coeffConvMinus.faceValue, var=roU) == 0.0

#----

eqnE = fipy.TransientTerm(var=roE) + \
	   fipy.ExponentialConvectionTerm(coeff=coeffConv.faceValue, var=roE) == \
	   -(roU*p/ro).grad.dot([1.,0.]) - (roV*p/ro).grad.dot([0.,1.])
	   # -fipy.CentralDifferenceConvectionTerm(coeff=coeffConv.faceValue, var=p)
	   # (1.0+gm1)*fipy.UpwindConvectionTerm(coeff=coeffConv.faceValue, var=roE) - \
	   # 0.5*gm1*fipy.UpwindConvectionTerm(coeff=coeffConvSquare.faceValue, var=roU) - \
	   # 0.5*gm1*fipy.UpwindConvectionTerm(coeff=coeffConvSquareBis.faceValue, var=roV) == 0.0

#----

# eqnP = fipy.TransientTerm(var=p) == (1.0/dt) * ( gm1*roE - 0.5*gm1*(roU**2 + roV**2)/ro - gm1*roE.old + 0.5*gm1*(roU.old**2 + roV.old**2)/ro.old )
eqnP = fipy.ImplicitSourceTerm(coeff=1.0, var=p) == fipy.ImplicitSourceTerm(coeff=gm1, var=roE) - 0.5*gm1*(roU**2 + roV**2)/ro
# gm1*(roE - roE.old) / dt + 0.5*gm1*( (roU-roU.old)**2/dt**2 + (roV-roV.old)**2/dt**2 )/(ro)

#----
eqn = eqnC & eqnMx & eqnMy & eqnE & eqnP

#==============================
mesh1D = fipy.Grid1D(dx=dx, nx=nx)
xx = mesh1D.cellCenters[0]

imin1 = np.argmin(np.fabs(Y - Ly/2.0))

ro_cut = fipy.CellVariable(name="ro_cut Y=Ly/2", mesh=mesh1D)
ro_cut.setValue( ro((mesh1D.cellCenters[0], Y[imin1]*numerix.ones(ro_cut.mesh.numberOfCells)), order=0) )
ro_cut_init = fipy.CellVariable(name="ro_cut_init Y=Ly/2", mesh=mesh1D)
ro_cut_init.setValue( ro_init((mesh1D.cellCenters[0], Y[imin1]*numerix.ones(ro_cut_init.mesh.numberOfCells)), order=0) )
#ro_inf*((temp_inf - 0.5 * (Gamma * Gamma) * numerix.exp(-( (xx-X0)**2 - (Y[imin1]-Y0)**2 ) / Rc**2) / Cp) / temp_inf)**(1.0/gm1)

imin2 = np.argmin(np.fabs(Y - 2.0*Ly/3.0))

ro_cut_higher = fipy.CellVariable(name="ro_cut Y=2Ly/3", mesh=mesh1D)
ro_cut_higher.setValue( ro((mesh1D.cellCenters[0], Y[imin2]*numerix.ones(ro_cut_higher.mesh.numberOfCells)), order=0) )
ro_cut_higher_init = fipy.CellVariable(name="ro_cut_init Y=2Ly/3", mesh=mesh1D)
ro_cut_higher_init.setValue( ro_init((mesh1D.cellCenters[0], Y[imin2]*numerix.ones(ro_cut_higher_init.mesh.numberOfCells)), order=0) )

if parallel.procID == 0:
	vi1D = fipy.Viewer(vars=(ro_cut_init,ro_cut))
	# vars=(np.fabs(ro_cut-ro_cut_init)/np.fabs(ro_cut_init), np.fabs(ro_cut_higher-ro_cut_higher_init)/np.fabs(ro_cut_higher_init)), ylog=True
	vi1D.plot()

# raw_input("1D cut, before computation. Press <return> to continue ...")

# vi2D = fipy.Viewer(vars=ro)

tcur = 0.0
steps = 100
for step in range(steps):
	ro.updateOld()
	roU.updateOld()
	roV.updateOld()
	roE.updateOld()
	# p.updateOld()
	#
	# eqn.solve(dt=dt)
	eqnC.sweep(dt=dt)#, underRelaxation=0.2)
	eqnMx.sweep(dt=dt)#, underRelaxation=0.2)
	eqnMy.sweep(dt=dt)#, underRelaxation=0.2)
	eqnE.sweep(dt=dt)#, underRelaxation=0.2)
	#
	p.setValue( gm1*roE - 0.5*gm1*((roU/ro)**2 + (roV/ro)**2) )
	#
	if parallel.procID == 0:
		vi2D.plot()
	ro_cut.setValue( ro((mesh1D.cellCenters[0], Y[imin1]*numerix.ones(ro_cut.mesh.numberOfCells)), order=0) )
	if parallel.procID == 0:
		vi1D.plot()
	#
	tcur += dt
	#
	if parallel.procID == 0:
		print "Time t=%.2e, distance from exact 1D=%.6e, distance from exact 2D=%.6e"%(tcur, np.linalg.norm(ro_cut-ro_cut_init, ord=2)/np.linalg.norm(ro_cut_init, ord=2), np.linalg.norm(ro-ro_init, ord=2)/np.linalg.norm(ro_init, ord=2))

raw_input("Final state ...")
_______________________________________________
fipy mailing list
fipy@nist.gov
http://www.ctcms.nist.gov/fipy
  [ NIST internal ONLY: https://email.nist.gov/mailman/listinfo/fipy ]

Reply via email to