def test_validation3DVF_cubes(): start = time.time() ### 3D FV rectangular mesh meshList = [11, 21, 41] meshType = "Regular_cubes" testColor = "Green" nbMeshes = len(meshList) error_tab = [0] * nbMeshes mesh_size_tab = [0] * nbMeshes mesh_name = 'meshCubeWithCuboids3DFV' diag_data = [0] * nbMeshes time_tab = [0] * nbMeshes resolution = 100 curv_abs = np.linspace(0, sqrt(2), resolution + 1) plt.close('all') i = 0 # Storing of numerical errors, mesh sizes and diagonal values i = 0 # Computation of the numerical error for nx in meshList: my_mesh = cdmath.Mesh(0, 1, nx, 0, 1, nx, 0, 1, nx) error_tab[i], mesh_size_tab[i], diag_data[ i], min_sol_num, max_sol_num, time_tab[ i] = FiniteVolumes3DPoisson_CUBE.solve( my_mesh, str(nx) + 'x' + str(nx) + 'x' + str(nx), resolution, meshType, testColor) assert min_sol_num > -0.01 assert max_sol_num < 1.2 plt.plot(curv_abs, diag_data[i], label=str(mesh_size_tab[i]) + ' cells') error_tab[i] = log10(error_tab[i]) time_tab[i] = log10(time_tab[i]) mesh_size_tab[i] = 1. / 3 * log10(mesh_size_tab[i]) i = i + 1 end = time.time() # Plot over diagonal line plt.legend() plt.xlabel('Position on diagonal line') plt.ylabel('Value on diagonal line') plt.title( 'Plot over diagonal line for finite volumes \n for Laplace operator on 3D cuboid meshes' ) plt.savefig(mesh_name + "_3DPoissonVFs_PlotOverDiagonalLine.png") # 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 b1 = np.dot(error_tab, mesh_size_tab) b2 = np.sum(error_tab) det = a1 * a3 - a2 * a2 assert det != 0, 'test_validation3DVF_s() : Make sure you use distinct meshes and at least two meshes' a = (a3 * b1 - a2 * b2) / det b = (-a2 * b1 + a1 * b2) / det print "FV on 3D rectangular parallelepiped mesh : scheme order is ", -a assert abs(a + 2) < 0.01 # Plot of convergence curve plt.close() plt.plot(mesh_size_tab, error_tab, label='log(|numerical-exact|)') plt.plot(mesh_size_tab, a * np.array(mesh_size_tab) + b, label='least square slope : ' + '%.3f' % a) plt.legend() plt.xlabel('1/3 log(number of cells)') plt.ylabel('log(error)') plt.title( 'Convergence of finite volumes for Laplace operator on 3D cuboid meshes' ) plt.savefig(mesh_name + "_3DPoissonVFs_ConvergenceCurve.png") # Plot of computational time plt.close() plt.plot(mesh_size_tab, time_tab, label='log(cpu time)') plt.legend() plt.xlabel('1/3 log(number of cells)') plt.ylabel('log(cpu time)') plt.title( 'Computational time of finite volumes \n for Laplace operator on 3D cuboid meshes' ) plt.savefig(mesh_name + "_3DPoissonVFs_ComputationalTime.png") plt.close('all') convergence_synthesis["Mesh_names"] = meshList convergence_synthesis["Mesh_type"] = meshType #convergence_synthesis["Mesh_path"]=mesh_path convergence_synthesis["Mesh_description"] = mesh_name convergence_synthesis["Mesh_sizes"] = [10**x for x in mesh_size_tab] convergence_synthesis["Space_dimension"] = 3 convergence_synthesis["Mesh_dimension"] = 3 convergence_synthesis["Mesh_cell_type"] = "Cubes" convergence_synthesis["Errors"] = [10**x for x in error_tab] convergence_synthesis["Scheme_order"] = -a convergence_synthesis["Test_color"] = testColor convergence_synthesis["Computational_time"] = end - start with open('Convergence_Poisson_3DFV_' + mesh_name + '.json', 'w') as outfile: json.dump(convergence_synthesis, outfile)
test_desc["Mesh_max_number_of_neighbours"]=10 test_desc["Geometry"]="Square" test_desc["Boundary_conditions"]=test_bc test_desc["Initial_data"]=test_initial_data test_desc["Part_of_mesh_convergence_analysis"]=True test_desc["Numerical_parameter_cfl"]=cfl test_desc["Simulation_parameter_maximum_time_step"]=ntmax test_desc["Simulation_parameter_maximum_time"]=tmax test_desc["Simulation_output_frequency"]=output_freq test_desc["Simulation_final_time_after_run"]=t_final test_desc["Simulation_final_number_of_time_steps_after_run"]=ndt_final test_desc["Computational_time_taken_by_run"]=end-start test_desc["Absolute_error"]=max(error_p*p0,error_u) test_desc["Relative_error"]=max(error_p,error_u) with open('test_WaveSystem'+str(my_mesh.getMeshDimension())+'DCentered_'+meshName+ "Cells.json", 'w') as outfile: json.dump(test_desc, outfile) return error_p, error_u, nbCells, t_final, ndt_final, max_vel, diag_data_press, diag_data_vel, end - start, cond_number def solve_file( filename,meshName, resolution,scaling, meshType, testColor,cfl): my_mesh = cdmath.Mesh(filename+".med") return solve(my_mesh, meshName+str(my_mesh.getNumberOfCells()),resolution,scaling, meshType, testColor,cfl) if __name__ == """__main__""": M1=cdmath.Mesh(0,1,20,0,1,20) cfl=0.5 solve(M1,"SquareWithSquares",100,2,"Regular squares","Green",cfl)
PV_routines.Save_PV_data_to_picture_file("WaveSystem"+str(dim)+"DUpwind"+meshName+"_pressure_Stat"+'_0.vtu',"Pressure",'CELLS',"WaveSystem"+str(dim)+"DUpwind"+meshName+"_pressure_Stat") PV_routines.Save_PV_data_to_picture_file("WaveSystem"+str(dim)+"DUpwind"+meshName+"_velocity_Stat"+'_0.vtu',"Velocity",'CELLS',"WaveSystem"+str(dim)+"DUpwind"+meshName+"_velocity_Stat") else: print "Temps maximum Tmax= ", tmax, " atteint" def solve(my_mesh,filename,resolution): print("Resolution of the Wave system with Wall boundary conditions:") # Problem data tmax = 1. ntmax = 100 cfl = 0.45 output_freq = 100 WaveSystemVF(ntmax, tmax, cfl, my_mesh, output_freq, filename,resolution) def solve_file( filename,resolution): my_mesh = cdmath.Mesh(filename+".med") solve(my_mesh, filename,resolution) if __name__ == """__main__""": if len(sys.argv) >1 : filename=sys.argv[1] my_mesh = cdmath.Mesh(filename) solve(my_mesh,filename,100) else : raise ValueError("WaveSystemUpwind.py expects a mesh file name")
#================ # Extraction of the diagonal data diag_data = VTK_routines.Extract_field_data_over_line_to_numpyArray( my_ResultField, [0, 1, 0], [1, 0, 0], resolution) # save 2D picture PV_routines.Save_PV_data_to_picture_file( "FiniteVolumes2D_square_ResultField" + str(nbCells) + '_0.vtu', "ResultField", 'CELLS', "FiniteVolumes2D_square_ResultField" + str(nbCells)) test_desc["Computational_time_taken_by_run"] = end - start test_desc["Absolute_error"] = erreur_abs test_desc["Relative_error"] = erreur_abs / max_abs_sol_exacte with open( 'test_Poisson' + str(my_mesh.getMeshDimension()) + 'D_VF_' + str(nbCells) + "Cells.json", 'w') as outfile: json.dump(test_desc, outfile) return erreur_abs / max_abs_sol_exacte, nbCells, diag_data, min_sol_num, max_sol_num, end - start def solve_file(filename, resolution, meshType, testColor): my_mesh = cdmath.Mesh(filename + ".med") return solve(my_mesh, filename, resolution, meshType, testColor) if __name__ == """__main__""": mesh51 = cdmath.Mesh(0, 1, 51, 0, 1, 51) solve(mesh51, '51', 100, "Regular squares", "Green")
test_desc["Simulation_parameter_maximum_time"] = tmax test_desc["Simulation_output_frequency"] = output_freq test_desc["Simulation_final_time_after_run"] = t_final test_desc["Simulation_final_number_of_time_steps_after_run"] = ndt_final test_desc["Computational_time_taken_by_run"] = end - start test_desc["Absolute_error"] = max(error_p * p0, error_u) test_desc["Relative_error"] = max(error_p, error_u) with open( 'test_WaveSystem' + str(my_mesh.getMeshDimension()) + 'DUpwind_' + meshName + "Cells.json", 'w') as outfile: json.dump(test_desc, outfile) return error_p, error_u, nbCells, t_final, ndt_final, max_vel, diag_data_press, diag_data_vel, end - start def solve_file(filename, meshName, resolution, scaling, meshType, testColor, cfl, test_bc): my_mesh = cdmath.Mesh(filename + ".med") return solve(my_mesh, meshName + str(my_mesh.getNumberOfCells()), resolution, scaling, meshType, testColor, cfl, test_bc) if __name__ == """__main__""": M1 = cdmath.Mesh(0., 1., 20, 0., 1., 20) cfl = 0.5 scaling = 0 solve(M1, "SquareRegularSquares", 100, scaling, "Regular_squares", "Green", cfl, "Periodic")
# Description : Utilisation de la méthode des éléménts finis P1 avec champs u et f discrétisés aux noeuds d'un maillage triangulaire # Création et sauvegarde du champ résultant ainsi que du champ second membre en utilisant la librairie CDMATH # Référence : M. A. Olshanskii, A. Reusken, and J. Grande. A finite element method for elliptic equations # on surfaces. SIAM J. Num. Anal., 47, p. 3355 #================================================================================================================================ import cdmath from math import pow import numpy as np import PV_routines import VTK_routines import paraview.simple as pvs #Chargement du maillage triangulaire de la sphère #======================================================================================= my_mesh = cdmath.Mesh("meshSphere.med") if (not my_mesh.isTriangular()): raise ValueError("Wrong cell types : mesh is not made of triangles") if (my_mesh.getMeshDimension() != 2): raise ValueError( "Wrong mesh dimension : expected a surface of dimension 2") if (my_mesh.getSpaceDimension() != 3): raise ValueError("Wrong space dimension : expected a space of dimension 3") nbNodes = my_mesh.getNumberOfNodes() nbCells = my_mesh.getNumberOfCells() print("Mesh building/loading done") print("nb of nodes=", nbNodes) print("nb of cells=", nbCells)
# Description : Utilisation de la méthode des éléménts finis P1 avec champs u et f discrétisés aux noeuds d'un maillage 1D quelconque # Création et sauvegarde du champ résultant ainsi que du champ second membre en utilisant la librairie CDMATH # Comparaison de la solution numérique avec la solution exacte u=-sin(pi*x) #================================================================================================================================ import cdmath from math import sin, pi, sqrt from numpy import linspace import matplotlib.pyplot as plt import PV_routines import VTK_routines #Création d'un maillage uniforme du segment [0,1], définition des bords #====================================================================== nx=100 my_mesh = cdmath.Mesh(0,1,nx) if( my_mesh.getSpaceDimension()!=1 or my_mesh.getMeshDimension()!=1) : raise ValueError("Wrong space or mesh dimension : space and mesh dimensions should be 1") eps=1e-6 my_mesh.setGroupAtPlan(0.,0,eps,"DirichletBorder")#Bord GAUCHE my_mesh.setGroupAtPlan(1.,0,eps,"DirichletBorder")#Bord DROIT nbNodes = my_mesh.getNumberOfNodes() nbCells = my_mesh.getNumberOfCells() print("Mesh loading/building done") print("Number of nodes=", nbNodes) print("Number of cells=", nbCells) #Discrétisation du second membre et détermination des noeuds intérieurs
print "Numerical method : staggered scheme" print "Initial data : Spherical wave" print "Periodic boundary conditions" print "Mesh name : ", meshName, my_mesh.getNumberOfCells(), " cells" # Problem data tmax = 1000. ntmax = 500 cfl = 1. / my_mesh.getSpaceDimension() output_freq = 1 WaveSystemStaggered(ntmax, tmax, cfl, my_mesh, output_freq, meshName, resolution) def solve_file(filename, meshName, resolution): my_mesh = cdmath.Mesh(filename + ".med") return solve(my_mesh, meshName + str(my_mesh.getNumberOfCells()), resolution) if __name__ == """__main__""": if len(sys.argv) > 1: my_mesh = cdmath.Mesh(sys.argv[1]) solve(my_mesh, my_mesh.getName(), 100) else: nx = 50 my_mesh = cdmath.Mesh(0, 1, nx, 0, 1, nx) solve(my_mesh, my_mesh.getName(), 100)
def solve_file(filename, meshName, resolution): my_mesh = cdmath.Mesh(filename + ".med") return solve(my_mesh, meshName + str(my_mesh.getNumberOfCells()), resolution)
def solve(my_mesh, meshName, resolution): print "Resolution of the Wave system in dimension ", my_mesh.getSpaceDimension( ) print "Numerical method : implicit pseudo staggered" print "Initial data : constant pressure, divergence free velocity" print "Wall boundary conditions" print "Mesh name : ", meshName, my_mesh.getNumberOfCells(), " cells" # Problem data tmax = 1000. ntmax = 100 cfl = 1. / my_mesh.getSpaceDimension() output_freq = 100 WaveSystemVF(ntmax, tmax, cfl, my_mesh, output_freq, meshName, resolution) def solve_file(filename, meshName, resolution): my_mesh = cdmath.Mesh(filename + ".med") return solve(my_mesh, meshName + str(my_mesh.getNumberOfCells()), resolution) if __name__ == """__main__""": if len(sys.argv) > 1: my_mesh = cdmath.Mesh(sys.argv[1]) solve(my_mesh, my_mesh.getName(), 100) else: raise ValueError("WaveSystemPStag.py expects a mesh file name")
# Copyright : CEA Saclay 2017 # Description : Utilisation de la méthode des éléménts finis P1 avec champs u et f discrétisés aux noeuds d'un maillage tétraédrique # Création et sauvegarde du champ résultant ainsi que du champ second membre en utilisant la librairie CDMATH # Comparaison de la solution numérique avec la solution exacte u=-sin(pi*x)*sin(pi*y)*sin(pi*z) #================================================================================================================================ import cdmath from math import sin, pi, sqrt import numpy as np import matplotlib.pyplot as plt import PV_routines import VTK_routines #Chargement du maillage tétraédrique du domaine cubique [0,1]x[0,1]x[0,1], définition des bords #============================================================================================== my_mesh = cdmath.Mesh("meshCube.med") if (my_mesh.getSpaceDimension() != 3 or my_mesh.getMeshDimension() != 3): raise ValueError( "Wrong space or mesh dimension : space and mesh dimensions should be 3" ) if (not my_mesh.isTetrahedral()): raise ValueError("Wrong cell types : mesh is not made of tetrahedra") eps = 1e-6 my_mesh.setGroupAtPlan(0., 0, eps, "DirichletBorder") #Bord GAUCHE my_mesh.setGroupAtPlan(1., 0, eps, "DirichletBorder") #Bord DROIT my_mesh.setGroupAtPlan(0., 1, eps, "DirichletBorder") #Bord BAS my_mesh.setGroupAtPlan(1., 1, eps, "DirichletBorder") #Bord HAUT my_mesh.setGroupAtPlan(0., 2, eps, "DirichletBorder") #Bord AVANT my_mesh.setGroupAtPlan(1., 2, eps, "DirichletBorder") #Bord ARRIERE nbNodes = my_mesh.getNumberOfNodes()
def test_validation3DWaveSystemUpwind_cubes(): start = time.time() #### 3D cubic mesh meshList=[6,11,21] meshType="Regular cubes" testColor="Green" nbMeshes=len(meshList) error_p_tab=[0]*nbMeshes error_u_tab=[0]*nbMeshes mesh_size_tab=[0]*nbMeshes mesh_name='CubeWithCubes' diag_data_press=[0]*nbMeshes diag_data_vel=[0]*nbMeshes time_tab=[0]*nbMeshes t_final=[0]*nbMeshes ndt_final=[0]*nbMeshes max_vel=[0]*nbMeshes resolution=100 curv_abs=np.linspace(0,sqrt(3),resolution+1) plt.close('all') i=0 cfl=1./3 bctype="Periodic" # Storing of numerical errors, mesh sizes and diagonal values for nx in meshList: my_mesh=cdmath.Mesh(0,1,nx,0,1,nx,0,1,nx) error_p_tab[i], error_u_tab[i], mesh_size_tab[i], t_final[i], ndt_final[i], max_vel[i], diag_data_press[i], diag_data_vel[i], time_tab[i] =WaveSystemUpwind.solve(my_mesh, mesh_name+str(my_mesh.getNumberOfCells()), resolution,meshType,testColor,cfl,bctype) assert max_vel[i]>1.4 and max_vel[i]<2 i=i+1 end = time.time() # Plot over diagonal line for i in range(nbMeshes): plt.plot(curv_abs, diag_data_press[i], label= str(mesh_size_tab[i]) + ' cells') plt.legend() plt.xlabel('Position on diagonal line') plt.ylabel('Pressure on diagonal line') plt.title('Plot over diagonal line for stationary wave system \n on 3D cube meshes') plt.savefig(mesh_name+'_Pressure_3DWaveSystem_'+"PlotOverDiagonalLine.png") plt.close() plt.clf() for i in range(nbMeshes): plt.plot(curv_abs, diag_data_vel[i], label= str(mesh_size_tab[i]) + ' cells') plt.legend() plt.xlabel('Position on diagonal line') plt.ylabel('Velocity on diagonal line') plt.title('Plot over diagonal line for the stationary wave system \n on 3D cube meshes') plt.savefig(mesh_name+"_Velocity_3DWaveSystem_"+"PlotOverDiagonalLine.png") plt.close() # 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_validation3DWaveSystem_cubes() : Make sure you use distinct meshes and at least two meshes' b1p=np.dot(error_p_tab,mesh_size_tab) b2p=np.sum(error_p_tab) ap=( a3*b1p-a2*b2p)/det bp=(-a2*b1p+a1*b2p)/det print "FV upwind on 3D cubee meshes : scheme order for pressure is ", -ap b1u=np.dot(error_u_tab,mesh_size_tab) b2u=np.sum(error_u_tab) au=( a3*b1u-a2*b2u)/det bu=(-a2*b1u+a1*b2u)/det print "FV upwind on 3D cube meshes : scheme order for velocity is ", -au # Plot of number of time steps plt.close() plt.plot(mesh_size_tab, ndt_final, label='Number of time step to reach stationary regime') plt.legend() plt.xlabel('number of cells') plt.ylabel('Max time steps for stationary regime') plt.title('Number of times steps required \n for the stationary Wave System on 3D cube meshes') plt.savefig(mesh_name+"_3DWaveSystem_"+"TimeSteps.png") # Plot of number of stationary time plt.close() plt.plot(mesh_size_tab, t_final, label='Time where stationary regime is reached') plt.legend() plt.xlabel('number of cells') plt.ylabel('Max time for stationary regime') plt.title('Simulated time \n for the stationary Wave System on 3D cube meshes') plt.savefig(mesh_name+"_3DWaveSystem_"+"TimeFinal.png") # Plot of number of maximal velocity norm plt.close() plt.plot(mesh_size_tab, max_vel, label='Maximum velocity norm') plt.legend() plt.xlabel('number of cells') plt.ylabel('Max velocity norm') plt.title('Maximum velocity norm \n for the stationary Wave System on 3D cube meshes') plt.savefig(mesh_name+"_3DWaveSystem_"+"MaxVelNorm.png") # Plot of convergence curves plt.close() plt.plot(mesh_size_tab, error_p_tab, label='|error on stationary pressure|') plt.legend() plt.xlabel('number of cells') plt.ylabel('|error p|') plt.title('Convergence of finite volumes \n for the stationary Wave System on 3D cube meshes') plt.savefig(mesh_name+"_Pressure_3DWaveSystem_"+"ConvergenceCurve.png") plt.close() plt.plot(mesh_size_tab, error_u_tab, label='log(|error on stationary velocity|)') plt.legend() plt.xlabel('number of cells') plt.ylabel('|error u|') plt.title('Convergence of finite volumes \n for the stationary Wave System on 3D cube meshes') plt.savefig(mesh_name+"_Velocity_3DWaveSystem_"+"ConvergenceCurve.png") # Plot of computational time plt.close() plt.plot(mesh_size_tab, time_tab, label='log(cpu time)') plt.legend() plt.xlabel('number of cells') plt.ylabel('cpu time') plt.title('Computational time of finite volumes \n for the stationary Wave System on 3D cube meshes') plt.savefig(mesh_name+"3DWaveSystem_ComputationalTime.png") plt.close('all') convergence_synthesis={} convergence_synthesis["PDE_model"]="Wave system" convergence_synthesis["PDE_is_stationary"]=False convergence_synthesis["PDE_search_for_stationary_solution"]=True convergence_synthesis["Numerical_method_name"]="Upwind" convergence_synthesis["Numerical_method_space_discretization"]="Finite volumes" convergence_synthesis["Numerical_method_time_discretization"]="Implicit" convergence_synthesis["Initial_data"]="Constant pressure, divergence free velocity" convergence_synthesis["Boundary_conditions"]="Periodic" convergence_synthesis["Numerical_parameter_cfl"]=cfl convergence_synthesis["Space_dimension"]=3 convergence_synthesis["Mesh_dimension"]=3 convergence_synthesis["Mesh_names"]=meshList convergence_synthesis["Mesh_type"]=meshType #convergence_synthesis["Mesh_path"]=mesh_path convergence_synthesis["Mesh_description"]=mesh_name convergence_synthesis["Mesh_sizes"]=mesh_size_tab convergence_synthesis["Mesh_cell_type"]="Cubes" convergence_synthesis["Numerical_error_velocity"]=error_u_tab convergence_synthesis["Numerical_error_pressure"]=error_p_tab convergence_synthesis["Max_vel_norm"]=max_vel convergence_synthesis["Final_time"]=t_final convergence_synthesis["Final_time_step"]=ndt_final convergence_synthesis["Scheme_order"]=min(-au,-ap) convergence_synthesis["Scheme_order_vel"]=-au convergence_synthesis["Scheme_order_press"]=-ap convergence_synthesis["Scaling_preconditioner"]="None" convergence_synthesis["Test_color"]=testColor convergence_synthesis["Computational_time"]=end-start with open('Convergence_WaveSystem_3DFV_Upwind_'+mesh_name+'.json', 'w') as outfile: json.dump(convergence_synthesis, outfile)
# Copyright : CEA Saclay 2016 # Description : Utilisation de la méthode des éléménts finis P1 avec champs u et f discrétisés aux noeuds d'un maillage triangulaire # Création et sauvegarde du champ résultant ainsi que du champ second membre en utilisant la librairie CDMATH # Comparaison de la solution numérique avec la solution exacte u=-sin(pi*x)*sin(pi*y) #================================================================================================================================ import cdmath from math import sin, pi, sqrt import numpy as np import matplotlib.pyplot as plt import PV_routines import VTK_routines #Chargement du maillage triangulaire du domaine carré [0,1]x[0,1], définition des bords #======================================================================================= my_mesh = cdmath.Mesh("squareWithTriangles.med") if (my_mesh.getSpaceDimension() != 2 or my_mesh.getMeshDimension() != 2): raise ValueError( "Wrong space or mesh dimension : space and mesh dimensions should be 2" ) if (not my_mesh.isTriangular()): raise ValueError("Wrong cell types : mesh is not made of triangles") eps = 1e-6 my_mesh.setGroupAtPlan(0., 0, eps, "DirichletBorder") #Bord GAUCHE my_mesh.setGroupAtPlan(1., 0, eps, "DirichletBorder") #Bord DROIT my_mesh.setGroupAtPlan(0., 1, eps, "DirichletBorder") #Bord BAS my_mesh.setGroupAtPlan(1., 1, eps, "DirichletBorder") #Bord HAUT nbNodes = my_mesh.getNumberOfNodes() nbCells = my_mesh.getNumberOfCells()
def solve(filename, resolution, meshType, testColor): start = time.time() test_desc["Mesh_type"] = meshType test_desc["Test_color"] = testColor #Chargement du maillage triangulaire du domaine carré [0,1]x[0,1], définition des bords #======================================================================================= my_mesh = cdmath.Mesh(filename + ".med") if (not my_mesh.isTriangular()): raise ValueError("Wrong cell types : mesh is not made of triangles") eps = 1e-6 my_mesh.setGroupAtPlan(0., 0, eps, "DirichletBorder") #Bord GAUCHE my_mesh.setGroupAtPlan(1., 0, eps, "DirichletBorder") #Bord DROIT my_mesh.setGroupAtPlan(0., 1, eps, "DirichletBorder") #Bord BAS my_mesh.setGroupAtPlan(1., 1, eps, "DirichletBorder") #Bord HAUT nbNodes = my_mesh.getNumberOfNodes() nbCells = my_mesh.getNumberOfCells() test_desc["Space_dimension"] = my_mesh.getSpaceDimension() test_desc["Mesh_dimension"] = my_mesh.getMeshDimension() test_desc["Mesh_number_of_elements"] = my_mesh.getNumberOfNodes() test_desc["Mesh_cell_type"] = my_mesh.getElementTypes() print("Mesh loading done") print("Number of nodes=", nbNodes) print("Number of cells=", nbCells) #Discrétisation du second membre et détermination des noeuds intérieurs #====================================================================== my_RHSfield = cdmath.Field("RHS_field", cdmath.NODES, my_mesh, 1) nbInteriorNodes = 0 nbBoundaryNodes = 0 maxNbNeighbours = 0 #This is to determine the number of non zero coefficients in the sparse finite element rigidity matrix interiorNodes = [] boundaryNodes = [] #parcours des noeuds pour discrétisation du second membre et extraction 1) des noeuds intérieur 2) des noeuds frontière 3) du nb max voisins d'un noeud for i in range(nbNodes): Ni = my_mesh.getNode(i) x = Ni.x() y = Ni.y() my_RHSfield[i] = 2 * pi * pi * sin(pi * x) * sin( pi * y) #mettre la fonction definie au second membre de l'edp if my_mesh.isBorderNode(i): # Détection des noeuds frontière boundaryNodes.append(i) nbBoundaryNodes = nbBoundaryNodes + 1 else: # Détection des noeuds intérieurs interiorNodes.append(i) nbInteriorNodes = nbInteriorNodes + 1 maxNbNeighbours = max( 1 + Ni.getNumberOfCells(), maxNbNeighbours ) #true only in 2D, need a function Ni.getNumberOfNeighbourNodes() test_desc["Mesh_max_number_of_neighbours"] = maxNbNeighbours print("Right hand side discretisation done") print("Number of interior nodes=", nbInteriorNodes) print("Number of boundary nodes=", nbBoundaryNodes) print("Max number of neighbours=", maxNbNeighbours) # Construction de la matrice de rigidité et du vecteur second membre du système linéaire #======================================================================================= Rigidite = cdmath.SparseMatrixPetsc( nbInteriorNodes, nbInteriorNodes, maxNbNeighbours ) # warning : third argument is maximum number of non zero coefficients per line of the matrix RHS = cdmath.Vector(nbInteriorNodes) # Vecteurs gradient de la fonction de forme associée à chaque noeud d'un triangle (hypothèse 2D) GradShapeFunc0 = cdmath.Vector(2) GradShapeFunc1 = cdmath.Vector(2) GradShapeFunc2 = cdmath.Vector(2) #On parcourt les triangles du domaine for i in range(nbCells): Ci = my_mesh.getCell(i) #Contribution à la matrice de rigidité nodeId0 = Ci.getNodeId(0) nodeId1 = Ci.getNodeId(1) nodeId2 = Ci.getNodeId(2) N0 = my_mesh.getNode(nodeId0) N1 = my_mesh.getNode(nodeId1) N2 = my_mesh.getNode(nodeId2) #Formule des gradients voir EF P1 -> calcul déterminants GradShapeFunc0[0] = (N1.y() - N2.y()) / 2 GradShapeFunc0[1] = -(N1.x() - N2.x()) / 2 GradShapeFunc1[0] = -(N0.y() - N2.y()) / 2 GradShapeFunc1[1] = (N0.x() - N2.x()) / 2 GradShapeFunc2[0] = (N0.y() - N1.y()) / 2 GradShapeFunc2[1] = -(N0.x() - N1.x()) / 2 #Création d'un tableau (numéro du noeud, gradient de la fonction de forme GradShapeFuncs = {nodeId0: GradShapeFunc0} GradShapeFuncs[nodeId1] = GradShapeFunc1 GradShapeFuncs[nodeId2] = GradShapeFunc2 # Remplissage de la matrice de rigidité et du second membre for j in [nodeId0, nodeId1, nodeId2]: if boundaryNodes.count( j ) == 0: #seuls les noeuds intérieurs contribuent au système linéaire (matrice de rigidité et second membre) j_int = interiorNodes.index( j) #indice du noeud j en tant que noeud intérieur #Ajout de la contribution de la cellule triangulaire i au second membre du noeud j RHS[j_int] = Ci.getMeasure() / 3 * my_RHSfield[j] + RHS[ j_int] # intégrale dans le triangle du produit f x fonction de base #Contribution de la cellule triangulaire i à la ligne j_int du système linéaire for k in [nodeId0, nodeId1, nodeId2]: if boundaryNodes.count( k ) == 0: #seuls les noeuds intérieurs contribuent à la matrice du système linéaire k_int = interiorNodes.index( k) #indice du noeud k en tant que noeud intérieur Rigidite.addValue( j_int, k_int, GradShapeFuncs[j] * GradShapeFuncs[k] / Ci.getMeasure()) #else: si condition limite non nulle au bord, ajouter la contribution du bord au second membre de la cellule j print("Linear system matrix building done") # Résolution du système linéaire #================================= LS = cdmath.LinearSolver( Rigidite, RHS, 100, 1.E-6, "CG", "ILU") #Remplacer CG par CHOLESKY pour solveur direct LS.setComputeConditionNumber() SolSyst = LS.solve() print "Preconditioner used : ", LS.getNameOfPc() print "Number of iterations used : ", LS.getNumberOfIter() print("Linear system solved") test_desc["Linear_solver_algorithm"] = LS.getNameOfMethod() test_desc["Linear_solver_preconditioner"] = LS.getNameOfPc() test_desc["Linear_solver_precision"] = LS.getTolerance() test_desc["Linear_solver_maximum_iterations"] = LS.getNumberMaxOfIter() test_desc[ "Linear_system_max_actual_iterations_number"] = LS.getNumberOfIter() test_desc["Linear_system_max_actual_error"] = LS.getResidu() test_desc[ "Linear_system_max_actual_condition number"] = LS.getConditionNumber() # Création du champ résultat #=========================== my_ResultField = cdmath.Field("ResultField", cdmath.NODES, my_mesh, 1) for j in range(nbInteriorNodes): my_ResultField[interiorNodes[j]] = SolSyst[j] #remplissage des valeurs pour les noeuds intérieurs for j in range(nbBoundaryNodes): my_ResultField[boundaryNodes[j]] = 0 #remplissage des valeurs pour les noeuds frontière (condition limite) #sauvegarde sur le disque dur du résultat dans un fichier paraview my_ResultField.writeVTK("FiniteElements2D_SQUARE_" + meshType + str(nbNodes)) print( "Numerical solution of 2D Poisson equation on a square using finite elements done" ) end = time.time() #Calcul de l'erreur commise par rapport à la solution exacte #=========================================================== #The following formulas use the fact that the exact solution is equal the right hand side divided by 2*pi*pi max_abs_sol_exacte = max(my_RHSfield.max(), -my_RHSfield.min()) / (2 * pi * pi) max_sol_num = my_ResultField.max() min_sol_num = my_ResultField.min() erreur_abs = 0 for i in range(nbNodes): if erreur_abs < abs(my_RHSfield[i] / (2 * pi * pi) - my_ResultField[i]): erreur_abs = abs(my_RHSfield[i] / (2 * pi * pi) - my_ResultField[i]) print( "Relative error = max(| exact solution - numerical solution |)/max(| exact solution |) = ", erreur_abs / max_abs_sol_exacte) print("Maximum numerical solution = ", max_sol_num, " Minimum numerical solution = ", min_sol_num) #Postprocessing : #================ # Extraction of the diagonal data diag_data = VTK_routines.Extract_field_data_over_line_to_numpyArray( my_ResultField, [0, 1, 0], [1, 0, 0], resolution) # save 2D picture PV_routines.Save_PV_data_to_picture_file( "FiniteElements2D_SQUARE_" + meshType + str(nbNodes) + '_0.vtu', "ResultField", 'NODES', "FiniteElements2D_SQUARE_" + meshType + str(nbNodes)) test_desc["Computational_time_taken_by_run"] = end - start test_desc["Absolute_error"] = erreur_abs test_desc["Relative_error"] = erreur_abs / max_abs_sol_exacte with open( 'test_Poisson' + str(my_mesh.getMeshDimension()) + 'D_EF_' + "SQUARE_" + meshType + str(nbCells) + "Cells.json", 'w') as outfile: json.dump(test_desc, outfile) return erreur_abs / max_abs_sol_exacte, nbNodes, diag_data, min_sol_num, max_sol_num, end - start
def test_validation2DWaveSystemCentered_squares(scaling): start = time.time() #### 2D square mesh meshList = [7, 15, 31, 51] #,81,101 #meshList=['squareWithSquares_1','squareWithSquares_2','squareWithSquares_3','squareWithSquares_4','squareWithSquares_5'] mesh_path = '../../../ressources/2DCartesien/' meshType = "Regular squares" testColor = "Green" nbMeshes = len(meshList) mesh_size_tab = [0] * nbMeshes mesh_name = 'squareWithSquares' resolution = 100 curv_abs = np.linspace(0, sqrt(2), resolution + 1) error_p_tab = [0] * nbMeshes error_u_tab = [0] * nbMeshes diag_data_press = [0] * nbMeshes diag_data_vel = [0] * nbMeshes time_tab = [0] * nbMeshes t_final = [0] * nbMeshes ndt_final = [0] * nbMeshes max_vel = [0] * nbMeshes cond_number = [0] * nbMeshes plt.close('all') i = 0 cfl = 0.5 # Storing of numerical errors, mesh sizes and diagonal values #for filename in meshList: for nx in meshList: my_mesh = cdmath.Mesh(0, 1, nx, 0, 1, nx) error_p_tab[i], error_u_tab[i], mesh_size_tab[i], t_final[ i], ndt_final[i], max_vel[i], diag_data_press[i], diag_data_vel[ i], time_tab[i], cond_number[i] = WaveSystemCentered.solve( my_mesh, "square" + str(nx) + 'x' + str(nx), resolution, scaling, meshType, testColor, cfl, "Periodic") #error_p_tab[i], error_u_tab[i], mesh_size_tab[i], t_final[i], ndt_final[i], max_vel[i], diag_data_press[i], diag_data_vel[i], time_tab[i], cond_number[i] =WaveSystemCentered.solve_file(mesh_path+filename, mesh_name, resolution,scaling,meshType,testColor,cfl) assert max_vel[i] > 0.8 and max_vel[i] < 1.03 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() # Plot over diagonal line for i in range(nbMeshes): if (scaling == 0): plt.plot(curv_abs, diag_data_press[i], label=str(mesh_size_tab[i]) + ' cells - no scaling') else: plt.plot(curv_abs, diag_data_press[i], label=str(mesh_size_tab[i]) + ' cells - with scaling') plt.legend() plt.xlabel('Position on diagonal line') plt.ylabel('Pressure on diagonal line') plt.title( 'Plot over diagonal line for stationary wave system \n with centered scheme on 2D square meshes' ) plt.savefig(mesh_name + '_Pressure_2DWaveSystemCentered_' + "scaling" + str(scaling) + "_PlotOverDiagonalLine.png") plt.close() plt.clf() for i in range(nbMeshes): if (scaling == 0): plt.plot(curv_abs, diag_data_vel[i], label=str(mesh_size_tab[i]) + ' cells - no scaling') else: plt.plot(curv_abs, diag_data_vel[i], label=str(mesh_size_tab[i]) + ' cells - with scaling') plt.legend() plt.xlabel('Position on diagonal line') plt.ylabel('Velocity on diagonal line') plt.title( 'Plot over diagonal line for the stationary wave system \n with centered scheme on 2D square meshes' ) plt.savefig(mesh_name + "_Velocity_2DWaveSystemCentered_" + "scaling" + str(scaling) + "_PlotOverDiagonalLine.png") plt.close() # Plot of number of time steps plt.close() if (scaling == 0): plt.plot( mesh_size_tab, ndt_final, label='Number of time step to reach stationary regime - no scaling' ) else: plt.plot( mesh_size_tab, ndt_final, label= 'Number of time step to reach stationary regime - with scaling') plt.legend() plt.xlabel('Number of cells') plt.ylabel('Max time steps for stationary regime') plt.title( 'Number of times steps required for the stationary Wave System \n with centered scheme on 2D square meshes' ) plt.savefig(mesh_name + "_2DWaveSystemCentered_" + "scaling" + str(scaling) + "_TimeSteps.png") # Plot of number of stationary time plt.close() if (scaling == 0): plt.plot(mesh_size_tab, t_final, label='Time where stationary regime is reached - no scaling') else: plt.plot( mesh_size_tab, t_final, label='Time where stationary regime is reached - with scaling') plt.legend() plt.xlabel('Number of cells') plt.ylabel('Max time for stationary regime') plt.title( 'Simulated time for the stationary Wave System \n with centered scheme on 2D square meshes' ) plt.savefig(mesh_name + "_2DWaveSystemCentered_" + "scaling" + str(scaling) + "_FinalTime.png") # Plot of number of maximal velocity norm plt.close() if (scaling == 0): plt.plot(mesh_size_tab, max_vel, label='Maximum velocity norm - no scaling') else: plt.plot(mesh_size_tab, max_vel, label='Maximum velocity norm - with scaling') plt.legend() plt.xlabel('Number of cells') plt.ylabel('Max velocity norm') plt.title( 'Maximum velocity norm for the stationary Wave System \n with centered scheme on 2D square meshes' ) plt.savefig(mesh_name + "_2DWaveSystemCentered_" + "scaling" + str(scaling) + "_MaxVelNorm.png") # Plot of condition number plt.close() if (scaling == 0): plt.plot(mesh_size_tab, cond_number, label='Condition number - no scaling') else: plt.plot(mesh_size_tab, cond_number, label='Condition number - with scaling') plt.legend() plt.xlabel('Number of cells') plt.ylabel('Condition number') plt.title( 'Condition number for the stationary Wave System \n with centered scheme on 2D square meshes' ) plt.savefig(mesh_name + "_2DWaveSystemCentered_" + "scaling" + str(scaling) + "_condition_number.png") for i in range(nbMeshes): mesh_size_tab[i] = 0.5 * 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_validation2DWaveSystemSquaresFVCentered_squares() : Make sure you use distinct meshes and at least two meshes' b1p = np.dot(error_p_tab, mesh_size_tab) b2p = np.sum(error_p_tab) ap = (a3 * b1p - a2 * b2p) / det bp = (-a2 * b1p + a1 * b2p) / det if (scaling == 0): print( "FV Centered on 2D square meshes : scheme order for pressure without scaling is ", -ap) else: print( "FV Centered on 2D square meshes : scheme order for pressure with scaling is ", -ap) b1u = np.dot(error_u_tab, mesh_size_tab) b2u = np.sum(error_u_tab) au = (a3 * b1u - a2 * b2u) / det bu = (-a2 * b1u + a1 * b2u) / det if (scaling == 0): print( "FV Centered on 2D square meshes : scheme order for velocity without scaling is ", -au) else: print( "FV Centered on 2D square meshes : scheme order for velocity with scaling is ", -au) # Plot of convergence curves plt.close() if (scaling == 0): plt.plot(mesh_size_tab, error_p_tab, label='|error on stationary pressure| - no scaling') else: plt.plot(mesh_size_tab, error_p_tab, label='|error on stationary pressure| - with scaling') plt.legend() plt.xlabel('1/2 log(number of cells)') plt.ylabel('log(|error p|)') plt.title( 'Convergence of finite volumes for the stationary Wave System \n with centered scheme on 2D square meshes' ) plt.savefig(mesh_name + "_Pressure_2DWaveSystemCentered_" + "scaling" + str(scaling) + "_ConvergenceCurve.png") plt.close() if (scaling == 0): plt.plot(mesh_size_tab, error_u_tab, label='log(|error on stationary velocity|) - no scaling') else: plt.plot(mesh_size_tab, error_u_tab, label='log(|error on stationary velocity|) - with scaling') plt.legend() plt.xlabel('1/2 log(number of cells)') plt.ylabel('log(|error u|)') plt.title( 'Convergence of finite volumes for the stationary Wave System \n with centered scheme on 2D square meshes' ) plt.savefig(mesh_name + "_Velocity_2DWaveSystemCentered_" + "scaling" + str(scaling) + "_ConvergenceCurve.png") # Plot of computational time plt.close() if (scaling == 0): plt.plot(mesh_size_tab, time_tab, label='log(cpu time) - no scaling') else: plt.plot(mesh_size_tab, time_tab, label='log(cpu time) - with scaling') plt.legend() plt.xlabel('1/2 log(number of cells)') plt.ylabel('log(cpu time)') plt.title( 'Computational time of finite volumes for the stationary Wave System \n with centered scheme on 2D square meshes' ) plt.savefig(mesh_name + "2DWaveSystemCentered_" + "scaling" + str(scaling) + "_ComputationalTimeSquares.png") plt.close('all') convergence_synthesis = {} convergence_synthesis["PDE_model"] = "Wave system" convergence_synthesis["PDE_is_stationary"] = False convergence_synthesis["PDE_search_for_stationary_solution"] = True if (scaling == 0): convergence_synthesis[ "Numerical_method_name"] = "Centered scheme no scaling" else: convergence_synthesis[ "Numerical_method_name"] = "Centered scheme scaling" convergence_synthesis[ "Numerical_method_space_discretization"] = "Finite volumes" convergence_synthesis["Numerical_method_time_discretization"] = "Implicit" convergence_synthesis[ "Initial_data"] = "Constant pressure, divergence free velocity" 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_path"] = mesh_path convergence_synthesis["Mesh_description"] = mesh_name convergence_synthesis["Mesh_sizes"] = mesh_size_tab convergence_synthesis["Mesh_cell_type"] = "Squares" convergence_synthesis["Numerical_error_velocity"] = error_u_tab convergence_synthesis["Numerical_error_pressure"] = error_p_tab convergence_synthesis["Max_vel_norm"] = max_vel convergence_synthesis["Final_time"] = t_final convergence_synthesis["Final_time_step"] = ndt_final convergence_synthesis["Scheme_order"] = min(-au, -ap) convergence_synthesis["Scheme_order_vel"] = -au convergence_synthesis["Scheme_order_press"] = -ap convergence_synthesis["Scaling_preconditioner"] = scaling convergence_synthesis["Condition_numbers"] = cond_number convergence_synthesis["Test_color"] = testColor convergence_synthesis["Computational_time"] = end - start with open('Convergence_WaveSystem_2DFV_Centered_' + mesh_name + '.json', 'w') as outfile: json.dump(convergence_synthesis, outfile)
for i in range(len(values)-1): matrices[i] = M.deepCopy() for j in range(len(values)): matrices[i][j,i] = values[j] result = cdmath.Vector(len(values)-1) for i in range(len(values)-1): result[i] = matrices[i].determinant() return result #Chargement du maillage triangulaire du carré unité #======================================================================================= meshName="squareWithTriangles" my_mesh = cdmath.Mesh(meshName+".med") if( my_mesh.getSpaceDimension()!=2 or my_mesh.getMeshDimension()!=2) : raise ValueError("Wrong space or mesh dimension : space and mesh dimensions should be 2") if(not my_mesh.isTriangular()) : raise ValueError("Wrong cell types : mesh is not made of triangles") nbNodes = my_mesh.getNumberOfNodes() nbCells = my_mesh.getNumberOfCells() print("Mesh loading done") print("Number of nodes=", nbNodes) print("Number of cells=", nbCells) #Détermination des noeuds intérieurs #====================================================================== my_ExactSol = cdmath.Field("Exact_field", cdmath.NODES, my_mesh, 1)
def solve(filename,resolution,meshName, testColor): start = time.time() test_desc["Mesh_name"]=meshName test_desc["Test_color"]=testColor #Chargement du maillage triangulaire du carré unité [0,1]x[0,1] #================================================================ my_mesh = cdmath.Mesh(filename+".med") if( my_mesh.getSpaceDimension()!=2 or my_mesh.getMeshDimension()!=2) : raise ValueError("Wrong space or mesh dimension : space and mesh dimensions should be 2") if(not my_mesh.isTriangular()) : raise ValueError("Wrong cell types : mesh is not made of triangles") nbNodes = my_mesh.getNumberOfNodes() nbCells = my_mesh.getNumberOfCells() test_desc["Space_dimension"]=my_mesh.getSpaceDimension() test_desc["Mesh_dimension"]=my_mesh.getMeshDimension() test_desc["Mesh_number_of_elements"]=my_mesh.getNumberOfNodes() test_desc["Mesh_cell_type"]=my_mesh.getElementTypesNames() print("Mesh loading done") print("Number of nodes=", nbNodes) print("Number of cells=", nbCells) #Détermination des noeuds intérieurs #=================================== my_ExactSol = cdmath.Field("Exact_field", cdmath.NODES, my_mesh, 1) nbInteriorNodes = 0 nbBoundaryNodes = 0 maxNbNeighbours = 0#This is to determine the number of non zero coefficients in the sparse finite element rigidity matrix interiorNodes=[] boundaryNodes=[] eps=1e-6 #parcours des noeuds pour discrétisation du second membre et extraction 1) des noeuds intérieur 2) des noeuds frontière 3) du nb max voisins d'un noeud for i in range(nbNodes): Ni=my_mesh.getNode(i) x = Ni.x() y = Ni.y() #Robust calculation of atan((x*x-y*y)/(2*x*y)) if x<-eps or x>1+eps or y<-eps or y>1+eps : print("!!! Warning Mesh ", meshName," !!! Node is not in the unit square.",", eps=",eps, ", x= ",x, ", y= ",y) #raise ValueError("!!! Domain should be the unit square.") if abs(x*y) > eps : my_ExactSol[i] = atan((x*x-y*y)/(2*x*y)) elif x**2-y**2>0 : my_ExactSol[i] = pi/2 elif x**2-y**2<0 : my_ExactSol[i] = -pi/2 else : #x=0 my_ExactSol[i] = 0 if my_mesh.isBorderNode(i): # Détection des noeuds frontière boundaryNodes.append(i) nbBoundaryNodes=nbBoundaryNodes+1 else: # Détection des noeuds intérieurs interiorNodes.append(i) nbInteriorNodes=nbInteriorNodes+1 maxNbNeighbours= max(1+Ni.getNumberOfCells(),maxNbNeighbours) #true only in 2D, need a function Ni.getNumberOfNeighbourNodes() test_desc["Mesh_max_number_of_neighbours"]=maxNbNeighbours print("Right hand side discretisation done") print("Number of interior nodes=", nbInteriorNodes) print("Number of boundary nodes=", nbBoundaryNodes) print("Max number of neighbours=", maxNbNeighbours) # Construction de la matrice de rigidité et du vecteur second membre du système linéaire #======================================================================================= Rigidite=cdmath.SparseMatrixPetsc(nbInteriorNodes,nbInteriorNodes,maxNbNeighbours) # warning : third argument is maximum number of non zero coefficients per line of the matrix RHS=cdmath.Vector(nbInteriorNodes) M=cdmath.Matrix(3,3) # Vecteurs gradient de la fonction de forme associée à chaque noeud d'un triangle (hypothèse 2D) GradShapeFunc0=cdmath.Vector(2) GradShapeFunc1=cdmath.Vector(2) GradShapeFunc2=cdmath.Vector(2) #On parcourt les triangles du domaine for i in range(nbCells): Ci=my_mesh.getCell(i) #Contribution à la matrice de rigidité nodeId0=Ci.getNodeId(0) nodeId1=Ci.getNodeId(1) nodeId2=Ci.getNodeId(2) N0=my_mesh.getNode(nodeId0) N1=my_mesh.getNode(nodeId1) N2=my_mesh.getNode(nodeId2) M[0,0]=N0.x() M[0,1]=N0.y() M[0,2]=1 M[1,0]=N1.x() M[1,1]=N1.y() M[1,2]=1 M[2,0]=N2.x() M[2,1]=N2.y() M[2,2]=1 #Values of each shape function at each node values0=[1,0,0] values1=[0,1,0] values2=[0,0,1] GradShapeFunc0 = gradientNodal(M,values0)/2 GradShapeFunc1 = gradientNodal(M,values1)/2 GradShapeFunc2 = gradientNodal(M,values2)/2 #Création d'un tableau (numéro du noeud, gradient de la fonction de forme) GradShapeFuncs={nodeId0 : GradShapeFunc0} GradShapeFuncs[nodeId1]=GradShapeFunc1 GradShapeFuncs[nodeId2]=GradShapeFunc2 # Remplissage de la matrice de rigidité et du second membre for j in [nodeId0,nodeId1,nodeId2] : if boundaryNodes.count(j)==0 : #seuls les noeuds intérieurs contribuent au système linéaire (matrice de rigidité et second membre) j_int=interiorNodes.index(j)#indice du noeud j en tant que noeud intérieur #Pas de contribution au second membre car pas de terme source boundaryContributionAdded=False#Needed in case j is a border cell #Contribution de la cellule triangulaire i à la ligne j_int du système linéaire for k in [nodeId0,nodeId1,nodeId2] : if boundaryNodes.count(k)==0 : #seuls les noeuds intérieurs contribuent à la matrice du système linéaire k_int=interiorNodes.index(k)#indice du noeud k en tant que noeud intérieur Rigidite.addValue(j_int,k_int,GradShapeFuncs[j]*GradShapeFuncs[k]/Ci.getMeasure()) elif boundaryContributionAdded == False: #si condition limite non nulle au bord (ou maillage non recouvrant), ajouter la contribution du bord au second membre de la cellule j if boundaryNodes.count(nodeId0)!=0 : u0=my_ExactSol[nodeId0] else: u0=0 if boundaryNodes.count(nodeId1)!=0 : u1=my_ExactSol[nodeId1] else: u1=0 if boundaryNodes.count(nodeId2)!=0 : u2=my_ExactSol[nodeId2] else: u2=0 boundaryContributionAdded=True#Contribution from the boundary to matrix line j is done in one step GradGh = gradientNodal(M,[u0,u1,u2])/2 RHS[j_int] += -(GradGh*GradShapeFuncs[j])/Ci.getMeasure() print("Linear system matrix building done") # Résolution du système linéaire #================================= LS=cdmath.LinearSolver(Rigidite,RHS,100,1.E-6,"CG","LU")#Remplacer CG par CHOLESKY pour solveur direct LS.setComputeConditionNumber() SolSyst=LS.solve() print( "Preconditioner used : ", LS.getNameOfPc() ) print( "Number of iterations used : ", LS.getNumberOfIter() ) print("Linear system solved") test_desc["Linear_solver_algorithm"]=LS.getNameOfMethod() test_desc["Linear_solver_preconditioner"]=LS.getNameOfPc() test_desc["Linear_solver_precision"]=LS.getTolerance() test_desc["Linear_solver_maximum_iterations"]=LS.getNumberMaxOfIter() test_desc["Linear_system_max_actual_iterations_number"]=LS.getNumberOfIter() test_desc["Linear_system_max_actual_error"]=LS.getResidu() test_desc["Linear_system_max_actual_condition number"]=LS.getConditionNumber() # Création du champ résultat #=========================== my_ResultField = cdmath.Field("ResultField", cdmath.NODES, my_mesh, 1) for j in range(nbInteriorNodes): my_ResultField[interiorNodes[j]]=SolSyst[j];#remplissage des valeurs pour les noeuds intérieurs for j in range(nbBoundaryNodes): my_ResultField[boundaryNodes[j]]=my_ExactSol[boundaryNodes[j]];#remplissage des valeurs pour les noeuds frontière (condition limite) #sauvegarde sur le disque dur du résultat dans un fichier paraview my_ResultField.writeVTK("FiniteElements2DPoissonStiffBC_SQUARE_"+meshName+str(nbNodes)) print("Numerical solution of 2D Poisson equation on a square using finite elements done") end = time.time() #Calcul de l'erreur commise par rapport à la solution exacte #=========================================================== l2_norm_sol_exacte=my_ExactSol.normL2()[0] l2_error = (my_ExactSol - my_ResultField).normL2()[0] print("L2 relative error = norm( exact solution - numerical solution )/norm( exact solution ) = ", l2_error/l2_norm_sol_exacte) print("Maximum numerical solution = ", my_ResultField.max(), " Minimum numerical solution = ", my_ResultField.min()) print("Maximum exact solution = ", my_ExactSol.max(), " Minimum exact solution = ", my_ExactSol.min()) #Postprocessing : #================ # Extraction of the diagonal data diag_data=VTK_routines.Extract_field_data_over_line_to_numpyArray(my_ResultField,[0,0,0],[1,1,0], resolution) # save 2D picture PV_routines.Save_PV_data_to_picture_file("FiniteElements2DPoissonStiffBC_SQUARE_"+meshName+str(nbNodes)+'_0.vtu',"ResultField",'NODES',"FiniteElements2DPoissonStiffBC_SQUARE_"+meshName+str(nbNodes)) test_desc["Computational_time_taken_by_run"]=end-start test_desc["Absolute_error"]=l2_error test_desc["Relative_error"]=l2_error/l2_norm_sol_exacte with open('test_PoissonStiffBC'+str(my_mesh.getMeshDimension())+'D_EF_'+"SQUARE_"+meshName+str(nbCells)+ "Cells.json", 'w') as outfile: json.dump(test_desc, outfile) return l2_error/l2_norm_sol_exacte, nbNodes, diag_data, my_ResultField.min(), my_ResultField.max(), end - start
def test_validation2DVF_long_rectangles(): start = time.time() ### 2D FV long rectangles mesh meshList=[5,11,21,31] #meshList=['squareWithFlatTriangles_0','squareWithLongRectangles_1','squareWithLongRectangles_2','squareWithLongRectangles_3','squareWithLongRectangles_4','squareWithLongRectangles_5'] mesh_path='../../../ressources/2DLongRectangles/' meshType="Regular_long_rectangles" testColor="Green" nbMeshes=len(meshList) error_tab=[0]*nbMeshes mesh_size_tab=[0]*nbMeshes mesh_name='squareWithLongRectangles' diag_data=[0]*nbMeshes time_tab=[0]*nbMeshes resolution=100 curv_abs=np.linspace(0,sqrt(2),resolution+1) plt.close('all') i=0 # Storing of numerical errors, mesh sizes and diagonal values #for filename in meshList: for nx in meshList: my_mesh=cdmath.Mesh(0,1,nx,0,1,nx*nx) error_tab[i], mesh_size_tab[i], diag_data[i], min_sol_num, max_sol_num, time_tab[i] =FiniteVolumes2DPoisson_SQUARE.solve(my_mesh,str(nx)+'x'+str(nx),resolution,meshType,testColor) # error_tab[i], mesh_size_tab[i], diag_data[i], min_sol_num, max_sol_num, time_tab[i] =FiniteVolumes2DPoisson_SQUARE.solve_file(mesh_path+filename,resolution,meshType,testColor) assert min_sol_num>-0.01 assert max_sol_num<1.2 plt.plot(curv_abs, diag_data[i], label= str(mesh_size_tab[i]) + ' cells') error_tab[i]=log10(error_tab[i]) time_tab[i]=log10(time_tab[i]) mesh_size_tab[i] = 0.5*log10(mesh_size_tab[i]) i=i+1 end = time.time() # Plot over diagonal line plt.legend() plt.xlabel('Position on diagonal line') plt.ylabel('Value on diagonal line') plt.title('Plot over diagonal line for finite volumes \n for Laplace operator on 2D long rectangles meshes') plt.savefig(mesh_name+"_2DPoissonFV_PlotOverDiagonalLine.png") # 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 b1=np.dot(error_tab,mesh_size_tab) b2=np.sum(error_tab) det=a1*a3-a2*a2 assert det!=0, 'test_validation2DVF_long_rectangles() : Make sure you use distinct meshes and at least two meshes' a=( a3*b1-a2*b2)/det b=(-a2*b1+a1*b2)/det print "FV on 2D long rectangles mesh : scheme order is ", -a assert abs(a+1.33)<0.1 # Plot of convergence curve plt.close() plt.plot(mesh_size_tab, error_tab, label='log(|numerical-exact|)') plt.plot(mesh_size_tab, a*np.array(mesh_size_tab)+b,label='least square slope : '+'%.3f' % a) plt.legend() plt.plot(mesh_size_tab, error_tab) plt.xlabel('log(sqrt(number of cells))') plt.ylabel('log(error)') plt.title('Convergence of finite volumes for \n Laplace operator on 2D long rectangles meshes') plt.savefig(mesh_name+"_2DPoissonFV_ConvergenceCurve.png") # Plot of computational time plt.close() plt.plot(mesh_size_tab, time_tab, label='log(cpu time)') plt.legend() plt.xlabel('log(sqrt(number of cells))') plt.ylabel('log(cpu time)') plt.title('Computational time of finite volumes \n for Laplace operator on 2D long rectangles meshes') plt.savefig(mesh_name+"_2DPoissonFV_ComputationalTime.png") plt.close('all') convergence_synthesis["Mesh_names"]=meshList convergence_synthesis["Mesh_type"]=meshType convergence_synthesis["Mesh_path"]=mesh_path convergence_synthesis["Mesh_description"]=mesh_name convergence_synthesis["Mesh_sizes"]=[10**x for x in mesh_size_tab] convergence_synthesis["Space_dimension"]=2 convergence_synthesis["Mesh_dimension"]=2 convergence_synthesis["Mesh_cell_type"]="Long rectangles" convergence_synthesis["Errors"]=[10**x for x in error_tab] convergence_synthesis["Scheme_order"]=-a convergence_synthesis["Test_color"]=testColor convergence_synthesis["Computational_time"]=end-start with open('Convergence_Poisson_2DVF_'+mesh_name+'.json', 'w') as outfile: json.dump(convergence_synthesis, outfile) import os os.system("jupyter-nbconvert --to notebook --execute Convergence_Poisson_FV5_SQUARE_long_rectangles.ipynb") os.system("jupyter-nbconvert --to html Convergence_Poisson_FV5_SQUARE_long_rectangles.ipynb") os.system("jupyter-nbconvert --to pdf Convergence_Poisson_FV5_SQUARE_long_rectangles.ipynb")
# Copyright : CEA Saclay 2016 # Description : Utilisation de la méthode des volumes finis avec champs u et f discrétisés aux cellules d'un maillage quelconque # Création et sauvegarde du champ résultant ainsi que du champ second membre en utilisant CDMATH # Comparaison de la solution numérique avec la solution exacte u=sin(pi*x)*sin(pi*y) #================================================================================================================================ import cdmath from math import sin, pi, sqrt import numpy as np import matplotlib.pyplot as plt import PV_routines import VTK_routines import sys if len(sys.argv) > 1: #non rectangular mesh my_mesh = cdmath.Mesh(sys.argv[1]) else: #rectangular mesh # Création d'un maillage cartésien du domaine carré [0,1]x[0,1], définition des bords #==================================================================================== xmin = 0 xmax = 1 ymin = 0 ymax = 1 nx = 15 ny = 15 my_mesh = cdmath.Mesh(xmin, xmax, nx, ymin, ymax, ny) eps = 1e-6 my_mesh.setGroupAtPlan(0, 0, eps, "DirichletBorder") #Bord GAUCHE
# Copyright : CEA Saclay 2018 # Description : Utilisation de la méthode des éléménts finis P1 avec champs u et f discrétisés aux noeuds d'un maillage triangulaire # Création et sauvegarde du champ résultant ainsi que du champ second membre en utilisant la librairie CDMATH # Référence : M. A. Olshanskii, A. Reusken, and J. Grande. A finite element method for elliptic equations # on surfaces. SIAM J. Num. Anal., 47, p. 3355 #================================================================================================================================ import cdmath from math import sin, cos, atan2, sqrt import PV_routines import VTK_routines import paraview.simple as pvs #Chargement du maillage triangulaire du tore #======================================================================================= my_mesh = cdmath.Mesh("meshTorus.med") if(not my_mesh.isTriangular()) : raise ValueError("Wrong cell types : mesh is not made of triangles") if(my_mesh.getMeshDimension()!=2) : raise ValueError("Wrong mesh dimension : expected a surface of dimension 2") if(my_mesh.getSpaceDimension()!=3) : raise ValueError("Wrong space dimension : expected a space of dimension 3") nbNodes = my_mesh.getNumberOfNodes() nbCells = my_mesh.getNumberOfCells() print("Mesh building/loading done") print("nb of nodes=", nbNodes) print("nb of cells=", nbCells) # Torus radii (calculation will fail if the mesh is not correct)
def solve_file( filename,meshName, resolution,meshType, testColor,cfl,test_bc,with_source=False): my_mesh = cdmath.Mesh(filename+".med")
def solve(filename, resolution, meshType, testColor): start = time.time() test_desc["Mesh_type"] = meshType test_desc["Test_color"] = testColor #Chargement du maillage triangulaire de la sphère #======================================================================================= my_mesh = cdmath.Mesh(filename + ".med") if (not my_mesh.isTriangular()): raise ValueError("Wrong cell types : mesh is not made of triangles") if (my_mesh.getMeshDimension() != 2): raise ValueError( "Wrong mesh dimension : expected a surface of dimension 2") if (my_mesh.getSpaceDimension() != 3): raise ValueError( "Wrong space dimension : expected a space of dimension 3") nbNodes = my_mesh.getNumberOfNodes() nbCells = my_mesh.getNumberOfCells() test_desc["Space_dimension"] = my_mesh.getSpaceDimension() test_desc["Mesh_dimension"] = my_mesh.getMeshDimension() test_desc["Mesh_number_of_elements"] = my_mesh.getNumberOfNodes() test_desc["Mesh_cell_type"] = my_mesh.getElementTypes() print("Mesh building/loading done") print("nb of nodes=", nbNodes) print("nb of cells=", nbCells) #Discrétisation du second membre et détermination des noeuds intérieurs #====================================================================== my_RHSfield = cdmath.Field("RHS_field", cdmath.NODES, my_mesh, 1) maxNbNeighbours = 0 #This is to determine the number of non zero coefficients in the sparse finite element rigidity matrix #parcours des noeuds pour discrétisation du second membre et extraction du nb max voisins d'un noeud for i in range(nbNodes): Ni = my_mesh.getNode(i) x = Ni.x() y = Ni.y() z = Ni.z() my_RHSfield[i] = 12 * y * (3 * x * x - y * y) / pow( x * x + y * y + z * z, 3 / 2) #vecteur propre du laplacien sur la sphère if my_mesh.isBorderNode(i): # Détection des noeuds frontière raise ValueError("Mesh should not contain borders") else: maxNbNeighbours = max(1 + Ni.getNumberOfCells(), maxNbNeighbours) test_desc["Mesh_max_number_of_neighbours"] = maxNbNeighbours print("Right hand side discretisation done") print("Max nb of neighbours=", maxNbNeighbours) print("Integral of the RHS", my_RHSfield.integral(0)) # Construction de la matrice de rigidité et du vecteur second membre du système linéaire #======================================================================================= Rigidite = cdmath.SparseMatrixPetsc( nbNodes, nbNodes, maxNbNeighbours ) # warning : third argument is number of non zero coefficients per line RHS = cdmath.Vector(nbNodes) # Vecteurs gradient de la fonction de forme associée à chaque noeud d'un triangle GradShapeFunc0 = cdmath.Vector(3) GradShapeFunc1 = cdmath.Vector(3) GradShapeFunc2 = cdmath.Vector(3) normalFace0 = cdmath.Vector(3) normalFace1 = cdmath.Vector(3) #On parcourt les triangles du domaine for i in range(nbCells): Ci = my_mesh.getCell(i) #Contribution à la matrice de rigidité nodeId0 = Ci.getNodeId(0) nodeId1 = Ci.getNodeId(1) nodeId2 = Ci.getNodeId(2) N0 = my_mesh.getNode(nodeId0) N1 = my_mesh.getNode(nodeId1) N2 = my_mesh.getNode(nodeId2) #Build normal to cell Ci normalFace0[0] = Ci.getNormalVector(0, 0) normalFace0[1] = Ci.getNormalVector(0, 1) normalFace0[2] = Ci.getNormalVector(0, 2) normalFace1[0] = Ci.getNormalVector(1, 0) normalFace1[1] = Ci.getNormalVector(1, 1) normalFace1[2] = Ci.getNormalVector(1, 2) normalCell = normalFace0.crossProduct(normalFace1) test = normalFace0.tensProduct(normalFace1) normalCell = normalCell / normalCell.norm() cellMat = cdmath.Matrix(4) cellMat[0, 0] = N0.x() cellMat[0, 1] = N0.y() cellMat[0, 2] = N0.z() cellMat[1, 0] = N1.x() cellMat[1, 1] = N1.y() cellMat[1, 2] = N1.z() cellMat[2, 0] = N2.x() cellMat[2, 1] = N2.y() cellMat[2, 2] = N2.z() cellMat[3, 0] = normalCell[0] cellMat[3, 1] = normalCell[1] cellMat[3, 2] = normalCell[2] cellMat[0, 3] = 1 cellMat[1, 3] = 1 cellMat[2, 3] = 1 cellMat[3, 3] = 0 #Formule des gradients voir EF P1 -> calcul déterminants GradShapeFunc0[0] = cellMat.partMatrix(0, 0).determinant() / 2 GradShapeFunc0[1] = -cellMat.partMatrix(0, 1).determinant() / 2 GradShapeFunc0[2] = cellMat.partMatrix(0, 2).determinant() / 2 GradShapeFunc1[0] = -cellMat.partMatrix(1, 0).determinant() / 2 GradShapeFunc1[1] = cellMat.partMatrix(1, 1).determinant() / 2 GradShapeFunc1[2] = -cellMat.partMatrix(1, 2).determinant() / 2 GradShapeFunc2[0] = cellMat.partMatrix(2, 0).determinant() / 2 GradShapeFunc2[1] = -cellMat.partMatrix(2, 1).determinant() / 2 GradShapeFunc2[2] = cellMat.partMatrix(2, 2).determinant() / 2 #Création d'un tableau (numéro du noeud, gradient de la fonction de forme GradShapeFuncs = {nodeId0: GradShapeFunc0} GradShapeFuncs[nodeId1] = GradShapeFunc1 GradShapeFuncs[nodeId2] = GradShapeFunc2 # Remplissage de la matrice de rigidité et du second membre for j in [nodeId0, nodeId1, nodeId2]: #Ajout de la contribution de la cellule triangulaire i au second membre du noeud j RHS[j] = Ci.getMeasure() / 3 * my_RHSfield[j] + RHS[ j] # intégrale dans le triangle du produit f x fonction de base #Contribution de la cellule triangulaire i à la ligne j du système linéaire for k in [nodeId0, nodeId1, nodeId2]: Rigidite.addValue( j, k, GradShapeFuncs[j] * GradShapeFuncs[k] / Ci.getMeasure()) print("Linear system matrix building done") # Résolution du système linéaire #================================= LS = cdmath.LinearSolver( Rigidite, RHS, 100, 1.E-2, "CG", "ILU") #Remplacer CG par CHOLESKY pour solveur direct LS.isSingular() #En raison de l'absence de bord LS.setComputeConditionNumber() SolSyst = LS.solve() print "Preconditioner used : ", LS.getNameOfPc() print "Number of iterations used : ", LS.getNumberOfIter() print "Final residual : ", LS.getResidu() print("Linear system solved") test_desc["Linear_solver_algorithm"] = LS.getNameOfMethod() test_desc["Linear_solver_preconditioner"] = LS.getNameOfPc() test_desc["Linear_solver_precision"] = LS.getTolerance() test_desc["Linear_solver_maximum_iterations"] = LS.getNumberMaxOfIter() test_desc[ "Linear_system_max_actual_iterations_number"] = LS.getNumberOfIter() test_desc["Linear_system_max_actual_error"] = LS.getResidu() test_desc[ "Linear_system_max_actual_condition number"] = LS.getConditionNumber() # Création du champ résultat #=========================== my_ResultField = cdmath.Field("ResultField", cdmath.NODES, my_mesh, 1) for j in range(nbNodes): my_ResultField[j] = SolSyst[j] #remplissage des valeurs pour les noeuds intérieurs #sauvegarde sur le disque dur du résultat dans un fichier paraview my_ResultField.writeVTK("FiniteElementsOnSphere_" + meshType + str(nbNodes)) end = time.time() print("Integral of the numerical solution", my_ResultField.integral(0)) print( "Numerical solution of poisson equation on a sphere using finite elements done" ) #Calcul de l'erreur commise par rapport à la solution exacte #=========================================================== #The following formulas use the fact that the exact solution is equal the right hand side divided by 12 max_abs_sol_exacte = 0 erreur_abs = 0 max_sol_num = 0 min_sol_num = 0 for i in range(nbNodes): if max_abs_sol_exacte < abs(my_RHSfield[i]): max_abs_sol_exacte = abs(my_RHSfield[i]) if erreur_abs < abs(my_RHSfield[i] / 12 - my_ResultField[i]): erreur_abs = abs(my_RHSfield[i] / 12 - my_ResultField[i]) if max_sol_num < my_ResultField[i]: max_sol_num = my_ResultField[i] if min_sol_num > my_ResultField[i]: min_sol_num = my_ResultField[i] max_abs_sol_exacte = max_abs_sol_exacte / 12 print("Absolute error = max(| exact solution - numerical solution |) = ", erreur_abs) print( "Relative error = max(| exact solution - numerical solution |)/max(| exact solution |) = ", erreur_abs / max_abs_sol_exacte) print("Maximum numerical solution = ", max_sol_num, " Minimum numerical solution = ", min_sol_num) test_desc["Computational_time_taken_by_run"] = end - start test_desc["Absolute_error"] = erreur_abs test_desc["Relative_error"] = erreur_abs / max_abs_sol_exacte #Postprocessing : #================ # save 3D picture PV_routines.Save_PV_data_to_picture_file( "FiniteElementsOnSphere_" + meshType + str(nbNodes) + '_0.vtu', "ResultField", 'NODES', "FiniteElementsOnSphere_" + meshType + str(nbNodes)) # save 3D clip VTK_routines.Clip_VTK_data_to_VTK( "FiniteElementsOnSphere_" + meshType + str(nbNodes) + '_0.vtu', "Clip_VTK_data_to_VTK_" + "FiniteElementsOnSphere_" + meshType + str(nbNodes) + '_0.vtu', [0.25, 0.25, 0.25], [-0.5, -0.5, -0.5], resolution) PV_routines.Save_PV_data_to_picture_file( "Clip_VTK_data_to_VTK_" + "FiniteElementsOnSphere_" + meshType + str(nbNodes) + '_0.vtu', "ResultField", 'NODES', "Clip_VTK_data_to_VTK_" + "FiniteElementsOnSphere_" + meshType + str(nbNodes)) # save plot around circumference finiteElementsOnSphere_0vtu = pvs.XMLUnstructuredGridReader(FileName=[ "FiniteElementsOnSphere_" + meshType + str(nbNodes) + '_0.vtu' ]) slice1 = pvs.Slice(Input=finiteElementsOnSphere_0vtu) slice1.SliceType.Normal = [0.5, 0.5, 0.5] renderView1 = pvs.GetActiveViewOrCreate('RenderView') finiteElementsOnSphere_0vtuDisplay = pvs.Show(finiteElementsOnSphere_0vtu, renderView1) pvs.ColorBy(finiteElementsOnSphere_0vtuDisplay, ('POINTS', 'ResultField')) slice1Display = pvs.Show(slice1, renderView1) pvs.SaveScreenshot("./FiniteElementsOnSphere" + "_Slice_" + meshType + str(nbNodes) + '.png', magnification=1, quality=100, view=renderView1) plotOnSortedLines1 = pvs.PlotOnSortedLines(Input=slice1) pvs.SaveData('./FiniteElementsOnSphere_PlotOnSortedLines' + meshType + str(nbNodes) + '.csv', proxy=plotOnSortedLines1) lineChartView2 = pvs.CreateView('XYChartView') plotOnSortedLines1Display = pvs.Show(plotOnSortedLines1, lineChartView2) plotOnSortedLines1Display.UseIndexForXAxis = 0 plotOnSortedLines1Display.XArrayName = 'arc_length' plotOnSortedLines1Display.SeriesVisibility = ['ResultField (1)'] pvs.SaveScreenshot("./FiniteElementsOnSphere" + "_PlotOnSortedLine_" + meshType + str(nbNodes) + '.png', magnification=1, quality=100, view=lineChartView2) pvs.Delete(lineChartView2) with open( 'test_Poisson' + str(my_mesh.getMeshDimension()) + 'D_EF_' + meshType + str(nbCells) + "Cells.json", 'w') as outfile: json.dump(test_desc, outfile) return erreur_abs / max_abs_sol_exacte, nbNodes, min_sol_num, max_sol_num, end - start
def solve_file(filename, resolution, meshType, testColor): my_mesh = cdmath.Mesh(filename + ".med") return solve(my_mesh, filename, resolution, meshType, testColor)
output_freq = 1 WaveSystemVF(ntmax, tmax, cfl, my_mesh, output_freq, meshName, resolution, scaling, test_bc, with_source) return def solve_file(filename, meshName, resolution, scaling, meshType, testColor, cfl, test_bc, with_source=False): my_mesh = cdmath.Mesh(filename + ".med") return solve(my_mesh, meshName + str(my_mesh.getNumberOfCells()), resolution, scaling, meshType, testColor, cfl, test_bc, with_source) if __name__ == """__main__""": M1 = cdmath.Mesh(0., 1., 50, 0., 1., 50) cfl = 0.5 scaling = 0 solve(M1, "SquareRegularSquares", 100, scaling, "RegularSquares", "Green", cfl, "Periodic", False)
# Création et sauvegarde du champ résultant ainsi que du champ second membre en utilisant CDMATH # Comparaison de la solution numérique avec la solution exacte u=-(r-1)*r**2*sin(theta)**2*cos(phi) #================================================================================================================================ import cdmath from math import sin, cos, pi, sqrt, atan2 import numpy as np import matplotlib.pyplot as plt import PV_routines import VTK_routines import sys #Chargement du maillage tétraédrique du domaine cubique [0,1]x[0,1]x[0,1], définition des bords #============================================================================================== my_mesh = cdmath.Mesh("ballWithTetrahedra.med") if( my_mesh.getSpaceDimension()!=3 or my_mesh.getMeshDimension()!=3) : raise ValueError("Wrong space or mesh dimension : space and mesh dimensions should be 3") eps=1e-6 my_mesh.setGroupAtPlan(0,0,eps,"DirichletBorder")#Bord GAUCHE my_mesh.setGroupAtPlan(1,0,eps,"DirichletBorder")#Bord DROIT my_mesh.setGroupAtPlan(0,1,eps,"DirichletBorder")#Bord BAS my_mesh.setGroupAtPlan(1,1,eps,"DirichletBorder")#Bord HAUT my_mesh.setGroupAtPlan(0,2,eps,"DirichletBorder")#Bord AVANT my_mesh.setGroupAtPlan(1,2,eps,"DirichletBorder")#Bord ARRIERE nbCells = my_mesh.getNumberOfCells() print("Mesh loading done") print("Number of cells ", nbCells)
test_desc["Relative_error"] = max(error_p, error_u) with open( 'test_WaveSystem' + str(my_mesh.getMeshDimension()) + 'DCentered_' + meshName + "Cells.json", 'w') as outfile: json.dump(test_desc, outfile) return error_p, error_u, nbCells, t_final, ndt_final, max_vel, diag_data_press, diag_data_vel, end - start, cond_number def solve_file(filename, meshName, resolution, scaling, meshType, testColor, cfl, test_bc): my_mesh = cdmath.Mesh(filename + ".med") return solve(my_mesh, meshName + str(my_mesh.getNumberOfCells()), resolution, scaling, meshType, testColor, cfl, test_bc) if __name__ == """__main__""": M1 = cdmath.Mesh(0., 1., 20, 0., 1., 20) cfl = 0.5 scaling = 0 solve(M1, "SquareRegularSquares", 100, scaling, "Regular_squares", "Green", cfl, "Periodic") M2 = cdmath.Mesh(0., 1., 10, 0., 1., 10, 0., 1., 10, 6) cfl = 1. / 3 scaling = 2 solve(M2, "CubeRegularTetrahedra", 100, scaling, "Regular_tetrahedra", "Green", cfl, "Wall")
def solve_file( filename,meshName, resolution,scaling, meshType, testColor,cfl): my_mesh = cdmath.Mesh(filename+".med") return solve(my_mesh, meshName+str(my_mesh.getNumberOfCells()),resolution,scaling, meshType, testColor,cfl)
import cdmath import analyticalFunction_discretizer as anSol def Density(x): return x * 2 def Pressure(x): return x * 3 var_dict = { 'Density': Density, 'Pressure': Pressure, } xMin = 0, xMax = 1.0, nx = 100 mesh = cdmath.Mesh(xMin, xMax, nx) solution = anSol.analyticalFunction_discretizer(mesh, output_dir="./tmp", var_dict=var_dict) print(solution.var_list) for varName in solution.var_dict: print varName + "=", solution.var_eval[varName] solution.save_all_variables() print "done"
def solve_file( filename,resolution): my_mesh = cdmath.Mesh(filename+".med") solve(my_mesh, filename,resolution)
test_desc["Space_dimension"]=my_mesh.getSpaceDimension() test_desc["Mesh_dimension"]=my_mesh.getMeshDimension() test_desc["Mesh_is_unstructured"]=False test_desc["Mesh_cell_type"]="Quadrangles" test_desc["Mesh_number_of_elements"]=my_mesh.getNumberOfCells() test_desc["Mesh_max_number_of_neighbours"]=2 test_desc["Geometry"]="Interval" test_desc["Boundary_conditions"]=test_bc test_desc["Initial_data"]=test_initial_data test_desc["Part_of_mesh_convergence_analysis"]=True test_desc["Numerical_parameter_cfl"]=cfl test_desc["Simulation_parameter_maximum_time_step"]=ntmax test_desc["Simulation_parameter_maximum_time"]=tmax test_desc["Simulation_output_frequency"]=output_freq test_desc["Simulation_final_time_after_run"]=t_final test_desc["Simulation_final_number_of_time_steps_after_run"]=ndt_final test_desc["Computational_time_taken_by_run"]=end-start test_desc["Part_of_mesh_convergence_analysis"]=True with open('test_Transport'+str(my_mesh.getMeshDimension())+'DFV_'+meshName+ "Cells.json", 'w') as outfile: json.dump(test_desc, outfile) if __name__ == """__main__""": xinf=0 xsup=1 M=cdmath.Mesh(xinf,xsup,50) solve(M,100)