首页/文章/ 详情

如何写出一份“完整”的CFD仿真报告?美国国家航天局NASA如是说

1月前浏览1021

这份文件是美国NASA关于如何分析和编写CFD模拟结果报告的指南。或者说,写一份“完整”的CFD分析报告,要执行哪些动作和写哪些内容

虽然内容是NASA在好些年之前写的,但是今天仍然具有参考作用。

本文前半段将先进行中文总结,后半段给出英文原文(28页,文末有下载方式)。

主要内容包括以下几个方面:

1. 报告CFD模拟结果的几个方面


   


  • 不确定性和误差(Uncertainty and Error
  • 确定和验证(Verification and Validation)
  • 迭代收敛(Iterative Convergence)
  • 网格收敛(Grid Convergence)
  • CFD仿真报告要具备的内容

2. 不确定性和误差 


   


  • 不确定性:由于缺乏知识而可能存在的模型过程中的缺陷。

  • 误差:由于缺乏知识以外的原因而在模型和模拟的任何阶段或活动中存在的可识别缺陷。

3. CFD结果中的误差


   


  • 总误差 = 物理建模误差 + 离散化误差 + 编程误差 + 计算机舍入误差 + 使用误差 + 后处理误差。

  • 物理建模误差通常是已知的,并且可以量化。

  • 离散化误差依赖于网格,但通常缺乏对所需精度的适当网格的先验知识。

4. 确定和验证


   


  • 确定:确定模型实现是否准确代表了开发者对模型的概念描述和模型的解决方案。

  • 验证:确定模型从预期用途的角度来看是否准确代表了现实世界。

5. 迭代收敛和网格收敛


   


  • 迭代收敛:模拟结果应显示迭代收敛。随着算法迭代,模拟结果接近一个固定值(残差下降并趋于平稳)。

  • 网格收敛:随着网格间距的减少,模拟结果变得对网格不敏感,并接近连续结果。

6. CFD结果报告要具备的内容


   


  • CFD分析的目的。

  • 几何简化。

  • 网格分辨率。

  • 边界和初始条件。

  • 方程和物理模型。

  • 算法设置。

  • 迭代收敛标准。

  • 网格收敛标准。

  • 结果(值,图表,可视化)。

  • 可以量化的错误。
  • 对模型和参数(湍流,化学)的敏感性。


以下是部分英文原文:



来源:CFD饭圈
化学湍流航天电子CONVERGE
著作权归作者所有,欢迎分享,未经许可,不得转载
首次发布时间:2024-09-08
最近编辑:1月前
CFD饭圈
硕士 分享CFD文章,感谢关注
获赞 22粉丝 23文章 378课程 0
点赞
收藏
作者推荐

能用ChatGPT写一个CFD求解器吗?

ChatGPT是啥?我就不在这里展开了,因为这是街知巷闻的了。用CFD时使用ChatGPT吗?嗯,你可以在几乎所有项目中使用ChatGPT来满足你的兴趣。但一个大问题是:你对工具有什么期望?正如你们可能知道的,CFD是一个需要广泛经验和比ChatGPT目前能力(至少在目前)更详细建模的复杂主题。然而,你仍然可以使用它来生成2D/3D典型流动的简单CFD求解器。一旦你增加了问题的复杂性,你就必须非常小心地处理你输入给模型的内容(这需要你自己编写代码的经验水平)。我不是说这个工具在这方面没用;我是说为了使用它,你必须有基础水平的知识,成为工具输出给你的内容的一个好的裁判。换句话说,让工具提高你的效率,但不要盲目跟随输出的文本。例如,我让ChatGPT为使用有限差分法(FDM)的层流2D盖驱动腔流编写了一个Python脚本。第一次它给了我一个非常基础的脚本,它不起作用,我不断细化我的输入(通过非常具体地说明代码结构、问题设置和编写解决方案结果的方式)。这是结果:正方形腔盖驱动流动在Paraview中可视化输出vtk文件如下:[代码片段见下面]:importnumpyasnimportsysfromdatetimeimportdatetimeimportdatetimeasdt#clockstartstotickT0=datetime.now()#Definingspatialresolutiondefcreate_mesh(nx,ny,Lx,Ly):dx=Lx/(nx-1)dy=Ly/(ny-1)x=np.linspace(0,Lx,nx)y=np.linspace(0,Ly,ny)X,Y=np.meshgrid(x,y)returnX,Y,dx,dy#Initializingthedomaindefinitial_conditions(X,Y,nx,ny,U_top):U=np.zeros((ny,nx))V=np.zeros((ny,nx))P=np.zeros((ny,nx))U[-1,:]=U_topreturnU,V,P#pressurePoissonequationdefpressure_poisson(P,dx,dy,U,V,rho,dt,n_iter_pressure):P_new=np.copy(P)b=np.zeros_like(P)b[1:-1,1:-1]=(rho*(1/dt*((U[1:-1,2:]-U[1:-1,0:-2])/(2*dx)+(V[2:,1:-1]-V[0:-2,1:-1])/(2*dy))-((U[1:-1,2:]-U[1:-1,0:-2])/(2*dx))**2-2*((U[2:,1:-1]-U[0:-2,1:-1])/(2*dy)*(V[1:-1,2:]-V[1:-1,0:-2])/(2*dx))-((V[2:,1:-1]-V[0:-2,1:-1])/(2*dy))**2))#for_inrange(n_iter_pressure):#P_new[1:-1,1:-1]=(((P[1:-1,2:]+P[1:-1,0:-2])*dy**2+(P[2:,1:-1]+P[0:-2,1:-1])*dx**2)/(2*(dx**2+dy**2))-dx**2*dy**2/(2*(dx**2+dy**2))*b[1:-1,1:-1])#P_new[:,0]=P_new[:,1]#Leftboundary#P_new[:,-1]=P_new[:,-2]#Rightboundary#P_new[0,:]=P_new[1,:]#Bottomboundary#P_new[-1,:]=P_new[-2,:]#Topboundary#Iterateoverthepressuresolverforaspecifiednumberofiterationsfor_inrange(n_iter_pressure):#UpdatethepressurefieldusingthefinitevolumemethodP_new[1:-1,1:-1]=((#Pressurevaluesfromtheneighboringcellsinthexandydirections(P[1:-1,2:]+P[1:-1,0:-2])*dy**2+(P[2:,1:-1]+P[0:-2,1:-1])*dx**2)/(2*(dx**2+dy**2))#Dividebythesumofsquareddistancesinxandydirections-dx**2*dy**2/(2*(dx**2+dy**2))*b[1:-1,1:-1]#Subtractthepressurecorrectionterm)#UpdateboundaryconditionsforpressureP_new[:,0]=P_new[:,1]#LeftboundaryP_new[:,-1]=P_new[:,-2]#RightboundaryP_new[0,:]=P_new[1,:]#BottomboundaryP_new[-1,:]=P_new[-2,:]#TopboundaryreturnP_new#Updatethevelocityfielddefvelocity_field(U,V,P,dx,dy,dt,nu,rho,U_top):U_new=np.copy(U)V_new=np.copy(V)U_new[1:-1,1:-1]=(U[1:-1,1:-1]-U[1:-1,1:-1]*dt/dx*(U[1:-1,1:-1]-U[1:-1,0:-2])-V[1:-1,1:-1]*dt/dy*(U[1:-1,1:-1]-U[0:-2,1:-1])-dt/(2*rho*dx)*(P[1:-1,2:]-P[1:-1,0:-2])+nu*(dt/(dx**2)*(U[1:-1,2:]-2*U[1:-1,1:-1]+U[1:-1,0:-2])+dt/(dy**2)*(U[2:,1:-1]-2*U[1:-1,1:-1]+U[0:-2,1:-1])))V_new[1:-1,1:-1]=(V[1:-1,1:-1]-U[1:-1,1:-1]*dt/dx*(V[1:-1,1:-1]-V[1:-1,0:-2])-V[1:-1,1:-1]*dt/dy*(V[1:-1,1:-1]-V[0:-2,1:-1])-dt/(2*rho*dy)*(P[2:,1:-1]-P[0:-2,1:-1])+nu*(dt/(dx**2)*(V[1:-1,2:]-2*V[1:-1,1:-1]+V[1:-1,0:-2])+dt/(dy**2)*(V[2:,1:-1]-2*V[1:-1,1:-1]+V[0:-2,1:-1])))#BoundaryconditionsU_new[0,:]=0U_new[-1,:]=U_topU_new[:,0]=0U_new[:,-1]=0V_new[0,:]=0V_new[-1,:]=0V_new[:,0]=0V_new[:,-1]=0returnU_new,V_new#contentofVTKfilesforsolutionresultsdefwrite_vtk(X,Y,U,V,P,file_name,nx,ny):withopen(file_name,'w')asf:f.write('#vtkDataFileVersion3.0\n')f.write('2DCavityFlow\n')f.write('ASCII\n')f.write('DATASETSTRUCTURED_GRID\n')f.write('DIMENSIONS{0}{1}1\n'.format(nx,ny))f.write('POINTS{0}float\n'.format(nx*ny))forjinrange(ny):foriinrange(nx):f.write('{0}{1}0\n'.format(X[j,i],Y[j,i]))f.write('POINT_DATA{0}\n'.format(nx*ny))f.write('VECTORSvelocityfloat\n')forjinrange(ny):foriinrange(nx):f.write('{0}{1}0\n'.format(U[j,i],V[j,i]))f.write('SCALARSpressurefloat\n')f.write('LOOKUP_TABLEdefault\n')forjinrange(ny):foriinrange(nx):f.write('{0}\n'.format(P[j,i]))defmain():Lx,Ly=1.0,1.0nx,ny=41,41n_iter_pressure=50n_time_steps=10000U_top=0.5rho=1.0nu=0.01dt=0.001#CreatemeshX,Y,dx,dy=create_mesh(nx,ny,Lx,Ly)#InitializevelocityandpressurefieldsU,V,P=initial_conditions(X,Y,nx,ny,U_top)#Time-steppingloopforninrange(n_time_steps):#UpdatepressurefieldP=pressure_poisson(P,dx,dy,U,V,rho,dt,n_iter_pressure)#UpdatevelocityfieldU,V=velocity_field(U,V,P,dx,dy,dt,nu,rho,U_top)#SaveresultseveryNtimestepsN=200ifn%N==0:file_name=f'cavity_flow_2D_{n:04d}.vtk'print('====================================')print('Writingsolutionfortimestep:',n)#print('====================================')write_vtk(X,Y,U,V,P,file_name,nx,ny)ifn==n_time_steps:print('====================================')print('Jobiscompletedsuccessfully')print('====================================')#WriteresultstoaVTKfile[whenuncommented,willwritethesolutionateverytimestep!]#write_vtk(X,Y,U,V,P,'cavity_flow.vtk',nx,ny)if__name__=='__main__':main()#PrintinitalandfinaltimesTf=datetime.now()print()print('+++++++++++++++++++++++++++++++++++++++++++')print('---------------DATE&TIME---------------')print(T0)print('+++++++++++++++++++++++++++++++++++++++++++')print(Tf)print('+++++++++++++++++++++++++++++++++++++++++++')#=========#Summary#========#ThisPythoncodeisascriptforsimulating2Dincompressibleflowinacavityusingthefinitedifferencemethod.Thecavityhasatoplidthatismovingataconstantvelocity,whiletheotherthreewallsarestationary.ThesimulationaimstosolvetheNavier-Stokesequationsforfluidflow,whichdescribetheconservationofmomentum,andthepressurePoissonequation,whichisderivedfromthecontinuityequationtomaintaintheincompressibleflowcondition.#Here'sabriefoverviewofthecode:#Importthenecessarylibraries:numpyandsys.#Defineafunctioncreate_mesh()tocreateastructuredgridinthex-yplanewithspecifieddimensionsandnumberofpointsineachdirection.#Defineafunctioninitial_conditions()tosettheinitialvaluesforthevelocity(UandV)andpressure(P)fields.Thetoplidisinitializedwithagivenvelocity(U_top).#Defineafunctionpressure_poisson()tosolvethepressurePoissonequationusinggivennumberofiterations.#Defineafunctionvelocity_field()toupdatethevelocityfields(UandV)usingtheupdatedpressurefieldandthegivenparameters(timestep,fluidviscosity,fluiddensity,andlidvelocity).#Defineafunctionwrite_vtk()tooutputtheresults(velocityandpressurefields)toaVTKfile,whichcanbevisualizedusingasoftwarelikeParaView.#Definethemain()function,whichinitializesthesimulationparameters,createsthemesh,setstheinitialconditions,runsthetime-steppingloopforupdatingthepressureandvelocityfields,andwritestheresultstoaVTKfile.#Finally,thescriptchecksifitisbeingrunasthemainmoduleandcallsthemain()function.#Thecodeisstructuredandwritteninawaythatitcanbeeasilymodifiedtoaccommodatedifferentsimulationparametersorotherboundaryconditions.注意!正如我上面提到的,你不应该直接信任来自ChatGPT的代码。生成的代码必须逐行追踪,并且在使用前必须经过验证和测试。这只是一个说明性的例子,用来展示到目前为止这个工具能走多远。VisualChat-GPT在CFD中的应用你可能听说过,Visual-ChatGPT是ChatGPT架构的一个最新扩展,专门设计用来根据视觉输入(如图像或视频)生成自然语言文本。该模型是在大量图像-标题对的数据集上训练的,每张图像都与一个或多个描述图像内容的自然语言标题相关联。到目前为止,Visual-ChatGPT在生成图像的自然语言描述、回答视觉场景的问题,甚至根据文本描述生成新图像方面,都显示出了非常令人印象深刻的结果。这些能力可能在优化CFD模拟中的网格时非常有用,例如,允许用户使用自然语言文本描述几何形状,结果将是:基于这些描述生成高质量的网格🤯这将是CFD领域真正的游戏规则改变者。例如,你可以提供所需的网格特性描述,如“一个高质量的网格,具有统一的单元大小和低畸变,集中在锐利边缘周围的区域,并在靠近墙壁的地方至少生成15层棱柱层”,Visual-ChatGPT可以生成满足这些要求的相应网格。这可以帮助简化网格生成过程,使其更容易为非专家使用,同时也提高了CFD模拟的准确性和效率。另一个特性可能是提供网格的快照,并要求在某些区域提高质量。或者输入一个网格图片,比如说2D网格,然后让ChatGPT为这个网格生成一个可定制的脚本。再次强调,这只是一个语言模型。因此,请记住,生成高质量的网格不仅需要描述所需的网格特性,还需要理解被模拟的物理几何和流场,这可能需要事先在网格生成方面拥有现有的专业知识。如何更好使用ChatGPT1)记住,这是一个AI语言模型!这意味着什么?这意味着,尽管这个工具非常能够生成优化的基于文本的输出,但它仍然容易"出错"。2)请记住,ChatGPT以块结构化的方式工作,这意味着你必须逐步构建块才能得到你需要的东西。如果你从一个非常详细的问题开始,提出一个高度技术性的问题,它可能会给你一个非常通用的答案(这里我指的是它可能给出的最通用的答案)。相反,给出你来自哪里和你去哪里的想法(介绍性背景-->明确定义的问题-->有用的答案)。3)你必须充分意识到ChatGPT不是谷歌那样的搜索引擎。除了每个工具给出的单一/多重输出外,ChatGPT基于它的训练数据和它接收到的输入。也就是说,除非你用正确的输入喂养它,否则ChatGPT不会给你你寻求的效率-你需要具体(记住我们关于注意力基础变换器的话)。假设你需要知道你想承担的项目预算的大致估计。不要输入像“为巧克力工厂的平面设计项目可能的预算是多少”这样的内容,你需要更详细,并为模型提供“参数”,以便它考虑计算你项目的预算。你可以写一些像“我是一名有XX年经验的平面设计师,我即将承担一个为巧克力工厂设计标志的项目。这个标志需要以动画版本交付,可能需要像Adobe软件包这样的复杂工具。设计可能需要一个高规格的图形卡进行渲染。考虑到设计可能需要多次迭代直到最终标志被同意,你能给我一个这个项目应该花费多少的大致估计吗”。4)为了最大限度地利用ChatGPT(如第2点所述),你需要花些时间首先了解你的情况。当ChatGPT在任何领域通过复制粘贴的方式使用时,这是毫无意义的。5)你必须意识到,除了ChatGPT可能存在的文字/编码错误外,它也可能给出不完整的答案(特别是当你的输入不足时)-因为简单地说,它没有足够的数据来知道你想知道什么。来源:CFD饭圈

未登录
还没有评论
课程
培训
服务
行家
VIP会员 学习 福利任务 兑换礼品
下载APP
联系我们
帮助与反馈