忙碌的组会结束,想要把源码过程解读的工作总结出来,把工作推进到下一阶段
就从梳理整个CAM大致运行过程最后总结我可能插入的新的参数化方案的位置
首先CAM的总体框架位于cam_comp文件,主要包括6个方法
init方法最简单,基本可以跳过,全是一些前期准备
然后就是run1,run1代码如下
首先整个过程是运行在其他模块(海洋,陆地,海冰)之前
参数是比较熟悉的cam_in&out,之后关键代码就是调用动力核心的stepon_run1和物理参数化方案的phys_run1
然后看stepon1方法,主要代码如下:
参数中的dyn_in&out似乎只为了兼容而设定,实际的dyn_import_t的定义中也没有找到实例
整个动力核心的run1的主要作用似乎只有将变量写入IC文件以及做一次耦合
整个d_p_couping基本都在将动力核心变量赋值给物理变量,故不细看
对于phsic_run1,核心就是调用了tphysbc,该例程将调用很多物理过程
对于cam_run2,核心就是调用phsic_run2,调用tphysac子例程,step_run2主要调用p_d_couping
进行一次耦合过程
对于cam_run3,对于多数核心来说,这将是第一次运行真正的动力核心
在dynpkg.F90文件开始第一次调用,对于dynpkg子例程而言,主要参数如下
其中输出非常好理解,t,u,v三个重要变量的梯度,对于输出参数:
etamid
: 垂直坐标的中间点位置,是一个一维数组。cwava
: 应用于全球积分的权重,是一个一维数组。detam
: 垂直全层之间的间隔,也是一个一维数组。flx_net
: 来自物理过程的净通量,是一个二维数组。ztodt
: 时间步长,以秒为单位。adv_state
: 对流状态,可能是用于跟踪对流过程的一些状态信息。
接下来是一些傅里叶系数数组,因为是sld核心所以有快速傅里叶变化,需要系数数组
然后进行动力学扫描,将开始更新动力学变量
参数都是刚刚定义或者已有的形参和实参
做好准备之后,scandyn子例程第一步就是直接调用slt_run_setup方法
该方法主要是用于设置半拉格朗日传输运行所需的内部平流状态
这段代码计算了时间步长为 n + 1/2 时的 U 和 V 值,这些值将在后续的轨迹计算中使用。代码中的主要步骤如下:
- 使用 OpenMP 并行指令对循环进行并行化处理,以加快计算速度。
- 在循环中,对每个经度和纬度格点进行迭代计算。
- 对于每个格点,根据给定的计算公式计算 U 和 V 的值,并存储在相应的数组中。
- 如果是第一次重启步骤,则额外计算了 etadot 的值,并将其存储在相应的数组中。
之后在所有纬度范围执行非线性动力学计算,但是为啥是按每个纬度计算?(不解)
该子例程第一部分计算每个纬度上的最大风速vmax
和 vmaxt
,该风速值大概率为u3和v3的平方和
而且引入了utfac和vtfac两个系数进行调整
然后开始计算当前纬度余弦值并存储在coslat中,并计算科里奥利参数coriol,与纬度正弦值和自转角速度相关
之后使用plevs0过程设置模型层面当前时间压力数组,主要计算模型接口的压力以及模型中间层的压力和层厚度
对于stats过程,该子程序计算特定纬度上的诊断信息,计算地表总压力。计算收敛场、温度平方和水汽量的厚度加权平方和。对结果进行加权平均,以考虑纬度的变化。
之后计算压力的自然对数,并可能调用etadtn方法,子程序 etadtn
用于计算时间步骤大于0时的 (1/ps) * etadot(dp/deta)。该计算主要是为了在当前时间步骤完成部分计算,这部分计算可能在前一个时间步骤(SCANDYN
)中开始。
计算步骤:将输入的 d
和 edstar
(部分计算的 etadot)与压力系数相乘,求和以计算纬向发散的积分 ddpn
。使用 ddpn
和 ddpk
计算 etadot。最后一个高度层(plev)的 etadot 设置为零。
之后继续调用engy_te
子程序,该子程序主要计算当前纬度上的总能量积分,对温度、风速和地表位势高度的加权积分来计算总能量。
调用了 flxint
子程序,计算了地表上和底层之间的通量积分,并将其加到 engy1lat(lat)
上。
最后两步,先保存变量fu,fv,调用grmult_run子例程,该方法较长,主要计算网格点空间中的非线性动力学项(为SLD插值做准备)
这里简述grmult_run子例程的过程:
-
计算 U 和 V 的中间时刻值(时间步长的一半),这些值将用于 Hortal 温度修正中。
-
将辅助字段初始化为零。
-
计算虚拟温度。
-
计算一些辅助量,如 etadot 和 ddpn。
-
计算垂直速度 etadot 以及在某一垂直层上的水平散度的积分。
- 将 eta-dot(dp/deta) 转换为 eta-dot。
- 计算动量方程中的 hydrostatic term 的水平和纵向导数。
- 计算所有预报方程的右手边项,包括 Surface Pressure、Temperature、U/V 方程。
- 准备用于插值的 SLD 数组,将每个变量的时间步长按比例分配给到达点和离开点。
最后计算纬度上的最大垂直数(Courant number),Courant 数是计算数值模拟中的时间步长的一种方法,用于确保解决方案的稳定性。
至此linemsdyn方法运行结束
回到scandyn方法,之后执行slt_run子例程,执行SLT物理过程。
该例程第一个重要部分就是调用da_coupling方法
da_coupling方法是动力学和平流的耦合过程,将湿度、温度、风场、湿度变量等复制到 adv_state
结构体的相应成员中
这里scanslt_alloc是内存分配过程,而scanslt_bft则是傅里叶前向传播,在每个纬度上运行,该方法比较复杂,进行了大量的三维和二维插值,最后结果fu,fv,T,q,Ps将会被放到fft缓存区中,后续将用其进行傅里叶变换