endfunction(CreatePythonConvergenceTest)
add_subdirectory (Convergence/StationaryDiffusion)
+add_subdirectory (Convergence/SinglePhase)
--- /dev/null
+
+add_subdirectory (RiemannProblem)
--- /dev/null
+
+SET(SCRIPT
+ ./SinglePhase_1DRiemannProblem.py
+ )
+
+file(COPY ${SCRIPT} DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
+
+if (CDMATH_WITH_PYTHON )
+
+ SET(SCHEME Upwind )
+
+ install(FILES ${SCRIPT} DESTINATION share/convergence/test_convergenceSinglePhase_1DRiemannProblem_Upwind)
+
+ SET(ISEXPLICIT 1 )
+
+ SET(CFL 0.5 )#Courant Friedrichs Lewy number
+
+ ADD_TEST(convergenceSinglePhase_1DRiemannProblem_UpwindExplicit_CFL0.5 ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test_convergenceSinglePhase_1DRiemannProblem.py ${CFL} ${ISEXPLICIT} ${SCHEME})
+
+ SET(CFL 0.99 )#Courant Friedrichs Lewy number
+
+ ADD_TEST(convergenceSinglePhase_1DRiemannProblem_UpwindExplicit_CFL1 ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test_convergenceSinglePhase_1DRiemannProblem.py ${CFL} ${ISEXPLICIT} ${SCHEME} )
+
+ SET(ISEXPLICIT 0 )
+
+ SET(CFL 0.99 )#Courant Friedrichs Lewy number
+
+ ADD_TEST(convergenceSinglePhase_1DRiemannProblem_UpwindImplicit_CFL1 ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test_convergenceSinglePhase_1DRiemannProblem.py ${CFL} ${ISEXPLICIT} ${SCHEME} )
+
+ SET(CFL 10 )#Courant Friedrichs Lewy number
+
+ ADD_TEST(convergenceSinglePhase_1DRiemannProblem_UpwindImplicit_CFL10 ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test_convergenceSinglePhase_1DRiemannProblem.py ${CFL} ${ISEXPLICIT} ${SCHEME} )
+
+ SET(SCHEME Centered )
+
+ install(FILES ${SCRIPT} DESTINATION share/convergence/test_convergenceSinglePhase_1DRiemannProblem_Centered)
+
+ SET(ISEXPLICIT 0 )
+
+ SET(CFL 0.99 )#Courant Friedrichs Lewy number
+
+ ADD_TEST(convergenceSinglePhase_1DRiemannProblem_CenteredImplicit_CFL1 ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test_convergenceSinglePhase_1DRiemannProblem.py ${CFL} ${ISEXPLICIT} ${SCHEME} )
+
+ SET(CFL 10 )#Courant Friedrichs Lewy number
+
+ ADD_TEST(convergenceSinglePhase_1DRiemannProblem_CenteredImplicit_CFL10 ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test_convergenceSinglePhase_1DRiemannProblem.py ${CFL} ${ISEXPLICIT} ${SCHEME} )
+
+endif (CDMATH_WITH_PYTHON )
+
+
--- /dev/null
+#!/usr/bin/env python
+# -*-coding:utf-8 -*
+
+import CoreFlows as cf
+import cdmath as cm
+import VTK_routines
+import exact_rs_stiffenedgas
+import matplotlib.pyplot as plt
+from numpy.linalg import norm
+import time
+
+test_desc={}
+test_desc["Initial_data"]="Riemann problem"
+test_desc["PDE_model"]="Euler"
+test_desc["PDE_is_stationary"]=False
+test_desc["PDE_search_for_stationary_solution"]=False
+test_desc["Mesh_is_unstructured"]=False
+test_desc["Part_of_mesh_convergence_analysis"]=True
+test_desc["Numerical_method_name"]="Upwind"
+test_desc["Numerical_method_space_discretization"]="Finite volumes"
+test_desc["Boundary_conditions"]="Neumann"
+test_desc["Geometry"]="Segment"
+
+
+def solve(xinf,xsup,nx,cfl,isExplicit,scheme):
+ start = time.time()
+
+ if(isExplicit):
+ ExplicitOrImplicit="Explicit"
+ else:
+ ExplicitOrImplicit="Implicit"
+
+ test_desc["Numerical_method_time_discretization"]=ExplicitOrImplicit
+
+ spaceDim = 1;
+ # Prepare for the mesh
+ print("Building mesh " );
+ discontinuity=(xinf+xsup)/2
+ M=cm.Mesh(xinf,xsup,nx)
+ eps=1e-6
+ M.setGroupAtPlan(xsup,0,eps,"RightBoundary")
+ M.setGroupAtPlan(xinf,0,eps,"LeftBoundary")
+
+ test_desc["Space_dimension"]=M.getSpaceDimension()
+ test_desc["Mesh_dimension"]=M.getMeshDimension()
+ test_desc["Mesh_number_of_elements"]=M.getNumberOfCells()
+ test_desc["Mesh_cell_type"]=M.getElementTypesNames()
+
+ # Prepare initial data
+ initialVelocity_Left=1;
+ initialTemperature_Left=565;
+ initialPressure_Left=155e5;
+ initialVelocity_Right=1;
+ initialTemperature_Right=565;
+ initialPressure_Right=1e5;
+
+ myProblem = cf.SinglePhase(cf.Liquid,cf.around155bars600K,spaceDim);
+ nVar = myProblem.getNumberOfVariables();
+
+ # Prepare for the initial condition
+ VV_Left = cm.Vector(nVar)
+ VV_Right = cm.Vector(nVar)
+
+ # left and right constant vectors
+ VV_Left[0] = initialPressure_Left;
+ VV_Left[1] = initialVelocity_Left;
+ VV_Left[2] = initialTemperature_Left ;
+ VV_Right[0] = initialPressure_Right;
+ VV_Right[1] = initialVelocity_Right;
+ VV_Right[2] = initialTemperature_Right ;
+
+
+ #Initial field creation
+ print("Building initial data " );
+ myProblem.setInitialFieldStepFunction(M,VV_Left,VV_Right,discontinuity);
+
+ # set the boundary conditions
+ myProblem.setNeumannBoundaryCondition("LeftBoundary");
+ myProblem.setNeumannBoundaryCondition("RightBoundary");
+
+ # set the numerical method
+ if(isExplicit):
+ cf_ExplicitOrImplicit=cf.Implicit
+ else:
+ cf_ExplicitOrImplicit=cf.Explicit
+
+ if(scheme=="Upwind"):
+ cf_Scheme=cf.upwind
+ elif(scheme=="Centered"):
+ cf_Scheme=cf.centered
+
+ myProblem.setNumericalScheme(cf_Scheme, cf_ExplicitOrImplicit);
+
+ # name of result file
+ fileName = "1DRiemannProblem_"+ExplicitOrImplicit+scheme;
+
+ # simulation parameters
+ MaxNbOfTimeStep = nx ;
+ freqSave = 10;
+ maxTime = (xsup-xinf)/4./max(myProblem.getFluidEOS().vitesseSonPressure(initialPressure_Left,initialTemperature_Left), myProblem.getFluidEOS().vitesseSonPressure(initialPressure_Right,initialTemperature_Right) )
+ precision = 1e-6;
+
+ myProblem.setCFL(cfl);
+ myProblem.setPrecision(precision);
+ myProblem.setMaxNbOfTimeStep(MaxNbOfTimeStep);
+ myProblem.setTimeMax(maxTime);
+ myProblem.setFreqSave(freqSave);
+ myProblem.setFileName(fileName);
+ myProblem.saveConservativeField(True);
+
+ myProblem.setLinearSolver(cf.GMRES, cf.NOPC)
+ myProblem.setNewtonSolver(precision,20, cf.Newton_SOLVERLAB)
+ myProblem.usePrimitiveVarsInNewton(False)
+
+ # evolution
+ myProblem.initialize();
+
+ ok = myProblem.run();
+
+ if (not ok):
+ print( "Python simulation of " + fileName + " failed ! " );
+ pass
+ else:
+ print( "Python simulation of " + fileName + " is successful !" );
+ ####################### Postprocessing #########################
+
+ dx=(xsup-xinf)/nx
+ x=[ i*dx for i in range(nx+1)] # array of cell center (1D mesh)
+ fig, ([axDensity, axPressure], [axVelocity, axTemperature]) = plt.subplots(2, 2,sharex=True, figsize=(10,10))
+ plt.gcf().subplots_adjust(wspace = 0.5)
+
+ myEOS = myProblem.getFluidEOS()## Needed to retrieve gamma, pinfnity, convert (p,T) to density and (p, rho) to temperature
+ initialDensity_Left = myEOS.getDensity( initialPressure_Left, initialTemperature_Left)
+ initialDensity_Right = myEOS.getDensity( initialPressure_Right, initialTemperature_Right)
+
+ #Determine exact solution
+ exactDensity, exactVelocity, exactPressure = exact_rs_stiffenedgas.exact_sol_Riemann_problem(xinf, xsup, myProblem.presentTime(), myEOS.constante("gamma"), myEOS.constante("p0"), [ initialDensity_Left, initialVelocity_Left, initialPressure_Left ], [ initialDensity_Right, initialVelocity_Right, initialPressure_Right ], (xinf+xsup)/2, nx+1)
+
+ ### Plot curves
+ axPressure.plot(x, exactPressure, label='Exact Pressure ')
+ myPressureField = myProblem.getPressureField()
+ myPressureField.writeVTK("PressureField")
+ pressureArray=VTK_routines. Extract_VTK_data_over_line_to_numpyArray("PressureField_"+str(myProblem.getNbTimeStep())+".vtu", [xinf,0,0], [xsup,0,0],nx)
+ axPressure.plot(x, pressureArray, label='Pressure time step '+str(myProblem.getNbTimeStep()))
+ axPressure.legend()
+
+ axDensity.plot(x, exactDensity, label='Exact Density ')
+ myDensityField = myProblem.getDensityField()
+ myDensityField.writeVTK("DensityField")
+ densityArray=VTK_routines. Extract_VTK_data_over_line_to_numpyArray("DensityField_"+str(myProblem.getNbTimeStep())+".vtu", [xinf,0,0], [xsup,0,0],nx)
+ axDensity.plot(x, densityArray, label='Density time step '+str(myProblem.getNbTimeStep()))
+ axDensity.legend()
+
+ axVelocity.plot(x, exactVelocity, label='Exact Velocity ')
+ myVelocityField = myProblem.getVelocityXField()
+ myVelocityField.writeVTK("VelocityField")
+ velocityArray=VTK_routines. Extract_VTK_data_over_line_to_numpyArray("VelocityField_"+str(myProblem.getNbTimeStep())+".vtu", [xinf,0,0], [xsup,0,0],nx)
+ axVelocity.plot(x, velocityArray, label='Velocity time step '+str(myProblem.getNbTimeStep()))
+ axVelocity.legend()
+
+ exactTemperature = [0.]*(nx+1)
+ for i in range(nx+1):
+ exactTemperature[i] = myEOS.getTemperatureFromPressure(exactPressure[i], exactDensity[i])
+
+ axTemperature.plot(x, exactTemperature, label='Exact Temperature ')
+ myTemperatureField = myProblem.getTemperatureField()
+ myTemperatureField.writeVTK("TemperatureField")
+ temperatureArray=VTK_routines. Extract_VTK_data_over_line_to_numpyArray("TemperatureField_"+str(myProblem.getNbTimeStep())+".vtu", [xinf,0,0], [xsup,0,0],nx)
+ axTemperature.plot(x, temperatureArray, label='Temperature time step '+str(myProblem.getNbTimeStep()))
+ axTemperature.legend()
+
+ #plt.title('Solving Riemann problem for Euler equations\n with Finite volume schemes method')
+ plt.savefig(fileName+".png")
+
+ #Compute numerical error
+ error_pressure = norm( exactPressure - pressureArray )/norm( exactPressure )
+ error_velocity = norm( exactVelocity - velocityArray )/norm( exactVelocity )
+ error_temperature = norm( exactTemperature - temperatureArray )/norm( exactTemperature )
+
+ print("Absolute error = ", error_pressure, " (pressure), ", error_velocity, " (velocity), ", error_temperature, " (temperature), " )
+
+ assert error_pressure <1.
+ assert error_velocity <1.
+ assert error_temperature <1.
+
+ myProblem.terminate();
+
+ end = time.time()
+
+ test_desc["Computational_time_taken_by_run"]=end-start
+
+ return pressureArray, velocityArray, temperatureArray, error_pressure, error_velocity, error_temperature, x, end - start
+
+if __name__ == """__main__""":
+ solve(0.99,True,Upwind)
--- /dev/null
+#!/usr/bin/env python3
+# -*-coding:utf-8 -*
+
+######################################################################################################################
+# This file contains a class to solve for the exact solution of the Riemann Problem for the one dimensional Euler
+# equations with stiffened gas equation of state
+#
+# Author: Michael Ndjinga
+# Date: 18/02/2021
+# Description : Translated from C++ package developped by Murray Cutforth
+#######################################################################################################################
+
+from math import pow, fabs, sqrt
+
+def exact_sol_Riemann_problem(xmin, xmax, t, gamma, p0, WL, WR, offset, numsamples = 100):#offset= position of the initial discontinuity
+ print("")
+ print("Determination of the exact solution of the Riemann problem for the Euler equations, gamma=", gamma, ", p0= ", p0)
+
+ RS = exact_rs_stiffenedgas(gamma, gamma, p0, p0);
+ RS.solve_RP(WL,WR);
+
+ delx = (xmax - xmin)/numsamples;
+
+ density = [0.]*numsamples
+ velocity = [0.]*numsamples
+ pressure = [0.]*numsamples
+
+ for i in range(numsamples):
+ S = i*delx/t;
+ soln = RS.sample_solution(WL, WR, S - offset/t);
+ density[i] = soln[0]
+ velocity[i]= soln[1]
+ pressure[i]= soln[2]
+
+ return density, velocity, pressure
+
+class exact_rs_stiffenedgas :
+
+ def __init__(self, gamma_L, gamma_R, pinf_L, pinf_R, tol=1.e-6, max_iter=100):
+ self.TOL = tol
+ self.MAX_NB_ITER = max_iter
+
+ self.gamma_L = gamma_L
+ self.gamma_R = gamma_R
+ self.pinf_L = pinf_L
+ self.pinf_R = pinf_R
+
+ self.S_STAR = 0.
+ self.P_STAR = 0.
+ self.rho_star_L = 0.
+ self.rho_star_R = 0.
+
+ self.S_L = 0.
+ self.S_R = 0.
+ self.S_HL = 0.
+ self.S_TL = 0.
+ self.S_HR = 0.
+ self.S_TR = 0.
+
+
+
+ # Functions used to generate exact solutions to Riemann problems
+
+ def solve_RP (self, W_L, W_R):
+ assert len(W_L) == 3, "Left state should have three components (rho, u p)"
+ assert len(W_R) == 3, "Right state should have three components (rho, u p)"
+ assert W_L[0] >= 0.0, "Left density should be positive"
+ assert W_R[0] >= 0.0, "Right density should be positive"
+ # assert W_L[2] >= 0.0 # Since stiffened gases will often exhibit p<0..
+ # assert W_R[2] >= 0.0 #
+
+ print("")
+ print("Solving Riemann problem for left state W_L=", W_L, ", and right state W_R=",W_R)
+
+ # Calculate p_star
+
+ self.P_STAR = self.find_p_star_newtonraphson(W_L[0], W_L[1], W_L[2], W_R[0], W_R[1], W_R[2])
+
+
+ # Calculate u_star
+
+ self.S_STAR = 0.5*(W_L[1]+W_R[1]) + 0.5*(self.f(self.P_STAR,W_R[0],W_R[2],self.gamma_R,self.pinf_R) - self.f(self.P_STAR,W_L[0],W_L[2],self.gamma_L,self.pinf_L))
+
+
+ # Solution now depends on character of 1st and 3rd waves
+
+ if (self.P_STAR > W_L[2]):
+ # Left shock
+
+ self.rho_star_L = W_L[0]*((2.0*self.gamma_L*self.pinf_L + (self.gamma_L+1.0)*self.P_STAR + (self.gamma_L-1.0)*W_L[2])/(2.0*(W_L[2] + self.gamma_L*self.pinf_L) + (self.gamma_L-1.0)*self.P_STAR + (self.gamma_L-1.0)*W_L[2]))
+ self.S_L = W_L[1] - (self.Q_K(self.P_STAR,W_L[0],W_L[2],self.gamma_L,self.pinf_L)/W_L[0])
+ else:
+ # Left rarefaction
+
+ self.rho_star_L = W_L[0]*pow((self.P_STAR + self.pinf_L)/(W_L[2] + self.pinf_L), 1.0/self.gamma_L)
+
+ a_L = self.a(W_L[0], W_L[2], self.gamma_L, self.pinf_L)
+ a_star_L = a_L*pow((self.P_STAR + self.pinf_L)/(W_L[2] + self.pinf_L), (self.gamma_L-1.0)/(2.0*self.gamma_L))
+
+ self.S_HL = W_L[1] - a_L
+ self.S_TL = self.S_STAR - a_star_L
+
+ if (self.P_STAR > W_R[2]):
+ # Right shock
+
+ self.rho_star_R = W_R[0]*((2.0*self.gamma_R*self.pinf_R + (self.gamma_R+1.0)*self.P_STAR + (self.gamma_R-1.0)*W_R[2])/(2.0*(W_R[2] + self.gamma_R*self.pinf_R) + (self.gamma_R-1.0)*self.P_STAR + (self.gamma_R-1.0)*W_R[2]))
+
+ self.S_R = W_R[1] + (self.Q_K(self.P_STAR,W_R[0],W_R[2],self.gamma_R,self.pinf_R)/W_R[0])
+ else:
+ # Right rarefaction
+
+ self.rho_star_R = W_R[0]*pow((self.P_STAR + self.pinf_R)/(W_R[2] + self.pinf_R), 1.0/self.gamma_R)
+
+ a_R = self.a(W_R[0],W_R[2],self.gamma_R, self.pinf_R)
+ a_star_R = a_R*pow((self.P_STAR + self.pinf_R)/(W_R[2] + self.pinf_R), (self.gamma_R-1.0)/(2.0*self.gamma_R))
+
+ self.S_HR = W_R[1] + a_R
+ self.S_TR = self.S_STAR + a_star_R
+
+ def sample_solution (self, W_L, W_R, S):
+ W = [0.]*3
+
+ # Find appropriate part of solution and return primitives
+
+ if (S < self.S_STAR):
+ # To the left of the contact
+
+ if (self.P_STAR > W_L[2]):
+ # Left shock
+
+ if (S < self.S_L):
+ W = W_L
+ else:
+ W[0] = self.rho_star_L
+ W[1] = self.S_STAR
+ W[2] = self.P_STAR
+ else:
+ # Left rarefaction
+
+ if (S < self.S_HL):
+ W = W_L
+ else:
+ if (S > self.S_TL):
+ W[0] = self.rho_star_L
+ W[1] = self.S_STAR
+ W[2] = self.P_STAR
+ else:
+ self.set_left_rarefaction_fan_state(W_L, S, W)
+ else:
+ # To the right of the contact
+
+ if (self.P_STAR > W_R[2]):
+ # Right shock
+
+ if (S > self.S_R):
+ W = W_R
+ else:
+ W[0] = self.rho_star_R
+ W[1] = self.S_STAR
+ W[2] = self.P_STAR
+ else:
+ # Right rarefaction
+
+ if (S > self.S_HR):
+ W = W_R
+ else:
+ if (S < self.S_TR):
+ W[0] = self.rho_star_R
+ W[1] = self.S_STAR
+ W[2] = self.P_STAR
+ else:
+ self.set_right_rarefaction_fan_state(W_R, S, W)
+
+ return W
+
+ # Functions used to solve for p_star iteratively
+
+ def find_p_star_newtonraphson (self, rho_L, u_L, p_L, rho_R, u_R, p_R ):
+
+ # First we set the initial guess for p_star using a simple mean-value approximation
+
+ p_star_next = 0.5*(p_L+p_R)
+ n = 0
+
+
+ # Now use the Newton-Raphson algorithm
+
+ while True:#conversion of do ... while by while True... if (...) break
+ p_star = p_star_next
+
+ p_star_next = p_star - self.total_pressure_function(p_star,rho_L,u_L,p_L,rho_R,u_R,p_R)/self.total_pressure_function_deriv(p_star,rho_L,p_L,rho_R,p_R)
+
+ p_star_next = max(p_star_next, self.TOL)
+
+ n+=1
+
+ if not ((fabs(p_star_next - p_star)/(0.5*(p_star+p_star_next)) > self.TOL) and n < self.MAX_NB_ITER):
+ break
+
+ if (n == self.MAX_NB_ITER):
+ raise ValueError("!!!!!!!!!!Newton algorithm did not converge. Increase tolerance or maximum number of time steps. Current values : tol=" + str(self.TOL) + ", max_iter=" + str(self.MAX_NB_ITER) )
+ #p_star_next = 0.5*(p_L+p_R)
+
+ return p_star_next
+
+ def total_pressure_function (self, p_star, rho_L, u_L, p_L, rho_R, u_R, p_R ):
+
+ return self.f(p_star, rho_L, p_L, self.gamma_L, self.pinf_L) + self.f(p_star, rho_R, p_R, self.gamma_R, self.pinf_R) + u_R - u_L
+
+ def total_pressure_function_deriv (self, p_star, rho_L, p_L, rho_R, p_R ):
+
+ return self.f_deriv (p_star, rho_L, p_L, self.gamma_L, self.pinf_L) + self.f_deriv (p_star, rho_R, p_R, self.gamma_R, self.pinf_R)
+
+
+ def f (self, p_star, rho, p, gamma, pinf):
+ if (p_star > p):
+
+ return (p_star - p)/self.Q_K(p_star, rho, p, gamma, pinf)
+
+ else:
+
+ return (2.0*self.a(rho,p,gamma,pinf)/(gamma-1.0))*(pow((p_star + pinf)/(p + pinf), (gamma-1.0)/(2.0*gamma)) - 1.0)
+
+
+ def f_deriv (self, p_star, rho, p, gamma, pinf):
+ A = 2.0/((gamma+1.0)*rho)
+ B = (p+pinf)*(gamma-1.0)/(gamma+1.0)
+
+ if (p_star > p):
+
+ return sqrt(A/(B+p_star+pinf))*(1.0 - ((p_star-p)/(2.0*(B+p_star+pinf))))
+
+ else:
+
+ return (1.0/(rho*self.a(rho,p,gamma,pinf)))*pow((p_star+pinf)/(p+pinf), -(gamma+1.0)/(2.0*gamma))
+
+
+
+ # Functions to find the state inside a rarefaction fan
+
+ def set_left_rarefaction_fan_state (self, W_L, S, W):
+ a_L = self.a(W_L[0],W_L[2],self.gamma_L,self.pinf_L)
+ W[0] = W_L[0]*pow((2.0/(self.gamma_L+1.0)) + ((self.gamma_L-1.0)/(a_L*(self.gamma_L+1.0)))*(W_L[1] - S), 2.0/(self.gamma_L - 1.0))
+ W[1] = (2.0/(self.gamma_L+1.0))*(a_L + S + ((self.gamma_L-1.0)/2.0)*W_L[1])
+ W[2] = (W_L[2] + self.pinf_L)*pow((2.0/(self.gamma_L+1.0)) + ((self.gamma_L-1.0)/(a_L*(self.gamma_L+1.0)))*(W_L[1] - S), (2.0*self.gamma_L)/(self.gamma_L-1.0)) - self.pinf_L
+
+ def set_right_rarefaction_fan_state (self, W_R, S, W):
+ a_R = self.a(W_R[0],W_R[2],self.gamma_R,self.pinf_R)
+ W[0] = W_R[0]*pow((2.0/(self.gamma_R+1.0)) - ((self.gamma_R-1.0)/(a_R*(self.gamma_R+1.0)))*(W_R[1] - S), 2.0/(self.gamma_R - 1.0))
+ W[1] = (2.0/(self.gamma_R+1.0))*(- a_R + S + ((self.gamma_R-1.0)/2.0)*W_R[1])
+ W[2] = (W_R[2] + self.pinf_R)*pow((2.0/(self.gamma_R+1.0)) - ((self.gamma_R-1.0)/(a_R*(self.gamma_R+1.0)))*(W_R[1] - S), (2.0*self.gamma_R)/(self.gamma_R-1.0)) - self.pinf_R
+
+
+
+ # Misc functions
+
+ def Q_K (self, p_star, rho, p, gamma, pinf):
+ A = 2.0/((gamma+1.0)*rho)
+ B = (p+pinf)*(gamma-1.0)/(gamma+1.0)
+ return sqrt((p_star+pinf+B)/A)
+
+
+
+ # Equation of state functions
+
+ def a (self, rho, p, gamma, pinf):#sound speed
+ return sqrt(gamma*((p+pinf)/rho))
+
+
--- /dev/null
+import SinglePhase_1DRiemannProblem
+import matplotlib
+matplotlib.use("Agg")
+import matplotlib.pyplot as plt
+import numpy as np
+from math import log10, sqrt
+import sys
+import time, json
+
+
+def test_validationSinglePhase_1DRiemannProblem(cfl,isExplicit,scheme):
+ start = time.time()
+ #### 1D regular grid
+ meshList=[10,20,50,100,200, 400]
+ meshType="1D regular grid"
+ testColor="Green"
+ nbMeshes=len(meshList)
+ mesh_size_tab=meshList
+ mesh_name='RegularGrid'
+
+ a=0. ; b=1.
+ x=[0]*nbMeshes
+ error_p_tab=[0]*nbMeshes
+ error_u_tab=[0]*nbMeshes
+ error_T_tab=[0]*nbMeshes
+ sol_p=[0]*nbMeshes
+ sol_u=[0]*nbMeshes
+ sol_T=[0]*nbMeshes
+ time_tab=[0]*nbMeshes
+ diag_data_press=[0]*nbMeshes
+ diag_data_vel=[0]*nbMeshes
+
+ plt.close('all')
+ i=0
+
+ # Storing of numerical errors, mesh sizes and solution
+ for nx in meshList:
+ sol_u[i], sol_p[i], sol_T[i], error_u_tab[i], error_p_tab[i], error_T_tab[i], x[i], time_tab[i] = SinglePhase_1DRiemannProblem.solve(a,b,nx,cfl,isExplicit, scheme)
+ error_p_tab[i]=log10(error_p_tab[i])
+ error_u_tab[i]=log10(error_u_tab[i])
+ time_tab[i]=log10(time_tab[i])
+ i=i+1
+
+ end = time.time()
+
+ if(isExplicit):
+ ExplicitOrImplicit="Explicit"
+ else:
+ ExplicitOrImplicit="Implicit"
+
+ # Plot of results
+ for i in range(nbMeshes):
+ plt.plot(x[i], sol_p[i], label= str(mesh_size_tab[i]) + ' cells')
+ plt.legend()
+ plt.xlabel('Position (m)')
+ plt.ylabel('Pressure (bar)')
+ plt.title('Plot of pressure in 1D Euler system \n with '+ExplicitOrImplicit+scheme+' scheme')
+ plt.savefig(mesh_name+'_1DEulerSystem'+scheme+'_Pressure.png')
+ plt.close()
+
+ plt.clf()
+ for i in range(nbMeshes):
+ plt.plot(x[i], sol_u[i], label= str(mesh_size_tab[i]) + ' cells')
+ plt.legend()
+ plt.xlabel('Position (m)')
+ plt.ylabel('Velocity (m/s)')
+ plt.title('Plot of velocity in 1D Euler system \n with '+ExplicitOrImplicit+scheme+' scheme')
+ plt.savefig(mesh_name+'_1DEulerSystem'+scheme+'_Velocity.png')
+ plt.close()
+
+ plt.clf()
+ for i in range(nbMeshes):
+ plt.plot(x[i], sol_T[i], label= str(mesh_size_tab[i]) + ' cells')
+ plt.legend()
+ plt.xlabel('Position (m)')
+ plt.ylabel('Temperature (K)')
+ plt.title('Plot of temperature in 1D Euler system \n with '+ExplicitOrImplicit+scheme+' scheme')
+ plt.savefig(mesh_name+'_1DEulerSystem'+scheme+'_Temperature.png')
+ plt.close()
+
+ for i in range(nbMeshes):
+ mesh_size_tab[i]=log10(mesh_size_tab[i])
+
+ # Least square linear regression
+ # Find the best a,b such that f(x)=ax+b best approximates the convergence curve
+ # The vector X=(a,b) solves a symmetric linear system AX=B with A=(a1,a2\\a2,a3), B=(b1,b2)
+ a1=np.dot(mesh_size_tab,mesh_size_tab)
+ a2=np.sum(mesh_size_tab)
+ a3=nbMeshes
+
+ det=a1*a3-a2*a2
+ assert det!=0, 'test_validationSinglePhase_1DRiemannProblem() : Make sure you use distinct meshes and at least two meshes'
+
+ b1u=np.dot(error_u_tab,mesh_size_tab)
+ b2u=np.sum(error_u_tab)
+ a=( a3*b1u-a2*b2u)/det
+ b=(-a2*b1u+a1*b2u)/det
+
+ print( ExplicitOrImplicit + scheme+" scheme for Euler equation on 1D regular grid : scheme order is ", -a)
+
+ assert abs(a+0.26 )<0.01
+
+ # Plot of convergence curve
+ plt.close()
+ plt.plot(mesh_size_tab, error_p_tab, label='log(|error pressure|)')
+ plt.plot(mesh_size_tab, a*np.array(mesh_size_tab)+b,label='straight line with slope : '+'%.3f' % a)
+ plt.legend()
+ plt.xlabel('log(Number of cells)')
+ plt.ylabel('log(|error p|)')
+ plt.title('Convergence of finite volumes for the Euler equation \n with '+ExplicitOrImplicit+scheme+' scheme on a 1D regular grid (pressure)')
+
+ plt.savefig(mesh_name+"SinglePhase_1DRiemannProblem_"+scheme+ExplicitOrImplicit+"_CFL"+str(cfl)+"_ConvergenceCurve_pressure.png")
+
+ plt.close()
+ plt.plot(mesh_size_tab, error_u_tab, label='log(|error velocity|)')
+ plt.plot(mesh_size_tab, a*np.array(mesh_size_tab)+b,label='straight line with slope : '+'%.3f' % a)
+ plt.legend()
+ plt.xlabel('log(Number of cells)')
+ plt.ylabel('log(|error u|)')
+ plt.title('Convergence of finite volumes for the Euler equation \n with '+ExplicitOrImplicit+scheme+' scheme on a 1D regular grid (velocity)')
+
+ plt.savefig(mesh_name+"SinglePhase_1DRiemannProblem_"+scheme+ExplicitOrImplicit+"_CFL"+str(cfl)+"_ConvergenceCurve_velocity.png")
+
+ # Plot of computational time
+ plt.close()
+ plt.plot(mesh_size_tab, time_tab, label='log(cpu time)')
+ plt.legend()
+ plt.xlabel('log(Number of cells)')
+ plt.ylabel('log(cpu time)')
+ plt.title('Computational time of finite volumes for the Euler equation \n with '+ExplicitOrImplicit+scheme+' scheme on a 1D regular grid')
+
+ plt.savefig(mesh_name+"SinglePhase_1DRiemannProblem_"+scheme+ExplicitOrImplicit+"_CFL"+str(cfl)+"_ComputationalTime.png")
+
+ plt.close('all')
+
+ convergence_synthesis={}
+
+ convergence_synthesis["PDE_model"]="Euler_Equation"
+ convergence_synthesis["PDE_is_stationary"]=False
+ convergence_synthesis["PDE_search_for_stationary_solution"]=True
+ convergence_synthesis["Numerical_method_name"]=scheme+" scheme"
+ convergence_synthesis["Numerical_method_space_discretization"]="Finite volumes"
+ convergence_synthesis["Numerical_method_time_discretization"]=ExplicitOrImplicit
+ convergence_synthesis["Initial_data"]="Riemann problem"
+ convergence_synthesis["Boundary_conditions"]="Periodic"
+ convergence_synthesis["Numerical_parameter_cfl"]=cfl
+ convergence_synthesis["Space_dimension"]=2
+ convergence_synthesis["Mesh_dimension"]=2
+ convergence_synthesis["Mesh_names"]=meshList
+ convergence_synthesis["Mesh_type"]=meshType
+ convergence_synthesis["Mesh_description"]=mesh_name
+ convergence_synthesis["Mesh_sizes"]=mesh_size_tab
+ convergence_synthesis["Mesh_cell_type"]="1D regular grid"
+ convergence_synthesis["Scheme_order"]=-a
+ convergence_synthesis["Test_color"]=testColor
+ convergence_synthesis["Computational_time"]=end-start
+
+ with open('Convergence_SinglePhase_1DRiemannProblem'+ExplicitOrImplicit+'_'+mesh_name+'.json', 'w') as outfile:
+ json.dump(convergence_synthesis, outfile)
+
+if __name__ == """__main__""":
+ if len(sys.argv) >3 :
+ cfl = float(sys.argv[1])
+ isExplicit = bool(int(sys.argv[2]))
+ scheme = sys.argv[3]
+ test_validationSinglePhase_1DRiemannProblem(cfl,isExplicit, scheme)
+ else :
+ test_validationSinglePhase_1DRiemannProblem(0.99,True, "Upwind")