【PY】多项式拟合与样条插值(以及积分)
2017-08-28 本文已影响0人
中场休息室
问题的提出
昨天打算处理叶尖泄漏流动量的,参考GT2017-63655,单位轴向弦长的轴向动量(the tip leakage flow axial momentum per unit axial chord)如下式定义:
image.png式子里各个参数我都可以通过输出间隙中间平面的参数来得到,然后乘除之后做一个积分。
那么首先我要弄清楚这个平面上的数据结构
面上的数据结构
间隙中间平面的网格,可以认为是一个长的矩形网格,如图:
image.png然后利用Post中的Export之后,选择这个面,选择要输出的物理量,就得到一个csv文件。
- 间隙网格配置
径向方向上17个点,弦向方向上是44个点,所以一共有17*44=748个数据点。 - 数据点的排布
csv文件中也同样给了748个数据点,那么这些数据点是怎么排布的呢?- 是输出相同轴向位置上的17个径向点,然后再移动到下一个轴向位置输出
- 且先输出尾缘,再逐渐前移
- 径向方向上则是从tip到casing的顺序,如果用叶高来表达是98%-100%叶高
- P.S. 有个地方需要注意的是,输出的头34个数据,就是尾缘位置处,两组相近的17个数据重叠在一起,跟后面的规律不一样,所以头34个数据先不用
积分的问题
那么首先我就要对某个轴向位置上的17个径向点进行积分
积分应该怎么做呢,照理说积分其实就是相加,但是有问题:
- 径向点数少,只有17个
- 分布很不均匀(近壁面加密)
- 我还想做不同叶高范围的动量对比,如果按照径向高度来分,中间33%的区域只有三四个点
那么应该怎么做?想了想其实也好解决,而且应该也是更合理的做法:
- 把我17个离散的数据拟合或插值,得到径向方向上n多数据,然后就可以方便的积分了,结果肯定比我用17个点做出来的要精确的多
多项式拟合
我一开始用的是多项式拟合,用numpy里的polyfit,其实很简单:
import numpy as np
coeffs = np.polyfit(x, y, degree)
p = np.poly1d(coeffs)
说明:
- 把离散的x和y数据导入,然后用polyfit一处理,degree是你要用几次多项式来拟合,这样就会得到一个coeffs的list,这是多项式前的系数
- 比如f=ax3 + bx2 + cx3 +d,那么coeffts就是[a,b,c,d]
- 然后再用poly1d的命令, p就等于ax3 + bx2 + cx3 +d了
- 也就是你比如再弄一个xnew = np.arange(0,1,1000)
那么的ynew=p(xnew),这就是拟合之后0-1范围内的x和y的值了
问题:
- 拟合效果不好,于是还是用了样条插值,这样不管能不能用拟合,效果都不错
样条插值
样条插值的做法也很简单:
from scipy import interpolate
tck = interpolate.splrep(x, y) #需要先使用splrep函数计算出B-Spline曲线的参数
x_new = np.linspace(min(x), max(x), 10000)
y_bspline = interpolate.splev(x_new, tck) #将参数传递给splev函数计算出各个取样点的插值结果
说明:
- 就是这样,先import插值的命令
- 然后先用splrep计算出b样条曲线的参数tck
- 然后再将参数传递给splev函数计算出各取样点的插值结果
这样得到的结果就很美啦
这样我在98-100%的间隙范围内就可以去对低、中、高三个范围进行积分了。当然,要先把数据准备好的
对各个轴向位置的径向17个点进行积分,就得到泄漏流动量沿着弦向方向的44个点,如果要积分得到总的动量,就再进行插值和积分的步骤。
积分
- trapz
积分使用的是trapz的命令
trapz其实是trapezoid的缩写,也就是梯形
就是梯形法数值积分,也就是一个个矩形块的面积相加吧
应用起来也非常简单
res = np.trapz(y_bspline,x_new)
在b样条处理中得到的y值和x值,用这个命令已处理,就能得到积分结果了
积分的精确度当然是和x_new的分隔挂钩的,分得区间越多积分越精确。
- quad
此外,还有quad的命令, 这个精度比trapz搞,但是需要精确表达式
例如:
from scipy import integrate
def half_circle(x):
return (1-x**2)**0.5
pi_half, err = integrate.quad(half_circle, -1, 1)
half_circle是圆面积的表达式,后面的两个参数-1和1是积分的范围
quad运行之后得到一个结果和一个误差,所以最后一句里还有个err