From d12fefd4a46d3eb2b7a13d575b231d44648a0283 Mon Sep 17 00:00:00 2001 From: Dengda98 Date: Fri, 25 Apr 2025 18:37:56 +0800 Subject: [PATCH 01/25] REFAC: refactor whole codes --- pygrt/C_extension/include/common/const.h | 19 + pygrt/C_extension/include/common/dwm.h | 46 +- pygrt/C_extension/include/common/fim.h | 51 +- pygrt/C_extension/include/common/integral.h | 76 +-- pygrt/C_extension/include/common/iostats.h | 45 +- pygrt/C_extension/include/common/kernel.h | 10 +- pygrt/C_extension/include/common/model.h | 12 - pygrt/C_extension/include/common/ptam.h | 50 +- pygrt/C_extension/include/dynamic/grt.h | 164 +----- pygrt/C_extension/include/dynamic/propagate.h | 24 +- pygrt/C_extension/include/dynamic/source.h | 19 +- .../include/static/static_propagate.h | 6 +- .../include/static/static_source.h | 12 +- pygrt/C_extension/include/static/stgrt.h | 51 +- pygrt/C_extension/src/common/const.c | 22 + pygrt/C_extension/src/common/dwm.c | 105 ++-- pygrt/C_extension/src/common/fim.c | 297 +++------- pygrt/C_extension/src/common/integral.c | 219 +++---- pygrt/C_extension/src/common/iostats.c | 73 +-- pygrt/C_extension/src/common/ptam.c | 423 ++++---------- pygrt/C_extension/src/dynamic/grt.c | 541 ++---------------- pygrt/C_extension/src/dynamic/grt_main.c | 214 ++----- pygrt/C_extension/src/dynamic/propagate.c | 103 +--- pygrt/C_extension/src/dynamic/source.c | 48 +- .../C_extension/src/static/static_propagate.c | 108 +--- pygrt/C_extension/src/static/static_source.c | 53 +- pygrt/C_extension/src/static/stgrt.c | 202 ++----- pygrt/C_extension/src/static/stgrt_main.c | 118 ++-- pygrt/utils.py | 29 +- 29 files changed, 780 insertions(+), 2360 deletions(-) create mode 100644 pygrt/C_extension/src/common/const.c diff --git a/pygrt/C_extension/include/common/const.h b/pygrt/C_extension/include/common/const.h index ba2e0604..af39a486 100755 --- a/pygrt/C_extension/include/common/const.h +++ b/pygrt/C_extension/include/common/const.h @@ -127,3 +127,22 @@ typedef int MYINT; ///< 整数 #define GRT_CMPLX_FMT "%18.8e%-+14.8eJ" ///< 复数输出格式 #define GRT_STR_CMPLX_FMT "%34s" ///< 与复数格式同长度的字符串输出格式 + +// ----------------------------------------------------------------------------- +#define GRT_SRC_CHA_COUNTS 3 ///< 3, 代码中分量个数(ZRT,ZNE) +#define GRT_SRC_QWV_COUNTS 3 ///< 3, 代码中核函数类型个数(q, w, v) +#define GRT_SRC_P_COUNTS 4 ///< 4, 代码中积分类型个数 +#define GRT_SRC_M_MAX 2 ///< 代码中阶数m的最大值 +#define GRT_SRC_M_COUNTS 6 ///< 6, 代码中不同震源、不同阶数的个数 + +/** 分别对应爆炸源(0阶),垂直力源(0阶),水平力源(1阶),剪切源(0,1,2阶) */ +extern const MYINT GRT_SRC_M_ORDERS[GRT_SRC_M_COUNTS]; + +/** 不同震源,不同阶数的名称简写,用于命名 */ +extern const char *GRT_SRC_M_NAME_ABBR[GRT_SRC_M_COUNTS]; + +/** ZRT三分量代号 */ +extern const char GRT_ZRTchs[]; + +/** ZNE三分量代号 */ +extern const char GRT_ZNEchs[]; \ No newline at end of file diff --git a/pygrt/C_extension/include/common/dwm.h b/pygrt/C_extension/include/common/dwm.h index 22c42b46..b716766f 100644 --- a/pygrt/C_extension/include/common/dwm.h +++ b/pygrt/C_extension/include/common/dwm.h @@ -20,45 +20,33 @@ /** - * 传统的离散波数积分,结果以三维数组的形式返回,形状为[nr][3][4], 分别代表震中距、阶数(m=0,1,2) + * 传统的离散波数积分,结果以三维数组的形式返回,形状分别代表震中距、不同震源不同阶数 * 和4种积分类型(p=0,1,2,3) * - * @param mod1d (in)`MODEL1D` 结构体指针 - * @param dk (in)波数积分间隔 - * @param kmax (in)波数积分的上限 - * @param keps (in)波数积分的收敛条件,要求在某震中距下所有格林函数都收敛,为负数代表不提前判断收敛,按照波数积分上限进行积分 - * @param omega (in)复数频率 - * @param nr (in)震中距数量 - * @param rs (in)震中距数组 + * @param[in] mod1d (in)`MODEL1D` 结构体指针 + * @param[in] dk (in)波数积分间隔 + * @param[in] kmax (in)波数积分的上限 + * @param[in] keps (in)波数积分的收敛条件,要求在某震中距下所有格林函数都收敛,为负数代表不提前判断收敛,按照波数积分上限进行积分 + * @param[in] omega (in)复数频率 + * @param[in] nr (in)震中距数量 + * @param[in] rs (in)震中距数组 * - * @param sum_EXP_J[nr][3][4] (out)爆炸源 - * @param sum_VF_J[nr][3][4] (out)垂直力源 - * @param sum_HF_J[nr][3][4] (out)水平力源 - * @param sum_DC_J[nr][3][4] (out)剪切源 + * @param[out] sum_J 积分值 * - * @param calc_upar (in)是否计算位移u的空间导数 - * @param sum_EXP_uiz_J[nr][3][4] (out)爆炸源产生的ui_z(位移u对坐标z的偏导),下同 - * @param sum_VF_uiz_J[nr][3][4] (out)垂直力源 - * @param sum_HF_uiz_J[nr][3][4] (out)水平力源 - * @param sum_DC_uiz_J[nr][3][4] (out)剪切源 - * @param sum_EXP_uir_J[nr][3][4] (out)爆炸源产生的ui_r(位移u对坐标r的偏导),下同 - * @param sum_VF_uir_J[nr][3][4] (out)垂直力源 - * @param sum_HF_uir_J[nr][3][4] (out)水平力源 - * @param sum_DC_uir_J[nr][3][4] (out)剪切源 + * @param[in] calc_upar 是否计算位移u的空间导数 + * @param[out] sum_uiz_J uiz的积分值 + * @param[out] sum_uir_J uir的积分值 * - * @param fstats (out)文件指针,保存不同k值的格林函数积分核函数 - * @param kerfunc (in)计算核函数的函数指针 + * @param[out] fstats 文件指针,保存不同k值的格林函数积分核函数 + * @param[in] kerfunc 计算核函数的函数指针 * * @return k 积分截至时的波数 */ MYREAL discrete_integ( const MODEL1D *mod1d, MYREAL dk, MYREAL kmax, MYREAL keps, MYCOMPLEX omega, MYINT nr, MYREAL *rs, - MYCOMPLEX sum_EXP_J[nr][3][4], MYCOMPLEX sum_VF_J[nr][3][4], - MYCOMPLEX sum_HF_J[nr][3][4], MYCOMPLEX sum_DC_J[nr][3][4], + MYCOMPLEX sum_J[nr][GRT_SRC_M_COUNTS][GRT_SRC_P_COUNTS], bool calc_upar, - MYCOMPLEX sum_EXP_uiz_J[nr][3][4], MYCOMPLEX sum_VF_uiz_J[nr][3][4], - MYCOMPLEX sum_HF_uiz_J[nr][3][4], MYCOMPLEX sum_DC_uiz_J[nr][3][4], - MYCOMPLEX sum_EXP_uir_J[nr][3][4], MYCOMPLEX sum_VF_uir_J[nr][3][4], - MYCOMPLEX sum_HF_uir_J[nr][3][4], MYCOMPLEX sum_DC_uir_J[nr][3][4], + MYCOMPLEX sum_uiz_J[nr][GRT_SRC_M_COUNTS][GRT_SRC_P_COUNTS], + MYCOMPLEX sum_uir_J[nr][GRT_SRC_M_COUNTS][GRT_SRC_P_COUNTS], FILE *fstats, KernelFunc kerfunc); diff --git a/pygrt/C_extension/include/common/fim.h b/pygrt/C_extension/include/common/fim.h index ec1d61b1..813cc14f 100755 --- a/pygrt/C_extension/include/common/fim.h +++ b/pygrt/C_extension/include/common/fim.h @@ -25,50 +25,37 @@ * \f[ * J_m(x) \approx \sqrt{\frac{2}{\pi x}} \cos(x - \frac{m \pi}{2} - \frac{\pi}{4}) * \f] - * 其中\f$x=kr\f$. 结果以三维数组的形式返回,形状为[nr][3][4], 分别代表震中距、阶数(m=0,1,2) - * 和4种积分类型(p=0,1,2,3) + * 其中\f$x=kr\f$. * * - * @param mod1d (in)`MODEL1D` 结构体指针 - * @param k0 (in)前一部分的波数积分结束点k值 - * @param dk0 (in)前一部分的波数积分间隔 - * @param filondk (in)filon积分间隔 - * @param kmax (in)波数积分的上限 - * @param keps (in)波数积分的收敛条件,要求在某震中距下所有格林函数都收敛 - * @param omega (in)复数频率 - * @param nr (in)震中距数量 - * @param rs (in)震中距数组 + * @param[in] mod1d (in)`MODEL1D` 结构体指针 + * @param[in] k0 (in)前一部分的波数积分结束点k值 + * @param[in] dk0 (in)前一部分的波数积分间隔 + * @param[in] filondk (in)filon积分间隔 + * @param[in] kmax (in)波数积分的上限 + * @param[in] keps (in)波数积分的收敛条件,要求在某震中距下所有格林函数都收敛 + * @param[in] omega (in)复数频率 + * @param[in] nr (in)震中距数量 + * @param[in] rs (in)震中距数组 * - * @param sum_EXP_J[nr][3][4] (out)爆炸源 - * @param sum_VF_J[nr][3][4] (out)垂直力源 - * @param sum_HF_J[nr][3][4] (out)水平力源 - * @param sum_DC_J[nr][3][4] (out)剪切源 + * @param[out] sum_J 积分值 * - * @param calc_upar (in)是否计算位移u的空间导数 - * @param sum_EXP_uiz_J[nr][3][4] (out)爆炸源产生的ui_z(位移u对坐标z的偏导),下同 - * @param sum_VF_uiz_J[nr][3][4] (out)垂直力源 - * @param sum_HF_uiz_J[nr][3][4] (out)水平力源 - * @param sum_DC_uiz_J[nr][3][4] (out)剪切源 - * @param sum_EXP_uir_J[nr][3][4] (out)爆炸源产生的ui_r(位移u对坐标r的偏导),下同 - * @param sum_VF_uir_J[nr][3][4] (out)垂直力源 - * @param sum_HF_uir_J[nr][3][4] (out)水平力源 - * @param sum_DC_uir_J[nr][3][4] (out)剪切源 + * @param[in] calc_upar 是否计算位移u的空间导数 + * @param[out] sum_uiz_J uiz的积分值 + * @param[out] sum_uir_J uir的积分值 * - * @param fstats (out)文件指针,保存不同k值的格林函数积分核函数 - * @param kerfunc (in)计算核函数的函数指针 + * @param[out] fstats (out)文件指针,保存不同k值的格林函数积分核函数 + * @param[in] kerfunc (in)计算核函数的函数指针 * * @return k 积分截至时的波数 */ MYREAL linear_filon_integ( const MODEL1D *mod1d, MYREAL k0, MYREAL dk0, MYREAL filondk, MYREAL kmax, MYREAL keps, MYCOMPLEX omega, MYINT nr, MYREAL *rs, - MYCOMPLEX sum_EXP_J[nr][3][4], MYCOMPLEX sum_VF_J[nr][3][4], - MYCOMPLEX sum_HF_J[nr][3][4], MYCOMPLEX sum_DC_J[nr][3][4], + MYCOMPLEX sum_J[nr][GRT_SRC_M_COUNTS][GRT_SRC_P_COUNTS], bool calc_upar, - MYCOMPLEX sum_EXP_uiz_J[nr][3][4], MYCOMPLEX sum_VF_uiz_J[nr][3][4], - MYCOMPLEX sum_HF_uiz_J[nr][3][4], MYCOMPLEX sum_DC_uiz_J[nr][3][4], - MYCOMPLEX sum_EXP_uir_J[nr][3][4], MYCOMPLEX sum_VF_uir_J[nr][3][4], - MYCOMPLEX sum_HF_uir_J[nr][3][4], MYCOMPLEX sum_DC_uir_J[nr][3][4], + MYCOMPLEX sum_uiz_J[nr][GRT_SRC_M_COUNTS][GRT_SRC_P_COUNTS], + MYCOMPLEX sum_uir_J[nr][GRT_SRC_M_COUNTS][GRT_SRC_P_COUNTS], FILE *fstats, KernelFunc kerfunc); diff --git a/pygrt/C_extension/include/common/integral.h b/pygrt/C_extension/include/common/integral.h index a20297de..ec9335d9 100644 --- a/pygrt/C_extension/include/common/integral.h +++ b/pygrt/C_extension/include/common/integral.h @@ -13,81 +13,53 @@ /** * 计算核函数和Bessel函数的乘积,相当于计算了一个小积分区间内的值。参数中涉及两种数组形状: - * + [3][3]. 存储的是核函数,第一个维度3代表阶数m=0,1,2,第二个维度3代表三类系数qm,wm,vm - * + [3][4]. 存储的是该dk区间内的积分值,维度3代表阶数m=0,1,2,维度4代表4种类型的F(k,w)Jm(kr)k的类型 + * + QWV. 存储的是核函数,第一个维度不同震源,不同阶数,第二个维度3代表三类系数qm,wm,vm + * + SUM. 存储的是该dk区间内的积分值,第一个维度不同震源,不同阶数,维度4代表4种类型的F(k,w)Jm(kr)k的类型 * * - * @param k (in)波数 - * @param r (in)震中距 - * @param EXP_qwv[3][3] (in)爆炸源核函数 - * @param VF_qwv[3][3] (in)垂直力源核函数 - * @param HF_qwv[3][3] (in)水平力源核函数 - * @param DC_qwv[3][3] (in)剪切源核函数 - * @param calc_uir (in)是否计算ui_r(位移u对坐标r的偏导) - * @param EXP_J[3][4] (out)爆炸源,该dk区间内的积分值,下同 - * @param VF_J[3][4] (out)垂直力源 - * @param HF_J[3][4] (out)水平力源 - * @param DC_J[3][4] (out)剪切源 + * @param[in] k 波数 + * @param[in] r 震中距 + * @param[out] QWV 不同震源,不同阶数的核函数 \f$ q_m, w_m, v_m \f$ + * @param[in] calc_uir 是否计算ui_r(位移u对坐标r的偏导) + * @param[out] SUM 该dk区间内的积分值 * */ void int_Pk( MYREAL k, MYREAL r, - const MYCOMPLEX EXP_qwv[3][3], const MYCOMPLEX VF_qwv[3][3], - const MYCOMPLEX HF_qwv[3][3], const MYCOMPLEX DC_qwv[3][3], + const MYCOMPLEX QWV[GRT_SRC_M_COUNTS][GRT_SRC_QWV_COUNTS], bool calc_uir, - MYCOMPLEX EXP_J[3][4], MYCOMPLEX VF_J[3][4], - MYCOMPLEX HF_J[3][4], MYCOMPLEX DC_J[3][4] ); + MYCOMPLEX SUM[GRT_SRC_M_COUNTS][GRT_SRC_P_COUNTS]); /** - * 将最终计算好的多个积分值,按照公式(5.6.22)组装成3分量。数组形状[3][4],\ - * 存储的是最终的积分值,维度3代表阶数m=0,1,2,维度4代表4种类型的F(k,w)Jm(kr)k的类型 + * 将最终计算好的多个积分值,按照公式(5.6.22)组装成3分量。 * - * @param sum_EXP_J[3][4] (in)爆炸源,最终的积分值,下同 - * @param sum_VF_J[3][4] (in)垂直力源 - * @param sum_HF_J[3][4] (in)水平力源 - * @param sum_DC_J[3][4] (in)剪切源 - * @param tol_EXP[2] (out)爆炸源的Z、R分量频谱结果 - * @param tol_VF[2] (out)垂直力源的Z、R分量频谱结果 - * @param tol_HF[3] (out)水平力源的Z、R、T分量频谱结果 - * @param tol_DD[2] (out)45度倾滑的Z、R分量频谱结果 - * @param tol_DS[3] (out)90度倾滑的Z、R、T分量频谱结果 - * @param tol_SS[3] (out)90度走滑的Z、R、T分量频谱结果 + * @param[in] sum_J 积分结果 + * @param[out] tol Z、R、T分量频谱结果 */ void merge_Pk( - const MYCOMPLEX sum_EXP_J[3][4], const MYCOMPLEX sum_VF_J[3][4], - const MYCOMPLEX sum_HF_J[3][4], const MYCOMPLEX sum_DC_J[3][4], - MYCOMPLEX tol_EXP[2], MYCOMPLEX tol_VF[2], MYCOMPLEX tol_HF[3], - MYCOMPLEX tol_DD[2], MYCOMPLEX tol_DS[3], MYCOMPLEX tol_SS[3]); + const MYCOMPLEX sum_J[GRT_SRC_M_COUNTS][GRT_SRC_P_COUNTS], MYCOMPLEX tol[GRT_SRC_M_COUNTS][GRT_SRC_CHA_COUNTS]); /** * 和int_Pk函数类似,不过是计算核函数和渐近Bessel函数的乘积 sqrt(k) * F(k,w) * cos ,其中涉及两种数组形状: - * + [3][3]. 存储的是核函数,第一个维度3代表阶数m=0,1,2,第二个维度3代表三类系数qm,wm,vm - * + [3][4]. 存储的是该dk区间内的积分值,维度3代表阶数m=0,1,2,维度4代表4种类型的F(k,w)Jm(kr)k的类型 + * + QWV. 存储的是核函数,第一个维度不同震源,不同阶数,第二个维度3代表三类系数qm,wm,vm + * + SUM. 存储的是该dk区间内的积分值,第一个维度不同震源,不同阶数,维度4代表4种类型的F(k,w)Jm(kr)k的类型 * * - * @param k (in)波数 - * @param r (in)震中距 - * @param iscos (in)计算sin函数 - * @param EXP_qwv[3][3] (in)爆炸源核函数 - * @param VF_qwv[3][3] (in)垂直力源核函数 - * @param HF_qwv[3][3] (in)水平力源核函数 - * @param DC_qwv[3][3] (in)剪切源核函数 - * @param calc_uir (in)是否计算ui_r(位移u对坐标r的偏导) - * @param EXP_J[3][4] (out)爆炸源,该dk区间内的积分值,下同 - * @param VF_J[3][4] (out)垂直力源 - * @param HF_J[3][4] (out)水平力源 - * @param DC_J[3][4] (out)剪切源 + * @param[in] k 波数 + * @param[in] r 震中距 + * @param[in] iscos 是否使用cos函数,否则使用sin函数 + * @param[out] QWV 不同震源,不同阶数的核函数 \f$ q_m, w_m, v_m \f$ + * @param[in] calc_uir 是否计算ui_r(位移u对坐标r的偏导) + * @param[out] SUM 该dk区间内的积分值 * */ void int_Pk_filon( MYREAL k, MYREAL r, bool iscos, - const MYCOMPLEX EXP_qwv[3][3], const MYCOMPLEX VF_qwv[3][3], - const MYCOMPLEX HF_qwv[3][3], const MYCOMPLEX DC_qwv[3][3], - bool calc_uir, - MYCOMPLEX EXP_J[3][4], MYCOMPLEX VF_J[3][4], - MYCOMPLEX HF_J[3][4], MYCOMPLEX DC_J[3][4] ); + const MYCOMPLEX QWV[GRT_SRC_M_COUNTS][GRT_SRC_QWV_COUNTS], + bool calc_uir, + MYCOMPLEX SUM[GRT_SRC_M_COUNTS][GRT_SRC_P_COUNTS]); diff --git a/pygrt/C_extension/include/common/iostats.h b/pygrt/C_extension/include/common/iostats.h index cc8131be..a5c77bea 100755 --- a/pygrt/C_extension/include/common/iostats.h +++ b/pygrt/C_extension/include/common/iostats.h @@ -16,46 +16,29 @@ /** - * 对离散波数法以及Filon积分的中间结果进行记录,其中涉及两种数组形状: - * + [3][3]. 存储的是核函数,第一个维度3代表阶数m=0,1,2,第二个维度3代表三类系数qm,wm,vm - * + [3][4]. 存储的是该dk区间内的积分值,维度3代表阶数m=0,1,2,维度4代表4种类型的F(k,w)Jm(kr)k的类型 + * 将积分过程中计算的核函数写入文件 * - * @param f0 (out)二进制文件指针 - * @param k (in)波数 - * @param EXP_qwv[3][3] (in)爆炸源核函数 - * @param VF_qwv[3][3] (in)垂直力源核函数 - * @param HF_qwv[3][3] (in)水平力源核函数 - * @param DC_qwv[3][3] (in)剪切源核函数 + * @param[out] f0 二进制文件指针 + * @param[in] k 波数 + * @param[in] QWV 不同震源,不同阶数的核函数 \f$ q_m, w_m, v_m \f$ * * * @note 文件记录的值均为波数积分的中间结果,与最终的结果还差一系列的系数, * 记录其值主要用于参考其变化趋势。 */ void write_stats( - FILE *f0, MYREAL k, - const MYCOMPLEX EXP_qwv[3][3], const MYCOMPLEX VF_qwv[3][3], - const MYCOMPLEX HF_qwv[3][3], const MYCOMPLEX DC_qwv[3][3] - // const MYCOMPLEX EXP_J[3][4], const MYCOMPLEX VF_J[3][4], - // const MYCOMPLEX HF_J[3][4], const MYCOMPLEX DC_J[3][4] -); + FILE *f0, MYREAL k, const MYCOMPLEX QWV[GRT_SRC_M_COUNTS][GRT_SRC_QWV_COUNTS]); /** - * 对峰谷平均法的中间结果进行记录,其中[3][4]的数组形状代表存储的 - * 是最终的积分值,维度3代表阶数m=0,1,2,维度4代表4种类型的F(k,w)Jm(kr)k的类型 + * 记录峰谷平均法的峰谷位置 * - * @param f0 (out)二进制文件指针 - * @param k (in)波数 - * @param maxNpt (in)波峰+波谷的数量(本质是计算中提前预设的量,见ptam.c文件中PTA_method函数) - * @param EXPpt[3][4][maxNpt] (in)爆炸源,最终收敛积分值使用的波峰波谷值,下同 - * @param VFpt[3][4][maxNpt] (in)垂直力源 - * @param HFpt[3][4][maxNpt] (in)水平力源 - * @param DCpt[3][4][maxNpt] (in)剪切源 - * @param kEXPpt[3][4][maxNpt] (in)爆炸源,最终收敛积分值使用的波峰波谷值对应的波数k值,下同 - * @param kVFpt[3][4][maxNpt] (in)垂直力源 - * @param kHFpt[3][4][maxNpt] (in)水平力源 - * @param kDCpt[3][4][maxNpt] (in)剪切源 + * @param[out] f0 (out)二进制文件指针 + * @param[in] k (in)波数 + * @param[in] maxNpt (in)波峰+波谷的数量(本质是计算中提前预设的量,见ptam.c文件中PTA_method函数) + * @param[in] Kpt (in)最终收敛积分值使用的波峰波谷位置 + * @param[in] Fpt (in)最终收敛积分值使用的波峰波谷幅值 * * @note 文件记录的积分值与最终的结果还差一系列的系数, * 记录其值主要用于参考其变化趋势。 @@ -63,7 +46,5 @@ void write_stats( */ void write_stats_ptam( FILE *f0, MYREAL k, MYINT maxNpt, - const MYCOMPLEX EXPpt[3][4][maxNpt], const MYCOMPLEX VFpt[3][4][maxNpt], - const MYCOMPLEX HFpt[3][4][maxNpt], const MYCOMPLEX DCpt[3][4][maxNpt], - const MYREAL kEXPpt[3][4][maxNpt], const MYREAL kVFpt[3][4][maxNpt], - const MYREAL kHFpt[3][4][maxNpt], const MYREAL kDCpt[3][4][maxNpt]); \ No newline at end of file + MYREAL Kpt[GRT_SRC_M_COUNTS][GRT_SRC_P_COUNTS][maxNpt], + MYCOMPLEX Fpt[GRT_SRC_M_COUNTS][GRT_SRC_P_COUNTS][maxNpt]); \ No newline at end of file diff --git a/pygrt/C_extension/include/common/kernel.h b/pygrt/C_extension/include/common/kernel.h index f9d2e86a..1a978b5b 100644 --- a/pygrt/C_extension/include/common/kernel.h +++ b/pygrt/C_extension/include/common/kernel.h @@ -13,9 +13,9 @@ #include "common/model.h" - +/** + * 计算核函数的函数指针,动态与静态的接口一致 + */ typedef void (*KernelFunc) ( - const MODEL1D *mod1d, MYCOMPLEX omega, MYREAL k, - MYCOMPLEX EXP_qwv[3][3], MYCOMPLEX VF_qwv[3][3], MYCOMPLEX HF_qwv[3][3], MYCOMPLEX DC_qwv[3][3], - bool calc_uiz, - MYCOMPLEX EXP_uiz_qwv[3][3], MYCOMPLEX VF_uiz_qwv[3][3], MYCOMPLEX HF_uiz_qwv[3][3], MYCOMPLEX DC_uiz_qwv[3][3]); \ No newline at end of file + const MODEL1D *mod1d, MYCOMPLEX omega, MYREAL k, MYCOMPLEX QWV[GRT_SRC_M_COUNTS][GRT_SRC_QWV_COUNTS], + bool calc_uiz, MYCOMPLEX QWV_uiz[GRT_SRC_M_COUNTS][GRT_SRC_QWV_COUNTS]); \ No newline at end of file diff --git a/pygrt/C_extension/include/common/model.h b/pygrt/C_extension/include/common/model.h index 1892fa8f..c2b09023 100755 --- a/pygrt/C_extension/include/common/model.h +++ b/pygrt/C_extension/include/common/model.h @@ -63,18 +63,6 @@ typedef struct _PYMODEL1D { MYREAL *Qb; ///< Qb[n] S波Q值 } PYMODEL1D; -/** - * 格林函数的频谱,仅作为将结果返回至Python使用 - */ -typedef struct _GRN { - MYINT nf; ///< 频点个数 - MYREAL *Re; ///< Re[nf] 实部 - MYREAL *Im; ///< Im[nf] 虚部 - // float *Re; - // float *Im; -} GRN; - - /** * 打印模型参数信息,主要用于调试程序 diff --git a/pygrt/C_extension/include/common/ptam.h b/pygrt/C_extension/include/common/ptam.h index d49985b0..16ccc4d4 100755 --- a/pygrt/C_extension/include/common/ptam.h +++ b/pygrt/C_extension/include/common/ptam.h @@ -28,45 +28,33 @@ /** * 峰谷平均法 Peak-Trough Averaging Method,最后收敛的积分结果以三维数组的形式返回, - * 形状为[nr][3][4], 分别代表震中距、阶数(m=0,1,2) 和4种积分类型(p=0,1,2,3) * - * @param mod1d (in)`MODEL1D` 结构体指针 - * @param k0 (in)先前的积分已经进行到了波数k0 - * @param predk (in)先前的积分使用的积分间隔dk,因为峰谷平均法使用的 + * @param[in] mod1d (in)`MODEL1D` 结构体指针 + * @param[in] k0 (in)先前的积分已经进行到了波数k0 + * @param[in] predk (in)先前的积分使用的积分间隔dk,因为峰谷平均法使用的 * 积分间隔会和之前的不一致,这里传入该系数以做预先调整 - * @param omega (in)复数频率 - * @param nr (in)震中距数量 - * @param rs (in)震中距数组 - * @param sum_EXP_J0[nr][3][4] (out)爆炸源 - * @param sum_VF_J0[nr][3][4] (out)垂直力源 - * @param sum_HF_J0[nr][3][4] (out)水平力源 - * @param sum_DC_J0[nr][3][4] (out)剪切源 + * @param[in] omega (in)复数频率 + * @param[in] nr (in)震中距数量 + * @param[in] rs (in)震中距数组 * - * @param calc_upar (in)是否计算位移u的空间导数 - * @param sum_EXP_uiz_J0[nr][3][4] (out)爆炸源产生的ui_z(位移u对坐标z的偏导),下同 - * @param sum_VF_uiz_J0[nr][3][4] (out)垂直力源 - * @param sum_HF_uiz_J0[nr][3][4] (out)水平力源 - * @param sum_DC_uiz_J0[nr][3][4] (out)剪切源 - * @param sum_EXP_uir_J0[nr][3][4] (out)爆炸源产生的ui_r(位移u对坐标r的偏导),下同 - * @param sum_VF_uir_J0[nr][3][4] (out)垂直力源 - * @param sum_HF_uir_J0[nr][3][4] (out)水平力源 - * @param sum_DC_uir_J0[nr][3][4] (out)剪切源 + * @param[out] sum_J0 积分值 * - * @param ptam_fstatsnr (out)峰谷平均法过程文件指针数组 - * @param kerfunc (in)计算核函数的函数指针 + * @param[in] calc_upar 是否计算位移u的空间导数 + * @param[out] sum_uiz_J0 uiz的积分值 + * @param[out] sum_uir_J0 uir的积分值 + * + * @param[out] ptam_fstatsnr (out)峰谷平均法过程文件指针数组 + * @param[in] kerfunc (in)计算核函数的函数指针 * * */ void PTA_method( const MODEL1D *mod1d, MYREAL k0, MYREAL predk, MYCOMPLEX omega, MYINT nr, MYREAL *rs, - MYCOMPLEX sum_EXP_J0[nr][3][4], MYCOMPLEX sum_VF_J0[nr][3][4], - MYCOMPLEX sum_HF_J0[nr][3][4], MYCOMPLEX sum_DC_J0[nr][3][4], + MYCOMPLEX sum_J0[nr][GRT_SRC_M_COUNTS][GRT_SRC_P_COUNTS], bool calc_upar, - MYCOMPLEX sum_EXP_uiz_J0[nr][3][4], MYCOMPLEX sum_VF_uiz_J0[nr][3][4], - MYCOMPLEX sum_HF_uiz_J0[nr][3][4], MYCOMPLEX sum_DC_uiz_J0[nr][3][4], - MYCOMPLEX sum_EXP_uir_J0[nr][3][4], MYCOMPLEX sum_VF_uir_J0[nr][3][4], - MYCOMPLEX sum_HF_uir_J0[nr][3][4], MYCOMPLEX sum_DC_uir_J0[nr][3][4], + MYCOMPLEX sum_uiz_J0[nr][GRT_SRC_M_COUNTS][GRT_SRC_P_COUNTS], + MYCOMPLEX sum_uir_J0[nr][GRT_SRC_M_COUNTS][GRT_SRC_P_COUNTS], FILE *ptam_fstatsnr[nr][2], KernelFunc kerfunc); @@ -75,12 +63,10 @@ void PTA_method( /** * 观察连续3个点的函数值的实部变化,判断是波峰(1)还是波谷(-1), 并计算对应值。 - * 其中存储函数值的数组形状为[3][3][4], 分别代表 - * 连续3个点、阶数(m=0,1,2) 和4种积分类型(p=0,1,2,3) * * @param idx1 (in)阶数索引 * @param idx2 (in)积分类型索引 - * @param arr[3][3][4] (in)存有连续三个点的函数值的数组 + * @param arr (in)存有连续三个点的函数值的数组 * @param k (in)三个点的起始波数 * @param dk (in)三个点的波数间隔,这样使用k和dk定义了三个点的位置 * @param pk (out)估计的波峰或波谷处的波数 @@ -90,7 +76,7 @@ void PTA_method( * */ MYINT cplx_peak_or_trough( - MYINT idx1, MYINT idx2, const MYCOMPLEX arr[3][3][4], + MYINT idx1, MYINT idx2, const MYCOMPLEX arr[3][GRT_SRC_M_COUNTS][GRT_SRC_P_COUNTS], MYREAL k, MYREAL dk, MYREAL *pk, MYCOMPLEX *value); diff --git a/pygrt/C_extension/include/dynamic/grt.h b/pygrt/C_extension/include/dynamic/grt.h index 67294cb2..b52e6bd9 100755 --- a/pygrt/C_extension/include/dynamic/grt.h +++ b/pygrt/C_extension/include/dynamic/grt.h @@ -24,129 +24,36 @@ void set_num_threads(int num_threads); -/** - * 积分计算Z, R, T三个分量格林函数的频谱的核心函数(被C函数调用) - * - * @param pymod1d (in)`PYMODEL1D` 结构体指针 - * @param nf1 (in)开始计算频谱的频率索引值, 总范围在[nf1, nf2] - * @param nf2 (in)结束计算频谱的频率索引值, 总范围在[nf1, nf2] - * @param nf (in)所有频点个数 - * @param freqs (in)所有频点的频率值(包括未计算的) - * @param nr (in)震中距数量 - * @param rs (in)震中距数组 - * @param wI (in)虚频率, \f$ \tilde{\omega} =\omega - i \omega_I \f$ - * @param vmin_ref (in)参考最小速度,用于定义波数积分的上限 - * @param keps (in)波数积分的收敛条件,要求在某震中距下所有格林函数都收敛,为负数代表不提前判断收敛,按照波数积分上限进行积分 - * @param ampk (in)影响波数k积分上限的系数,见下方 - * @param k0 (in)波数积分的上限 \f$ \tilde{k_{max}}=\sqrt{(k_{0}*\pi/hs)^2 + (ampk*w/vmin_{ref})^2} \f$ ,k循环必须退出, hs=max(震源和台站深度差,1.0) - * @param Length (in)波数k积分间隔 \f$ dk=2\pi/(fabs(L)*r_{max}) \f$ - * @param filonLength (in)Filon积分间隔 - * @param filonCut (in)波数积分和Filon积分的分割点 - * @param print_progressbar (in)是否打印进度条 - * @param EXPgrn[nr][2] (out)复数数组,爆炸源的Z、R分量频谱结果 - * @param VFgrn[nr][2] (out)复数数组,垂直力源的Z、R分量频谱结果 - * @param HFgrn[nr][3] (out)复数数组,水平力源的Z、R、T分量频谱结果 - * @param DDgrn[nr][2] (out)复数数组,45度倾滑的Z、R分量频谱结果 - * @param DSgrn[nr][3] (out)复数数组,90度倾滑的Z、R、T分量频谱结果 - * @param SSgrn[nr][3] (out)复数数组,90度走滑的Z、R、T分量频谱结果 - * - * @param calc_upar (in)是否计算位移u的空间导数 - * @param EXPgrn_uiz[nr][2] (out)复数数组,爆炸源产生的ui_z(位移u对坐标z的偏导)的Z、R分量频谱结果,下同 - * @param VFgrn_uiz[nr][2] (out)复数数组,垂直力源的Z、R分量频谱结果 - * @param HFgrn_uiz[nr][3] (out)复数数组,水平力源的Z、R、T分量频谱结果 - * @param DDgrn_uiz[nr][2] (out)复数数组,45度倾滑的Z、R分量频谱结果 - * @param DSgrn_uiz[nr][3] (out)复数数组,90度倾滑的Z、R、T分量频谱结果 - * @param SSgrn_uiz[nr][3] (out)复数数组,90度走滑的Z、R、T分量频谱结果 - * @param EXPgrn_uir[nr][2] (out)复数数组,爆炸源产生的ui_r(位移u对坐标r的偏导)的Z、R分量频谱结果,下同 - * @param VFgrn_uir[nr][2] (out)复数数组,垂直力源的Z、R分量频谱结果 - * @param HFgrn_uir[nr][3] (out)复数数组,水平力源的Z、R、T分量频谱结果 - * @param DDgrn_uir[nr][2] (out)复数数组,45度倾滑的Z、R分量频谱结果 - * @param DSgrn_uir[nr][3] (out)复数数组,90度倾滑的Z、R、T分量频谱结果 - * @param SSgrn_uir[nr][3] (out)复数数组,90度走滑的Z、R、T分量频谱结果 - * - * - * @param statsstr (in) 积分结果输出目录 - * @param nstatsidxs (in) 输出积分结果的特定频点的个数 - * @param statsidxs (in) 特定频点的索引值 - * - */ -void integ_grn_spec_in_C( - PYMODEL1D *pymod1d, MYINT nf1, MYINT nf2, MYINT nf, MYREAL *freqs, - MYINT nr, MYREAL *rs, MYREAL wI, - MYREAL vmin_ref, MYREAL keps, MYREAL ampk, MYREAL k0, MYREAL Length, MYREAL filonLength, MYREAL filonCut, - bool print_progressbar, - - // 返回值,维度2代表Z、R分量,维度3代表Z、R、T分量 - MYCOMPLEX *EXPcplx[nr][2], // EXZ, EXR 的实部和虚部 - MYCOMPLEX *VFcplx[nr][2], // VFZ, VFR 的实部和虚部 - MYCOMPLEX *HFcplx[nr][3], // HFZ, HFR, HFT 的实部和虚部 - MYCOMPLEX *DDcplx[nr][2], // DDZ, DDR 的实部和虚部 [DD: 45-dip slip] - MYCOMPLEX *DScplx[nr][3], // DSZ, DSR, DST 的实部和虚部 [DS: 90-dip slip] - MYCOMPLEX *SScplx[nr][3], // SSZ, SSR, SST 的实部和虚部 [SS: strike slip] - - bool calc_upar, - MYCOMPLEX *EXPcplx_uiz[nr][2], // EXZ, EXR 的实部和虚部 - MYCOMPLEX *VFcplx_uiz[nr][2], // VFZ, VFR 的实部和虚部 - MYCOMPLEX *HFcplx_uiz[nr][3], // HFZ, HFR, HFT 的实部和虚部 - MYCOMPLEX *DDcplx_uiz[nr][2], // DDZ, DDR 的实部和虚部 [DD: 45-dip slip] - MYCOMPLEX *DScplx_uiz[nr][3], // DSZ, DSR, DST 的实部和虚部 [DS: 90-dip slip] - MYCOMPLEX *SScplx_uiz[nr][3], // SSZ, SSR, SST 的实部和虚部 [SS: strike slip] - MYCOMPLEX *EXPcplx_uir[nr][2], // EXZ, EXR 的实部和虚部 - MYCOMPLEX *VFcplx_uir[nr][2], // VFZ, VFR 的实部和虚部 - MYCOMPLEX *HFcplx_uir[nr][3], // HFZ, HFR, HFT 的实部和虚部 - MYCOMPLEX *DDcplx_uir[nr][2], // DDZ, DDR 的实部和虚部 [DD: 45-dip slip] - MYCOMPLEX *DScplx_uir[nr][3], // DSZ, DSR, DST 的实部和虚部 [DS: 90-dip slip] - MYCOMPLEX *SScplx_uir[nr][3], // SSZ, SSR, SST 的实部和虚部 [SS: strike slip] - - const char *statsstr, // 积分结果输出 - MYINT nstatsidxs, // 仅输出特定频点 - MYINT *statsidxs -); - /** * 积分计算Z, R, T三个分量格林函数的频谱的核心函数(被Python调用) * - * @param pymod1d (in)`PYMODEL1D` 结构体指针 - * @param nf1 (in)开始计算频谱的频率索引值, 总范围在[nf1, nf2] - * @param nf2 (in)结束计算频谱的频率索引值, 总范围在[nf1, nf2] - * @param nf (in)所有频点个数 - * @param freqs (in)所有频点的频率值(包括未计算的) - * @param nr (in)震中距数量 - * @param rs (in)震中距数组 - * @param wI (in)虚频率, \f$ \tilde{\omega} =\omega - i \omega_I \f$ - * @param vmin_ref (in)参考最小速度,用于定义波数积分的上限 - * @param keps (in)波数积分的收敛条件,要求在某震中距下所有格林函数都收敛,为负数代表不提前判断收敛,按照波数积分上限进行积分 - * @param ampk (in)影响波数k积分上限的系数,见下方 - * @param k0 (in)波数积分的上限 \f$ \tilde{k_{max}}=\sqrt{(k_{0}*\pi/hs)^2 + (ampk*w/vmin_{ref})^2} \f$ ,k循环必须退出, hs=max(震源和台站深度差,1.0) - * @param Length (in)波数k积分间隔 \f$ dk=2\pi/(fabs(L)*r_{max}) \f$ - * @param filonLength (in)Filon积分间隔 - * @param filonCut (in)波数积分和Filon积分的分割点 - * @param print_progressbar (in)是否打印进度条 - * @param EXPgrn[nr][2] (out)`GRN` 结构体指针,爆炸源的Z、R分量频谱结果 - * @param VFgrn[nr][2] (out)`GRN` 结构体指针,垂直力源的Z、R分量频谱结果 - * @param HFgrn[nr][3] (out)`GRN` 结构体指针,水平力源的Z、R、T分量频谱结果 - * @param DDgrn[nr][2] (out)`GRN` 结构体指针,45度倾滑的Z、R分量频谱结果 - * @param DSgrn[nr][3] (out)`GRN` 结构体指针,90度倾滑的Z、R、T分量频谱结果 - * @param SSgrn[nr][3] (out)`GRN` 结构体指针,90度走滑的Z、R、T分量频谱结果 + * @param[in] pymod1d (in)`PYMODEL1D` 结构体指针 + * @param[in] nf1 (in)开始计算频谱的频率索引值, 总范围在[nf1, nf2] + * @param[in] nf2 (in)结束计算频谱的频率索引值, 总范围在[nf1, nf2] + * @param[in] nf (in)所有频点个数 + * @param[in] freqs (in)所有频点的频率值(包括未计算的) + * @param[in] nr (in)震中距数量 + * @param[in] rs (in)震中距数组 + * @param[in] wI (in)虚频率, \f$ \tilde{\omega} =\omega - i \omega_I \f$ + * @param[in] vmin_ref (in)参考最小速度,用于定义波数积分的上限 + * @param[in] keps (in)波数积分的收敛条件,要求在某震中距下所有格林函数都收敛,为负数代表不提前判断收敛,按照波数积分上限进行积分 + * @param[in] ampk (in)影响波数k积分上限的系数,见下方 + * @param[in] k0 (in)波数积分的上限 \f$ \tilde{k_{max}}=\sqrt{(k_{0}*\pi/hs)^2 + (ampk*w/vmin_{ref})^2} \f$ ,k循环必须退出, hs=max(震源和台站深度差,1.0) + * @param[in] Length (in)波数k积分间隔 \f$ dk=2\pi/(fabs(L)*r_{max}) \f$ + * @param[in] filonLength (in)Filon积分间隔 + * @param[in] filonCut (in)波数积分和Filon积分的分割点 + * @param[in] print_progressbar (in)是否打印进度条 + * + * @param[out] grn 不同震源不同阶数的格林函数的Z、R、T分量频谱结果 * - * @param calc_upar (in)是否计算位移u的空间导数 - * @param EXPgrn_uiz[nr][2] (out)`GRN` 结构体指针,爆炸源产生的ui_z(位移u对坐标z的偏导)的Z、R分量频谱结果,下同 - * @param VFgrn_uiz[nr][2] (out)`GRN` 结构体指针,垂直力源的Z、R分量频谱结果 - * @param HFgrn_uiz[nr][3] (out)`GRN` 结构体指针,水平力源的Z、R、T分量频谱结果 - * @param DDgrn_uiz[nr][2] (out)`GRN` 结构体指针,45度倾滑的Z、R分量频谱结果 - * @param DSgrn_uiz[nr][3] (out)`GRN` 结构体指针,90度倾滑的Z、R、T分量频谱结果 - * @param SSgrn_uiz[nr][3] (out)`GRN` 结构体指针,90度走滑的Z、R、T分量频谱结果 - * @param EXPgrn_uir[nr][2] (out)`GRN` 结构体指针,爆炸源产生的ui_r(位移u对坐标r的偏导)的Z、R分量频谱结果,下同 - * @param VFgrn_uir[nr][2] (out)`GRN` 结构体指针,垂直力源的Z、R分量频谱结果 - * @param HFgrn_uir[nr][3] (out)`GRN` 结构体指针,水平力源的Z、R、T分量频谱结果 - * @param DDgrn_uir[nr][2] (out)`GRN` 结构体指针,45度倾滑的Z、R分量频谱结果 - * @param DSgrn_uir[nr][3] (out)`GRN` 结构体指针,90度倾滑的Z、R、T分量频谱结果 - * @param SSgrn_uir[nr][3] (out)`GRN` 结构体指针,90度走滑的Z、R、T分量频谱结果 + * @param[in] calc_upar 是否计算位移u的空间导数 + * @param[out] grn_uiz 不同震源不同阶数的ui_z的Z、R、T分量频谱结果 + * @param[out] grn_uir 不同震源不同阶数的ui_r的Z、R、T分量频谱结果 * - * @param statsstr (in) 积分结果输出目录 - * @param nstatsidxs (in) 输出积分结果的特定频点的个数 - * @param statsidxs (in) 特定频点的索引值 + * @param[in] statsstr (in) 积分过程输出目录 + * @param[in] nstatsidxs (in) 输出积分过程的特定频点的个数 + * @param[in] statsidxs (in) 特定频点的索引值 * */ void integ_grn_spec( @@ -155,27 +62,12 @@ void integ_grn_spec( MYREAL vmin_ref, MYREAL keps, MYREAL ampk, MYREAL k0, MYREAL Length, MYREAL filonLength, MYREAL filonCut, bool print_progressbar, - // 返回值,维度2代表Z、R分量,维度3代表Z、R、T分量 - GRN *EXPgrn[nr][2], // EXZ, EXR 的实部和虚部 - GRN *VFgrn[nr][2], // VFZ, VFR 的实部和虚部 - GRN *HFgrn[nr][3], // HFZ, HFR, HFT 的实部和虚部 - GRN *DDgrn[nr][2], // DDZ, DDR 的实部和虚部 [DD: 45-dip slip] - GRN *DSgrn[nr][3], // DSZ, DSR, DST 的实部和虚部 [DS: 90-dip slip] - GRN *SSgrn[nr][3], // SSZ, SSR, SST 的实部和虚部 [SS: strike slip] + // 返回值,代表Z、R、T分量 + MYCOMPLEX *grn[nr][GRT_SRC_M_COUNTS][GRT_SRC_CHA_COUNTS], bool calc_upar, - GRN *EXPgrn_uiz[nr][2], // EXZ, EXR 的实部和虚部 - GRN *VFgrn_uiz[nr][2], // VFZ, VFR 的实部和虚部 - GRN *HFgrn_uiz[nr][3], // HFZ, HFR, HFT 的实部和虚部 - GRN *DDgrn_uiz[nr][2], // DDZ, DDR 的实部和虚部 [DD: 45-dip slip] - GRN *DSgrn_uiz[nr][3], // DSZ, DSR, DST 的实部和虚部 [DS: 90-dip slip] - GRN *SSgrn_uiz[nr][3], // SSZ, SSR, SST 的实部和虚部 [SS: strike slip] - GRN *EXPgrn_uir[nr][2], // EXZ, EXR 的实部和虚部 - GRN *VFgrn_uir[nr][2], // VFZ, VFR 的实部和虚部 - GRN *HFgrn_uir[nr][3], // HFZ, HFR, HFT 的实部和虚部 - GRN *DDgrn_uir[nr][2], // DDZ, DDR 的实部和虚部 [DD: 45-dip slip] - GRN *DSgrn_uir[nr][3], // DSZ, DSR, DST 的实部和虚部 [DS: 90-dip slip] - GRN *SSgrn_uir[nr][3], // SSZ, SSR, SST 的实部和虚部 [SS: strike slip] + MYCOMPLEX *grn_uiz[nr][GRT_SRC_M_COUNTS][GRT_SRC_CHA_COUNTS], + MYCOMPLEX *grn_uir[nr][GRT_SRC_M_COUNTS][GRT_SRC_CHA_COUNTS], const char *statsstr, // 积分结果输出 MYINT nstatsidxs, // 仅输出特定频点 diff --git a/pygrt/C_extension/include/dynamic/propagate.h b/pygrt/C_extension/include/dynamic/propagate.h index e56f46b6..0fa38a17 100755 --- a/pygrt/C_extension/include/dynamic/propagate.h +++ b/pygrt/C_extension/include/dynamic/propagate.h @@ -79,25 +79,17 @@ * 即空间划分为FA,AB,BL, 计算这三个广义层的系数矩阵,再讨论震源层和接收层的深浅, * 计算相应的矩阵。 * - * @param mod1d (in)`MODEL1D` 结构体指针 - * @param omega (in)复数频率 - * @param k (in)波数 - * @param EXP_qwv[3][3] (out)爆炸源核函数 - * @param VF_qwv[3][3] (out)垂直力源核函数 - * @param HF_qwv[3][3] (out)水平力源核函数 - * @param DC_qwv[3][3] (out)剪切源核函数 - * @param calc_uiz (in)是否计算ui_z(位移u对坐标z的偏导) - * @param EXP_uiz_qwv[3][3] (out)爆炸源产生的ui_z的核函数,下同 - * @param VF_uiz_qwv[3][3] (out)垂直力源核函数 - * @param HF_uiz_qwv[3][3] (out)水平力源核函数 - * @param DC_uiz_qwv[3][3] (out)剪切源核函数 + * @param[in] mod1d `MODEL1D` 结构体指针 + * @param[in] omega 复数频率 + * @param[in] k 波数 + * @param[out] QWV 不同震源,不同阶数的核函数 \f$ q_m, w_m, v_m \f$ + * @param[in] calc_uiz 是否计算ui_z(位移u对坐标z的偏导) + * @param[out] QWV_uiz 不同震源,不同阶数的核函数对z的偏导 \f$ \frac{\partial q_m}{\partial z}, \frac{\partial w_m}{\partial z}, \frac{\partial v_m}{\partial z} \f$ * */ void kernel( - const MODEL1D *mod1d, MYCOMPLEX omega, MYREAL k, - MYCOMPLEX EXP_qwv[3][3], MYCOMPLEX VF_qwv[3][3], MYCOMPLEX HF_qwv[3][3], MYCOMPLEX DC_qwv[3][3], - bool calc_uiz, - MYCOMPLEX EXP_uiz_qwv[3][3], MYCOMPLEX VF_uiz_qwv[3][3], MYCOMPLEX HF_uiz_qwv[3][3], MYCOMPLEX DC_uiz_qwv[3][3]); + const MODEL1D *mod1d, MYCOMPLEX omega, MYREAL k, MYCOMPLEX QWV[GRT_SRC_M_COUNTS][GRT_SRC_QWV_COUNTS], + bool calc_uiz, MYCOMPLEX QWV_uiz[GRT_SRC_M_COUNTS][GRT_SRC_QWV_COUNTS]); diff --git a/pygrt/C_extension/include/dynamic/source.h b/pygrt/C_extension/include/dynamic/source.h index 5b5cb38d..1b318f3c 100755 --- a/pygrt/C_extension/include/dynamic/source.h +++ b/pygrt/C_extension/include/dynamic/source.h @@ -20,19 +20,16 @@ * 数组形状[3][3][2],代表在[i][j][p]时表示m=i阶时的 * P(j=0),SV(j=1),SH(j=2)的震源系数(分别可记为q,w,v),且分为下行波(p=0)和上行波(p=1). * - * @param src_xa (in)震源层的P波归一化垂直波数 \f$ \sqrt{1 - (k_a/k)^2} \f$ - * @param src_xb (in)震源层的S波归一化垂直波数 \f$ \sqrt{1 - (k_b/k)^2} \f$ - * @param src_kaka (in)震源层的P波水平波数的平方 \f$ k_a^2=(\frac{\omega}{V_a})^2 \f$ - * @param src_kbkb (in)震源层的S波水平波数的平方 \f$ k_b^2=(\frac{\omega}{V_b})^2 \f$ - * @param omega (in)复数频率 - * @param k (in)波数 - * @param EXP[3][3][2] (out)爆炸源的震源系数,下同 - * @param VF[3][3][2] (out)垂直力源 - * @param HF[3][3][2] (out)水平力源 - * @param DC[3][3][2] (out)剪切源 + * @param[in] src_xa 震源层的P波归一化垂直波数 \f$ \sqrt{1 - (k_a/k)^2} \f$ + * @param[in] src_xb 震源层的S波归一化垂直波数 \f$ \sqrt{1 - (k_b/k)^2} \f$ + * @param[in] src_kaka 震源层的P波水平波数的平方 \f$ k_a^2=(\frac{\omega}{V_a})^2 \f$ + * @param[in] src_kbkb 震源层的S波水平波数的平方 \f$ k_b^2=(\frac{\omega}{V_b})^2 \f$ + * @param[in] omega 复数频率 + * @param[in] k 波数 + * @param[out] coef 震源系数 \f$ P_m, SV_m, SH_m \f$ * */ void source_coef( MYCOMPLEX src_xa, MYCOMPLEX src_xb, MYCOMPLEX src_kaka, MYCOMPLEX src_kbkb, MYCOMPLEX omega, MYREAL k, - MYCOMPLEX EXP[3][3][2], MYCOMPLEX VF[3][3][2], MYCOMPLEX HF[3][3][2], MYCOMPLEX DC[3][3][2]); + MYCOMPLEX coef[GRT_SRC_M_COUNTS][GRT_SRC_QWV_COUNTS][2]); diff --git a/pygrt/C_extension/include/static/static_propagate.h b/pygrt/C_extension/include/static/static_propagate.h index f539a11e..fcb6573f 100644 --- a/pygrt/C_extension/include/static/static_propagate.h +++ b/pygrt/C_extension/include/static/static_propagate.h @@ -24,7 +24,5 @@ * 此处omega未使用,传入0即可 */ void static_kernel( - const MODEL1D *mod1d, MYCOMPLEX omega, MYREAL k, - MYCOMPLEX EXP_qwv[3][3], MYCOMPLEX VF_qwv[3][3], MYCOMPLEX HF_qwv[3][3], MYCOMPLEX DC_qwv[3][3], - bool calc_uiz, - MYCOMPLEX EXP_uiz_qwv[3][3], MYCOMPLEX VF_uiz_qwv[3][3], MYCOMPLEX HF_uiz_qwv[3][3], MYCOMPLEX DC_uiz_qwv[3][3]); \ No newline at end of file + const MODEL1D *mod1d, MYCOMPLEX omega, MYREAL k, MYCOMPLEX QWV[GRT_SRC_M_COUNTS][GRT_SRC_QWV_COUNTS], + bool calc_uiz, MYCOMPLEX QWV_uiz[GRT_SRC_M_COUNTS][GRT_SRC_QWV_COUNTS]); \ No newline at end of file diff --git a/pygrt/C_extension/include/static/static_source.h b/pygrt/C_extension/include/static/static_source.h index 8bfd679d..8420f341 100644 --- a/pygrt/C_extension/include/static/static_source.h +++ b/pygrt/C_extension/include/static/static_source.h @@ -18,14 +18,10 @@ * 数组形状[3][3][2],代表在[i][j][p]时表示m=i阶时的 * P(j=0),SV(j=1),SH(j=2)的震源系数(分别可记为q,w,v),且分为下行波(p=0)和上行波(p=1). * - * @param delta (in)震源层的\f$ \Delta \f$ - * @param k (in)波数 - * @param EXP[3][3][2] (out)爆炸源的震源系数,下同 - * @param VF[3][3][2] (out)垂直力源 - * @param HF[3][3][2] (out)水平力源 - * @param DC[3][3][2] (out)剪切源 + * @param[in] delta 震源层的\f$ \Delta \f$ + * @param[in] k 波数 + * @param[out] coef 震源系数 \f$ P_m, SV_m, SH_m \f$ */ void static_source_coef( - MYCOMPLEX delta, MYREAL k, - MYCOMPLEX EXP[3][3][2], MYCOMPLEX VF[3][3][2], MYCOMPLEX HF[3][3][2], MYCOMPLEX DC[3][3][2]); + MYCOMPLEX delta, MYREAL k, MYCOMPLEX coef[GRT_SRC_M_COUNTS][GRT_SRC_QWV_COUNTS][2]); \ No newline at end of file diff --git a/pygrt/C_extension/include/static/stgrt.h b/pygrt/C_extension/include/static/stgrt.h index 861ebe78..0f61d2c1 100644 --- a/pygrt/C_extension/include/static/stgrt.h +++ b/pygrt/C_extension/include/static/stgrt.h @@ -30,53 +30,26 @@ * @param Length (in)波数k积分间隔 \f$ dk=2\pi/(fabs(L)*r_{max}) \f$ * @param filonLength (in)Filon积分间隔 * @param filonCut (in)波数积分和Filon积分的分割点 - * @param EXPgrn[nr][2] (out)浮点数数组,爆炸源的Z、R分量频谱结果 - * @param VFgrn[nr][2] (out)浮点数数组,垂直力源的Z、R分量频谱结果 - * @param HFgrn[nr][3] (out)浮点数数组,水平力源的Z、R、T分量频谱结果 - * @param DDgrn[nr][2] (out)浮点数数组,45度倾滑的Z、R分量频谱结果 - * @param DSgrn[nr][3] (out)浮点数数组,90度倾滑的Z、R、T分量频谱结果 - * @param SSgrn[nr][3] (out)浮点数数组,90度走滑的Z、R、T分量频谱结果 - * - * @param calc_upar (in)是否计算位移u的空间导数 - * @param EXPgrn_uiz[nr][2] (out)浮点数数组,爆炸源产生的ui_z(位移u对坐标z的偏导)的Z、R分量频谱结果,下同 - * @param VFgrn_uiz[nr][2] (out)浮点数数组,垂直力源的Z、R分量频谱结果 - * @param HFgrn_uiz[nr][3] (out)浮点数数组,水平力源的Z、R、T分量频谱结果 - * @param DDgrn_uiz[nr][2] (out)浮点数数组,45度倾滑的Z、R分量频谱结果 - * @param DSgrn_uiz[nr][3] (out)浮点数数组,90度倾滑的Z、R、T分量频谱结果 - * @param SSgrn_uiz[nr][3] (out)浮点数数组,90度走滑的Z、R、T分量频谱结果 - * @param EXPgrn_uir[nr][2] (out)浮点数数组,爆炸源产生的ui_r(位移u对坐标r的偏导)的Z、R分量频谱结果,下同 - * @param VFgrn_uir[nr][2] (out)浮点数数组,垂直力源的Z、R分量频谱结果 - * @param HFgrn_uir[nr][3] (out)浮点数数组,水平力源的Z、R、T分量频谱结果 - * @param DDgrn_uir[nr][2] (out)浮点数数组,45度倾滑的Z、R分量频谱结果 - * @param DSgrn_uir[nr][3] (out)浮点数数组,90度倾滑的Z、R、T分量频谱结果 - * @param SSgrn_uir[nr][3] (out)浮点数数组,90度走滑的Z、R、T分量频谱结果 + * + * @param[out] grn 浮点数数组,不同震源不同阶数的静态格林函数的Z、R、T分量 + * + * @param[in] calc_upar 是否计算位移u的空间导数 + * @param[out] grn_uiz 浮点数数组,不同震源不同阶数的ui_z的Z、R、T分量 + * @param[out] grn_uir 浮点数数组,不同震源不同阶数的ui_r的Z、R、T分量 + * + * @param[in] statsstr (in) 积分过程输出目录 * */ void integ_static_grn( PYMODEL1D *pymod1d, MYINT nr, MYREAL *rs, MYREAL vmin_ref, MYREAL keps, MYREAL k0, MYREAL Length, MYREAL filonLength, MYREAL filonCut, - // 返回值,维度2代表Z、R分量,维度3代表Z、R、T分量 - MYREAL EXPgrn[nr][2], // EXZ, EXR 的实部和虚部 - MYREAL VFgrn[nr][2], // VFZ, VFR 的实部和虚部 - MYREAL HFgrn[nr][3], // HFZ, HFR, HFT 的实部和虚部 - MYREAL DDgrn[nr][2], // DDZ, DDR 的实部和虚部 [DD: 45-dip slip] - MYREAL DSgrn[nr][3], // DSZ, DSR, DST 的实部和虚部 [DS: 90-dip slip] - MYREAL SSgrn[nr][3], // SSZ, SSR, SST 的实部和虚部 [SS: strike slip] + // 返回值,代表Z、R、T分量 + MYREAL grn[nr][GRT_SRC_M_COUNTS][GRT_SRC_CHA_COUNTS], bool calc_upar, - MYREAL EXPgrn_uiz[nr][2], // EXZ, EXR 的实部和虚部 - MYREAL VFgrn_uiz[nr][2], // VFZ, VFR 的实部和虚部 - MYREAL HFgrn_uiz[nr][3], // HFZ, HFR, HFT 的实部和虚部 - MYREAL DDgrn_uiz[nr][2], // DDZ, DDR 的实部和虚部 [DD: 45-dip slip] - MYREAL DSgrn_uiz[nr][3], // DSZ, DSR, DST 的实部和虚部 [DS: 90-dip slip] - MYREAL SSgrn_uiz[nr][3], // SSZ, SSR, SST 的实部和虚部 [SS: strike slip] - MYREAL EXPgrn_uir[nr][2], // EXZ, EXR 的实部和虚部 - MYREAL VFgrn_uir[nr][2], // VFZ, VFR 的实部和虚部 - MYREAL HFgrn_uir[nr][3], // HFZ, HFR, HFT 的实部和虚部 - MYREAL DDgrn_uir[nr][2], // DDZ, DDR 的实部和虚部 [DD: 45-dip slip] - MYREAL DSgrn_uir[nr][3], // DSZ, DSR, DST 的实部和虚部 [DS: 90-dip slip] - MYREAL SSgrn_uir[nr][3], // SSZ, SSR, SST 的实部和虚部 [SS: strike slip] + MYREAL grn_uiz[nr][GRT_SRC_M_COUNTS][GRT_SRC_CHA_COUNTS], + MYREAL grn_uir[nr][GRT_SRC_M_COUNTS][GRT_SRC_CHA_COUNTS], const char *statsstr // 积分结果输出 ); \ No newline at end of file diff --git a/pygrt/C_extension/src/common/const.c b/pygrt/C_extension/src/common/const.c new file mode 100644 index 00000000..7ce41ab7 --- /dev/null +++ b/pygrt/C_extension/src/common/const.c @@ -0,0 +1,22 @@ +/** + * @file const.c + * @author Zhu Dengda (zhudengda@mail.iggcas.ac.cn) + * @date 2025-04-25 + * + * 将全局变量放在该文件中 + */ + +#include "common/const.h" + + +/** 分别对应爆炸源(0阶),垂直力源(0阶),水平力源(1阶),剪切源(0,1,2阶) */ +const MYINT GRT_SRC_M_ORDERS[GRT_SRC_M_COUNTS] = {0, 0, 1, 0, 1, 2}; + +/** 不同震源,不同阶数的名称简写,用于命名 */ +const char *GRT_SRC_M_NAME_ABBR[GRT_SRC_M_COUNTS] = {"EX", "VF", "HF", "DD", "DS", "SS"}; + +/** ZRT三分量代号 */ +const char GRT_ZRTchs[] = {'Z', 'R', 'T'}; + +/** ZNE三分量代号 */ +const char GRT_ZNEchs[] = {'Z', 'N', 'E'}; diff --git a/pygrt/C_extension/src/common/dwm.c b/pygrt/C_extension/src/common/dwm.c index e4fd072f..cd613e7f 100644 --- a/pygrt/C_extension/src/common/dwm.c +++ b/pygrt/C_extension/src/common/dwm.c @@ -26,32 +26,17 @@ MYREAL discrete_integ( const MODEL1D *mod1d, MYREAL dk, MYREAL kmax, MYREAL keps, MYCOMPLEX omega, MYINT nr, MYREAL *rs, - MYCOMPLEX sum_EXP_J[nr][3][4], MYCOMPLEX sum_VF_J[nr][3][4], - MYCOMPLEX sum_HF_J[nr][3][4], MYCOMPLEX sum_DC_J[nr][3][4], + MYCOMPLEX sum_J[nr][GRT_SRC_M_COUNTS][GRT_SRC_P_COUNTS], bool calc_upar, - MYCOMPLEX sum_EXP_uiz_J[nr][3][4], MYCOMPLEX sum_VF_uiz_J[nr][3][4], - MYCOMPLEX sum_HF_uiz_J[nr][3][4], MYCOMPLEX sum_DC_uiz_J[nr][3][4], - MYCOMPLEX sum_EXP_uir_J[nr][3][4], MYCOMPLEX sum_VF_uir_J[nr][3][4], - MYCOMPLEX sum_HF_uir_J[nr][3][4], MYCOMPLEX sum_DC_uir_J[nr][3][4], + MYCOMPLEX sum_uiz_J[nr][GRT_SRC_M_COUNTS][GRT_SRC_P_COUNTS], + MYCOMPLEX sum_uir_J[nr][GRT_SRC_M_COUNTS][GRT_SRC_P_COUNTS], FILE *fstats, KernelFunc kerfunc) { - MYCOMPLEX EXP_J[3][4], VF_J[3][4], HF_J[3][4], DC_J[3][4]; - - // 不同震源的核函数 F(k, w) - // 第一个维度3代表阶数m=0,1,2,第二个维度3代表三类系数qm,wm,vm - // 实际上对于不同震源只有特定阶数/系数才有值,不需要建立3x3的小矩阵, - // 但这里还是为了方便可读性,牺牲了部分性能 - MYCOMPLEX EXP_qwv[3][3], VF_qwv[3][3], HF_qwv[3][3], DC_qwv[3][3]; - MYCOMPLEX (*pEXP_qwv)[3] = (sum_EXP_J!=NULL)? EXP_qwv : NULL; - MYCOMPLEX (*pVF_qwv)[3] = (sum_VF_J!=NULL)? VF_qwv : NULL; - MYCOMPLEX (*pHF_qwv)[3] = (sum_HF_J!=NULL)? HF_qwv : NULL; - MYCOMPLEX (*pDC_qwv)[3] = (sum_DC_J!=NULL)? DC_qwv : NULL; - - MYCOMPLEX EXP_uiz_qwv[3][3], VF_uiz_qwv[3][3], HF_uiz_qwv[3][3], DC_uiz_qwv[3][3]; - MYCOMPLEX (*pEXP_uiz_qwv)[3] = (sum_EXP_uiz_J!=NULL)? EXP_uiz_qwv : NULL; - MYCOMPLEX (*pVF_uiz_qwv)[3] = (sum_VF_uiz_J!=NULL)? VF_uiz_qwv : NULL; - MYCOMPLEX (*pHF_uiz_qwv)[3] = (sum_HF_uiz_J!=NULL)? HF_uiz_qwv : NULL; - MYCOMPLEX (*pDC_uiz_qwv)[3] = (sum_DC_uiz_J!=NULL)? DC_uiz_qwv : NULL; + MYCOMPLEX SUM[GRT_SRC_M_COUNTS][GRT_SRC_P_COUNTS]; + + // 不同震源不同阶数的核函数 F(k, w) + MYCOMPLEX QWV[GRT_SRC_M_COUNTS][GRT_SRC_QWV_COUNTS]; + MYCOMPLEX QWV_uiz[GRT_SRC_M_COUNTS][GRT_SRC_QWV_COUNTS]; MYREAL k = 0.0; MYINT ik = 0; @@ -73,47 +58,36 @@ MYREAL discrete_integ( // printf("w=%15.5e, ik=%d\n", CREAL(omega), ik); // 计算核函数 F(k, w) - kerfunc(mod1d, omega, k, pEXP_qwv, pVF_qwv, pHF_qwv, pDC_qwv, - calc_upar, pEXP_uiz_qwv, pVF_uiz_qwv, pHF_uiz_qwv, pDC_uiz_qwv); + kerfunc(mod1d, omega, k, QWV, calc_upar, QWV_uiz); // 记录积分核函数 - if(fstats!=NULL){ - write_stats( - fstats, k, - EXP_qwv, VF_qwv, HF_qwv, DC_qwv); - } + if(fstats!=NULL) write_stats(fstats, k, QWV); // 震中距rs循环 iendk = true; for(MYINT ir=0; ir RZERO){ - // 判断是否达到收敛条件 - if(sum_EXP_J!=NULL && m==0 && (v==0||v==2)) iendk0 = iendk0 && (CABS(EXP_J[m][v])/ CABS(sum_EXP_J[ir][m][v]) <= keps); - if(sum_VF_J!=NULL && m==0 && (v==0||v==2)) iendk0 = iendk0 && (CABS(VF_J[m][v]) / CABS(sum_VF_J[ir][m][v]) <= keps); - if(sum_HF_J!=NULL && m==1) iendk0 = iendk0 && (CABS(HF_J[m][v]) / CABS(sum_HF_J[ir][m][v]) <= keps); - if(sum_DC_J!=NULL && ((m==0 && (v==0||v==2)) || m!=0)) iendk0 = iendk0 && (CABS(DC_J[m][v]) / CABS(sum_DC_J[ir][m][v]) <= keps); - } + for(MYINT i=0; i 0.0){ - // 判断是否达到收敛条件 - if(sum_EXP_J!=NULL && m==0 && (v==0||v==2)) iendk0 = iendk0 && (CABS(EXP_J[m][v])/ CABS(sum_EXP_J[ir][m][v]) <= keps); - if(sum_VF_J!=NULL && m==0 && (v==0||v==2)) iendk0 = iendk0 && (CABS(VF_J[m][v]) / CABS(sum_VF_J[ir][m][v]) <= keps); - if(sum_HF_J!=NULL && m==1) iendk0 = iendk0 && (CABS(HF_J[m][v]) / CABS(sum_HF_J[ir][m][v]) <= keps); - if(sum_DC_J!=NULL && ((m==0 && (v==0||v==2)) || m!=0)) iendk0 = iendk0 && (CABS(DC_J[m][v]) / CABS(sum_DC_J[ir][m][v]) <= keps); - } + for(MYINT i=0; i= 2 && ipt[ir][m][v] < maxNpt) { - if (cplx_peak_or_trough(m, v, J3[ir], k, dk, &kpt[ir][m][v][ipt[ir][m][v]], &tmp0) != 0) { - pt[ir][m][v][ipt[ir][m][v]++] = tmp0; - gpt[ir][m][v] = 0; - } else if (gpt[ir][m][v] >= maxnwait) { - kpt[ir][m][v][ipt[ir][m][v]] = k - dk; - pt[ir][m][v][ipt[ir][m][v]++] = J3[ir][1][m][v]; - gpt[ir][m][v] = 0; + if (gpt[ir][im][v] >= 2 && ipt[ir][im][v] < maxNpt) { + if (cplx_peak_or_trough(im, v, J3[ir], k, dk, &kpt[ir][im][v][ipt[ir][im][v]], &tmp0) != 0) { + pt[ir][im][v][ipt[ir][im][v]++] = tmp0; + gpt[ir][im][v] = 0; + } else if (gpt[ir][im][v] >= maxnwait) { + kpt[ir][im][v][ipt[ir][im][v]] = k - dk; + pt[ir][im][v][ipt[ir][im][v]++] = J3[ir][1][im][v]; + gpt[ir][im][v] = 0; } } - *iendk0 = *iendk0 && (ipt[ir][m][v] == maxNpt); + *iendk0 = *iendk0 && (ipt[ir][im][v] == maxNpt); } @@ -73,121 +73,61 @@ static void process_peak_or_trough( * @param maxnwait 最大等待次数 * @param k 波数 * @param dk 波数步长 - * @param EXP_J3 爆炸源对应的被积函数的幅值数组,下同 - * @param VF_J3 垂直力源 - * @param HF_J3 水平力源 - * @param DC_J3 剪切源 - * @param sum_EXP_J 爆炸源对应的积分值数组,下同 - * @param sum_VF_J 垂直力源 - * @param sum_HF_J 水平力源 - * @param sum_DC_J 剪切源 + * @param SUM3 被积函数的幅值数组 + * @param sum_J 的积分值数组 * - * @param kEXPpt 爆炸源对应的积分值峰谷的波数数组,下同 - * @param EXPpt 爆炸源对应的用于存储波峰/波谷点的幅值数组,下同 - * @param iEXPpt 爆炸源对应的用于存储波峰/波谷点的个数数组,下同 - * @param gEXPpt 爆炸源对应的用于存储等待迭次数的数组,下同 - * @param kVFpt 垂直力源 - * @param VFpt 垂直力源 - * @param iVFpt 垂直力源 - * @param gVFpt 垂直力源 - * @param kHFpt 水平力源 - * @param HFpt 水平力源 - * @param iHFpt 水平力源 - * @param gHFpt 水平力源 - * @param kDCpt 剪切源 - * @param DCpt 剪切源 - * @param iDCpt 剪切源 - * @param gDCpt 剪切源 + * @param Kpt 积分值峰谷的波数数组 + * @param Fpt 用于存储波峰/波谷点的幅值数组 + * @param Ipt 用于存储波峰/波谷点的个数数组 + * @param Gpt 用于存储等待迭次数的数组 * + * @param iendk0 是否收集足够峰谷 * */ static void ptam_once( const MYINT ir, const MYINT nr, const MYREAL precoef, MYINT maxNpt, MYINT maxnwait, MYREAL k, MYREAL dk, - MYCOMPLEX EXP_J3[nr][3][3][4], MYCOMPLEX VF_J3[nr][3][3][4], - MYCOMPLEX HF_J3[nr][3][3][4], MYCOMPLEX DC_J3[nr][3][3][4], - MYCOMPLEX sum_EXP_J[nr][3][4], MYCOMPLEX sum_VF_J[nr][3][4], - MYCOMPLEX sum_HF_J[nr][3][4], MYCOMPLEX sum_DC_J[nr][3][4], - MYREAL kEXPpt[nr][3][4][maxNpt], MYCOMPLEX EXPpt[nr][3][4][maxNpt], MYINT iEXPpt[nr][3][4], MYINT gEXPpt[nr][3][4], - MYREAL kVFpt[nr][3][4][maxNpt], MYCOMPLEX VFpt[nr][3][4][maxNpt], MYINT iVFpt[nr][3][4], MYINT gVFpt[nr][3][4], - MYREAL kHFpt[nr][3][4][maxNpt], MYCOMPLEX HFpt[nr][3][4][maxNpt], MYINT iHFpt[nr][3][4], MYINT gHFpt[nr][3][4], - MYREAL kDCpt[nr][3][4][maxNpt], MYCOMPLEX DCpt[nr][3][4][maxNpt], MYINT iDCpt[nr][3][4], MYINT gDCpt[nr][3][4], + MYCOMPLEX SUM3[nr][3][GRT_SRC_M_COUNTS][GRT_SRC_P_COUNTS], + MYCOMPLEX sum_J[nr][GRT_SRC_M_COUNTS][GRT_SRC_P_COUNTS], + MYREAL Kpt[nr][GRT_SRC_M_COUNTS][GRT_SRC_P_COUNTS][maxNpt], + MYCOMPLEX Fpt[nr][GRT_SRC_M_COUNTS][GRT_SRC_P_COUNTS][maxNpt], + MYINT Ipt[nr][GRT_SRC_M_COUNTS][GRT_SRC_P_COUNTS], + MYINT Gpt[nr][GRT_SRC_M_COUNTS][GRT_SRC_P_COUNTS], bool *iendk0) { - // 赋更新量 - for(MYINT m=0; m<3; ++m){ - for(MYINT v=0; v<4; ++v){ - // EXP_J3, VF_J3, HF_J3, DC_J3转为求和结果 - if(sum_EXP_J!=NULL) { - sum_EXP_J[ir][m][v] += EXP_J3[ir][2][m][v] * precoef; - EXP_J3[ir][2][m][v] = sum_EXP_J[ir][m][v]; - } - if(sum_VF_J!=NULL){ - sum_VF_J[ir][m][v] += VF_J3[ir][2][m][v] * precoef; - VF_J3[ir][2][m][v] = sum_VF_J[ir][m][v]; - } - if(sum_HF_J!=NULL){ - sum_HF_J[ir][m][v] += HF_J3[ir][2][m][v] * precoef; - HF_J3[ir][2][m][v] = sum_HF_J[ir][m][v]; - } - if(sum_DC_J!=NULL){ - sum_DC_J[ir][m][v] += DC_J3[ir][2][m][v] * precoef; - DC_J3[ir][2][m][v] = sum_DC_J[ir][m][v]; - } - - } - } - - // 3点以上,判断波峰波谷 *iendk0 = true; - for (MYINT m = 0; m < 3; ++m) { - for (MYINT v = 0; v < 4; ++v) { - if (sum_EXP_J != NULL && m == 0 && (v == 0 || v == 2)) { - process_peak_or_trough(ir, m, v, maxNpt, maxnwait, k, dk, EXP_J3, kEXPpt, EXPpt, iEXPpt, gEXPpt, iendk0); - } - if (sum_VF_J != NULL && m == 0 && (v == 0 || v == 2)) { - process_peak_or_trough(ir, m, v, maxNpt, maxnwait, k, dk, VF_J3, kVFpt, VFpt, iVFpt, gVFpt, iendk0); - } - if (sum_HF_J != NULL && m == 1) { - process_peak_or_trough(ir, m, v, maxNpt, maxnwait, k, dk, HF_J3, kHFpt, HFpt, iHFpt, gHFpt, iendk0); - } - if (sum_DC_J != NULL && ((m == 0 && (v == 0 || v == 2)) || m != 0)) { - process_peak_or_trough(ir, m, v, maxNpt, maxnwait, k, dk, DC_J3, kDCpt, DCpt, iDCpt, gDCpt, iendk0); - } - } - } - + for(MYINT i=0; iRe = (MYREAL*)calloc(nf, sizeof(MYREAL)); - EXPgrn[ir][i]->Im = (MYREAL*)calloc(nf, sizeof(MYREAL)); - } - if(EXPcplx_uiz) { - EXPgrn_uiz[ir][i] = (GRN*)calloc(1, sizeof(GRN)); - EXPgrn_uiz[ir][i]->Re = (MYREAL*)calloc(nf, sizeof(MYREAL)); - EXPgrn_uiz[ir][i]->Im = (MYREAL*)calloc(nf, sizeof(MYREAL)); - } - if(EXPcplx_uir) { - EXPgrn_uir[ir][i] = (GRN*)calloc(1, sizeof(GRN)); - EXPgrn_uir[ir][i]->Re = (MYREAL*)calloc(nf, sizeof(MYREAL)); - EXPgrn_uir[ir][i]->Im = (MYREAL*)calloc(nf, sizeof(MYREAL)); - } - // - if(VFcplx) { - VFgrn[ir][i] = (GRN*)calloc(1, sizeof(GRN)); - VFgrn[ir][i]->Re = (MYREAL*)calloc(nf, sizeof(MYREAL)); - VFgrn[ir][i]->Im = (MYREAL*)calloc(nf, sizeof(MYREAL)); - } - if(VFcplx_uiz) { - VFgrn_uiz[ir][i] = (GRN*)calloc(1, sizeof(GRN)); - VFgrn_uiz[ir][i]->Re = (MYREAL*)calloc(nf, sizeof(MYREAL)); - VFgrn_uiz[ir][i]->Im = (MYREAL*)calloc(nf, sizeof(MYREAL)); - } - if(VFcplx_uir) { - VFgrn_uir[ir][i] = (GRN*)calloc(1, sizeof(GRN)); - VFgrn_uir[ir][i]->Re = (MYREAL*)calloc(nf, sizeof(MYREAL)); - VFgrn_uir[ir][i]->Im = (MYREAL*)calloc(nf, sizeof(MYREAL)); - } - // - if(DDcplx) { - DDgrn[ir][i] = (GRN*)calloc(1, sizeof(GRN)); - DDgrn[ir][i]->Re = (MYREAL*)calloc(nf, sizeof(MYREAL)); - DDgrn[ir][i]->Im = (MYREAL*)calloc(nf, sizeof(MYREAL)); - } - if(DDcplx_uiz) { - DDgrn_uiz[ir][i] = (GRN*)calloc(1, sizeof(GRN)); - DDgrn_uiz[ir][i]->Re = (MYREAL*)calloc(nf, sizeof(MYREAL)); - DDgrn_uiz[ir][i]->Im = (MYREAL*)calloc(nf, sizeof(MYREAL)); - } - if(DDcplx_uir) { - DDgrn_uir[ir][i] = (GRN*)calloc(1, sizeof(GRN)); - DDgrn_uir[ir][i]->Re = (MYREAL*)calloc(nf, sizeof(MYREAL)); - DDgrn_uir[ir][i]->Im = (MYREAL*)calloc(nf, sizeof(MYREAL)); - } - } - // - if(HFcplx) { - HFgrn[ir][i] = (GRN*)calloc(1, sizeof(GRN)); - HFgrn[ir][i]->Re = (MYREAL*)calloc(nf, sizeof(MYREAL)); - HFgrn[ir][i]->Im = (MYREAL*)calloc(nf, sizeof(MYREAL)); - } - if(HFcplx_uiz) { - HFgrn_uiz[ir][i] = (GRN*)calloc(1, sizeof(GRN)); - HFgrn_uiz[ir][i]->Re = (MYREAL*)calloc(nf, sizeof(MYREAL)); - HFgrn_uiz[ir][i]->Im = (MYREAL*)calloc(nf, sizeof(MYREAL)); - } - if(HFcplx_uir) { - HFgrn_uir[ir][i] = (GRN*)calloc(1, sizeof(GRN)); - HFgrn_uir[ir][i]->Re = (MYREAL*)calloc(nf, sizeof(MYREAL)); - HFgrn_uir[ir][i]->Im = (MYREAL*)calloc(nf, sizeof(MYREAL)); - } - // - if(DScplx) { - DSgrn[ir][i] = (GRN*)calloc(1, sizeof(GRN)); - DSgrn[ir][i]->Re = (MYREAL*)calloc(nf, sizeof(MYREAL)); - DSgrn[ir][i]->Im = (MYREAL*)calloc(nf, sizeof(MYREAL)); - } - if(DScplx_uiz) { - DSgrn_uiz[ir][i] = (GRN*)calloc(1, sizeof(GRN)); - DSgrn_uiz[ir][i]->Re = (MYREAL*)calloc(nf, sizeof(MYREAL)); - DSgrn_uiz[ir][i]->Im = (MYREAL*)calloc(nf, sizeof(MYREAL)); - } - if(DScplx_uir) { - DSgrn_uir[ir][i] = (GRN*)calloc(1, sizeof(GRN)); - DSgrn_uir[ir][i]->Re = (MYREAL*)calloc(nf, sizeof(MYREAL)); - DSgrn_uir[ir][i]->Im = (MYREAL*)calloc(nf, sizeof(MYREAL)); - } - // - if(SScplx) { - SSgrn[ir][i] = (GRN*)calloc(1, sizeof(GRN)); - SSgrn[ir][i]->Re = (MYREAL*)calloc(nf, sizeof(MYREAL)); - SSgrn[ir][i]->Im = (MYREAL*)calloc(nf, sizeof(MYREAL)); - } - if(SScplx_uiz) { - SSgrn_uiz[ir][i] = (GRN*)calloc(1, sizeof(GRN)); - SSgrn_uiz[ir][i]->Re = (MYREAL*)calloc(nf, sizeof(MYREAL)); - SSgrn_uiz[ir][i]->Im = (MYREAL*)calloc(nf, sizeof(MYREAL)); - } - if(SScplx_uir) { - SSgrn_uir[ir][i] = (GRN*)calloc(1, sizeof(GRN)); - SSgrn_uir[ir][i]->Re = (MYREAL*)calloc(nf, sizeof(MYREAL)); - SSgrn_uir[ir][i]->Im = (MYREAL*)calloc(nf, sizeof(MYREAL)); - } - } - } - - - //============================================================================== - // 计算格林函数 - integ_grn_spec( - pymod1d, nf1, nf2, nf, freqs, nr, rs, wI, - vmin_ref, keps, ampk, k0, Length, filonLength, filonCut, print_progressbar, - EXPgrn, VFgrn, HFgrn, DDgrn, DSgrn, SSgrn, - calc_upar, - EXPgrn_uiz, VFgrn_uiz, HFgrn_uiz, DDgrn_uiz, DSgrn_uiz, SSgrn_uiz, - EXPgrn_uir, VFgrn_uir, HFgrn_uir, DDgrn_uir, DSgrn_uir, SSgrn_uir, - statsstr, nstatsidxs, statsidxs - ); - //============================================================================== - - - // 写入complex数组 - for(int ir=0; irRe[n], EXPgrn[ir][i]->Im[n]); - if(EXPcplx_uiz) EXPcplx_uiz[ir][i][n] = CMPLX(EXPgrn_uiz[ir][i]->Re[n], EXPgrn_uiz[ir][i]->Im[n]); - if(EXPcplx_uir) EXPcplx_uir[ir][i][n] = CMPLX(EXPgrn_uir[ir][i]->Re[n], EXPgrn_uir[ir][i]->Im[n]); - // - if(VFcplx) VFcplx[ir][i][n] = CMPLX(VFgrn[ir][i]->Re[n], VFgrn[ir][i]->Im[n]); - if(VFcplx_uiz) VFcplx_uiz[ir][i][n] = CMPLX(VFgrn_uiz[ir][i]->Re[n], VFgrn_uiz[ir][i]->Im[n]); - if(VFcplx_uir) VFcplx_uir[ir][i][n] = CMPLX(VFgrn_uir[ir][i]->Re[n], VFgrn_uir[ir][i]->Im[n]); - if(DDcplx) DDcplx[ir][i][n] = CMPLX(DDgrn[ir][i]->Re[n], DDgrn[ir][i]->Im[n]); - // - if(DDcplx_uiz) DDcplx_uiz[ir][i][n] = CMPLX(DDgrn_uiz[ir][i]->Re[n], DDgrn_uiz[ir][i]->Im[n]); - if(DDcplx_uir) DDcplx_uir[ir][i][n] = CMPLX(DDgrn_uir[ir][i]->Re[n], DDgrn_uir[ir][i]->Im[n]); - } - // - if(HFcplx) HFcplx[ir][i][n] = CMPLX(HFgrn[ir][i]->Re[n], HFgrn[ir][i]->Im[n]); - if(HFcplx_uiz) HFcplx_uiz[ir][i][n] = CMPLX(HFgrn_uiz[ir][i]->Re[n], HFgrn_uiz[ir][i]->Im[n]); - if(HFcplx_uir) HFcplx_uir[ir][i][n] = CMPLX(HFgrn_uir[ir][i]->Re[n], HFgrn_uir[ir][i]->Im[n]); - // - if(DScplx) DScplx[ir][i][n] = CMPLX(DSgrn[ir][i]->Re[n], DSgrn[ir][i]->Im[n]); - if(DScplx_uiz) DScplx_uiz[ir][i][n] = CMPLX(DSgrn_uiz[ir][i]->Re[n], DSgrn_uiz[ir][i]->Im[n]); - if(DScplx_uir) DScplx_uir[ir][i][n] = CMPLX(DSgrn_uir[ir][i]->Re[n], DSgrn_uir[ir][i]->Im[n]); - // - if(SScplx) SScplx[ir][i][n] = CMPLX(SSgrn[ir][i]->Re[n], SSgrn[ir][i]->Im[n]); - if(SScplx_uiz) SScplx_uiz[ir][i][n] = CMPLX(SSgrn_uiz[ir][i]->Re[n], SSgrn_uiz[ir][i]->Im[n]); - if(SScplx_uir) SScplx_uir[ir][i][n] = CMPLX(SSgrn_uir[ir][i]->Re[n], SSgrn_uir[ir][i]->Im[n]); - } - } - } - - - // Free allocated memory - for(int ir=0; irRe); - free(EXPgrn[ir][i]->Im); - free(EXPgrn[ir][i]); - } - if(EXPgrn_uiz) { - free(EXPgrn_uiz[ir][i]->Re); - free(EXPgrn_uiz[ir][i]->Im); - free(EXPgrn_uiz[ir][i]); - } - if(EXPgrn_uir) { - free(EXPgrn_uir[ir][i]->Re); - free(EXPgrn_uir[ir][i]->Im); - free(EXPgrn_uir[ir][i]); - } - // - if(VFgrn) { - free(VFgrn[ir][i]->Re); - free(VFgrn[ir][i]->Im); - free(VFgrn[ir][i]); - } - if(VFgrn_uiz) { - free(VFgrn_uiz[ir][i]->Re); - free(VFgrn_uiz[ir][i]->Im); - free(VFgrn_uiz[ir][i]); - } - if(VFgrn_uir) { - free(VFgrn_uir[ir][i]->Re); - free(VFgrn_uir[ir][i]->Im); - free(VFgrn_uir[ir][i]); - } - // - if(DDgrn) { - free(DDgrn[ir][i]->Re); - free(DDgrn[ir][i]->Im); - free(DDgrn[ir][i]); - } - if(DDgrn_uiz) { - free(DDgrn_uiz[ir][i]->Re); - free(DDgrn_uiz[ir][i]->Im); - free(DDgrn_uiz[ir][i]); - } - if(DDgrn_uir) { - free(DDgrn_uir[ir][i]->Re); - free(DDgrn_uir[ir][i]->Im); - free(DDgrn_uir[ir][i]); - } - } - // - if(HFcplx) { - free(HFgrn[ir][i]->Re); - free(HFgrn[ir][i]->Im); - free(HFgrn[ir][i]); - } - if(HFcplx_uiz) { - free(HFgrn_uiz[ir][i]->Re); - free(HFgrn_uiz[ir][i]->Im); - free(HFgrn_uiz[ir][i]); - } - if(HFcplx_uir) { - free(HFgrn_uir[ir][i]->Re); - free(HFgrn_uir[ir][i]->Im); - free(HFgrn_uir[ir][i]); - } - // - if(DScplx) { - free(DSgrn[ir][i]->Re); - free(DSgrn[ir][i]->Im); - free(DSgrn[ir][i]); - } - if(DScplx_uiz) { - free(DSgrn_uiz[ir][i]->Re); - free(DSgrn_uiz[ir][i]->Im); - free(DSgrn_uiz[ir][i]); - } - if(DScplx_uir) { - free(DSgrn_uir[ir][i]->Re); - free(DSgrn_uir[ir][i]->Im); - free(DSgrn_uir[ir][i]); - } - // - if(SScplx) { - free(SSgrn[ir][i]->Re); - free(SSgrn[ir][i]->Im); - free(SSgrn[ir][i]); - } - if(SScplx_uiz) { - free(SSgrn_uiz[ir][i]->Re); - free(SSgrn_uiz[ir][i]->Im); - free(SSgrn_uiz[ir][i]); - } - if(SScplx_uir) { - free(SSgrn_uir[ir][i]->Re); - free(SSgrn_uir[ir][i]->Im); - free(SSgrn_uir[ir][i]); - } - } - } - if(EXPgrn) free(EXPgrn); - if(EXPgrn_uiz) free(EXPgrn_uiz); - if(EXPgrn_uir) free(EXPgrn_uir); - if(VFgrn) free(VFgrn); - if(VFgrn_uiz) free(VFgrn_uiz); - if(VFgrn_uir) free(VFgrn_uir); - if(HFgrn) free(HFgrn); - if(HFgrn_uiz) free(HFgrn_uiz); - if(HFgrn_uir) free(HFgrn_uir); - if(DDgrn) free(DDgrn); - if(DDgrn_uiz) free(DDgrn_uiz); - if(DDgrn_uir) free(DDgrn_uir); - if(DSgrn) free(DSgrn); - if(DSgrn_uiz) free(DSgrn_uiz); - if(DSgrn_uir) free(DSgrn_uir); - if(SSgrn) free(SSgrn); - if(SSgrn_uiz) free(SSgrn_uiz); - if(SSgrn_uir) free(SSgrn_uir); -} - - /** * 将计算好的复数形式的积分结果记录到GRN结构体中 * - * @param iw (in)当前频率索引值 - * @param nr (in)震中距个数 - * @param coef (in)统一系数 - * @param sum_EXP_J[nr][3][4] (in)爆炸源 - * @param sum_VF_J[nr][3][4] (in)垂直力源 - * @param sum_HF_J[nr][3][4] (in)水平力源 - * @param sum_DC_J[nr][3][4] (in)剪切源 - * @param EXPgrn[nr][2] (out)`GRN` 结构体指针,爆炸源的Z、R分量频谱结果 - * @param VFgrn[nr][2] (out)`GRN` 结构体指针,垂直力源的Z、R分量频谱结果 - * @param HFgrn[nr][3] (out)`GRN` 结构体指针,水平力源的Z、R、T分量频谱结果 - * @param DDgrn[nr][2] (out)`GRN` 结构体指针,45度倾滑的Z、R分量频谱结果 - * @param DSgrn[nr][3] (out)`GRN` 结构体指针,90度倾滑的Z、R、T分量频谱结果 - * @param SSgrn[nr][3] (out)`GRN` 结构体指针,90度走滑的Z、R、T分量频谱结果 + * @param[in] iw 当前频率索引值 + * @param[in] nr 震中距个数 + * @param[in] coef 统一系数 + * @param[in] sum_J 积分结果 + * @param[out] grn 三分量频谱 */ static void recordin_GRN( - MYINT iw, MYINT nr, MYCOMPLEX coef, - MYCOMPLEX sum_EXP_J[nr][3][4], MYCOMPLEX sum_VF_J[nr][3][4], - MYCOMPLEX sum_HF_J[nr][3][4], MYCOMPLEX sum_DC_J[nr][3][4], - GRN *EXPgrn[nr][2], GRN *VFgrn[nr][2], GRN *HFgrn[nr][3], - GRN *DDgrn[nr][2], GRN *DSgrn[nr][3], GRN *SSgrn[nr][3] + MYINT iw, MYINT nr, MYCOMPLEX coef, MYCOMPLEX sum_J[nr][GRT_SRC_M_COUNTS][GRT_SRC_P_COUNTS], + MYCOMPLEX *grn[nr][GRT_SRC_M_COUNTS][GRT_SRC_CHA_COUNTS] ) { // 局部变量,将某个频点的格林函数谱临时存放 - MYCOMPLEX (*tmp_EXP)[2] = (MYCOMPLEX(*)[2])calloc(nr, sizeof(*tmp_EXP)); - MYCOMPLEX (*tmp_VF)[2] = (MYCOMPLEX(*)[2])calloc(nr, sizeof(*tmp_VF)); - MYCOMPLEX (*tmp_HF)[3] = (MYCOMPLEX(*)[3])calloc(nr, sizeof(*tmp_HF)); - MYCOMPLEX (*tmp_DD)[2] = (MYCOMPLEX(*)[2])calloc(nr, sizeof(*tmp_DD)); - MYCOMPLEX (*tmp_DS)[3] = (MYCOMPLEX(*)[3])calloc(nr, sizeof(*tmp_DS)); - MYCOMPLEX (*tmp_SS)[3] = (MYCOMPLEX(*)[3])calloc(nr, sizeof(*tmp_SS)); + MYCOMPLEX (*tmp_grn)[GRT_SRC_M_COUNTS][GRT_SRC_CHA_COUNTS] = (MYCOMPLEX(*)[GRT_SRC_M_COUNTS][GRT_SRC_CHA_COUNTS])calloc(nr, sizeof(*tmp_grn)); for(MYINT ir=0; irRe[iw] = CREAL(mtmp); - EXPgrn[ir][ii]->Im[iw] = CIMAG(mtmp); - } - if(VFgrn!=NULL){ - mtmp = coef*tmp_VF[ir][ii]; // m=0 垂直力源 - VFgrn[ir][ii]->Re[iw] = CREAL(mtmp); - VFgrn[ir][ii]->Im[iw] = CIMAG(mtmp); - } - if(DDgrn!=NULL){ - mtmp = coef*tmp_DD[ir][ii]; // m=0 45-倾滑 - DDgrn[ir][ii]->Re[iw] = CREAL(mtmp); - DDgrn[ir][ii]->Im[iw] = CIMAG(mtmp); - } - } - if(HFgrn!=NULL){ - mtmp = coef*tmp_HF[ir][ii]; // m=1 水平力源 - HFgrn[ir][ii]->Re[iw] = CREAL(mtmp); - HFgrn[ir][ii]->Im[iw] = CIMAG(mtmp); - } - if(DSgrn!=NULL){ - mtmp = coef*tmp_DS[ir][ii]; // m=1 90-倾滑 - DSgrn[ir][ii]->Re[iw] = CREAL(mtmp); - DSgrn[ir][ii]->Im[iw] = CIMAG(mtmp); - } - if(SSgrn!=NULL){ - mtmp = coef*tmp_SS[ir][ii]; // m=2 走滑 - SSgrn[ir][ii]->Re[iw] = CREAL(mtmp); - SSgrn[ir][ii]->Im[iw] = CIMAG(mtmp); + merge_Pk(sum_J[ir], tmp_grn[ir]); + + for(MYINT i=0; i RZERO)? filonK : kmax, keps, omega, nr, rs, - sum_EXP_J, sum_VF_J, sum_HF_J, sum_DC_J, - calc_upar, - sum_EXP_uiz_J, sum_VF_uiz_J, sum_HF_uiz_J, sum_DC_uiz_J, - sum_EXP_uir_J, sum_VF_uir_J, sum_HF_uir_J, sum_DC_uir_J, + sum_J, calc_upar, sum_uiz_J, sum_uir_J, fstats, kernel); // 基于线性插值的Filon积分 if(filondk > RZERO){ k = linear_filon_integ( local_mod1d, k, dk, filondk, kmax, keps, omega, nr, rs, - sum_EXP_J, sum_VF_J, sum_HF_J, sum_DC_J, - calc_upar, - sum_EXP_uiz_J, sum_VF_uiz_J, sum_HF_uiz_J, sum_DC_uiz_J, - sum_EXP_uir_J, sum_VF_uir_J, sum_HF_uir_J, sum_DC_uir_J, + sum_J, calc_upar, sum_uiz_J, sum_uir_J, fstats, kernel); } @@ -677,10 +235,7 @@ void integ_grn_spec( if(vmin_ref < RZERO){ PTA_method( local_mod1d, k, dk, omega, nr, rs, - sum_EXP_J, sum_VF_J, sum_HF_J, sum_DC_J, - calc_upar, - sum_EXP_uiz_J, sum_VF_uiz_J, sum_HF_uiz_J, sum_DC_uiz_J, - sum_EXP_uir_J, sum_VF_uir_J, sum_HF_uir_J, sum_DC_uir_J, + sum_J, calc_upar, sum_uiz_J, sum_uir_J, ptam_fstatsnr, kernel); } @@ -689,19 +244,10 @@ void integ_grn_spec( // 记录到格林函数结构体内 - recordin_GRN( - iw, nr, coef, - sum_EXP_J, sum_VF_J, sum_HF_J, sum_DC_J, - EXPgrn, VFgrn, HFgrn, DDgrn, DSgrn, SSgrn); + recordin_GRN(iw, nr, coef, sum_J, grn); if(calc_upar){ - recordin_GRN( - iw, nr, coef, - sum_EXP_uiz_J, sum_VF_uiz_J, sum_HF_uiz_J, sum_DC_uiz_J, - EXPgrn_uiz, VFgrn_uiz, HFgrn_uiz, DDgrn_uiz, DSgrn_uiz, SSgrn_uiz); - recordin_GRN( - iw, nr, coef, - sum_EXP_uir_J, sum_VF_uir_J, sum_HF_uir_J, sum_DC_uir_J, - EXPgrn_uir, VFgrn_uir, HFgrn_uir, DDgrn_uir, DSgrn_uir, SSgrn_uir); + recordin_GRN(iw, nr, coef, sum_uiz_J, grn_uiz); + recordin_GRN(iw, nr, coef, sum_uir_J, grn_uir); } @@ -731,20 +277,9 @@ void integ_grn_spec( // Free allocated memory for temporary variables - if (sum_EXP_J) free(sum_EXP_J); - if (sum_VF_J) free(sum_VF_J); - if (sum_HF_J) free(sum_HF_J); - if (sum_DC_J) free(sum_DC_J); - - if (sum_EXP_uiz_J) free(sum_EXP_uiz_J); - if (sum_VF_uiz_J) free(sum_VF_uiz_J); - if (sum_HF_uiz_J) free(sum_HF_uiz_J); - if (sum_DC_uiz_J) free(sum_DC_uiz_J); - - if (sum_EXP_uir_J) free(sum_EXP_uir_J); - if (sum_VF_uir_J) free(sum_VF_uir_J); - if (sum_HF_uir_J) free(sum_HF_uir_J); - if (sum_DC_uir_J) free(sum_DC_uir_J); + free(sum_J); + if(sum_uiz_J) free(sum_uiz_J); + if(sum_uir_J) free(sum_uir_J); } // END omega loop diff --git a/pygrt/C_extension/src/dynamic/grt_main.c b/pygrt/C_extension/src/dynamic/grt_main.c index 4c7e24a3..ff65d361 100644 --- a/pygrt/C_extension/src/dynamic/grt_main.c +++ b/pygrt/C_extension/src/dynamic/grt_main.c @@ -115,9 +115,6 @@ static int M_flag=0, D_flag=0, N_flag=0, S_flag=0, R_flag=0, P_flag=0, G_flag=0, e_flag=0; -// 三分量代号 -const char chs[3] = {'Z', 'R', 'T'}; - /** * 打印使用说明 @@ -1060,59 +1057,20 @@ int main(int argc, char **argv) { // 建立格林函数的complex数组 - MYCOMPLEX *(*EXPcplx)[2] = (doEXP) ? (MYCOMPLEX*(*)[2])calloc(nr, sizeof(*EXPcplx)) : NULL; - MYCOMPLEX *(*VFcplx)[2] = (doVF) ? (MYCOMPLEX*(*)[2])calloc(nr, sizeof(*VFcplx)) : NULL; - MYCOMPLEX *(*HFcplx)[3] = (doHF) ? (MYCOMPLEX*(*)[3])calloc(nr, sizeof(*HFcplx)) : NULL; - MYCOMPLEX *(*DDcplx)[2] = (doDC) ? (MYCOMPLEX*(*)[2])calloc(nr, sizeof(*DDcplx)) : NULL; - MYCOMPLEX *(*DScplx)[3] = (doDC) ? (MYCOMPLEX*(*)[3])calloc(nr, sizeof(*DScplx)) : NULL; - MYCOMPLEX *(*SScplx)[3] = (doDC) ? (MYCOMPLEX*(*)[3])calloc(nr, sizeof(*SScplx)) : NULL; - - MYCOMPLEX *(*EXPcplx_uiz)[2] = (calc_upar && doEXP) ? (MYCOMPLEX*(*)[2])calloc(nr, sizeof(*EXPcplx_uiz)) : NULL; - MYCOMPLEX *(*VFcplx_uiz)[2] = (calc_upar && doVF) ? (MYCOMPLEX*(*)[2])calloc(nr, sizeof(*VFcplx_uiz)) : NULL; - MYCOMPLEX *(*HFcplx_uiz)[3] = (calc_upar && doHF) ? (MYCOMPLEX*(*)[3])calloc(nr, sizeof(*HFcplx_uiz)) : NULL; - MYCOMPLEX *(*DDcplx_uiz)[2] = (calc_upar && doDC) ? (MYCOMPLEX*(*)[2])calloc(nr, sizeof(*DDcplx_uiz)) : NULL; - MYCOMPLEX *(*DScplx_uiz)[3] = (calc_upar && doDC) ? (MYCOMPLEX*(*)[3])calloc(nr, sizeof(*DScplx_uiz)) : NULL; - MYCOMPLEX *(*SScplx_uiz)[3] = (calc_upar && doDC) ? (MYCOMPLEX*(*)[3])calloc(nr, sizeof(*SScplx_uiz)) : NULL; - - MYCOMPLEX *(*EXPcplx_uir)[2] = (calc_upar && doEXP) ? (MYCOMPLEX*(*)[2])calloc(nr, sizeof(*EXPcplx_uir)) : NULL; - MYCOMPLEX *(*VFcplx_uir)[2] = (calc_upar && doVF) ? (MYCOMPLEX*(*)[2])calloc(nr, sizeof(*VFcplx_uir)) : NULL; - MYCOMPLEX *(*HFcplx_uir)[3] = (calc_upar && doHF) ? (MYCOMPLEX*(*)[3])calloc(nr, sizeof(*HFcplx_uir)) : NULL; - MYCOMPLEX *(*DDcplx_uir)[2] = (calc_upar && doDC) ? (MYCOMPLEX*(*)[2])calloc(nr, sizeof(*DDcplx_uir)) : NULL; - MYCOMPLEX *(*DScplx_uir)[3] = (calc_upar && doDC) ? (MYCOMPLEX*(*)[3])calloc(nr, sizeof(*DScplx_uir)) : NULL; - MYCOMPLEX *(*SScplx_uir)[3] = (calc_upar && doDC) ? (MYCOMPLEX*(*)[3])calloc(nr, sizeof(*SScplx_uir)) : NULL; + MYCOMPLEX *(*grn)[GRT_SRC_M_COUNTS][GRT_SRC_CHA_COUNTS] = (MYCOMPLEX*(*)[GRT_SRC_M_COUNTS][GRT_SRC_CHA_COUNTS]) calloc(nr, sizeof(*grn)); + MYCOMPLEX *(*grn_uiz)[GRT_SRC_M_COUNTS][GRT_SRC_CHA_COUNTS] = (calc_upar)? (MYCOMPLEX*(*)[GRT_SRC_M_COUNTS][GRT_SRC_CHA_COUNTS]) calloc(nr, sizeof(*grn_uiz)) : NULL; + MYCOMPLEX *(*grn_uir)[GRT_SRC_M_COUNTS][GRT_SRC_CHA_COUNTS] = (calc_upar)? (MYCOMPLEX*(*)[GRT_SRC_M_COUNTS][GRT_SRC_CHA_COUNTS]) calloc(nr, sizeof(*grn_uir)) : NULL; for(int ir=0; irThk, pymod->Vb, pymod->n, pymod->isrc, pymod->ircv, rs[ir]); strcpy(hd.kt1, "S"); - // 用于反转Z分量 - int sgn=1; - for(int i=0; i<3; ++i){ - // 文件保存总路径 - // char *s_outpath = (char*)malloc(sizeof(char)*(strlen(s_output_dir)+100)); - char *s_outpath = (char*)malloc(sizeof(char)*(strlen(s_output_subdir)+100)); - // char *s_suffix = (char*)malloc(sizeof(char)*(strlen(s_depsrc)+strlen(s_deprcv)+strlen(s_rs[ir])+100)); - // sprintf(s_suffix, "%s_%s_%s", s_depsrc, s_deprcv, s_rs[ir]); - char s_prefix[] = ""; - - // Z分量反转 - sgn = (i==0) ? -1 : 1; - if(i<2){ - if(doEXP){ - write_one_to_sac("EX", chs[i], &hd, s_outpath, s_output_subdir, s_prefix, sgn, EXPcplx[ir][i], fftw_grn, out, float_arr, plan); - if(calc_upar){ - write_one_to_sac("EX", chs[i], &hd, s_outpath, s_output_subdir, "z", sgn*(-1), EXPcplx_uiz[ir][i], fftw_grn, out, float_arr, plan); - write_one_to_sac("EX", chs[i], &hd, s_outpath, s_output_subdir, "r", sgn, EXPcplx_uir[ir][i], fftw_grn, out, float_arr, plan); - } - } - if(doVF){ - write_one_to_sac("VF", chs[i], &hd, s_outpath, s_output_subdir, s_prefix, sgn, VFcplx[ir][i], fftw_grn, out, float_arr, plan); - if(calc_upar){ - write_one_to_sac("VF", chs[i], &hd, s_outpath, s_output_subdir, "z", sgn*(-1), VFcplx_uiz[ir][i], fftw_grn, out, float_arr, plan); - write_one_to_sac("VF", chs[i], &hd, s_outpath, s_output_subdir, "r", sgn, VFcplx_uir[ir][i], fftw_grn, out, float_arr, plan); - } - } - if(doDC){ - write_one_to_sac("DD", chs[i], &hd, s_outpath, s_output_subdir, s_prefix, sgn, DDcplx[ir][i], fftw_grn, out, float_arr, plan); - if(calc_upar){ - write_one_to_sac("DD", chs[i], &hd, s_outpath, s_output_subdir, "z", sgn*(-1), DDcplx_uiz[ir][i], fftw_grn, out, float_arr, plan); - write_one_to_sac("DD", chs[i], &hd, s_outpath, s_output_subdir, "r", sgn, DDcplx_uir[ir][i], fftw_grn, out, float_arr, plan); - } - } - } + for(int im=0; im=3) continue; - if(doHF){ - write_one_to_sac("HF", chs[i], &hd, s_outpath, s_output_subdir, s_prefix, sgn, HFcplx[ir][i], fftw_grn, out, float_arr, plan); - if(calc_upar){ - write_one_to_sac("HF", chs[i], &hd, s_outpath, s_output_subdir, "z", sgn*(-1), HFcplx_uiz[ir][i], fftw_grn, out, float_arr, plan); - write_one_to_sac("HF", chs[i], &hd, s_outpath, s_output_subdir, "r", sgn, HFcplx_uir[ir][i], fftw_grn, out, float_arr, plan); - } - } + int modr = GRT_SRC_M_ORDERS[im]; + int sgn=1; // 用于反转Z分量 + for(int c=0; c ka^2/a - EXP[0][0][0] = tmp = src_kaka * src_a_inv; EXP[0][0][1] = tmp; - } + coef[0][0][0] = tmp = src_kaka * src_a_inv; coef[0][0][1] = tmp; - if(VF!=NULL){ // 垂直力源 (4.6.15) - VF[0][0][0] = tmp = -RONE; VF[0][0][1] = - tmp; - VF[0][1][0] = tmp = -k * src_b_inv; VF[0][1][1] = tmp; - } + coef[1][0][0] = tmp = -RONE; coef[1][0][1] = - tmp; + coef[1][1][0] = tmp = -k * src_b_inv; coef[1][1][1] = tmp; - if(HF!=NULL){ // 水平力源 (4.6.21,26), 这里可以把x1,x2方向的力转到r,theta方向 // 推导可发现,r方向的力形成P,SV波, theta方向的力形成SH波 // 方向性因子包含水平力方向与震源台站连线方向的夹角 - HF[1][0][0] = tmp = -k * src_a_inv; HF[1][0][1] = tmp; - HF[1][1][0] = tmp = -RONE; HF[1][1][1] = - tmp; - HF[1][2][0] = tmp = src_kbkb * k_inv * src_b_inv; HF[1][2][1] = tmp; - } + coef[2][0][0] = tmp = -k * src_a_inv; coef[2][0][1] = tmp; + coef[2][1][0] = tmp = -RONE; coef[2][1][1] = - tmp; + coef[2][2][0] = tmp = src_kbkb * k_inv * src_b_inv; coef[2][2][1] = tmp; - if(DC!=NULL){ // 剪切位错 (4.8.34) // m=0 - DC[0][0][0] = tmp = (RTWO*src_kaka - RTHREE*kk) * src_a_inv; DC[0][0][1] = tmp; - DC[0][1][0] = tmp = -RTHREE*k; DC[0][1][1] = - tmp; + coef[3][0][0] = tmp = (RTWO*src_kaka - RTHREE*kk) * src_a_inv; coef[3][0][1] = tmp; + coef[3][1][0] = tmp = -RTHREE*k; coef[3][1][1] = - tmp; // m=1 - DC[1][0][0] = tmp = RTWO*k; DC[1][0][1] = - tmp; - DC[1][1][0] = tmp = (RTWO*kk - src_kbkb) * src_b_inv; DC[1][1][1] = tmp; - DC[1][2][0] = tmp = - src_kbkb * k_inv; DC[1][2][1] = - tmp; + coef[4][0][0] = tmp = RTWO*k; coef[4][0][1] = - tmp; + coef[4][1][0] = tmp = (RTWO*kk - src_kbkb) * src_b_inv; coef[4][1][1] = tmp; + coef[4][2][0] = tmp = - src_kbkb * k_inv; coef[4][2][1] = - tmp; // m=2 - DC[2][0][0] = tmp = - kk * src_a_inv; DC[2][0][1] = tmp; - DC[2][1][0] = tmp = - k; DC[2][1][1] = - tmp; - DC[2][2][0] = tmp = src_kbkb * src_b_inv; DC[2][2][1] = tmp; - } + coef[5][0][0] = tmp = - kk * src_a_inv; coef[5][0][1] = tmp; + coef[5][1][0] = tmp = - k; coef[5][1][1] = - tmp; + coef[5][2][0] = tmp = src_kbkb * src_b_inv; coef[5][2][1] = tmp; } diff --git a/pygrt/C_extension/src/static/static_propagate.c b/pygrt/C_extension/src/static/static_propagate.c index fc86f704..8dc36181 100644 --- a/pygrt/C_extension/src/static/static_propagate.c +++ b/pygrt/C_extension/src/static/static_propagate.c @@ -27,33 +27,18 @@ void static_kernel( - const MODEL1D *mod1d, MYCOMPLEX omega, MYREAL k, - MYCOMPLEX EXP_qwv[3][3], MYCOMPLEX VF_qwv[3][3], MYCOMPLEX HF_qwv[3][3], MYCOMPLEX DC_qwv[3][3], - bool calc_uiz, - MYCOMPLEX EXP_uiz_qwv[3][3], MYCOMPLEX VF_uiz_qwv[3][3], MYCOMPLEX HF_uiz_qwv[3][3], MYCOMPLEX DC_uiz_qwv[3][3]) + const MODEL1D *mod1d, MYCOMPLEX omega, MYREAL k, MYCOMPLEX QWV[GRT_SRC_M_COUNTS][GRT_SRC_QWV_COUNTS], + bool calc_uiz, MYCOMPLEX QWV_uiz[GRT_SRC_M_COUNTS][GRT_SRC_QWV_COUNTS]) { // 初始化qwv为0 - for(MYINT i=0; i<3; ++i){ - for(MYINT j=0; j<3; ++j){ - if(EXP_qwv!=NULL) EXP_qwv[i][j] = RZERO; - if(VF_qwv!=NULL) VF_qwv[i][j] = RZERO; - if(HF_qwv!=NULL) HF_qwv[i][j] = RZERO; - if(DC_qwv!=NULL) DC_qwv[i][j] = RZERO; - } - } - - if(calc_uiz){ - // 初始化qwv为0 - for(MYINT i=0; i<3; ++i){ - for(MYINT j=0; j<3; ++j){ - if(EXP_uiz_qwv!=NULL) EXP_uiz_qwv[i][j] = RZERO; - if(VF_uiz_qwv!=NULL) VF_uiz_qwv[i][j] = RZERO; - if(HF_uiz_qwv!=NULL) HF_uiz_qwv[i][j] = RZERO; - if(DC_uiz_qwv!=NULL) DC_uiz_qwv[i][j] = RZERO; - } + for(MYINT i=0; iircvup; MYINT isrc = mod1d->isrc; // 震源所在虚拟层位, isrc>=1 MYINT ircv = mod1d->ircv; // 接收点所在虚拟层位, ircv>=1, ircv != isrc @@ -303,19 +288,8 @@ void static_kernel( // 计算震源系数 - MYCOMPLEX EXP[3][3][2], VF[3][3][2], HF[3][3][2], DC[3][3][2]; - MYCOMPLEX (*pEXP)[3][2] = (EXP_qwv!=NULL)? EXP : NULL; - MYCOMPLEX (*pVF)[3][2] = (VF_qwv!=NULL)? VF : NULL; - MYCOMPLEX (*pHF)[3][2] = (HF_qwv!=NULL)? HF : NULL; - MYCOMPLEX (*pDC)[3][2] = (DC_qwv!=NULL)? DC : NULL; - for(MYINT i=0; i<3; ++i){ - for(MYINT j=0; j<3; ++j){ - for(MYINT p=0; p<2; ++p){ - EXP[i][j][p] = VF[i][j][p] = HF[i][j][p] = DC[i][j][p] = RZERO; - } - } - } - static_source_coef(src_delta, k, pEXP, pVF, pHF, pDC); + MYCOMPLEX src_coef[GRT_SRC_M_COUNTS][GRT_SRC_QWV_COUNTS][2] = {0}; + static_source_coef(src_delta, k, src_coef); // 临时中转矩阵 (temperary) MYCOMPLEX tmpR1[2][2], tmpR2[2][2], tmp2x2[2][2], tmpRL, tmp2x2_uiz[2][2], tmpRL_uiz; @@ -356,19 +330,9 @@ void static_kernel( cmat2x2_mul(R_EV, tmp2x2, tmp2x2); tmpRL = R_EVL * invT / (RONE - RDL_BL * RUL_FB); - for(MYINT m=0; m<3; ++m){ - if(0==m){ - // 爆炸源 - if(EXP_qwv!=NULL) get_qwv(ircvup, tmp2x2, tmpRL, RD_BL, RDL_BL, EXP[m], EXP_qwv[m]); - // 垂直力源 - if(VF_qwv!=NULL) get_qwv(ircvup, tmp2x2, tmpRL, RD_BL, RDL_BL, VF[m], VF_qwv[m]); - } - - // 水平力源 - if(1==m && HF_qwv!=NULL) get_qwv(ircvup, tmp2x2, tmpRL, RD_BL, RDL_BL, HF[m], HF_qwv[m]); - // 剪切位错 - if(DC_qwv!=NULL) get_qwv(ircvup, tmp2x2, tmpRL, RD_BL, RDL_BL, DC[m], DC_qwv[m]); + for(MYINT i=0; i RZERO)? filonK : kmax, keps, 0.0, nr, rs, - sum_EXP_J, sum_VF_J, sum_HF_J, sum_DC_J, - calc_upar, - sum_EXP_uiz_J, sum_VF_uiz_J, sum_HF_uiz_J, sum_DC_uiz_J, - sum_EXP_uir_J, sum_VF_uir_J, sum_HF_uir_J, sum_DC_uir_J, + sum_J, calc_upar, sum_uiz_J, sum_uir_J, fstats, static_kernel); // 基于线性插值的Filon积分 if(filondk > RZERO){ k = linear_filon_integ( mod1d, k, dk, filondk, kmax, keps, 0.0, nr, rs, - sum_EXP_J, sum_VF_J, sum_HF_J, sum_DC_J, - calc_upar, - sum_EXP_uiz_J, sum_VF_uiz_J, sum_HF_uiz_J, sum_DC_uiz_J, - sum_EXP_uir_J, sum_VF_uir_J, sum_HF_uir_J, sum_DC_uir_J, + sum_J, calc_upar, sum_uiz_J, sum_uir_J, fstats, static_kernel); } @@ -279,10 +176,7 @@ void integ_static_grn( if(vmin_ref < RZERO){ PTA_method( mod1d, k, dk, 0.0, nr, rs, - sum_EXP_J, sum_VF_J, sum_HF_J, sum_DC_J, - calc_upar, - sum_EXP_uiz_J, sum_VF_uiz_J, sum_HF_uiz_J, sum_DC_uiz_J, - sum_EXP_uir_J, sum_VF_uir_J, sum_HF_uir_J, sum_DC_uir_J, + sum_J, calc_upar, sum_uiz_J, sum_uir_J, ptam_fstatsnr, static_kernel); } @@ -292,37 +186,17 @@ void integ_static_grn( MYCOMPLEX fac = dk * RONE/(RFOUR*PI * src_mu); // 将积分结果记录到浮点数数组中 - recordin_GRN( - nr, fac, - sum_EXP_J, sum_VF_J, sum_HF_J, sum_DC_J, - EXPgrn, VFgrn, HFgrn, DDgrn, DSgrn, SSgrn); + recordin_GRN(nr, fac, sum_J, grn); if(calc_upar){ - recordin_GRN( - nr, fac, - sum_EXP_uiz_J, sum_VF_uiz_J, sum_HF_uiz_J, sum_DC_uiz_J, - EXPgrn_uiz, VFgrn_uiz, HFgrn_uiz, DDgrn_uiz, DSgrn_uiz, SSgrn_uiz); - recordin_GRN( - nr, fac, - sum_EXP_uir_J, sum_VF_uir_J, sum_HF_uir_J, sum_DC_uir_J, - EXPgrn_uir, VFgrn_uir, HFgrn_uir, DDgrn_uir, DSgrn_uir, SSgrn_uir); + recordin_GRN(nr, fac, sum_uiz_J, grn_uiz); + recordin_GRN(nr, fac, sum_uir_J, grn_uir); } // Free allocated memory for temporary variables - if (sum_EXP_J) free(sum_EXP_J); - if (sum_VF_J) free(sum_VF_J); - if (sum_HF_J) free(sum_HF_J); - if (sum_DC_J) free(sum_DC_J); - - if (sum_EXP_uiz_J) free(sum_EXP_uiz_J); - if (sum_VF_uiz_J) free(sum_VF_uiz_J); - if (sum_HF_uiz_J) free(sum_HF_uiz_J); - if (sum_DC_uiz_J) free(sum_DC_uiz_J); - - if (sum_EXP_uir_J) free(sum_EXP_uir_J); - if (sum_VF_uir_J) free(sum_VF_uir_J); - if (sum_HF_uir_J) free(sum_HF_uir_J); - if (sum_DC_uir_J) free(sum_DC_uir_J); + free(sum_J); + if(sum_uiz_J) free(sum_uiz_J); + if(sum_uir_J) free(sum_uir_J); free_mod1d(mod1d); diff --git a/pygrt/C_extension/src/static/stgrt_main.c b/pygrt/C_extension/src/static/stgrt_main.c index c8cdbf09..eef9ca15 100644 --- a/pygrt/C_extension/src/static/stgrt_main.c +++ b/pygrt/C_extension/src/static/stgrt_main.c @@ -67,8 +67,6 @@ static int M_flag=0, D_flag=0, X_flag=0, Y_flag=0, e_flag=0; -// 三分量代号 -const char chs[3] = {'Z', 'R', 'T'}; /** * 打印使用说明 @@ -414,6 +412,43 @@ static void getopt_from_command(int argc, char **argv){ +/** + * 打印各分量的名称 + * + * @param[in] prefix 前缀字符串 + */ +static void print_grn_title(const char *prefix){ + for(int i=0; i Date: Sat, 26 Apr 2025 12:20:24 +0800 Subject: [PATCH 02/25] REFAC: continue refactor whole codes --- .../C_extension/include/common/attenuation.h | 5 +- pygrt/C_extension/include/common/bessel.h | 16 +- pygrt/C_extension/include/common/const.h | 23 +- pygrt/C_extension/include/common/coord.h | 16 +- pygrt/C_extension/include/common/dwm.h | 20 +- pygrt/C_extension/include/common/fim.h | 28 +-- pygrt/C_extension/include/common/integral.h | 12 +- pygrt/C_extension/include/common/iostats.h | 17 +- pygrt/C_extension/include/common/kernel.h | 4 +- pygrt/C_extension/include/common/matrix.h | 74 +++--- pygrt/C_extension/include/common/model.h | 44 ++-- .../C_extension/include/common/progressbar.h | 4 +- pygrt/C_extension/include/common/ptam.h | 51 ++-- pygrt/C_extension/include/common/quadratic.h | 28 +-- pygrt/C_extension/include/common/radiation.h | 22 +- pygrt/C_extension/include/common/recursion.h | 236 ++++++++---------- pygrt/C_extension/include/common/search.h | 24 +- pygrt/C_extension/include/common/version.h | 1 + pygrt/C_extension/include/dynamic/grt.h | 50 ++-- pygrt/C_extension/include/dynamic/layer.h | 98 ++++---- pygrt/C_extension/include/dynamic/propagate.h | 12 +- pygrt/C_extension/include/dynamic/signals.h | 86 +++---- pygrt/C_extension/include/dynamic/source.h | 8 +- .../C_extension/include/static/static_layer.h | 58 ++--- .../include/static/static_propagate.h | 4 +- .../include/static/static_source.h | 6 +- pygrt/C_extension/include/static/stgrt.h | 24 +- pygrt/C_extension/include/travt/travt.h | 12 +- pygrt/C_extension/src/common/const.c | 4 +- pygrt/C_extension/src/common/dwm.c | 30 +-- pygrt/C_extension/src/common/fim.c | 60 ++--- pygrt/C_extension/src/common/integral.c | 48 ++-- pygrt/C_extension/src/common/iostats.c | 16 +- pygrt/C_extension/src/common/ptam.c | 197 +++++++-------- pygrt/C_extension/src/common/recursion.c | 2 +- pygrt/C_extension/src/dynamic/grt.c | 26 +- pygrt/C_extension/src/dynamic/grt_main.c | 26 +- pygrt/C_extension/src/dynamic/propagate.c | 18 +- pygrt/C_extension/src/dynamic/source.c | 6 +- .../C_extension/src/static/static_propagate.c | 18 +- pygrt/C_extension/src/static/static_source.c | 6 +- pygrt/C_extension/src/static/stgrt.c | 26 +- pygrt/C_extension/src/static/stgrt_main.c | 22 +- 43 files changed, 719 insertions(+), 769 deletions(-) diff --git a/pygrt/C_extension/include/common/attenuation.h b/pygrt/C_extension/include/common/attenuation.h index 2d3bdfd6..ed09c73d 100755 --- a/pygrt/C_extension/include/common/attenuation.h +++ b/pygrt/C_extension/include/common/attenuation.h @@ -18,8 +18,9 @@ * \f] * 其中虚数部分的正负号和书中不同,是因为书中使用的傅里叶变换的e指数符号和我们通常使用的相反。 * - * @param Qinv (in) 1/Q - * @param omega (in)复数频率\f$ \tilde{\omega} =\omega - i\zeta \f$ + * @param[in] Qinv 1/Q + * @param[in] omega 复数频率\f$ \tilde{\omega} =\omega - i\zeta \f$ + * * @return atncoef 系数因子,作用在 \f$ k=\omega / c(\omega)\f$的计算 */ MYCOMPLEX attenuation_law(MYREAL Qinv, MYCOMPLEX omega); diff --git a/pygrt/C_extension/include/common/bessel.h b/pygrt/C_extension/include/common/bessel.h index d31ca039..361d61ad 100755 --- a/pygrt/C_extension/include/common/bessel.h +++ b/pygrt/C_extension/include/common/bessel.h @@ -13,10 +13,10 @@ /** * 计算Bessel函数 \f$ J_m(x), m=0,1,2 \f$ * - * @param x 自变量 - * @param bj0 (out) \f$ J_0(x) \f$ - * @param bj1 (out) \f$ J_1(x) \f$ - * @param bj2 (out) \f$ J_2(x) \f$ + * @param[in] x 自变量 + * @param[out] bj0 \f$ J_0(x) \f$ + * @param[out] bj1 \f$ J_1(x) \f$ + * @param[out] bj2 \f$ J_2(x) \f$ * */ void bessel012(MYREAL x, MYREAL *bj0, MYREAL *bj1, MYREAL *bj2); @@ -25,10 +25,10 @@ void bessel012(MYREAL x, MYREAL *bj0, MYREAL *bj1, MYREAL *bj2); /** * 计算Bessel函数的一阶导数 \f$ J_m^{'}(x), m=0,1,2 \f$ * - * @param x 自变量 - * @param bj0 (inout) 传入 \f$ J_0(x) \f$, 返回\f$ J_0^{'}(x) \f$ - * @param bj1 (inout) 传入 \f$ J_1(x) \f$, 返回\f$ J_1^{'}(x) \f$ - * @param bj2 (inout) 传入 \f$ J_2(x) \f$, 返回\f$ J_2^{'}(x) \f$ + * @param[in] x 自变量 + * @param[in,out] bj0 传入 \f$ J_0(x) \f$, 返回\f$ J_0^{'}(x) \f$ + * @param[in,out] bj1 传入 \f$ J_1(x) \f$, 返回\f$ J_1^{'}(x) \f$ + * @param[in,out] bj2 传入 \f$ J_2(x) \f$, 返回\f$ J_2^{'}(x) \f$ * */ void besselp012(MYREAL x, MYREAL *bj0, MYREAL *bj1, MYREAL *bj2); \ No newline at end of file diff --git a/pygrt/C_extension/include/common/const.h b/pygrt/C_extension/include/common/const.h index af39a486..a3d57129 100755 --- a/pygrt/C_extension/include/common/const.h +++ b/pygrt/C_extension/include/common/const.h @@ -15,6 +15,7 @@ // CMPLX macro not exist on MacOS #ifndef CMPLX #define CMPLX(real, imag) ((double)(real) + (double)(imag) * I) ///< 复数扩展宏,添加此指令以适配MacOS + #endif @@ -22,11 +23,13 @@ #define _TEST_WHETHER_WIN32_ 1 #else #define _TEST_WHETHER_WIN32_ 0 ///< 测试是否是windows系统 + #endif #if _TEST_WHETHER_WIN32_ #include /* _mkdir */ #define mkdir(x, y) _mkdir(x) ///< 为windows系统修改mkdir函数 + #endif @@ -129,17 +132,23 @@ typedef int MYINT; ///< 整数 // ----------------------------------------------------------------------------- -#define GRT_SRC_CHA_COUNTS 3 ///< 3, 代码中分量个数(ZRT,ZNE) -#define GRT_SRC_QWV_COUNTS 3 ///< 3, 代码中核函数类型个数(q, w, v) -#define GRT_SRC_P_COUNTS 4 ///< 4, 代码中积分类型个数 -#define GRT_SRC_M_MAX 2 ///< 代码中阶数m的最大值 -#define GRT_SRC_M_COUNTS 6 ///< 6, 代码中不同震源、不同阶数的个数 +#define CHANNEL_NUM 3 ///< 3, 代码中分量个数(ZRT,ZNE) + +#define QWV_NUM 3 ///< 3, 代码中核函数类型个数(q, w, v) +#define INTEG_NUM 4 ///< 4, 代码中积分类型个数 +#define MORDER_MAX 2 ///< 2, 代码中阶数m的最大值 +#define SRC_M_NUM 6 ///< 6, 代码中不同震源、不同阶数的个数 + +#define PTAM_MAX_PT 36 ///< 36, 最后统计波峰波谷的目标数量 +#define PTAM_WINDOW_SIZE 3 ///< 3, 使用连续点数判断是否为波峰或波谷 +#define PTAM_MAX_WAITS 9 ///< 9, 判断波峰或波谷的最大等待次数,不能太小 + /** 分别对应爆炸源(0阶),垂直力源(0阶),水平力源(1阶),剪切源(0,1,2阶) */ -extern const MYINT GRT_SRC_M_ORDERS[GRT_SRC_M_COUNTS]; +extern const MYINT SRC_M_ORDERS[SRC_M_NUM]; /** 不同震源,不同阶数的名称简写,用于命名 */ -extern const char *GRT_SRC_M_NAME_ABBR[GRT_SRC_M_COUNTS]; +extern const char *SRC_M_NAME_ABBR[SRC_M_NUM]; /** ZRT三分量代号 */ extern const char GRT_ZRTchs[]; diff --git a/pygrt/C_extension/include/common/coord.h b/pygrt/C_extension/include/common/coord.h index e810d900..9cc4482e 100644 --- a/pygrt/C_extension/include/common/coord.h +++ b/pygrt/C_extension/include/common/coord.h @@ -14,8 +14,8 @@ /** * 直角坐标zxy到柱坐标zrt的矢量旋转 * - * @param theta (in)r轴相对x轴的旋转弧度(负数表示逆变换,即zrt->zxy) - * @param A[3] (inout)待旋转的矢量(s1, s2, s3) + * @param[in] theta r轴相对x轴的旋转弧度(负数表示逆变换,即zrt->zxy) + * @param[out] A 待旋转的矢量(s1, s2, s3) */ void rot_zxy2zrt_vec(double theta, double A[3]); @@ -24,8 +24,8 @@ void rot_zxy2zrt_vec(double theta, double A[3]); /** * 直角坐标zxy到柱坐标zrt的二阶对称张量旋转 * - * @param theta (in)r轴相对x轴的旋转弧度(负数表示逆变换,即zrt->zxy) - * @param A[6] (inout)待旋转的二阶对称张量(s11, s12, s13, s22, s23, s33) + * @param[in] theta r轴相对x轴的旋转弧度(负数表示逆变换,即zrt->zxy) + * @param[out] A 待旋转的二阶对称张量(s11, s12, s13, s22, s23, s33) */ void rot_zxy2zrt_symtensor2odr(double theta, double A[6]); @@ -48,9 +48,9 @@ void rot_zxy2zrt_symtensor2odr(double theta, double A[6]); * * * - * @param theta (in)r轴相对x轴的旋转弧度 - * @param u[3] (inout)柱坐标下的位移矢量 - * @param upar[3][3] (inout)柱坐标下的位移空间偏导 - * @param r (in)r轴坐标 + * @param[in] theta r轴相对x轴的旋转弧度 + * @param[in,out] u 柱坐标下的位移矢量 + * @param[in,out] upar 柱坐标下的位移空间偏导 + * @param[in] r r轴坐标 */ void rot_zrt2zxy_upar(const double theta, double u[3], double upar[3][3], const double r); \ No newline at end of file diff --git a/pygrt/C_extension/include/common/dwm.h b/pygrt/C_extension/include/common/dwm.h index b716766f..cbcaf92f 100644 --- a/pygrt/C_extension/include/common/dwm.h +++ b/pygrt/C_extension/include/common/dwm.h @@ -23,13 +23,13 @@ * 传统的离散波数积分,结果以三维数组的形式返回,形状分别代表震中距、不同震源不同阶数 * 和4种积分类型(p=0,1,2,3) * - * @param[in] mod1d (in)`MODEL1D` 结构体指针 - * @param[in] dk (in)波数积分间隔 - * @param[in] kmax (in)波数积分的上限 - * @param[in] keps (in)波数积分的收敛条件,要求在某震中距下所有格林函数都收敛,为负数代表不提前判断收敛,按照波数积分上限进行积分 - * @param[in] omega (in)复数频率 - * @param[in] nr (in)震中距数量 - * @param[in] rs (in)震中距数组 + * @param[in] mod1d `MODEL1D` 结构体指针 + * @param[in] dk 波数积分间隔 + * @param[in] kmax 波数积分的上限 + * @param[in] keps 波数积分的收敛条件,要求在某震中距下所有格林函数都收敛,为负数代表不提前判断收敛,按照波数积分上限进行积分 + * @param[in] omega 复数频率 + * @param[in] nr 震中距数量 + * @param[in] rs 震中距数组 * * @param[out] sum_J 积分值 * @@ -45,8 +45,8 @@ MYREAL discrete_integ( const MODEL1D *mod1d, MYREAL dk, MYREAL kmax, MYREAL keps, MYCOMPLEX omega, MYINT nr, MYREAL *rs, - MYCOMPLEX sum_J[nr][GRT_SRC_M_COUNTS][GRT_SRC_P_COUNTS], + MYCOMPLEX sum_J[nr][SRC_M_NUM][INTEG_NUM], bool calc_upar, - MYCOMPLEX sum_uiz_J[nr][GRT_SRC_M_COUNTS][GRT_SRC_P_COUNTS], - MYCOMPLEX sum_uir_J[nr][GRT_SRC_M_COUNTS][GRT_SRC_P_COUNTS], + MYCOMPLEX sum_uiz_J[nr][SRC_M_NUM][INTEG_NUM], + MYCOMPLEX sum_uir_J[nr][SRC_M_NUM][INTEG_NUM], FILE *fstats, KernelFunc kerfunc); diff --git a/pygrt/C_extension/include/common/fim.h b/pygrt/C_extension/include/common/fim.h index 813cc14f..a60a0a93 100755 --- a/pygrt/C_extension/include/common/fim.h +++ b/pygrt/C_extension/include/common/fim.h @@ -28,15 +28,15 @@ * 其中\f$x=kr\f$. * * - * @param[in] mod1d (in)`MODEL1D` 结构体指针 - * @param[in] k0 (in)前一部分的波数积分结束点k值 - * @param[in] dk0 (in)前一部分的波数积分间隔 - * @param[in] filondk (in)filon积分间隔 - * @param[in] kmax (in)波数积分的上限 - * @param[in] keps (in)波数积分的收敛条件,要求在某震中距下所有格林函数都收敛 - * @param[in] omega (in)复数频率 - * @param[in] nr (in)震中距数量 - * @param[in] rs (in)震中距数组 + * @param[in] mod1d `MODEL1D` 结构体指针 + * @param[in] k0 前一部分的波数积分结束点k值 + * @param[in] dk0 前一部分的波数积分间隔 + * @param[in] filondk filon积分间隔 + * @param[in] kmax 波数积分的上限 + * @param[in] keps 波数积分的收敛条件,要求在某震中距下所有格林函数都收敛 + * @param[in] omega 复数频率 + * @param[in] nr 震中距数量 + * @param[in] rs 震中距数组 * * @param[out] sum_J 积分值 * @@ -44,18 +44,18 @@ * @param[out] sum_uiz_J uiz的积分值 * @param[out] sum_uir_J uir的积分值 * - * @param[out] fstats (out)文件指针,保存不同k值的格林函数积分核函数 - * @param[in] kerfunc (in)计算核函数的函数指针 + * @param[out] fstats 文件指针,保存不同k值的格林函数积分核函数 + * @param[in] kerfunc 计算核函数的函数指针 * * @return k 积分截至时的波数 */ MYREAL linear_filon_integ( const MODEL1D *mod1d, MYREAL k0, MYREAL dk0, MYREAL filondk, MYREAL kmax, MYREAL keps, MYCOMPLEX omega, MYINT nr, MYREAL *rs, - MYCOMPLEX sum_J[nr][GRT_SRC_M_COUNTS][GRT_SRC_P_COUNTS], + MYCOMPLEX sum_J[nr][SRC_M_NUM][INTEG_NUM], bool calc_upar, - MYCOMPLEX sum_uiz_J[nr][GRT_SRC_M_COUNTS][GRT_SRC_P_COUNTS], - MYCOMPLEX sum_uir_J[nr][GRT_SRC_M_COUNTS][GRT_SRC_P_COUNTS], + MYCOMPLEX sum_uiz_J[nr][SRC_M_NUM][INTEG_NUM], + MYCOMPLEX sum_uir_J[nr][SRC_M_NUM][INTEG_NUM], FILE *fstats, KernelFunc kerfunc); diff --git a/pygrt/C_extension/include/common/integral.h b/pygrt/C_extension/include/common/integral.h index ec9335d9..300dab61 100644 --- a/pygrt/C_extension/include/common/integral.h +++ b/pygrt/C_extension/include/common/integral.h @@ -26,9 +26,9 @@ */ void int_Pk( MYREAL k, MYREAL r, - const MYCOMPLEX QWV[GRT_SRC_M_COUNTS][GRT_SRC_QWV_COUNTS], + const MYCOMPLEX QWV[SRC_M_NUM][QWV_NUM], bool calc_uir, - MYCOMPLEX SUM[GRT_SRC_M_COUNTS][GRT_SRC_P_COUNTS]); + MYCOMPLEX SUM[SRC_M_NUM][INTEG_NUM]); @@ -37,10 +37,10 @@ void int_Pk( * 将最终计算好的多个积分值,按照公式(5.6.22)组装成3分量。 * * @param[in] sum_J 积分结果 - * @param[out] tol Z、R、T分量频谱结果 + * @param[out] tol Z、R、T分量结果 */ void merge_Pk( - const MYCOMPLEX sum_J[GRT_SRC_M_COUNTS][GRT_SRC_P_COUNTS], MYCOMPLEX tol[GRT_SRC_M_COUNTS][GRT_SRC_CHA_COUNTS]); + const MYCOMPLEX sum_J[SRC_M_NUM][INTEG_NUM], MYCOMPLEX tol[SRC_M_NUM][CHANNEL_NUM]); @@ -60,6 +60,6 @@ void merge_Pk( */ void int_Pk_filon( MYREAL k, MYREAL r, bool iscos, - const MYCOMPLEX QWV[GRT_SRC_M_COUNTS][GRT_SRC_QWV_COUNTS], + const MYCOMPLEX QWV[SRC_M_NUM][QWV_NUM], bool calc_uir, - MYCOMPLEX SUM[GRT_SRC_M_COUNTS][GRT_SRC_P_COUNTS]); + MYCOMPLEX SUM[SRC_M_NUM][INTEG_NUM]); diff --git a/pygrt/C_extension/include/common/iostats.h b/pygrt/C_extension/include/common/iostats.h index a5c77bea..389619d2 100755 --- a/pygrt/C_extension/include/common/iostats.h +++ b/pygrt/C_extension/include/common/iostats.h @@ -27,24 +27,23 @@ * 记录其值主要用于参考其变化趋势。 */ void write_stats( - FILE *f0, MYREAL k, const MYCOMPLEX QWV[GRT_SRC_M_COUNTS][GRT_SRC_QWV_COUNTS]); + FILE *f0, MYREAL k, const MYCOMPLEX QWV[SRC_M_NUM][QWV_NUM]); /** * 记录峰谷平均法的峰谷位置 * - * @param[out] f0 (out)二进制文件指针 - * @param[in] k (in)波数 - * @param[in] maxNpt (in)波峰+波谷的数量(本质是计算中提前预设的量,见ptam.c文件中PTA_method函数) - * @param[in] Kpt (in)最终收敛积分值使用的波峰波谷位置 - * @param[in] Fpt (in)最终收敛积分值使用的波峰波谷幅值 + * @param[out] f0 二进制文件指针 + * @param[in] k 波数 + * @param[in] Kpt 最终收敛积分值使用的波峰波谷位置 + * @param[in] Fpt 最终收敛积分值使用的波峰波谷幅值 * * @note 文件记录的积分值与最终的结果还差一系列的系数, * 记录其值主要用于参考其变化趋势。 * */ void write_stats_ptam( - FILE *f0, MYREAL k, MYINT maxNpt, - MYREAL Kpt[GRT_SRC_M_COUNTS][GRT_SRC_P_COUNTS][maxNpt], - MYCOMPLEX Fpt[GRT_SRC_M_COUNTS][GRT_SRC_P_COUNTS][maxNpt]); \ No newline at end of file + FILE *f0, MYREAL k, + MYREAL Kpt[SRC_M_NUM][INTEG_NUM][PTAM_MAX_PT], + MYCOMPLEX Fpt[SRC_M_NUM][INTEG_NUM][PTAM_MAX_PT]); \ No newline at end of file diff --git a/pygrt/C_extension/include/common/kernel.h b/pygrt/C_extension/include/common/kernel.h index 1a978b5b..31a0318a 100644 --- a/pygrt/C_extension/include/common/kernel.h +++ b/pygrt/C_extension/include/common/kernel.h @@ -17,5 +17,5 @@ * 计算核函数的函数指针,动态与静态的接口一致 */ typedef void (*KernelFunc) ( - const MODEL1D *mod1d, MYCOMPLEX omega, MYREAL k, MYCOMPLEX QWV[GRT_SRC_M_COUNTS][GRT_SRC_QWV_COUNTS], - bool calc_uiz, MYCOMPLEX QWV_uiz[GRT_SRC_M_COUNTS][GRT_SRC_QWV_COUNTS]); \ No newline at end of file + const MODEL1D *mod1d, MYCOMPLEX omega, MYREAL k, MYCOMPLEX QWV[SRC_M_NUM][QWV_NUM], + bool calc_uiz, MYCOMPLEX QWV_uiz[SRC_M_NUM][QWV_NUM]); \ No newline at end of file diff --git a/pygrt/C_extension/include/common/matrix.h b/pygrt/C_extension/include/common/matrix.h index b2d7776e..2f0c3884 100755 --- a/pygrt/C_extension/include/common/matrix.h +++ b/pygrt/C_extension/include/common/matrix.h @@ -13,8 +13,8 @@ /** * 计算2x2复矩阵的逆 * - * @param M[2][2] (in)原矩阵 - * @param invM[2][2] (out)逆矩阵 + * @param[in] M 原矩阵 + * @param[out] invM 逆矩阵 */ inline GCC_ALWAYS_INLINE void cmat2x2_inv(const MYCOMPLEX M[2][2], MYCOMPLEX invM[2][2]) { MYCOMPLEX M00 = M[0][0]; @@ -38,9 +38,9 @@ inline GCC_ALWAYS_INLINE void cmat2x2_inv(const MYCOMPLEX M[2][2], MYCOMPLEX inv /** * 计算2x2复矩阵的和 * - * @param M1[2][2] (in)矩阵1 - * @param M2[2][2] (in)矩阵2 - * @param M[2][2] (out)和矩阵 + * @param[in] M1 矩阵1 + * @param[in] M2 矩阵2 + * @param[out] M 和矩阵 */ inline GCC_ALWAYS_INLINE void cmat2x2_add(const MYCOMPLEX M1[2][2], const MYCOMPLEX M2[2][2], MYCOMPLEX M[2][2]){ M[0][0] = M1[0][0] + M2[0][0]; @@ -52,9 +52,9 @@ inline GCC_ALWAYS_INLINE void cmat2x2_add(const MYCOMPLEX M1[2][2], const MYCOMP /** * 计算2x2复矩阵的差 * - * @param M1[2][2] (in)矩阵1 - * @param M2[2][2] (in)矩阵2 - * @param M[2][2] (out)差矩阵 M1-M2 + * @param[in] M1 矩阵1 + * @param[in] M2 矩阵2 + * @param[out] M 差矩阵, M1 - M2 */ inline GCC_ALWAYS_INLINE void cmat2x2_sub(const MYCOMPLEX M1[2][2], const MYCOMPLEX M2[2][2], MYCOMPLEX M[2][2]){ M[0][0] = M1[0][0] - M2[0][0]; @@ -66,7 +66,7 @@ inline GCC_ALWAYS_INLINE void cmat2x2_sub(const MYCOMPLEX M1[2][2], const MYCOMP /** * 计算单位阵与2x2复矩阵的差 * - * @param M[2][2] (inout)差矩阵 I-M2 + * @param[in,out] M 差矩阵 I-M2 */ inline GCC_ALWAYS_INLINE void cmat2x2_one_sub(MYCOMPLEX M[2][2]){ M[0][0] = RONE - M[0][0]; @@ -78,9 +78,9 @@ inline GCC_ALWAYS_INLINE void cmat2x2_one_sub(MYCOMPLEX M[2][2]){ /** * 计算2x2复矩阵的积(矩阵相乘) * - * @param M1[2][2] (in)矩阵1 - * @param M2[2][2] (in)矩阵2 - * @param M[2][2] (out)积矩阵 M1 * M2 + * @param[in] M1 矩阵1 + * @param[in] M2 矩阵2 + * @param[out] M 积矩阵, M1 * M2 */ inline GCC_ALWAYS_INLINE void cmat2x2_mul(const MYCOMPLEX M1[2][2], const MYCOMPLEX M2[2][2], MYCOMPLEX M[2][2]){ MYCOMPLEX M011, M012, M021, M022; @@ -98,9 +98,9 @@ inline GCC_ALWAYS_INLINE void cmat2x2_mul(const MYCOMPLEX M1[2][2], const MYCOMP /** * 计算2x2复矩阵和常量的积 * - * @param M1[2][2] (in)矩阵1 - * @param k (in)常数 - * @param M[2][2] (out)积矩阵 k * M1 + * @param[in] M1 矩阵1 + * @param[in] k 常数 + * @param[out] M 积矩阵, k * M2 */ inline GCC_ALWAYS_INLINE void cmat2x2_k(const MYCOMPLEX M1[2][2], MYCOMPLEX k0, MYCOMPLEX M[2][2]){ M[0][0] = M1[0][0] * k0; @@ -112,9 +112,9 @@ inline GCC_ALWAYS_INLINE void cmat2x2_k(const MYCOMPLEX M1[2][2], MYCOMPLEX k0, /** * 计算2x2复矩阵和2x1的复向量的积 * - * @param M1[2][2] (in)矩阵1 - * @param M2[2] (in)向量2 - * @param M[2][2] (out)积向量 M1 * M2 + * @param[in] M1 矩阵1 + * @param[in] M2 向量 + * @param[out] M 积矩阵, M1 * M2 */ inline GCC_ALWAYS_INLINE void cmat2x1_mul(const MYCOMPLEX M1[2][2], const MYCOMPLEX M2[2], MYCOMPLEX M[2]){ MYCOMPLEX M00, M10; @@ -127,8 +127,8 @@ inline GCC_ALWAYS_INLINE void cmat2x1_mul(const MYCOMPLEX M1[2][2], const MYCOMP /** * 2x2复矩阵赋值 * - * @param M1[2][2] (in)源矩阵 - * @param M2[2][2] (out)目标矩阵 + * @param[in] M1 源矩阵 + * @param[out] M2 目标矩阵 */ inline GCC_ALWAYS_INLINE void cmat2x2_assign(const MYCOMPLEX M1[2][2], MYCOMPLEX M2[2][2]){ M2[0][0] = M1[0][0]; @@ -140,12 +140,12 @@ inline GCC_ALWAYS_INLINE void cmat2x2_assign(const MYCOMPLEX M1[2][2], MYCOMPLEX /** * 计算nxn复矩阵的积(小矩阵)(最暴力的方式) * - * @param m1 (in)M1矩阵行数 - * @param n1 (in)M1矩阵列数 - * @param p1 (in)M2矩阵列数 - * @param M1[m1][n1] (in)M1矩阵 - * @param M2[n1][p1] (in)M2矩阵 - * @param M[m1][p1] (out)积矩阵 M1 * M2 + * @param[in] m1 M1矩阵行数 + * @param[in] n1 M1矩阵列数 + * @param[in] p1 M2矩阵列数 + * @param[in] M1 M1矩阵 + * @param[in] M2 M2矩阵 + * @param[out] M 积矩阵 M1 * M2 */ inline GCC_ALWAYS_INLINE void cmatmxn_mul(MYINT m1, MYINT n1, MYINT p1, const MYCOMPLEX M1[m1][n1], const MYCOMPLEX M2[n1][p1], MYCOMPLEX M[m1][p1]){ MYINT m, n, k; @@ -170,14 +170,14 @@ inline GCC_ALWAYS_INLINE void cmatmxn_mul(MYINT m1, MYINT n1, MYINT p1, const MY /** * 从M1大矩阵中划分Q子矩阵 * - * @param m1 (in)M1矩阵行数 - * @param n1 (in)M1矩阵列数 - * @param M1[m1][n1] (in)M1矩阵 - * @param im (in)子矩阵起始行索引 - * @param in (in)子矩阵起始列索引 - * @param lm (in)子矩阵行数 - * @param ln (in)子矩阵列数 - * @param Q[lm][ln] (out)子矩阵 + * @param[in] m1 M1矩阵行数 + * @param[in] n1 M1矩阵列数 + * @param[in] M1 M1矩阵 + * @param[in] im 子矩阵起始行索引 + * @param[in] in 子矩阵起始列索引 + * @param[in] lm 子矩阵行数 + * @param[in] ln 子矩阵列数 + * @param[out] Q 子矩阵 */ inline GCC_ALWAYS_INLINE void cmatmxn_block(MYINT m1, MYINT n1, const MYCOMPLEX M[m1][n1], MYINT im, MYINT in, MYINT lm, MYINT ln, MYCOMPLEX Q[lm][ln]){ for(MYINT m=0; m #include "common/const.h" -/** - * 单个水平层的结构体 - */ +/** 单个水平层的结构体 */ typedef struct _LAYER { MYREAL thk; ///< 层厚,最后一层厚度不使用(当作正无穷), km MYREAL Va; ///< P波速度 km/s @@ -29,9 +27,7 @@ typedef struct _LAYER { MYCOMPLEX kbkb; ///< \f$ (\omega/V_b)^2 \f$ } LAYER; -/** - * 1D模型结构体,包括多个水平层 - */ +/** 1D模型结构体,包括多个水平层 */ typedef struct _MODEL1D { LAYER * lays; ///< 不同层的物性参数 MYINT n; ///< 层数,注意包括了震源和接收点的虚拟层,(n>=3) @@ -44,9 +40,7 @@ typedef struct _MODEL1D { } MODEL1D; -/** - * 用于从Python传递数据的中间结构体 - */ +/** 用于从Python传递数据的中间结构体 */ typedef struct _PYMODEL1D { MYINT n; ///< 层数,注意包括了震源和接收点的虚拟层,(n>=3) MYREAL depsrc; ///< 震源深度 km @@ -67,7 +61,7 @@ typedef struct _PYMODEL1D { /** * 打印模型参数信息,主要用于调试程序 * - * @param mod1d (in)`MODEL1D` 结构体指针 + * @param[in] mod1d `MODEL1D` 结构体指针 * */ void print_mod1d(const MODEL1D *mod1d); @@ -75,7 +69,7 @@ void print_mod1d(const MODEL1D *mod1d); /** * 打印PYMODEL1D模型参数信息,主要用于调试程序 * - * @param pymod (in)`PYMODEL1D` 结构体指针 + * @param[in] pymod `PYMODEL1D` 结构体指针 * */ void print_pymod(const PYMODEL1D *pymod); @@ -83,14 +77,14 @@ void print_pymod(const PYMODEL1D *pymod); /** * 释放 `PYMODEL1D` 结构体指针 * - * @param pymod (out)`PYMODEL1D` 结构体指针 + * @param[out] pymod `PYMODEL1D` 结构体指针 */ void free_pymod(PYMODEL1D *pymod); /** * 初始化模型内存空间 * - * @param n (in)模型层数 + * @param[in] n 模型层数 * * @return `MODEL1D` 结构体指针 * @@ -100,8 +94,8 @@ MODEL1D * init_mod1d(MYINT n); /** * 将 `PYMODEL1D` 结构体信息转到 `MODEL1D` 结构体中 * - * @param pymod1d (in)`PYMODEL1D` 结构体指针 - * @param mod1d (out) `MODEL1D` 结构体指针 + * @param[in] pymod1d `PYMODEL1D` 结构体指针 + * @param[out] mod1d `MODEL1D` 结构体指针 * */ void get_mod1d(const PYMODEL1D *pymod1d, MODEL1D *mod1d); @@ -109,8 +103,8 @@ void get_mod1d(const PYMODEL1D *pymod1d, MODEL1D *mod1d); /** * 复制 `MODEL1D` 结构体,要求都以初始化 * - * @param mod1d1 (in)`MODEL1D` 源结构体指针 - * @param mod1d2 (out)`MODEL1D` 目标结构体指针 + * @param[in] mod1d1 `MODEL1D` 源结构体指针 + * @param[out] mod1d2 `MODEL1D` 目标结构体指针 * */ void copy_mod1d(const MODEL1D *mod1d1, MODEL1D *mod1d2); @@ -118,7 +112,7 @@ void copy_mod1d(const MODEL1D *mod1d1, MODEL1D *mod1d2); /** * 释放 `MODEL1D` 结构体指针 * - * @param mod1d (out)`MODEL1D` 结构体指针 + * @param[out] mod1d `MODEL1D` 结构体指针 */ void free_mod1d(MODEL1D *mod1d); @@ -126,15 +120,15 @@ void free_mod1d(MODEL1D *mod1d); /** * 根据不同的omega, 更新模型的 \f$ k_a^2, k_b^2 \f$ 参数 * - * @param mod1d (inout)`MODEL1D` 结构体指针 - * @param omega (in)复数频率 + * @param[in,out] mod1d `MODEL1D` 结构体指针 + * @param[in] omega 复数频率 */ void update_mod1d_omega(MODEL1D *mod1d, MYCOMPLEX omega); /** * 初始化PYMODEL1D模型内存空间 * - * @param n (in)模型层数 + * @param[in] n 模型层数 * * @return `PYMODEL1D` 结构体指针 * @@ -144,10 +138,10 @@ PYMODEL1D * init_pymod(MYINT n); /** * 从文件中读取模型文件,以PYMODEL1D结构体形式 * - * @param command (in)命令名称 - * @param modelpath (in)模型文件路径 - * @param depsrc (in)震源深度 - * @param deprcv (in)接收深度 + * @param[in] command 命令名称 + * @param[in] modelpath 模型文件路径 + * @param[in] depsrc 震源深度 + * @param[in] deprcv 接收深度 * * @return `PYMODEL1D` 结构体指针 * diff --git a/pygrt/C_extension/include/common/progressbar.h b/pygrt/C_extension/include/common/progressbar.h index 6bf6174e..45274f82 100755 --- a/pygrt/C_extension/include/common/progressbar.h +++ b/pygrt/C_extension/include/common/progressbar.h @@ -16,7 +16,7 @@ /** * 根据百分比打印进度条 * - * @param prefix (in)进度条前缀字符串 - * @param percentage (in)百分比(整数) + * @param[in] prefix 进度条前缀字符串 + * @param[in] percentage 百分比(整数) */ void printprogressBar(const char *prefix, MYINT percentage); \ No newline at end of file diff --git a/pygrt/C_extension/include/common/ptam.h b/pygrt/C_extension/include/common/ptam.h index 16ccc4d4..f9b27c85 100755 --- a/pygrt/C_extension/include/common/ptam.h +++ b/pygrt/C_extension/include/common/ptam.h @@ -22,39 +22,36 @@ #include "common/kernel.h" -#define PTAM_MAX_PEAK_TROUGH 36 ///< 最后统计波峰波谷的目标数量 - - /** * 峰谷平均法 Peak-Trough Averaging Method,最后收敛的积分结果以三维数组的形式返回, * - * @param[in] mod1d (in)`MODEL1D` 结构体指针 - * @param[in] k0 (in)先前的积分已经进行到了波数k0 - * @param[in] predk (in)先前的积分使用的积分间隔dk,因为峰谷平均法使用的 - * 积分间隔会和之前的不一致,这里传入该系数以做预先调整 - * @param[in] omega (in)复数频率 - * @param[in] nr (in)震中距数量 - * @param[in] rs (in)震中距数组 + * @param[in] mod1d `MODEL1D` 结构体指针 + * @param[in] k0 先前的积分已经进行到了波数k0 + * @param[in] predk 先前的积分使用的积分间隔dk,因为峰谷平均法使用的 + * 积分间隔会和之前的不一致,这里传入该系数以做预先调整 + * @param[in] omega 复数频率 + * @param[in] nr 震中距数量 + * @param[in] rs 震中距数组 * - * @param[out] sum_J0 积分值 + * @param[out] sum_J0 积分值 * - * @param[in] calc_upar 是否计算位移u的空间导数 + * @param[in] calc_upar 是否计算位移u的空间导数 * @param[out] sum_uiz_J0 uiz的积分值 * @param[out] sum_uir_J0 uir的积分值 * - * @param[out] ptam_fstatsnr (out)峰谷平均法过程文件指针数组 - * @param[in] kerfunc (in)计算核函数的函数指针 + * @param[out] ptam_fstatsnr 峰谷平均法过程文件指针数组 + * @param[in] kerfunc 计算核函数的函数指针 * * */ void PTA_method( const MODEL1D *mod1d, MYREAL k0, MYREAL predk, MYCOMPLEX omega, MYINT nr, MYREAL *rs, - MYCOMPLEX sum_J0[nr][GRT_SRC_M_COUNTS][GRT_SRC_P_COUNTS], + MYCOMPLEX sum_J0[nr][SRC_M_NUM][INTEG_NUM], bool calc_upar, - MYCOMPLEX sum_uiz_J0[nr][GRT_SRC_M_COUNTS][GRT_SRC_P_COUNTS], - MYCOMPLEX sum_uir_J0[nr][GRT_SRC_M_COUNTS][GRT_SRC_P_COUNTS], + MYCOMPLEX sum_uiz_J0[nr][SRC_M_NUM][INTEG_NUM], + MYCOMPLEX sum_uir_J0[nr][SRC_M_NUM][INTEG_NUM], FILE *ptam_fstatsnr[nr][2], KernelFunc kerfunc); @@ -64,19 +61,19 @@ void PTA_method( /** * 观察连续3个点的函数值的实部变化,判断是波峰(1)还是波谷(-1), 并计算对应值。 * - * @param idx1 (in)阶数索引 - * @param idx2 (in)积分类型索引 - * @param arr (in)存有连续三个点的函数值的数组 - * @param k (in)三个点的起始波数 - * @param dk (in)三个点的波数间隔,这样使用k和dk定义了三个点的位置 - * @param pk (out)估计的波峰或波谷处的波数 - * @param value (out)估计的波峰或波谷处的函数值 + * @param[in] idx1 阶数索引 + * @param[in] idx2 积分类型索引 + * @param[in] arr 存有连续三个点的函数值的数组 + * @param[in] k 三个点的起始波数 + * @param[in] dk 三个点的波数间隔,这样使用k和dk定义了三个点的位置 + * @param[out] pk 估计的波峰或波谷处的波数 + * @param[out] value 估计的波峰或波谷处的函数值 * * @return 波峰(1),波谷(-1),其它(0) * */ MYINT cplx_peak_or_trough( - MYINT idx1, MYINT idx2, const MYCOMPLEX arr[3][GRT_SRC_M_COUNTS][GRT_SRC_P_COUNTS], + MYINT idx1, MYINT idx2, const MYCOMPLEX arr[PTAM_WINDOW_SIZE][SRC_M_NUM][INTEG_NUM], MYREAL k, MYREAL dk, MYREAL *pk, MYCOMPLEX *value); @@ -86,8 +83,8 @@ MYINT cplx_peak_or_trough( * M_i = 0.5\times (M_i + M_{i+1}) * \f] * - * @param n1 (in)数组长度 - * @param arr (inout)振荡的数组,最终收敛值在第一个,arr[0] + * @param[in] n1 数组长度 + * @param[in,out] arr 振荡的数组,最终收敛值在第一个,arr[0] * */ void cplx_shrink(MYINT n1, MYCOMPLEX *arr); \ No newline at end of file diff --git a/pygrt/C_extension/include/common/quadratic.h b/pygrt/C_extension/include/common/quadratic.h index c4085c40..d1c325ac 100755 --- a/pygrt/C_extension/include/common/quadratic.h +++ b/pygrt/C_extension/include/common/quadratic.h @@ -19,11 +19,11 @@ * 已知三个点x1,x2,x3,以及对应的函数值f1,f2,f3, 拟合函数 * * - * @param x[3] (in)自变量 - * @param f[3] (in)因变量 - * @param pa (out)拟合a值 - * @param pb (out)拟合b值 - * @param pc (out)拟合c值 + * @param[in] x 自变量 + * @param[in] f 因变量 + * @param[out] pa 拟合a值 + * @param[out] pb 拟合b值 + * @param[out] pc 拟合c值 */ void quad_term(const MYREAL x[3], const MYCOMPLEX f[3], MYCOMPLEX *pa, MYCOMPLEX *pb, MYCOMPLEX *pc); @@ -31,10 +31,10 @@ void quad_term(const MYREAL x[3], const MYCOMPLEX f[3], MYCOMPLEX *pa, MYCOMPLEX /** * 给定x,根据a,b,c值,估计 \f$ f(x) \f$ * - * @param x (in)自变量 - * @param a (in)a值 - * @param b (in)b值 - * @param c (in)c值 + * @param[in] x 自变量 + * @param[in] a a值 + * @param[in] b b值 + * @param[in] c c值 * @return \f$ f(x) = ax^2 + bx + c \f$ * */ @@ -44,11 +44,11 @@ MYCOMPLEX quad_eval(MYREAL x, MYCOMPLEX a, MYCOMPLEX b, MYCOMPLEX c); /** * 给定x,根据a,b,c值,估计 \f$ \int_{x_1}^{x_2} f(s)ds \f$ * - * @param x1 (in)积分下限 - * @param x2 (in)积分上限 - * @param a (in)a值 - * @param b (in)b值 - * @param c (in)c值 + * @param[in] x1 积分下限 + * @param[in] x2 积分上限 + * @param[in] a a值 + * @param[in] b b值 + * @param[in] c c值 * @return \f$ \frac{1}{3}a(x_2^3-x_1^3) + \frac{1}{2}b(x_2^2-x_1^2) + c(x_2-x_1) \f$ * */ diff --git a/pygrt/C_extension/include/common/radiation.h b/pygrt/C_extension/include/common/radiation.h index bc9a48af..dd06a4cc 100644 --- a/pygrt/C_extension/include/common/radiation.h +++ b/pygrt/C_extension/include/common/radiation.h @@ -19,18 +19,18 @@ /** * 设置每个震源的方向因子 * - * @param srcCoef (out)方向因子,[3]表示ZRT三分量,[6]表示6个震源(EX,VF,HF,DD,DS,SS) - * @param computeType (in)要计算的震源类型,使用宏定义 - * @param par_theta (in)方向因子中是否对theta(az)求导 - * @param M0 (in)放大系数,对于剪切源、爆炸源、张量震源,M0是标量地震矩;对于单力源,M0是放大系数 - * @param coef (in)放大系数,用于位移空间导数的计算 - * @param azrad (in)弧度制的方位角 - * @param mchn (in)震源机制参数, - * 对于单力源,mchn={fn, fe, fz}, - * 对于剪切源,mchn={strike, dip, rake}, - * 对于张量源,mchn={Mxx, Mxy, Mxz, Myy, Myz, Mzz} + * @param[out] srcRadi 方向因子,[3]表示ZRT三分量,[6]表示6个震源(EX,VF,HF,DD,DS,SS) + * @param[in] computeType 要计算的震源类型,使用宏定义 + * @param[in] par_theta 方向因子中是否对theta(az)求导 + * @param[in] M0 放大系数,对于剪切源、爆炸源、张量震源,M0是标量地震矩;对于单力源,M0是放大系数 + * @param[in] coef 放大系数,用于位移空间导数的计算 + * @param[in] azrad 弧度制的方位角 + * @param[in] mchn 震源机制参数, + * 对于单力源,mchn={fn, fe, fz}, + * 对于剪切源,mchn={strike, dip, rake}, + * 对于张量源,mchn={Mxx, Mxy, Mxz, Myy, Myz, Mzz} */ void set_source_radiation( - double srcCoef[3][6], const int computeType, const bool par_theta, + double srcRadi[3][6], const int computeType, const bool par_theta, const double M0, const double coef, const double azrad, const double mchn[6] ); \ No newline at end of file diff --git a/pygrt/C_extension/include/common/recursion.h b/pygrt/C_extension/include/common/recursion.h index 73299bfa..ece8ddd4 100644 --- a/pygrt/C_extension/include/common/recursion.h +++ b/pygrt/C_extension/include/common/recursion.h @@ -19,20 +19,20 @@ /** * 根据公式(5.5.3(1))进行递推 * - * @param RD1[2][2] (in)1层 P-SV 下传反射系数矩阵 - * @param RDL1 (in)1层 SH 下传反射系数 - * @param RU1[2][2] (in)1层 P-SV 上传反射系数矩阵 - * @param RUL1 (in)1层 SH 上传反射系数 - * @param TD1[2][2] (in)1层 P-SV 下传透射系数矩阵 - * @param TDL1 (in)1层 SH 下传透射系数 - * @param TU1[2][2] (in)1层 P-SV 上传透射系数矩阵 - * @param TUL1 (in)1层 SH 上传透射系数 - * @param RD2[2][2] (in)2层 P-SV 下传反射系数矩阵 - * @param RDL2 (in)2层 SH 下传反射系数 - * @param RD[2][2] (out)1+2层 P-SV 下传反射系数矩阵 - * @param RDL (out)1+2层 SH 下传反射系数 - * @param inv_2x2T[2][2] (out) 非NULL时,返回公式中的 \f$ (\mathbf{I} - \mathbf{R}_U^1 \mathbf{R}_D^2)^{-1} \mathbf{T}_D^1 \f$ 一项 - * @param invT (out) 非NULL时,返回上面inv_2x2T的标量形式 + * @param[in] RD1 1层 P-SV 下传反射系数矩阵 + * @param[in] RDL1 1层 SH 下传反射系数 + * @param[in] RU1 1层 P-SV 上传反射系数矩阵 + * @param[in] RUL1 1层 SH 上传反射系数 + * @param[in] TD1 1层 P-SV 下传透射系数矩阵 + * @param[in] TDL1 1层 SH 下传透射系数 + * @param[in] TU1 1层 P-SV 上传透射系数矩阵 + * @param[in] TUL1 1层 SH 上传透射系数 + * @param[in] RD2 2层 P-SV 下传反射系数矩阵 + * @param[in] RDL2 2层 SH 下传反射系数 + * @param[out] RD 1+2层 P-SV 下传反射系数矩阵 + * @param[out] RDL 1+2层 SH 下传反射系数 + * @param[out] inv_2x2T 非NULL时,返回公式中的 \f$ (\mathbf{I} - \mathbf{R}_U^1 \mathbf{R}_D^2)^{-1} \mathbf{T}_D^1 \f$ 一项 + * @param[out] invT 非NULL时,返回上面inv_2x2T的标量形式 * */ void recursion_RD( @@ -45,18 +45,18 @@ void recursion_RD( /** * 根据公式(5.5.3(2))进行递推 * - * @param RU1[2][2] (in)1层 P-SV 上传反射系数矩阵 - * @param RUL1 (in)1层 SH 上传反射系数 - * @param TD1[2][2] (in)1层 P-SV 下传透射系数矩阵 - * @param TDL1 (in)1层 SH 下传透射系数 - * @param RD2[2][2] (in)2层 P-SV 下传反射系数矩阵 - * @param RDL2 (in)2层 SH 下传反射系数 - * @param TD2[2][2] (in)2层 P-SV 下传透射系数矩阵 - * @param TDL2 (in)2层 SH 下传透射系数 - * @param TD[2][2] (out)1+2层 P-SV 下传透射系数矩阵 - * @param TDL (out)1+2层 SH 下传透射系数 - * @param inv_2x2T[2][2] (out) 非NULL时,返回公式中的 \f$ (\mathbf{I} - \mathbf{R}_U^1 \mathbf{R}_D^2)^{-1} \mathbf{T}_D^1 \f$ 一项 - * @param invT (out) 非NULL时,返回上面inv_2x2T的标量形式 + * @param[in] RU1 1层 P-SV 上传反射系数矩阵 + * @param[in] RUL1 1层 SH 上传反射系数 + * @param[in] TD1 1层 P-SV 下传透射系数矩阵 + * @param[in] TDL1 1层 SH 下传透射系数 + * @param[in] RD2 2层 P-SV 下传反射系数矩阵 + * @param[in] RDL2 2层 SH 下传反射系数 + * @param[in] TD2 2层 P-SV 下传透射系数矩阵 + * @param[in] TDL2 2层 SH 下传透射系数 + * @param[out] TD 1+2层 P-SV 下传透射系数矩阵 + * @param[out] TDL 1+2层 SH 下传透射系数 + * @param[out] inv_2x2T 非NULL时,返回公式中的 \f$ (\mathbf{I} - \mathbf{R}_U^1 \mathbf{R}_D^2)^{-1} \mathbf{T}_D^1 \f$ 一项 + * @param[out] invT 非NULL时,返回上面inv_2x2T的标量形式 * */ void recursion_TD( @@ -72,20 +72,20 @@ void recursion_TD( /** * 根据公式(5.5.3(3))进行递推 * - * @param RU1[2][2] (in)1层 P-SV 上传反射系数矩阵 - * @param RUL1 (in)1层 SH 上传反射系数 - * @param RD2[2][2] (in)2层 P-SV 下传反射系数矩阵 - * @param RDL2 (in)2层 SH 下传反射系数 - * @param RU2[2][2] (in)2层 P-SV 上传反射系数矩阵 - * @param RUL2 (in)2层 SH 上传反射系数 - * @param TD2[2][2] (in)2层 P-SV 下传透射系数矩阵 - * @param TDL2 (in)2层 SH 下传透射系数 - * @param TU2[2][2] (in)2层 P-SV 上传透射系数矩阵 - * @param TUL2 (in)2层 SH 上传透射系数 - * @param RU[2][2] (out)1+2层 P-SV 上传反射系数矩阵 - * @param RUL (out)1+2层 SH 上传反射系数 - * @param inv_2x2T[2][2] (out) 非NULL时,返回公式中的 \f$ (\mathbf{I} - \mathbf{R}_D^2 \mathbf{R}_U^1)^{-1} \mathbf{T}_U^2 \f$ 一项 - * @param invT (out) 非NULL时,返回上面inv_2x2T的标量形式 + * @param[in] RU1 1层 P-SV 上传反射系数矩阵 + * @param[in] RUL1 1层 SH 上传反射系数 + * @param[in] RD2 2层 P-SV 下传反射系数矩阵 + * @param[in] RDL2 2层 SH 下传反射系数 + * @param[in] RU2 2层 P-SV 上传反射系数矩阵 + * @param[in] RUL2 2层 SH 上传反射系数 + * @param[in] TD2 2层 P-SV 下传透射系数矩阵 + * @param[in] TDL2 2层 SH 下传透射系数 + * @param[in] TU2 2层 P-SV 上传透射系数矩阵 + * @param[in] TUL2 2层 SH 上传透射系数 + * @param[out] RU 1+2层 P-SV 上传反射系数矩阵 + * @param[out] RUL 1+2层 SH 上传反射系数 + * @param[out] inv_2x2T 非NULL时,返回公式中的 \f$ (\mathbf{I} - \mathbf{R}_D^2 \mathbf{R}_U^1)^{-1} \mathbf{T}_U^2 \f$ 一项 + * @param[out] invT 非NULL时,返回上面inv_2x2T的标量形式 * */ void recursion_RU( @@ -97,18 +97,18 @@ void recursion_RU( /** * 根据公式(5.5.3(4))进行递推 * - * @param RU1[2][2] (in)1层 P-SV 上传反射系数矩阵 - * @param RUL1 (in)1层 SH 上传反射系数 - * @param RD2[2][2] (in)2层 P-SV 下传反射系数矩阵 - * @param RDL2 (in)2层 SH 下传反射系数 - * @param RD2[2][2] (in)2层 P-SV 下传反射系数矩阵 - * @param RDL2 (in)2层 SH 下传反射系数 - * @param TU2[2][2] (in)2层 P-SV 上传透射系数矩阵 - * @param TUL2 (in)2层 SH 上传透射系数 - * @param TU[2][2] (out)1+2层 P-SV 上传透射系数矩阵 - * @param TUL (out)1+2层 SH 上传透射系数 - * @param inv_2x2T[2][2] (out) 非NULL时,返回公式中的 \f$ (\mathbf{I} - \mathbf{R}_D^2 \mathbf{R}_U^1)^{-1} \mathbf{T}_U^2 \f$ 一项 - * @param invT (out) 非NULL时,返回上面inv_2x2T的标量形式 + * @param[in] RU1 1层 P-SV 上传反射系数矩阵 + * @param[in] RUL1 1层 SH 上传反射系数 + * @param[in] RD2 2层 P-SV 下传反射系数矩阵 + * @param[in] RDL2 2层 SH 下传反射系数 + * @param[in] RD2 2层 P-SV 下传反射系数矩阵 + * @param[in] RDL2 2层 SH 下传反射系数 + * @param[in] TU2 2层 P-SV 上传透射系数矩阵 + * @param[in] TUL2 2层 SH 上传透射系数 + * @param[out] TU 1+2层 P-SV 上传透射系数矩阵 + * @param[out] TUL 1+2层 SH 上传透射系数 + * @param[out] inv_2x2T 非NULL时,返回公式中的 \f$ (\mathbf{I} - \mathbf{R}_D^2 \mathbf{R}_U^1)^{-1} \mathbf{T}_U^2 \f$ 一项 + * @param[out] invT 非NULL时,返回上面inv_2x2T的标量形式 * * */ @@ -124,30 +124,30 @@ void recursion_TU( /** * 根据公式(5.5.3)进行递推,相当于上面四个函数合并 * - * @param RD1[2][2] (in)1层 P-SV 下传反射系数矩阵 - * @param RDL1 (in)1层 SH 下传反射系数 - * @param RU1[2][2] (in)1层 P-SV 上传反射系数矩阵 - * @param RUL1 (in)1层 SH 上传反射系数 - * @param TD1[2][2] (in)1层 P-SV 下传透射系数矩阵 - * @param TDL1 (in)1层 SH 下传透射系数 - * @param TU1[2][2] (in)1层 P-SV 上传透射系数矩阵 - * @param TUL1 (in)1层 SH 上传透射系数 - * @param RD2[2][2] (in)2层 P-SV 下传反射系数矩阵 - * @param RDL2 (in)2层 SH 下传反射系数 - * @param RU2[2][2] (in)2层 P-SV 上传反射系数矩阵 - * @param RUL2 (in)2层 SH 上传反射系数 - * @param TD2[2][2] (in)2层 P-SV 下传透射系数矩阵 - * @param TDL2 (in)2层 SH 下传透射系数 - * @param TU2[2][2] (in)2层 P-SV 上传透射系数矩阵 - * @param TUL2 (in)2层 SH 上传透射系数 - * @param RD[2][2] (out)1+2层 P-SV 下传反射系数矩阵 - * @param RDL (out)1+2层 SH 下传反射系数 - * @param RU[2][2] (out)1+2层 P-SV 上传反射系数矩阵 - * @param RUL (out)1+2层 SH 上传反射系数 - * @param TD[2][2] (out)1+2层 P-SV 下传透射系数矩阵 - * @param TDL (out)1+2层 SH 下传透射系数 - * @param TU[2][2] (out)1+2层 P-SV 上传透射系数矩阵 - * @param TUL (out)1+2层 SH 上传透射系数 + * @param[in] RD1 1层 P-SV 下传反射系数矩阵 + * @param[in] RDL1 1层 SH 下传反射系数 + * @param[in] RU1 1层 P-SV 上传反射系数矩阵 + * @param[in] RUL1 1层 SH 上传反射系数 + * @param[in] TD1 1层 P-SV 下传透射系数矩阵 + * @param[in] TDL1 1层 SH 下传透射系数 + * @param[in] TU1 1层 P-SV 上传透射系数矩阵 + * @param[in] TUL1 1层 SH 上传透射系数 + * @param[in] RD2 2层 P-SV 下传反射系数矩阵 + * @param[in] RDL2 2层 SH 下传反射系数 + * @param[in] RU2 2层 P-SV 上传反射系数矩阵 + * @param[in] RUL2 2层 SH 上传反射系数 + * @param[in] TD2 2层 P-SV 下传透射系数矩阵 + * @param[in] TDL2 2层 SH 下传透射系数 + * @param[in] TU2 2层 P-SV 上传透射系数矩阵 + * @param[in] TUL2 2层 SH 上传透射系数 + * @param[out] RD 1+2层 P-SV 下传反射系数矩阵 + * @param[out] RDL 1+2层 SH 下传反射系数 + * @param[out] RU 1+2层 P-SV 上传反射系数矩阵 + * @param[out] RUL 1+2层 SH 上传反射系数 + * @param[out] TD 1+2层 P-SV 下传透射系数矩阵 + * @param[out] TDL 1+2层 SH 下传透射系数 + * @param[out] TU 1+2层 P-SV 上传透射系数矩阵 + * @param[out] TUL 1+2层 SH 上传透射系数 * */ void recursion_RT_2x2( @@ -162,16 +162,16 @@ void recursion_RT_2x2( /** * 对于虚拟层位,即上下层是相同的物性参数,对公式(5.5.3)进行简化,只剩下时间延迟因子 * - * @param xa1 (in)P波归一化垂直波数 \f$ \sqrt{1 - (k_a/k)^2} \f$ - * @param xb1 (in)S波归一化垂直波数 \f$ \sqrt{1 - (k_b/k)^2} \f$ - * @param thk (in)厚度 - * @param k (in)波数 - * @param RU[2][2] (inout)上层 P-SV 上传反射系数矩阵 - * @param RUL (inout)上层 SH 上传反射系数 - * @param TD[2][2] (inout)上层 P-SV 下传透射系数矩阵 - * @param TDL (inout)上层 SH 下传透射系数 - * @param TU[2][2] (inout)上层 P-SV 上传透射系数矩阵 - * @param TUL (inout)上层 SH 上传透射系数 + * @param[in] xa1 P波归一化垂直波数 \f$ \sqrt{1 - (k_a/k)^2} \f$ + * @param[in] xb1 S波归一化垂直波数 \f$ \sqrt{1 - (k_b/k)^2} \f$ + * @param[in] thk 厚度 + * @param[in] k 波数 + * @param[in,out] RU 上层 P-SV 上传反射系数矩阵 + * @param[in,out] RUL 上层 SH 上传反射系数 + * @param[in,out] TD 上层 P-SV 下传透射系数矩阵 + * @param[in,out] TDL 上层 SH 下传透射系数 + * @param[in,out] TU 上层 P-SV 上传透射系数矩阵 + * @param[in,out] TUL 上层 SH 上传透射系数 */ void recursion_RT_2x2_imaginary( MYCOMPLEX xa1, MYCOMPLEX xb1, MYREAL thk, MYREAL k, // 使用上层的厚度 @@ -184,68 +184,36 @@ void recursion_RT_2x2_imaginary( * 最终公式(5.7.12,13,26,27)简化为 (P-SV波) : * + 当台站在震源上方时: * - * \f[ - * \begin{pmatrix} - * q_m \\ - * w_m - * \end{pmatrix} - * = - * \mathbf{R_1} - * - * \left[ - * \mathbf{R_2} - * \begin{pmatrix} - * P_m^+ \\ - * SV_m^+ - * \end{pmatrix} - * + - * \begin{pmatrix} - * P_m^- \\ - * SV_m^- - * \end{pmatrix} - * + * \f[ + * \begin{pmatrix} q_m \\ w_m \end{pmatrix} = \mathbf{R_1} + * \left[ + * \mathbf{R_2} \begin{pmatrix} P_m^+ \\ SV_m^+ \end{pmatrix} + * + \begin{pmatrix} P_m^- \\ SV_m^- \end{pmatrix} * \right] - * * \f] * * + 当台站在震源下方时: * * \f[ - * \begin{pmatrix} - * q_m \\ - * w_m - * \end{pmatrix} - * = - * \mathbf{R_1} - * + * \begin{pmatrix} q_m \\ w_m \end{pmatrix} = \mathbf{R_1} * \left[ - * \begin{pmatrix} - * P_m^+ \\ - * SV_m^+ - * \end{pmatrix} - * + - * \mathbf{R_2} - * \begin{pmatrix} - * P_m^- \\ - * SV_m^- - * \end{pmatrix} - * + * \begin{pmatrix} P_m^+ \\ SV_m^+ \end{pmatrix} + * + \mathbf{R_2} \begin{pmatrix} P_m^- \\ SV_m^- \end{pmatrix} * \right] - * * \f] * * SH波类似,但是是标量形式。 * - * @param ircvup (in)接收层是否浅于震源层 - * @param R1[2][2] (in)P-SV波,\f$\mathbf{R_1}\f$矩阵 - * @param RL1 (in)SH波, \f$ R_1\f$ - * @param R2[2][2] (in)P-SV波,\f$\mathbf{R_2}\f$矩阵 - * @param RL2 (in)SH波, \f$ R_2\f$ - * @param coef[3][2] (in)震源系数,维度3表示震源附近的\f$ q_m,w_m,v_m\f$ ,维度2表示下行波(p=0)和上行波(p=1) - * @param qwv[3] (out)最终通过矩阵传播计算出的在台站位置的\f$ q_m,w_m,v_m\f$ + * @param[in] ircvup 接收层是否浅于震源层 + * @param[in] R1 P-SV波,\f$\mathbf{R_1}\f$矩阵 + * @param[in] RL1 SH波, \f$ R_1\f$ + * @param[in] R2 P-SV波,\f$\mathbf{R_2}\f$矩阵 + * @param[in] RL2 SH波, \f$ R_2\f$ + * @param[in] coef 震源系数,\f$ P_m, SV_m, SH_m \f$ ,维度2表示下行波(p=0)和上行波(p=1) + * @param[out] qwv 最终通过矩阵传播计算出的在台站位置的\f$ q_m,w_m,v_m\f$ */ void get_qwv( bool ircvup, const MYCOMPLEX R1[2][2], MYCOMPLEX RL1, const MYCOMPLEX R2[2][2], MYCOMPLEX RL2, - const MYCOMPLEX coef[3][2], MYCOMPLEX qwv[3]); + const MYCOMPLEX coef[QWV_NUM][2], MYCOMPLEX qwv[QWV_NUM]); diff --git a/pygrt/C_extension/include/common/search.h b/pygrt/C_extension/include/common/search.h index 7ef63a4a..e0d02d24 100644 --- a/pygrt/C_extension/include/common/search.h +++ b/pygrt/C_extension/include/common/search.h @@ -15,9 +15,9 @@ * 该函数对输入的整数数组进行线性搜索,找到目标值时返回其索引。 * 如果目标值在数组中未找到,则返回 -1。 * - * @param array (in)要搜索的整数数组。 - * @param size (in)数组的大小(元素个数)。 - * @param target (in)要查找的目标值。 + * @param[in] array 要搜索的整数数组。 + * @param[in] size 数组的大小(元素个数)。 + * @param[in] target 要查找的目标值。 * * @return idx 目标值的索引,如果未找到则返回 -1。 * @@ -30,9 +30,9 @@ MYINT findElement_MYINT(const MYINT array[], MYINT size, MYINT target); * 搜索浮点数数组中最接近目标值且小于目标值的索引。 * 如果目标值在数组中未找到,则返回 -1。 * - * @param array (in)要搜索的浮点数数组。 - * @param size (in)数组的大小(元素个数)。 - * @param target (in)要查找的目标值。 + * @param[in] array 要搜索的浮点数数组。 + * @param[in] size 数组的大小(元素个数)。 + * @param[in] target 要查找的目标值。 * * @return idx 目标值的索引,如果未找到则返回 -1。 * @@ -44,9 +44,9 @@ MYINT findLessEqualClosest_MYREAL(const MYREAL array[], MYINT size, MYREAL targe /** * 搜索浮点数数组中最接近目标值的索引。 * - * @param array (in)要搜索的浮点数数组。 - * @param size (in)数组的大小(元素个数)。 - * @param target (in)要查找的目标值。 + * @param[in] array 要搜索的浮点数数组。 + * @param[in] size 数组的大小(元素个数)。 + * @param[in] target 要查找的目标值。 * * @return idx 目标值的索引 * @@ -58,9 +58,9 @@ MYINT findClosest_MYREAL(const MYREAL array[], MYINT size, MYREAL target); /** * 搜索浮点数数组的最大或最小值,返回其索引。 * - * @param array (in)要搜索的浮点数数组。 - * @param size (in)数组的大小(元素个数)。 - * @param isMax (in)是否要找最大值,否则找最小值。 + * @param[in] array 要搜索的浮点数数组。 + * @param[in] size 数组的大小(元素个数)。 + * @param[in] isMax 是否要找最大值,否则找最小值。 * * @return idx 目标值的索引。 * diff --git a/pygrt/C_extension/include/common/version.h b/pygrt/C_extension/include/common/version.h index c3334df0..94e75841 100644 --- a/pygrt/C_extension/include/common/version.h +++ b/pygrt/C_extension/include/common/version.h @@ -11,4 +11,5 @@ #ifndef GRT_VERSION #define GRT_VERSION "none" ///< 默认值,编译时会被替换 + #endif diff --git a/pygrt/C_extension/include/dynamic/grt.h b/pygrt/C_extension/include/dynamic/grt.h index b52e6bd9..335fd929 100755 --- a/pygrt/C_extension/include/dynamic/grt.h +++ b/pygrt/C_extension/include/dynamic/grt.h @@ -19,7 +19,7 @@ /** * 设置OpenMP多线程数 * - * @param num_threads (in)线程数 + * @param[in] num_threads 线程数 */ void set_num_threads(int num_threads); @@ -28,32 +28,32 @@ void set_num_threads(int num_threads); /** * 积分计算Z, R, T三个分量格林函数的频谱的核心函数(被Python调用) * - * @param[in] pymod1d (in)`PYMODEL1D` 结构体指针 - * @param[in] nf1 (in)开始计算频谱的频率索引值, 总范围在[nf1, nf2] - * @param[in] nf2 (in)结束计算频谱的频率索引值, 总范围在[nf1, nf2] - * @param[in] nf (in)所有频点个数 - * @param[in] freqs (in)所有频点的频率值(包括未计算的) - * @param[in] nr (in)震中距数量 - * @param[in] rs (in)震中距数组 - * @param[in] wI (in)虚频率, \f$ \tilde{\omega} =\omega - i \omega_I \f$ - * @param[in] vmin_ref (in)参考最小速度,用于定义波数积分的上限 - * @param[in] keps (in)波数积分的收敛条件,要求在某震中距下所有格林函数都收敛,为负数代表不提前判断收敛,按照波数积分上限进行积分 - * @param[in] ampk (in)影响波数k积分上限的系数,见下方 - * @param[in] k0 (in)波数积分的上限 \f$ \tilde{k_{max}}=\sqrt{(k_{0}*\pi/hs)^2 + (ampk*w/vmin_{ref})^2} \f$ ,k循环必须退出, hs=max(震源和台站深度差,1.0) - * @param[in] Length (in)波数k积分间隔 \f$ dk=2\pi/(fabs(L)*r_{max}) \f$ - * @param[in] filonLength (in)Filon积分间隔 - * @param[in] filonCut (in)波数积分和Filon积分的分割点 - * @param[in] print_progressbar (in)是否打印进度条 + * @param[in] pymod1d `PYMODEL1D` 结构体指针 + * @param[in] nf1 开始计算频谱的频率索引值, 总范围在[nf1, nf2] + * @param[in] nf2 结束计算频谱的频率索引值, 总范围在[nf1, nf2] + * @param[in] nf 所有频点个数 + * @param[in] freqs 所有频点的频率值(包括未计算的) + * @param[in] nr 震中距数量 + * @param[in] rs 震中距数组 + * @param[in] wI 虚频率, \f$ \tilde{\omega} =\omega - i \omega_I \f$ + * @param[in] vmin_ref 参考最小速度,用于定义波数积分的上限 + * @param[in] keps 波数积分的收敛条件,要求在某震中距下所有格林函数都收敛,为负数代表不提前判断收敛,按照波数积分上限进行积分 + * @param[in] ampk 影响波数k积分上限的系数,见下方 + * @param[in] k0 波数积分的上限 \f$ \tilde{k_{max}}=\sqrt{(k_{0}*\pi/hs)^2 + (ampk*w/vmin_{ref})^2} \f$ ,k循环必须退出, hs=max(震源和台站深度差,1.0) + * @param[in] Length 波数k积分间隔 \f$ dk=2\pi/(fabs(L)*r_{max}) \f$ + * @param[in] filonLength Filon积分间隔 + * @param[in] filonCut 波数积分和Filon积分的分割点 + * @param[in] print_progressbar 是否打印进度条 * * @param[out] grn 不同震源不同阶数的格林函数的Z、R、T分量频谱结果 * - * @param[in] calc_upar 是否计算位移u的空间导数 + * @param[in] calc_upar 是否计算位移u的空间导数 * @param[out] grn_uiz 不同震源不同阶数的ui_z的Z、R、T分量频谱结果 * @param[out] grn_uir 不同震源不同阶数的ui_r的Z、R、T分量频谱结果 * - * @param[in] statsstr (in) 积分过程输出目录 - * @param[in] nstatsidxs (in) 输出积分过程的特定频点的个数 - * @param[in] statsidxs (in) 特定频点的索引值 + * @param[in] statsstr 积分过程输出目录 + * @param[in] nstatsidxs 输出积分过程的特定频点的个数 + * @param[in] statsidxs 特定频点的索引值 * */ void integ_grn_spec( @@ -63,13 +63,13 @@ void integ_grn_spec( bool print_progressbar, // 返回值,代表Z、R、T分量 - MYCOMPLEX *grn[nr][GRT_SRC_M_COUNTS][GRT_SRC_CHA_COUNTS], + MYCOMPLEX *grn[nr][SRC_M_NUM][CHANNEL_NUM], bool calc_upar, - MYCOMPLEX *grn_uiz[nr][GRT_SRC_M_COUNTS][GRT_SRC_CHA_COUNTS], - MYCOMPLEX *grn_uir[nr][GRT_SRC_M_COUNTS][GRT_SRC_CHA_COUNTS], + MYCOMPLEX *grn_uiz[nr][SRC_M_NUM][CHANNEL_NUM], + MYCOMPLEX *grn_uir[nr][SRC_M_NUM][CHANNEL_NUM], - const char *statsstr, // 积分结果输出 + const char *statsstr, // 积分过程输出 MYINT nstatsidxs, // 仅输出特定频点 MYINT *statsidxs ); diff --git a/pygrt/C_extension/include/dynamic/layer.h b/pygrt/C_extension/include/dynamic/layer.h index 71487315..b793921d 100755 --- a/pygrt/C_extension/include/dynamic/layer.h +++ b/pygrt/C_extension/include/dynamic/layer.h @@ -19,11 +19,11 @@ /** * 计算自由表面的反射系数,公式(5.3.10-14) * - * @param xa0 (in)表层的P波归一化垂直波数 \f$ \sqrt{1 - (k_a/k)^2} \f$ - * @param xb0 (in)表层的S波归一化垂直波数 \f$ \sqrt{1 - (k_b/k)^2} \f$ - * @param kbkb0 (in)表层的S波水平波数的平方 \f$ k_b^2=(\frac{\omega}{V_b})^2 \f$ - * @param k (in)波数 - * @param R_tilt[2][2] (out)P-SV系数矩阵,SH系数为1 + * @param[in] xa0 表层的P波归一化垂直波数 \f$ \sqrt{1 - (k_a/k)^2} \f$ + * @param[in] xb0 表层的S波归一化垂直波数 \f$ \sqrt{1 - (k_b/k)^2} \f$ + * @param[in] kbkb0 表层的S波水平波数的平方 \f$ k_b^2=(\frac{\omega}{V_b})^2 \f$ + * @param[in] k 波数 + * @param[out] R_tilt P-SV系数矩阵,SH系数为1 * */ void calc_R_tilt( @@ -33,14 +33,14 @@ void calc_R_tilt( /** * 计算接收点位置的接收矩阵,将波场转为位移,公式(5.2.19) + (5.7.7,25) * - * @param xa_rcv (in)接受层的P波归一化垂直波数 \f$ \sqrt{1 - (k_a/k)^2} \f$ - * @param xb_rcv (in)接受层的S波归一化垂直波数 \f$ \sqrt{1 - (k_b/k)^2} \f$ - * @param ircvup (in)接收点是否浅于震源层 - * @param k (in)波数 - * @param R[2][2] (in)P-SV波场 - * @param RL (in)SH波场 - * @param R_EV[2][2] (out)P-SV接收函数矩阵 - * @param R_EVL (out)SH接收函数值 + * @param[in] xa_rcv 接受层的P波归一化垂直波数 \f$ \sqrt{1 - (k_a/k)^2} \f$ + * @param[in] xb_rcv 接受层的S波归一化垂直波数 \f$ \sqrt{1 - (k_b/k)^2} \f$ + * @param[in] ircvup 接收点是否浅于震源层 + * @param[in] k 波数 + * @param[in] R P-SV波场 + * @param[in] RL SH波场 + * @param[out] R_EV P-SV接收函数矩阵 + * @param[out] R_EVL SH接收函数值 * */ void calc_R_EV( @@ -54,14 +54,14 @@ void calc_R_EV( * 计算接收点位置的ui_z的接收矩阵,即将波场转为ui_z。 * 公式本质是推导ui_z关于q_m, w_m, v_m的连接矩阵(就是应力推导过程的一部分) * - * @param xa_rcv (in)接受层的P波归一化垂直波数 \f$ \sqrt{1 - (k_a/k)^2} \f$ - * @param xb_rcv (in)接受层的S波归一化垂直波数 \f$ \sqrt{1 - (k_b/k)^2} \f$ - * @param ircvup (in)接收点是否浅于震源层 - * @param k (in)波数 - * @param R[2][2] (in)P-SV波场 - * @param RL (in)SH波场 - * @param R_EV[2][2] (out)P-SV接收函数矩阵 - * @param R_EVL (out)SH接收函数值 + * @param[in] xa_rcv 接受层的P波归一化垂直波数 \f$ \sqrt{1 - (k_a/k)^2} \f$ + * @param[in] xb_rcv 接受层的S波归一化垂直波数 \f$ \sqrt{1 - (k_b/k)^2} \f$ + * @param[in] ircvup 接收点是否浅于震源层 + * @param[in] k 波数 + * @param[in] R P-SV波场 + * @param[in] RL SH波场 + * @param[out] R_EV P-SV接收函数矩阵 + * @param[out] R_EVL SH接收函数值 * */ void calc_uiz_R_EV( @@ -77,26 +77,26 @@ void calc_uiz_R_EV( * * @note 对公式(5.4.14)进行了重新整理。原公式各项之间的数量级差别过大,浮点数计算损失精度严重。 * - * @param Rho1 (in)上层的密度 - * @param xa1 (in)上层的P波归一化垂直波数 \f$ \sqrt{1 - (k_a/k)^2} \f$ - * @param xb1 (in)上层的S波归一化垂直波数 \f$ \sqrt{1 - (k_b/k)^2} \f$ - * @param kbkb1 (in)上层的S波水平波数的平方 \f$ k_b^2=(\frac{\omega}{V_b})^2 \f$ - * @param mu1 (in)上层的剪切模量 - * @param Rho2 (in)下层的密度 - * @param xa2 (in)下层的P波归一化垂直波数 \f$ \sqrt{1 - (k_a/k)^2} \f$ - * @param xb2 (in)下层的S波归一化垂直波数 \f$ \sqrt{1 - (k_b/k)^2} \f$ - * @param kbkb2 (in)下层的S波水平波数的平方 \f$ k_b^2=(\frac{\omega}{V_b})^2 \f$ - * @param mu2 (in)下层的剪切模量 - * @param thk (in)上层层厚 - * @param k (in)波数 - * @param RD[2][2] (out)P-SV 下传反射系数矩阵 - * @param RDL (out)SH 下传反射系数 - * @param RU[2][2] (out)P-SV 上传反射系数矩阵 - * @param RUL (out)SH 上传反射系数 - * @param TD[2][2] (out)P-SV 下传透射系数矩阵 - * @param TDL (out)SH 下传透射系数 - * @param TU[2][2] (out)P-SV 上传透射系数矩阵 - * @param TUL (out)SH 上传透射系数 + * @param[in] Rho1 上层的密度 + * @param[in] xa1 上层的P波归一化垂直波数 \f$ \sqrt{1 - (k_a/k)^2} \f$ + * @param[in] xb1 上层的S波归一化垂直波数 \f$ \sqrt{1 - (k_b/k)^2} \f$ + * @param[in] kbkb1 上层的S波水平波数的平方 \f$ k_b^2=(\frac{\omega}{V_b})^2 \f$ + * @param[in] mu1 上层的剪切模量 + * @param[in] Rho2 下层的密度 + * @param[in] xa2 下层的P波归一化垂直波数 \f$ \sqrt{1 - (k_a/k)^2} \f$ + * @param[in] xb2 下层的S波归一化垂直波数 \f$ \sqrt{1 - (k_b/k)^2} \f$ + * @param[in] kbkb2 下层的S波水平波数的平方 \f$ k_b^2=(\frac{\omega}{V_b})^2 \f$ + * @param[in] mu2 下层的剪切模量 + * @param[in] thk 上层层厚 + * @param[in] k 波数 + * @param[out] RD P-SV 下传反射系数矩阵 + * @param[out] RDL SH 下传反射系数 + * @param[out] RU P-SV 上传反射系数矩阵 + * @param[out] RUL SH 上传反射系数 + * @param[out] TD P-SV 下传透射系数矩阵 + * @param[out] TDL SH 下传透射系数 + * @param[out] TU P-SV 上传透射系数矩阵 + * @param[out] TUL SH 上传透射系数 * */ void calc_RT_2x2( @@ -114,15 +114,15 @@ void calc_RT_2x2( * 被calc_RT_2x2_from_4x4函数调用,生成该层的连接P-SV应力位移矢量与垂直波函数的D矩阵(或其逆矩阵), * 见公式(5.2.19-20) * - * @param xa (in)P波归一化垂直波数 \f$ \sqrt{1 - (k_a/k)^2} \f$ - * @param xb (in)S波归一化垂直波数 \f$ \sqrt{1 - (k_b/k)^2} \f$ - * @param kbkb (in)S波水平波数的平方 \f$ k_b^2=(\frac{\omega}{V_b})^2 \f$ - * @param mu (in)剪切模量 - * @param omega (in)复数频率 \f$ \tilde{\omega} =\omega - i\omega_I \f$ - * @param k (in)波数 + * @param[in] xa P波归一化垂直波数 \f$ \sqrt{1 - (k_a/k)^2} \f$ + * @param[in] xb S波归一化垂直波数 \f$ \sqrt{1 - (k_b/k)^2} \f$ + * @param[in] kbkb S波水平波数的平方 \f$ k_b^2=(\frac{\omega}{V_b})^2 \f$ + * @param[in] mu 剪切模量 + * @param[in] omega 复数频率 \f$ \tilde{\omega} =\omega - i\omega_I \f$ + * @param[in] k 波数 * - * @param D[4][4] (out) D矩阵(或其逆矩阵) - * @param inverse (in) 是否生成逆矩阵 + * @param[out] D D矩阵(或其逆矩阵) + * @param[in] inverse 是否生成逆矩阵 * */ void get_layer_D( diff --git a/pygrt/C_extension/include/dynamic/propagate.h b/pygrt/C_extension/include/dynamic/propagate.h index 0fa38a17..e1c82416 100755 --- a/pygrt/C_extension/include/dynamic/propagate.h +++ b/pygrt/C_extension/include/dynamic/propagate.h @@ -21,10 +21,10 @@ /** * kernel函数根据(5.5.3)式递推计算广义反射透射矩阵, 再根据公式得到 * - * 1.EXP 爆炸源, (P0) - * 2.VF 垂直力源, (P0, SV0) - * 3.HF 水平力源, (P1, SV1, SH1) - * 4.DC 剪切源, (P0, SV0), (P1, SV1, SH1), (P2, SV2, SH2) + * 1.EXP 爆炸源, (P0) + * 2.VF 垂直力源, (P0, SV0) + * 3.HF 水平力源, (P1, SV1, SH1) + * 4.DC 剪切源, (P0, SV0), (P1, SV1, SH1), (P2, SV2, SH2) * * 的 \f$ q_m, w_m, v_m \f$ 系数(\f$ m=0,1,2 \f$), * @@ -88,8 +88,8 @@ * */ void kernel( - const MODEL1D *mod1d, MYCOMPLEX omega, MYREAL k, MYCOMPLEX QWV[GRT_SRC_M_COUNTS][GRT_SRC_QWV_COUNTS], - bool calc_uiz, MYCOMPLEX QWV_uiz[GRT_SRC_M_COUNTS][GRT_SRC_QWV_COUNTS]); + const MODEL1D *mod1d, MYCOMPLEX omega, MYREAL k, MYCOMPLEX QWV[SRC_M_NUM][QWV_NUM], + bool calc_uiz, MYCOMPLEX QWV_uiz[SRC_M_NUM][QWV_NUM]); diff --git a/pygrt/C_extension/include/dynamic/signals.h b/pygrt/C_extension/include/dynamic/signals.h index 402aa368..bc3e33f3 100644 --- a/pygrt/C_extension/include/dynamic/signals.h +++ b/pygrt/C_extension/include/dynamic/signals.h @@ -21,8 +21,8 @@ /** * 检查时间函数的类型设置和参数设置是否符合要求 * - * @param tftype 单个字符,指代时间函数类型 - * @param tfparams 时间函数参数 + * @param[in] tftype 单个字符,指代时间函数类型 + * @param[in] tfparams 时间函数参数 * * @return 检查是否通过 */ @@ -31,10 +31,10 @@ bool check_tftype_tfparams(const char tftype, const char *tfparams); /** * 获得时间函数,要求提前运行check_tftype_tfparams函数以检查参数 * - * @param TFnt 返回的点数 - * @param dt 时间间隔 - * @param tftype 单个字符,指代时间函数类型 - * @param tfparams 时间函数参数 + * @param[out] TFnt 返回的点数 + * @param[in] dt 时间间隔 + * @param[in] tftype 单个字符,指代时间函数类型 + * @param[in] tfparams 时间函数参数 * * @return 时间函数指针 */ @@ -45,13 +45,13 @@ float * get_time_function(int *TFnt, float dt, const char tftype, const char *tf * 时域线性卷积,要求提前运行check_tftype_tfparams函数以检查参数 * 卷积结果会原地写入数组。 * - * @param arr 待卷积的信号 - * @param nt 信号点数 - * @param dt 信号点时间间隔 - * @param tftype 单个字符,指代时间函数类型 - * @param tfparams 时间函数参数 - * @param TFarr 指向时间函数的指针的指针 - * @param TFnt 返回的时间函数点数 + * @param[in,out] arr 待卷积的信号 + * @param[in] nt 信号点数 + * @param[in] dt 信号点时间间隔 + * @param[in] tftype 单个字符,指代时间函数类型 + * @param[in] tfparams 时间函数参数 + * @param[out] TFarr 指向时间函数的指针的指针 + * @param[out] TFnt 返回的时间函数点数 */ void linear_convolve_time_function(float *arr, int nt, float dt, const char tftype, const char *tfparams, float **TFarr, int *TFnt); @@ -59,13 +59,13 @@ void linear_convolve_time_function(float *arr, int nt, float dt, const char tfty /** * 时间序列卷积函数,只卷积x的长度 * - * @param x 长信号数组 - * @param nx 长信号点数 - * @param h 短信号数组 - * @param nh 短信号点数 - * @param y 输出数组 - * @param ny 输出数组点数 - * @param iscircular 是否使用循环卷积 + * @param[in] x 长信号数组 + * @param[in] nx 长信号点数 + * @param[in] h 短信号数组 + * @param[in] nh 短信号点数 + * @param[out] y 输出数组 + * @param[in] ny 输出数组点数 + * @param[in] iscircular 是否使用循环卷积 */ void oaconvolve(float *x, int nx, float *h, int nh, float *y, int ny, bool iscircular); @@ -73,9 +73,9 @@ void oaconvolve(float *x, int nx, float *h, int nh, float *y, int ny, bool iscir /** * 计算某序列整个梯形积分值 * - * @param x 信号数组 - * @param nx 数组长度 - * @param dt 时间间隔 + * @param[in] x 信号数组 + * @param[in] nx 数组长度 + * @param[in] dt 时间间隔 * * @return 积分结果 */ @@ -85,18 +85,18 @@ float trap_area(const float *x, int nx, float dt); /** * 使用梯形法对时间序列积分 * - * @param x 信号数组 - * @param nx 数组长度 - * @param dt 时间间隔 + * @param[in,out] x 信号数组 + * @param[in] nx 数组长度 + * @param[in] dt 时间间隔 */ void trap_integral(float *x, int nx, float dt); /** * 对时间序列做中心一阶差分 * - * @param x 信号数组 - * @param nx 数组长度 - * @param dt 时间间隔 + * @param[in,out] x 信号数组 + * @param[in] nx 数组长度 + * @param[in] dt 时间间隔 */ void differential(float *x, int nx, float dt); @@ -106,9 +106,9 @@ void differential(float *x, int nx, float dt); /** * 生成抛物线波 * - * @param dt (in)采样间隔 - * @param tlen (inout)信号时长 - * @param Nt (out)返回的点数 + * @param[in] dt 采样间隔 + * @param[in,out] tlen 信号时长 + * @param[out] Nt 返回的点数 * * @return float指针 */ @@ -136,11 +136,11 @@ float * get_parabola_wave(float dt, float *Tlen, int *Nt); * @endverbatim * * - * @param dt (in)采样间隔 - * @param T1 (inout)上坡截止时刻 - * @param T2 (inout)平台截止时刻 - * @param T3 (inout)下坡截止时刻 - * @param Nt (out)返回的点数 + * @param[in] dt 采样间隔 + * @param[in,out] T1 上坡截止时刻 + * @param[in,out] T2 平台截止时刻 + * @param[in,out] T3 下坡截止时刻 + * @param[out] Nt 返回的点数 * * @return float指针 */ @@ -153,9 +153,9 @@ float * get_trap_wave(float dt, float *T1, float *T2, float *T3, int *Nt); * * \f[ f(t)=(1-2 \pi^2 f_0^2 (t-t_0)^2 ) e^{ - \pi^2 f_0^2 (t-t_0)^2} \f] * - * @param dt (in)采样间隔 - * @param f0 (in)主频 - * @param Nt (out)返回的点数 + * @param[in] dt 采样间隔 + * @param[in] f0 主频 + * @param[out] Nt 返回的点数 * * @return float指针 */ @@ -165,8 +165,8 @@ float * get_ricker_wave(float dt, float f0, int *Nt); /** * 从文件中读入自定义时间函数 * - * @param Nt (out)返回的点数 - * @param tfparams 文件路径 + * @param[out] Nt 返回的点数 + * @param[in] tfparams 文件路径 * * @return float指针 */ @@ -175,6 +175,6 @@ float * get_custom_wave(int *Nt, const char *tfparams); /** * 专用于在Python端释放C中申请的内存 * - * @param pt 指针 + * @param[out] pt 指针 */ void free1d(void *pt); \ No newline at end of file diff --git a/pygrt/C_extension/include/dynamic/source.h b/pygrt/C_extension/include/dynamic/source.h index 1b318f3c..7b0c0d11 100755 --- a/pygrt/C_extension/include/dynamic/source.h +++ b/pygrt/C_extension/include/dynamic/source.h @@ -16,9 +16,9 @@ /** - * 根据公式(4.6.6),(4.6.15),(4.6.21,26),(4.8.34)计算不同震源的震源系数, - * 数组形状[3][3][2],代表在[i][j][p]时表示m=i阶时的 - * P(j=0),SV(j=1),SH(j=2)的震源系数(分别可记为q,w,v),且分为下行波(p=0)和上行波(p=1). + * 根据公式(4.6.6),(4.6.15),(4.6.21,26),(4.8.34)计算不同震源不同阶数的震源系数, + * 数组形状代表在[i][j][p]时表示i类震源的 + * P(j=0),SV(j=1),SH(j=2)的震源系数(分别对应q,w,v),且分为下行波(p=0)和上行波(p=1). * * @param[in] src_xa 震源层的P波归一化垂直波数 \f$ \sqrt{1 - (k_a/k)^2} \f$ * @param[in] src_xb 震源层的S波归一化垂直波数 \f$ \sqrt{1 - (k_b/k)^2} \f$ @@ -32,4 +32,4 @@ void source_coef( MYCOMPLEX src_xa, MYCOMPLEX src_xb, MYCOMPLEX src_kaka, MYCOMPLEX src_kbkb, MYCOMPLEX omega, MYREAL k, - MYCOMPLEX coef[GRT_SRC_M_COUNTS][GRT_SRC_QWV_COUNTS][2]); + MYCOMPLEX coef[SRC_M_NUM][QWV_NUM][2]); diff --git a/pygrt/C_extension/include/static/static_layer.h b/pygrt/C_extension/include/static/static_layer.h index 3e6f4ee4..0b8dfc51 100644 --- a/pygrt/C_extension/include/static/static_layer.h +++ b/pygrt/C_extension/include/static/static_layer.h @@ -20,8 +20,8 @@ /** * 计算自由表面的静态反射系数,公式(6.3.12) * - * @param delta1 (in)表层的 \f$ \Delta = \frac{\lambda + \mu}{\lambda + 3\mu} \f$ - * @param R_tilt[2][2] (out)P-SV系数矩阵,SH系数为1 + * @param[in] delta1 表层的 \f$ \Delta = \frac{\lambda + \mu}{\lambda + 3\mu} \f$ + * @param[out] R_tilt P-SV系数矩阵,SH系数为1 * */ void calc_static_R_tilt(MYCOMPLEX delta1, MYCOMPLEX R_tilt[2][2]); @@ -30,12 +30,12 @@ void calc_static_R_tilt(MYCOMPLEX delta1, MYCOMPLEX R_tilt[2][2]); /** * 计算接收点位置的静态接收矩阵,将波场转为位移,公式(6.3.35,37) * - * @param ircvup (in)接收点是否浅于震源层 - * @param k (in)波数 - * @param R[2][2] (in)P-SV波场 - * @param RL (in)SH波场 - * @param R_EV[2][2] (out)P-SV接收函数矩阵 - * @param R_EVL (out)SH接收函数值 + * @param[in] ircvup 接收点是否浅于震源层 + * @param[in] k 波数 + * @param[in] R P-SV波场 + * @param[in] RL SH波场 + * @param[out] R_EV P-SV接收函数矩阵 + * @param[out] R_EVL SH接收函数值 * */ void calc_static_R_EV( @@ -48,13 +48,13 @@ void calc_static_R_EV( * 计算接收点位置的ui_z的静态接收矩阵,即将波场转为ui_z。 * 公式本质是推导ui_z关于q_m, w_m, v_m的连接矩阵(就是应力推导过程的一部分) * - * @param delta1 (in)接收层的 \f$ \Delta \f$ - * @param ircvup (in)接收点是否浅于震源层 - * @param k (in)波数 - * @param R[2][2] (in)P-SV波场 - * @param RL (in)SH波场 - * @param R_EV[2][2] (out)P-SV接收函数矩阵 - * @param R_EVL (out)SH接收函数值 + * @param[in] delta1 接收层的 \f$ \Delta \f$ + * @param[in] ircvup 接收点是否浅于震源层 + * @param[in] k 波数 + * @param[in] R P-SV波场 + * @param[in] RL SH波场 + * @param[out] R_EV P-SV接收函数矩阵 + * @param[out] R_EVL SH接收函数值 * */ void calc_static_uiz_R_EV( @@ -67,20 +67,20 @@ void calc_static_uiz_R_EV( * 计算界面的静态反射系数RD/RDL/RU/RUL, 静态透射系数TD/TDL/TU/TUL, 包括时间延迟因子, * 后缀L表示SH波的系数, 其余表示P-SV波的系数, 根据公式(6.3.18) * - * @param delta1 (in)上层的 \f$ \Delta \f$ - * @param mu1 (in)上层的剪切模量 - * @param delta2 (in)下层的 \f$ \Delta \f$ - * @param mu2 (in)下层的剪切模量 - * @param thk (in)上层层厚 - * @param k (in)波数 - * @param RD[2][2] (out)P-SV 下传反射系数矩阵 - * @param RDL (out)SH 下传反射系数 - * @param RU[2][2] (out)P-SV 上传反射系数矩阵 - * @param RUL (out)SH 上传反射系数 - * @param TD[2][2] (out)P-SV 下传透射系数矩阵 - * @param TDL (out)SH 下传透射系数 - * @param TU[2][2] (out)P-SV 上传透射系数矩阵 - * @param TUL (out)SH 上传透射系数 + * @param[in] delta1 上层的 \f$ \Delta \f$ + * @param[in] mu1 上层的剪切模量 + * @param[in] delta2 下层的 \f$ \Delta \f$ + * @param[in] mu2 下层的剪切模量 + * @param[in] thk 上层层厚 + * @param[in] k 波数 + * @param[out] RD P-SV 下传反射系数矩阵 + * @param[out] RDL SH 下传反射系数 + * @param[out] RU P-SV 上传反射系数矩阵 + * @param[out] RUL SH 上传反射系数 + * @param[out] TD P-SV 下传透射系数矩阵 + * @param[out] TDL SH 下传透射系数 + * @param[out] TU P-SV 上传透射系数矩阵 + * @param[out] TUL SH 上传透射系数 * */ void calc_static_RT_2x2( diff --git a/pygrt/C_extension/include/static/static_propagate.h b/pygrt/C_extension/include/static/static_propagate.h index fcb6573f..d5dfb1d6 100644 --- a/pygrt/C_extension/include/static/static_propagate.h +++ b/pygrt/C_extension/include/static/static_propagate.h @@ -24,5 +24,5 @@ * 此处omega未使用,传入0即可 */ void static_kernel( - const MODEL1D *mod1d, MYCOMPLEX omega, MYREAL k, MYCOMPLEX QWV[GRT_SRC_M_COUNTS][GRT_SRC_QWV_COUNTS], - bool calc_uiz, MYCOMPLEX QWV_uiz[GRT_SRC_M_COUNTS][GRT_SRC_QWV_COUNTS]); \ No newline at end of file + const MODEL1D *mod1d, MYCOMPLEX omega, MYREAL k, MYCOMPLEX QWV[SRC_M_NUM][QWV_NUM], + bool calc_uiz, MYCOMPLEX QWV_uiz[SRC_M_NUM][QWV_NUM]); \ No newline at end of file diff --git a/pygrt/C_extension/include/static/static_source.h b/pygrt/C_extension/include/static/static_source.h index 8420f341..db82412c 100644 --- a/pygrt/C_extension/include/static/static_source.h +++ b/pygrt/C_extension/include/static/static_source.h @@ -15,13 +15,13 @@ /** * 计算不同震源的静态震源系数,文献/书中仅提供剪切源的震源系数,其它震源系数重新推导 * - * 数组形状[3][3][2],代表在[i][j][p]时表示m=i阶时的 - * P(j=0),SV(j=1),SH(j=2)的震源系数(分别可记为q,w,v),且分为下行波(p=0)和上行波(p=1). + * 数组形状代表在[i][j][p]时表示i类震源的 + * P(j=0),SV(j=1),SH(j=2)的震源系数(分别对应q,w,v),且分为下行波(p=0)和上行波(p=1). * * @param[in] delta 震源层的\f$ \Delta \f$ * @param[in] k 波数 * @param[out] coef 震源系数 \f$ P_m, SV_m, SH_m \f$ */ void static_source_coef( - MYCOMPLEX delta, MYREAL k, MYCOMPLEX coef[GRT_SRC_M_COUNTS][GRT_SRC_QWV_COUNTS][2]); + MYCOMPLEX delta, MYREAL k, MYCOMPLEX coef[SRC_M_NUM][QWV_NUM][2]); \ No newline at end of file diff --git a/pygrt/C_extension/include/static/stgrt.h b/pygrt/C_extension/include/static/stgrt.h index 0f61d2c1..0bea19c0 100644 --- a/pygrt/C_extension/include/static/stgrt.h +++ b/pygrt/C_extension/include/static/stgrt.h @@ -22,14 +22,14 @@ /** * 积分计算Z, R, T三个分量静态格林函数的核心函数 * - * @param pymod1d (in)`PYMODEL1D` 结构体指针 - * @param nr (in)震中距数量 - * @param rs (in)震中距数组 - * @param keps (in)波数积分的收敛条件,要求在某震中距下所有格林函数都收敛,为负数代表不提前判断收敛,按照波数积分上限进行积分 - * @param k0 (in)波数积分的上限 - * @param Length (in)波数k积分间隔 \f$ dk=2\pi/(fabs(L)*r_{max}) \f$ - * @param filonLength (in)Filon积分间隔 - * @param filonCut (in)波数积分和Filon积分的分割点 + * @param[in] pymod1d `PYMODEL1D` 结构体指针 + * @param[in] nr 震中距数量 + * @param[in] rs 震中距数组 + * @param[in] keps 波数积分的收敛条件,要求在某震中距下所有格林函数都收敛,为负数代表不提前判断收敛,按照波数积分上限进行积分 + * @param[in] k0 波数积分的上限 + * @param[in] Length 波数k积分间隔 \f$ dk=2\pi/(fabs(L)*r_{max}) \f$ + * @param[in] filonLength Filon积分间隔 + * @param[in] filonCut 波数积分和Filon积分的分割点 * * @param[out] grn 浮点数数组,不同震源不同阶数的静态格林函数的Z、R、T分量 * @@ -37,7 +37,7 @@ * @param[out] grn_uiz 浮点数数组,不同震源不同阶数的ui_z的Z、R、T分量 * @param[out] grn_uir 浮点数数组,不同震源不同阶数的ui_r的Z、R、T分量 * - * @param[in] statsstr (in) 积分过程输出目录 + * @param[in] statsstr 积分过程输出目录 * */ void integ_static_grn( @@ -45,11 +45,11 @@ void integ_static_grn( MYREAL filonLength, MYREAL filonCut, // 返回值,代表Z、R、T分量 - MYREAL grn[nr][GRT_SRC_M_COUNTS][GRT_SRC_CHA_COUNTS], + MYREAL grn[nr][SRC_M_NUM][CHANNEL_NUM], bool calc_upar, - MYREAL grn_uiz[nr][GRT_SRC_M_COUNTS][GRT_SRC_CHA_COUNTS], - MYREAL grn_uir[nr][GRT_SRC_M_COUNTS][GRT_SRC_CHA_COUNTS], + MYREAL grn_uiz[nr][SRC_M_NUM][CHANNEL_NUM], + MYREAL grn_uir[nr][SRC_M_NUM][CHANNEL_NUM], const char *statsstr // 积分结果输出 ); \ No newline at end of file diff --git a/pygrt/C_extension/include/travt/travt.h b/pygrt/C_extension/include/travt/travt.h index 0c854720..10251bfb 100644 --- a/pygrt/C_extension/include/travt/travt.h +++ b/pygrt/C_extension/include/travt/travt.h @@ -16,12 +16,12 @@ * 且不共享层位,即使深度相同,中间也考虑一个厚度为0的层。 * 故当abs(isrc-ircv)==1时,说明两点位于同一物理层 * - * @param Thk 每层厚度 - * @param Vel 每层速度 - * @param nlay 层数 - * @param isrc 震源所在层位 - * @param ircv 场点所在层位 - * @param epidist 震中距 + * @param[in] Thk 每层厚度 + * @param[in] Vel 每层速度 + * @param[in] nlay 层数 + * @param[in] isrc 震源所在层位 + * @param[in] ircv 场点所在层位 + * @param[in] epidist 震中距 */ MYREAL compute_travt1d( MYREAL *Thk, MYREAL *Vel, int nlay, diff --git a/pygrt/C_extension/src/common/const.c b/pygrt/C_extension/src/common/const.c index 7ce41ab7..e0d494b7 100644 --- a/pygrt/C_extension/src/common/const.c +++ b/pygrt/C_extension/src/common/const.c @@ -10,10 +10,10 @@ /** 分别对应爆炸源(0阶),垂直力源(0阶),水平力源(1阶),剪切源(0,1,2阶) */ -const MYINT GRT_SRC_M_ORDERS[GRT_SRC_M_COUNTS] = {0, 0, 1, 0, 1, 2}; +const MYINT SRC_M_ORDERS[SRC_M_NUM] = {0, 0, 1, 0, 1, 2}; /** 不同震源,不同阶数的名称简写,用于命名 */ -const char *GRT_SRC_M_NAME_ABBR[GRT_SRC_M_COUNTS] = {"EX", "VF", "HF", "DD", "DS", "SS"}; +const char *SRC_M_NAME_ABBR[SRC_M_NUM] = {"EX", "VF", "HF", "DD", "DS", "SS"}; /** ZRT三分量代号 */ const char GRT_ZRTchs[] = {'Z', 'R', 'T'}; diff --git a/pygrt/C_extension/src/common/dwm.c b/pygrt/C_extension/src/common/dwm.c index cd613e7f..a56a5d33 100644 --- a/pygrt/C_extension/src/common/dwm.c +++ b/pygrt/C_extension/src/common/dwm.c @@ -26,17 +26,17 @@ MYREAL discrete_integ( const MODEL1D *mod1d, MYREAL dk, MYREAL kmax, MYREAL keps, MYCOMPLEX omega, MYINT nr, MYREAL *rs, - MYCOMPLEX sum_J[nr][GRT_SRC_M_COUNTS][GRT_SRC_P_COUNTS], + MYCOMPLEX sum_J[nr][SRC_M_NUM][INTEG_NUM], bool calc_upar, - MYCOMPLEX sum_uiz_J[nr][GRT_SRC_M_COUNTS][GRT_SRC_P_COUNTS], - MYCOMPLEX sum_uir_J[nr][GRT_SRC_M_COUNTS][GRT_SRC_P_COUNTS], + MYCOMPLEX sum_uiz_J[nr][SRC_M_NUM][INTEG_NUM], + MYCOMPLEX sum_uir_J[nr][SRC_M_NUM][INTEG_NUM], FILE *fstats, KernelFunc kerfunc) { - MYCOMPLEX SUM[GRT_SRC_M_COUNTS][GRT_SRC_P_COUNTS]; + MYCOMPLEX SUM[SRC_M_NUM][INTEG_NUM]; // 不同震源不同阶数的核函数 F(k, w) - MYCOMPLEX QWV[GRT_SRC_M_COUNTS][GRT_SRC_QWV_COUNTS]; - MYCOMPLEX QWV_uiz[GRT_SRC_M_COUNTS][GRT_SRC_QWV_COUNTS]; + MYCOMPLEX QWV[SRC_M_NUM][QWV_NUM]; + MYCOMPLEX QWV_uiz[SRC_M_NUM][QWV_NUM]; MYREAL k = 0.0; MYINT ik = 0; @@ -68,8 +68,8 @@ MYREAL discrete_integ( for(MYINT ir=0; ir= 2 && ipt[ir][im][v] < maxNpt) { - if (cplx_peak_or_trough(im, v, J3[ir], k, dk, &kpt[ir][im][v][ipt[ir][im][v]], &tmp0) != 0) { - pt[ir][im][v][ipt[ir][im][v]++] = tmp0; - gpt[ir][im][v] = 0; - } else if (gpt[ir][im][v] >= maxnwait) { - kpt[ir][im][v][ipt[ir][im][v]] = k - dk; - pt[ir][im][v][ipt[ir][im][v]++] = J3[ir][1][im][v]; - gpt[ir][im][v] = 0; + if (Gpt[ir][im][v] >= PTAM_WINDOW_SIZE-1 && Ipt[ir][im][v] < PTAM_MAX_PT) { + if (cplx_peak_or_trough(im, v, J3[ir], k, dk, &Kpt[ir][im][v][Ipt[ir][im][v]], &tmp0) != 0) { + Fpt[ir][im][v][Ipt[ir][im][v]++] = tmp0; + Gpt[ir][im][v] = 0; + } else if (Gpt[ir][im][v] >= PTAM_MAX_WAITS) { // 不再等待,直接取中点作为波峰波谷 + Kpt[ir][im][v][Ipt[ir][im][v]] = k - dk; + Fpt[ir][im][v][Ipt[ir][im][v]++] = J3[ir][1][im][v]; + Gpt[ir][im][v] = 0; } } - *iendk0 = *iendk0 && (ipt[ir][im][v] == maxNpt); + *iendk0 = *iendk0 && (Ipt[ir][im][v] == PTAM_MAX_PT); } /** * 在输入被积函数的情况下,对不同震源使用峰谷平均法 * - * @param ir 震中距索引 - * @param nr 震中距个数 - * @param precoef 积分值系数 - * @param maxNpt 最大峰谷数 - * @param maxnwait 最大等待次数 - * @param k 波数 - * @param dk 波数步长 - * @param SUM3 被积函数的幅值数组 - * @param sum_J 的积分值数组 + * @param[in] ir 震中距索引 + * @param[in] nr 震中距个数 + * @param[in] precoef 积分值系数 + * @param[in] k 波数 + * @param[in] dk 波数步长 + * @param[in,out] SUM3 被积函数的幅值数组 + * @param[in,out] sum_J 积分值数组 * - * @param Kpt 积分值峰谷的波数数组 - * @param Fpt 用于存储波峰/波谷点的幅值数组 - * @param Ipt 用于存储波峰/波谷点的个数数组 - * @param Gpt 用于存储等待迭次数的数组 + * @param[in,out] Kpt 积分值峰谷的波数数组 + * @param[in,out] Fpt 用于存储波峰/波谷点的幅值数组 + * @param[in,out] Ipt 用于存储波峰/波谷点的个数数组 + * @param[in,out] Gpt 用于存储等待迭次数的数组 * - * @param iendk0 是否收集足够峰谷 + * @param[in,out] iendk0 是否收集足够峰谷 * */ static void ptam_once( - const MYINT ir, const MYINT nr, const MYREAL precoef, - MYINT maxNpt, MYINT maxnwait, MYREAL k, MYREAL dk, - MYCOMPLEX SUM3[nr][3][GRT_SRC_M_COUNTS][GRT_SRC_P_COUNTS], - MYCOMPLEX sum_J[nr][GRT_SRC_M_COUNTS][GRT_SRC_P_COUNTS], - MYREAL Kpt[nr][GRT_SRC_M_COUNTS][GRT_SRC_P_COUNTS][maxNpt], - MYCOMPLEX Fpt[nr][GRT_SRC_M_COUNTS][GRT_SRC_P_COUNTS][maxNpt], - MYINT Ipt[nr][GRT_SRC_M_COUNTS][GRT_SRC_P_COUNTS], - MYINT Gpt[nr][GRT_SRC_M_COUNTS][GRT_SRC_P_COUNTS], + const MYINT ir, const MYINT nr, const MYREAL precoef, MYREAL k, MYREAL dk, + MYCOMPLEX SUM3[nr][PTAM_WINDOW_SIZE][SRC_M_NUM][INTEG_NUM], + MYCOMPLEX sum_J[nr][SRC_M_NUM][INTEG_NUM], + MYREAL Kpt[nr][SRC_M_NUM][INTEG_NUM][PTAM_MAX_PT], + MYCOMPLEX Fpt[nr][SRC_M_NUM][INTEG_NUM][PTAM_MAX_PT], + MYINT Ipt[nr][SRC_M_NUM][INTEG_NUM], + MYINT Gpt[nr][SRC_M_NUM][INTEG_NUM], bool *iendk0) { *iendk0 = true; - for(MYINT i=0; iThk, pymod->Vb, pymod->n, pymod->isrc, pymod->ircv, rs[ir]); strcpy(hd.kt1, "S"); - for(int im=0; im=3) continue; - int modr = GRT_SRC_M_ORDERS[im]; + int modr = SRC_M_ORDERS[im]; int sgn=1; // 用于反转Z分量 - for(int c=0; c Date: Sat, 26 Apr 2025 15:56:08 +0800 Subject: [PATCH 03/25] REFAC: continue refactor whole codes --- pygrt/C_extension/include/common/const.h | 4 +- pygrt/C_extension/src/common/const.c | 4 +- pygrt/C_extension/src/dynamic/grt.c | 3 + pygrt/C_extension/src/dynamic/grt_main.c | 10 +- pygrt/C_extension/src/static/stgrt_main.c | 18 +- pygrt/c_interfaces.py | 29 +-- pygrt/c_structures.py | 37 ++-- pygrt/pygrn.py | 46 +---- pygrt/pymod.py | 231 +++++----------------- 9 files changed, 99 insertions(+), 283 deletions(-) diff --git a/pygrt/C_extension/include/common/const.h b/pygrt/C_extension/include/common/const.h index a3d57129..41efc72f 100755 --- a/pygrt/C_extension/include/common/const.h +++ b/pygrt/C_extension/include/common/const.h @@ -151,7 +151,7 @@ extern const MYINT SRC_M_ORDERS[SRC_M_NUM]; extern const char *SRC_M_NAME_ABBR[SRC_M_NUM]; /** ZRT三分量代号 */ -extern const char GRT_ZRTchs[]; +extern const char ZRTchs[]; /** ZNE三分量代号 */ -extern const char GRT_ZNEchs[]; \ No newline at end of file +extern const char ZNEchs[]; \ No newline at end of file diff --git a/pygrt/C_extension/src/common/const.c b/pygrt/C_extension/src/common/const.c index e0d494b7..586a723a 100644 --- a/pygrt/C_extension/src/common/const.c +++ b/pygrt/C_extension/src/common/const.c @@ -16,7 +16,7 @@ const MYINT SRC_M_ORDERS[SRC_M_NUM] = {0, 0, 1, 0, 1, 2}; const char *SRC_M_NAME_ABBR[SRC_M_NUM] = {"EX", "VF", "HF", "DD", "DS", "SS"}; /** ZRT三分量代号 */ -const char GRT_ZRTchs[] = {'Z', 'R', 'T'}; +const char ZRTchs[] = {'Z', 'R', 'T'}; /** ZNE三分量代号 */ -const char GRT_ZNEchs[] = {'Z', 'N', 'E'}; +const char ZNEchs[] = {'Z', 'N', 'E'}; diff --git a/pygrt/C_extension/src/dynamic/grt.c b/pygrt/C_extension/src/dynamic/grt.c index 1c191344..ef7167a2 100755 --- a/pygrt/C_extension/src/dynamic/grt.c +++ b/pygrt/C_extension/src/dynamic/grt.c @@ -63,7 +63,10 @@ static void recordin_GRN( merge_Pk(sum_J[ir], tmp_grn[ir]); for(MYINT i=0; i Date: Sat, 26 Apr 2025 20:17:49 +0800 Subject: [PATCH 04/25] REFAC: continue refactor whole codes, update statsfile format and kernel name --- pygrt/C_extension/include/common/const.h | 4 + pygrt/C_extension/include/common/iostats.h | 28 +- pygrt/C_extension/include/common/kernel.h | 2 +- pygrt/C_extension/include/common/radiation.h | 5 +- pygrt/C_extension/include/dynamic/grt.h | 3 +- pygrt/C_extension/include/dynamic/layer.h | 12 +- pygrt/C_extension/include/dynamic/propagate.h | 3 +- pygrt/C_extension/include/dynamic/source.h | 3 +- .../include/static/static_propagate.h | 2 +- pygrt/C_extension/src/common/const.c | 3 + pygrt/C_extension/src/common/dwm.c | 2 +- pygrt/C_extension/src/common/fim.c | 4 +- pygrt/C_extension/src/common/grt_k2a.c | 92 +---- pygrt/C_extension/src/common/iostats.c | 101 ++++- pygrt/C_extension/src/common/ptam.c | 4 +- pygrt/C_extension/src/common/radiation.c | 44 +-- pygrt/C_extension/src/dynamic/grt.c | 2 +- pygrt/C_extension/src/dynamic/grt_main.c | 2 +- pygrt/C_extension/src/dynamic/grt_rotation.c | 351 +++++++++--------- pygrt/C_extension/src/dynamic/grt_strain.c | 4 +- pygrt/C_extension/src/dynamic/grt_stress.c | 4 +- pygrt/C_extension/src/dynamic/grt_syn.c | 60 ++- pygrt/C_extension/src/dynamic/layer.c | 14 +- pygrt/C_extension/src/dynamic/propagate.c | 10 +- pygrt/C_extension/src/dynamic/source.c | 2 +- .../C_extension/src/static/static_propagate.c | 6 +- pygrt/C_extension/src/static/stgrt_rotation.c | 4 +- pygrt/C_extension/src/static/stgrt_strain.c | 4 +- pygrt/C_extension/src/static/stgrt_stress.c | 4 +- pygrt/C_extension/src/static/stgrt_syn.c | 69 ++-- pygrt/c_interfaces.py | 2 +- pygrt/c_structures.py | 6 + pygrt/pymod.py | 2 +- pygrt/utils.py | 315 ++++++---------- 34 files changed, 541 insertions(+), 632 deletions(-) diff --git a/pygrt/C_extension/include/common/const.h b/pygrt/C_extension/include/common/const.h index 41efc72f..4069a13d 100755 --- a/pygrt/C_extension/include/common/const.h +++ b/pygrt/C_extension/include/common/const.h @@ -138,6 +138,7 @@ typedef int MYINT; ///< 整数 #define INTEG_NUM 4 ///< 4, 代码中积分类型个数 #define MORDER_MAX 2 ///< 2, 代码中阶数m的最大值 #define SRC_M_NUM 6 ///< 6, 代码中不同震源、不同阶数的个数 +#define MECHANISM_NUM 6 ///< 6, 描述震源机制的最多参数 #define PTAM_MAX_PT 36 ///< 36, 最后统计波峰波谷的目标数量 #define PTAM_WINDOW_SIZE 3 ///< 3, 使用连续点数判断是否为波峰或波谷 @@ -150,6 +151,9 @@ extern const MYINT SRC_M_ORDERS[SRC_M_NUM]; /** 不同震源,不同阶数的名称简写,用于命名 */ extern const char *SRC_M_NAME_ABBR[SRC_M_NUM]; +/** q, w, v 名称代号 */ +extern const char qwvchs[]; + /** ZRT三分量代号 */ extern const char ZRTchs[]; diff --git a/pygrt/C_extension/include/common/iostats.h b/pygrt/C_extension/include/common/iostats.h index 389619d2..20289db0 100755 --- a/pygrt/C_extension/include/common/iostats.h +++ b/pygrt/C_extension/include/common/iostats.h @@ -30,12 +30,22 @@ void write_stats( FILE *f0, MYREAL k, const MYCOMPLEX QWV[SRC_M_NUM][QWV_NUM]); +/** + * 从二进制核函数文件读出一个数据块,写入到文本文件中 + * + * @param[in,out] bf0 二进制文件指针,如果为NULL则打印标题 + * @param[out] af0 文本文件指针 + * + * @return 0表示读取成功,-1表示读取结果/失败 + */ +MYINT extract_stats(FILE *bf0, FILE *af0); + + /** * 记录峰谷平均法的峰谷位置 * * @param[out] f0 二进制文件指针 - * @param[in] k 波数 * @param[in] Kpt 最终收敛积分值使用的波峰波谷位置 * @param[in] Fpt 最终收敛积分值使用的波峰波谷幅值 * @@ -44,6 +54,18 @@ void write_stats( * */ void write_stats_ptam( - FILE *f0, MYREAL k, + FILE *f0, MYREAL Kpt[SRC_M_NUM][INTEG_NUM][PTAM_MAX_PT], - MYCOMPLEX Fpt[SRC_M_NUM][INTEG_NUM][PTAM_MAX_PT]); \ No newline at end of file + MYCOMPLEX Fpt[SRC_M_NUM][INTEG_NUM][PTAM_MAX_PT]); + + +/** + * 从二进制峰谷位置文件读出一个数据块,写入到文本文件中 + * + * @param[in,out] bf0 二进制文件指针,如果为NULL则打印标题 + * @param[out] af0 文本文件指针 + * + * @return 0表示读取成功,-1表示读取结果/失败 + */ +MYINT extract_stats_ptam(FILE *bf0, FILE *af0); + diff --git a/pygrt/C_extension/include/common/kernel.h b/pygrt/C_extension/include/common/kernel.h index 31a0318a..760cdbdf 100644 --- a/pygrt/C_extension/include/common/kernel.h +++ b/pygrt/C_extension/include/common/kernel.h @@ -17,5 +17,5 @@ * 计算核函数的函数指针,动态与静态的接口一致 */ typedef void (*KernelFunc) ( - const MODEL1D *mod1d, MYCOMPLEX omega, MYREAL k, MYCOMPLEX QWV[SRC_M_NUM][QWV_NUM], + const MODEL1D *mod1d, MYREAL k, MYCOMPLEX QWV[SRC_M_NUM][QWV_NUM], bool calc_uiz, MYCOMPLEX QWV_uiz[SRC_M_NUM][QWV_NUM]); \ No newline at end of file diff --git a/pygrt/C_extension/include/common/radiation.h b/pygrt/C_extension/include/common/radiation.h index dd06a4cc..8e13362d 100644 --- a/pygrt/C_extension/include/common/radiation.h +++ b/pygrt/C_extension/include/common/radiation.h @@ -9,6 +9,7 @@ #pragma once +#include "common/const.h" #define GRT_SYN_COMPUTE_EX 0 ///< 计算爆炸源 #define GRT_SYN_COMPUTE_SF 1 ///< 计算单力源 @@ -31,6 +32,6 @@ * 对于张量源,mchn={Mxx, Mxy, Mxz, Myy, Myz, Mzz} */ void set_source_radiation( - double srcRadi[3][6], const int computeType, const bool par_theta, - const double M0, const double coef, const double azrad, const double mchn[6] + double srcRadi[SRC_M_NUM][CHANNEL_NUM], const int computeType, const bool par_theta, + const double M0, const double coef, const double azrad, const double mchn[MECHANISM_NUM] ); \ No newline at end of file diff --git a/pygrt/C_extension/include/dynamic/grt.h b/pygrt/C_extension/include/dynamic/grt.h index 335fd929..6dbec719 100755 --- a/pygrt/C_extension/include/dynamic/grt.h +++ b/pygrt/C_extension/include/dynamic/grt.h @@ -31,7 +31,6 @@ void set_num_threads(int num_threads); * @param[in] pymod1d `PYMODEL1D` 结构体指针 * @param[in] nf1 开始计算频谱的频率索引值, 总范围在[nf1, nf2] * @param[in] nf2 结束计算频谱的频率索引值, 总范围在[nf1, nf2] - * @param[in] nf 所有频点个数 * @param[in] freqs 所有频点的频率值(包括未计算的) * @param[in] nr 震中距数量 * @param[in] rs 震中距数组 @@ -57,7 +56,7 @@ void set_num_threads(int num_threads); * */ void integ_grn_spec( - PYMODEL1D *pymod1d, MYINT nf1, MYINT nf2, MYINT nf, MYREAL *freqs, + PYMODEL1D *pymod1d, MYINT nf1, MYINT nf2, MYREAL *freqs, MYINT nr, MYREAL *rs, MYREAL wI, MYREAL vmin_ref, MYREAL keps, MYREAL ampk, MYREAL k0, MYREAL Length, MYREAL filonLength, MYREAL filonCut, bool print_progressbar, diff --git a/pygrt/C_extension/include/dynamic/layer.h b/pygrt/C_extension/include/dynamic/layer.h index b793921d..ecedec13 100755 --- a/pygrt/C_extension/include/dynamic/layer.h +++ b/pygrt/C_extension/include/dynamic/layer.h @@ -102,8 +102,7 @@ void calc_uiz_R_EV( void calc_RT_2x2( MYREAL Rho1, MYCOMPLEX xa1, MYCOMPLEX xb1, MYCOMPLEX kbkb1, MYCOMPLEX mu1, MYREAL Rho2, MYCOMPLEX xa2, MYCOMPLEX xb2, MYCOMPLEX kbkb2, MYCOMPLEX mu2, - MYREAL thk, - MYCOMPLEX omega, MYREAL k, + MYREAL thk, MYREAL k, MYCOMPLEX RD[2][2], MYCOMPLEX *RDL, MYCOMPLEX RU[2][2], MYCOMPLEX *RUL, MYCOMPLEX TD[2][2], MYCOMPLEX *TDL, MYCOMPLEX TU[2][2], MYCOMPLEX *TUL); @@ -118,7 +117,6 @@ void calc_RT_2x2( * @param[in] xb S波归一化垂直波数 \f$ \sqrt{1 - (k_b/k)^2} \f$ * @param[in] kbkb S波水平波数的平方 \f$ k_b^2=(\frac{\omega}{V_b})^2 \f$ * @param[in] mu 剪切模量 - * @param[in] omega 复数频率 \f$ \tilde{\omega} =\omega - i\omega_I \f$ * @param[in] k 波数 * * @param[out] D D矩阵(或其逆矩阵) @@ -127,7 +125,7 @@ void calc_RT_2x2( */ void get_layer_D( MYCOMPLEX xa, MYCOMPLEX xb, MYCOMPLEX kbkb, MYCOMPLEX mu, - MYCOMPLEX omega, MYREAL k, MYCOMPLEX D[4][4], bool inverse); + MYREAL k, MYCOMPLEX D[4][4], bool inverse); @@ -137,8 +135,8 @@ void get_layer_D( * 函数接口也和 calc_RT_2x2函数 类似 */ void calc_RT_2x2_from_4x4( - MYREAL Rho1, MYCOMPLEX xa1, MYCOMPLEX xb1, MYCOMPLEX kbkb1, MYCOMPLEX mu1, - MYREAL Rho2, MYCOMPLEX xa2, MYCOMPLEX xb2, MYCOMPLEX kbkb2, MYCOMPLEX mu2, - MYCOMPLEX omega, MYREAL k, + MYCOMPLEX xa1, MYCOMPLEX xb1, MYCOMPLEX kbkb1, MYCOMPLEX mu1, + MYCOMPLEX xa2, MYCOMPLEX xb2, MYCOMPLEX kbkb2, MYCOMPLEX mu2, + MYREAL k, MYCOMPLEX RD[2][2], MYCOMPLEX *RDL, MYCOMPLEX RU[2][2], MYCOMPLEX *RUL, MYCOMPLEX TD[2][2], MYCOMPLEX *TDL, MYCOMPLEX TU[2][2], MYCOMPLEX *TUL); diff --git a/pygrt/C_extension/include/dynamic/propagate.h b/pygrt/C_extension/include/dynamic/propagate.h index e1c82416..9c26b218 100755 --- a/pygrt/C_extension/include/dynamic/propagate.h +++ b/pygrt/C_extension/include/dynamic/propagate.h @@ -80,7 +80,6 @@ * 计算相应的矩阵。 * * @param[in] mod1d `MODEL1D` 结构体指针 - * @param[in] omega 复数频率 * @param[in] k 波数 * @param[out] QWV 不同震源,不同阶数的核函数 \f$ q_m, w_m, v_m \f$ * @param[in] calc_uiz 是否计算ui_z(位移u对坐标z的偏导) @@ -88,7 +87,7 @@ * */ void kernel( - const MODEL1D *mod1d, MYCOMPLEX omega, MYREAL k, MYCOMPLEX QWV[SRC_M_NUM][QWV_NUM], + const MODEL1D *mod1d, MYREAL k, MYCOMPLEX QWV[SRC_M_NUM][QWV_NUM], bool calc_uiz, MYCOMPLEX QWV_uiz[SRC_M_NUM][QWV_NUM]); diff --git a/pygrt/C_extension/include/dynamic/source.h b/pygrt/C_extension/include/dynamic/source.h index 7b0c0d11..e5d244b8 100755 --- a/pygrt/C_extension/include/dynamic/source.h +++ b/pygrt/C_extension/include/dynamic/source.h @@ -24,12 +24,11 @@ * @param[in] src_xb 震源层的S波归一化垂直波数 \f$ \sqrt{1 - (k_b/k)^2} \f$ * @param[in] src_kaka 震源层的P波水平波数的平方 \f$ k_a^2=(\frac{\omega}{V_a})^2 \f$ * @param[in] src_kbkb 震源层的S波水平波数的平方 \f$ k_b^2=(\frac{\omega}{V_b})^2 \f$ - * @param[in] omega 复数频率 * @param[in] k 波数 * @param[out] coef 震源系数 \f$ P_m, SV_m, SH_m \f$ * */ void source_coef( MYCOMPLEX src_xa, MYCOMPLEX src_xb, MYCOMPLEX src_kaka, MYCOMPLEX src_kbkb, - MYCOMPLEX omega, MYREAL k, + MYREAL k, MYCOMPLEX coef[SRC_M_NUM][QWV_NUM][2]); diff --git a/pygrt/C_extension/include/static/static_propagate.h b/pygrt/C_extension/include/static/static_propagate.h index d5dfb1d6..16a56ce7 100644 --- a/pygrt/C_extension/include/static/static_propagate.h +++ b/pygrt/C_extension/include/static/static_propagate.h @@ -24,5 +24,5 @@ * 此处omega未使用,传入0即可 */ void static_kernel( - const MODEL1D *mod1d, MYCOMPLEX omega, MYREAL k, MYCOMPLEX QWV[SRC_M_NUM][QWV_NUM], + const MODEL1D *mod1d, MYREAL k, MYCOMPLEX QWV[SRC_M_NUM][QWV_NUM], bool calc_uiz, MYCOMPLEX QWV_uiz[SRC_M_NUM][QWV_NUM]); \ No newline at end of file diff --git a/pygrt/C_extension/src/common/const.c b/pygrt/C_extension/src/common/const.c index 586a723a..4ad293bb 100644 --- a/pygrt/C_extension/src/common/const.c +++ b/pygrt/C_extension/src/common/const.c @@ -15,6 +15,9 @@ const MYINT SRC_M_ORDERS[SRC_M_NUM] = {0, 0, 1, 0, 1, 2}; /** 不同震源,不同阶数的名称简写,用于命名 */ const char *SRC_M_NAME_ABBR[SRC_M_NUM] = {"EX", "VF", "HF", "DD", "DS", "SS"}; +/** q, w, v 名称代号 */ +const char qwvchs[] = {'q', 'w', 'v'}; + /** ZRT三分量代号 */ const char ZRTchs[] = {'Z', 'R', 'T'}; diff --git a/pygrt/C_extension/src/common/dwm.c b/pygrt/C_extension/src/common/dwm.c index a56a5d33..c117dba7 100644 --- a/pygrt/C_extension/src/common/dwm.c +++ b/pygrt/C_extension/src/common/dwm.c @@ -58,7 +58,7 @@ MYREAL discrete_integ( // printf("w=%15.5e, ik=%d\n", CREAL(omega), ik); // 计算核函数 F(k, w) - kerfunc(mod1d, omega, k, QWV, calc_upar, QWV_uiz); + kerfunc(mod1d, k, QWV, calc_upar, QWV_uiz); // 记录积分核函数 if(fstats!=NULL) write_stats(fstats, k, QWV); diff --git a/pygrt/C_extension/src/common/fim.c b/pygrt/C_extension/src/common/fim.c index 63e16b25..4d0bb1e6 100755 --- a/pygrt/C_extension/src/common/fim.c +++ b/pygrt/C_extension/src/common/fim.c @@ -59,7 +59,7 @@ MYREAL linear_filon_integ( k += dk; // 计算核函数 F(k, w) - kerfunc(mod1d, omega, k, QWV, calc_upar, QWV_uiz); + kerfunc(mod1d, k, QWV, calc_upar, QWV_uiz); // 记录积分结果 if(fstats!=NULL) write_stats(fstats, k, QWV); @@ -172,7 +172,7 @@ MYREAL linear_filon_integ( } // 计算核函数 F(k, w) - kerfunc(mod1d, omega, k0N, QWV, calc_upar, QWV_uiz); + kerfunc(mod1d, k0N, QWV, calc_upar, QWV_uiz); for(MYINT ir=0; ir +#include #include #include @@ -21,25 +22,59 @@ void write_stats( { fwrite(&k, sizeof(MYREAL), 1, f0); - fwrite(&QWV[0][0], sizeof(MYCOMPLEX), 2, f0); + for(MYINT im=0; im - #include - #include - #include - #include - #include - #include - - #include "common/sacio2.h" - #include "common/const.h" - #include "common/logo.h" - #include "common/colorstr.h" - - - //****************** 在该文件以内的全局变量 ***********************// - // 命令名称 - static char *command = NULL; - - // 输出分量格式,即是否需要旋转到ZNE - static bool rot2ZNE = false; - - // 三分量 - const char zrtchs[3] = {'Z', 'R', 'T'}; - const char znechs[3] = {'Z', 'N', 'E'}; - const char *chs = NULL; - - - /** - * 打印使用说明 - */ - static void print_help(){ - print_logo(); - printf("\n" - "[grt.rotation]\n\n" - " Conbine spatial derivatives of displacements into rotation tensor.\n" - " For example, \"ZR\" in filename means 0.5*(u_{z,r} - u_{r,z}).\n" - "\n\n" - "Usage:\n" - "----------------------------------------------------------------\n" - " grt.rotation /\n" - "\n\n\n" - ); - } - - - /** - * 从命令行中读取选项,处理后记录到全局变量中 - * - * @param argc 命令行的参数个数 - * @param argv 多个参数字符串指针 - */ - static void getopt_from_command(int argc, char **argv){ - int opt; - while ((opt = getopt(argc, argv, ":h")) != -1) { - switch (opt) { - - // 帮助 - case 'h': - print_help(); - exit(EXIT_SUCCESS); - break; - - // 参数缺失 - case ':': - fprintf(stderr, "[%s] " BOLD_RED "Error! Option '-%c' requires an argument. Use '-h' for help.\n" DEFAULT_RESTORE, command, optopt); - exit(EXIT_FAILURE); - break; - - // 非法选项 - case '?': - default: - fprintf(stderr, "[%s] " BOLD_RED "Error! Option '-%c' is invalid. Use '-h' for help.\n" DEFAULT_RESTORE, command, optopt); - exit(EXIT_FAILURE); - break; - } - } - - // 检查必选项有没有设置 - if(argc != 2){ - fprintf(stderr, "[%s] " BOLD_RED "Error! Need set options. Use '-h' for help.\n" DEFAULT_RESTORE, command); - exit(EXIT_FAILURE); - } - } - - - - int main(int argc, char **argv){ - command = argv[0]; - - getopt_from_command(argc, argv); - - - // 合成地震图目录路径 - char *s_synpath = (char*)malloc(sizeof(char)*(strlen(argv[1])+1)); - // 保存文件前缀 - char *s_prefix = (char*)malloc(sizeof(char)*(strlen(argv[1])+1)); - if(2 != sscanf(argv[1], "%[^/]/%s", s_synpath, s_prefix)){ - fprintf(stderr, "[%s] " BOLD_RED "Error format in \"%s\".\n" DEFAULT_RESTORE, command, argv[1]); - exit(EXIT_FAILURE); - } - - // 检查是否存在该目录 - DIR *dir = opendir(s_synpath); - if (dir == NULL) { - fprintf(stderr, "[%s] " BOLD_RED "Error! Directory \"%s\" not exists.\n" DEFAULT_RESTORE, command, s_synpath); - exit(EXIT_FAILURE); - } - - - // ---------------------------------------------------------------------------------- - // 开始读取计算,输出3个量 - float *arrin = NULL; - char c1, c2; - char *s_filepath = (char*)malloc(sizeof(char) * (strlen(s_synpath)+strlen(s_prefix)+100)); - - // 判断标志性文件是否存在,来判断输出使用ZNE还是ZRT - sprintf(s_filepath, "%s/n%sN.sac", s_synpath, s_prefix); - rot2ZNE = (access(s_filepath, F_OK) == 0); - - // 指示特定的通道名 - chs = (rot2ZNE)? znechs : zrtchs; - - - // 读取一个头段变量,获得基本参数,分配数组内存 - SACHEAD hd; - sprintf(s_filepath, "%s/%c%s%c.sac", s_synpath, tolower(chs[0]), s_prefix, chs[0]); - read_SAC_HEAD(command, s_filepath, &hd); - int npts=hd.npts; - float dist=hd.dist; - float *arrout = (float*)calloc(npts, sizeof(float)); - - // ---------------------------------------------------------------------------------- - // 循环3个分量 - for(int i1=0; i1<2; ++i1){ - c1 = chs[i1]; - for(int i2=i1+1; i2<3; ++i2){ - c2 = chs[i2]; - - // 读取数据 u_{i,j} - sprintf(s_filepath, "%s/%c%s%c.sac", s_synpath, tolower(c2), s_prefix, c1); - arrin = read_SAC(command, s_filepath, &hd, arrin); - - // 累加 - for(int i=0; icm - if(c1=='R' && c2=='T'){ - // 读取数据 u_T - sprintf(s_filepath, "%s/%sT.sac", s_synpath, s_prefix); - arrin = read_SAC(command, s_filepath, &hd, arrin); - for(int i=0; i +#include +#include +#include +#include +#include +#include + +#include "common/sacio2.h" +#include "common/const.h" +#include "common/logo.h" +#include "common/colorstr.h" + + +//****************** 在该文件以内的全局变量 ***********************// +// 命令名称 +static char *command = NULL; + +// 输出分量格式,即是否需要旋转到ZNE +static bool rot2ZNE = false; + +// 三分量 +const char *chs = NULL; + + +/** + * 打印使用说明 + */ +static void print_help(){ +print_logo(); +printf("\n" +"[grt.rotation]\n\n" +" Conbine spatial derivatives of displacements into rotation tensor.\n" +" For example, \"ZR\" in filename means 0.5*(u_{z,r} - u_{r,z}).\n" +"\n\n" +"Usage:\n" +"----------------------------------------------------------------\n" +" grt.rotation /\n" +"\n\n\n" +); +} + + +/** + * 从命令行中读取选项,处理后记录到全局变量中 + * + * @param argc 命令行的参数个数 + * @param argv 多个参数字符串指针 + */ +static void getopt_from_command(int argc, char **argv){ + int opt; + while ((opt = getopt(argc, argv, ":h")) != -1) { + switch (opt) { + + // 帮助 + case 'h': + print_help(); + exit(EXIT_SUCCESS); + break; + + // 参数缺失 + case ':': + fprintf(stderr, "[%s] " BOLD_RED "Error! Option '-%c' requires an argument. Use '-h' for help.\n" DEFAULT_RESTORE, command, optopt); + exit(EXIT_FAILURE); + break; + + // 非法选项 + case '?': + default: + fprintf(stderr, "[%s] " BOLD_RED "Error! Option '-%c' is invalid. Use '-h' for help.\n" DEFAULT_RESTORE, command, optopt); + exit(EXIT_FAILURE); + break; + } + } + + // 检查必选项有没有设置 + if(argc != 2){ + fprintf(stderr, "[%s] " BOLD_RED "Error! Need set options. Use '-h' for help.\n" DEFAULT_RESTORE, command); + exit(EXIT_FAILURE); + } +} + + + +int main(int argc, char **argv){ + command = argv[0]; + + getopt_from_command(argc, argv); + + + // 合成地震图目录路径 + char *s_synpath = (char*)malloc(sizeof(char)*(strlen(argv[1])+1)); + // 保存文件前缀 + char *s_prefix = (char*)malloc(sizeof(char)*(strlen(argv[1])+1)); + if(2 != sscanf(argv[1], "%[^/]/%s", s_synpath, s_prefix)){ + fprintf(stderr, "[%s] " BOLD_RED "Error format in \"%s\".\n" DEFAULT_RESTORE, command, argv[1]); + exit(EXIT_FAILURE); + } + + // 检查是否存在该目录 + DIR *dir = opendir(s_synpath); + if (dir == NULL) { + fprintf(stderr, "[%s] " BOLD_RED "Error! Directory \"%s\" not exists.\n" DEFAULT_RESTORE, command, s_synpath); + exit(EXIT_FAILURE); + } + + + // ---------------------------------------------------------------------------------- + // 开始读取计算,输出3个量 + float *arrin = NULL; + char c1, c2; + char *s_filepath = (char*)malloc(sizeof(char) * (strlen(s_synpath)+strlen(s_prefix)+100)); + + // 判断标志性文件是否存在,来判断输出使用ZNE还是ZRT + sprintf(s_filepath, "%s/n%sN.sac", s_synpath, s_prefix); + rot2ZNE = (access(s_filepath, F_OK) == 0); + + // 指示特定的通道名 + chs = (rot2ZNE)? ZNEchs : ZRTchs; + + + // 读取一个头段变量,获得基本参数,分配数组内存 + SACHEAD hd; + sprintf(s_filepath, "%s/%c%s%c.sac", s_synpath, tolower(chs[0]), s_prefix, chs[0]); + read_SAC_HEAD(command, s_filepath, &hd); + int npts=hd.npts; + float dist=hd.dist; + float *arrout = (float*)calloc(npts, sizeof(float)); + + // ---------------------------------------------------------------------------------- + // 循环3个分量 + for(int i1=0; i1<2; ++i1){ + c1 = chs[i1]; + for(int i2=i1+1; i2<3; ++i2){ + c2 = chs[i2]; + + // 读取数据 u_{i,j} + sprintf(s_filepath, "%s/%c%s%c.sac", s_synpath, tolower(c2), s_prefix, c1); + arrin = read_SAC(command, s_filepath, &hd, arrin); + + // 累加 + for(int i=0; icm + if(c1=='R' && c2=='T'){ + // 读取数据 u_T + sprintf(s_filepath, "%s/%sT.sac", s_synpath, s_prefix); + arrin = read_SAC(command, s_filepath, &hd, arrin); + for(int i=0; i 0: - chs = znechs + chs = ZNEchs dist = st_syn[0].stats.sac['dist'] @@ -661,13 +658,11 @@ def _compute_static_strain_rotation(syn:dict, Type:str): if k[-3:-1] != midname: raise ValueError("WRONG INPUT! inconsistent component names.") - zrtchs = ['Z', 'R', 'T'] - znechs = ['Z', 'N', 'E'] - chs = zrtchs + chs = ZRTchs # 判断是否有标志性的分量名 if f"n{midname}N" in syn.keys(): - chs = znechs + chs = ZNEchs xarr:np.ndarray = syn['_xarr'] yarr:np.ndarray = syn['_yarr'] @@ -781,14 +776,12 @@ def _compute_stress(st_syn:Stream): if tr.stats.channel[-3:-1] != midname: raise ValueError("WRONG INPUT! inconsistent component names.") - zrtchs = ['Z', 'R', 'T'] - znechs = ['Z', 'N', 'E'] - chs = zrtchs + chs = ZRTchs rot2ZNE:bool = False # 判断是否有标志性的trace if len(st_syn.select(channel=f"n{midname}N")) > 0: - chs = znechs + chs = ZNEchs rot2ZNE = True nt = st_syn[0].stats.npts @@ -912,14 +905,12 @@ def _compute_static_stress(syn:dict): if k[-3:-1] != midname: raise ValueError("WRONG INPUT! inconsistent component names.") - zrtchs = ['Z', 'R', 'T'] - znechs = ['Z', 'N', 'E'] - chs = zrtchs + chs = ZRTchs rot2ZNE:bool = False # 判断是否有标志性的分量名 if f"n{midname}N" in syn.keys(): - chs = znechs + chs = ZNEchs rot2ZNE = True xarr:np.ndarray = syn['_xarr'] @@ -1228,68 +1219,18 @@ def read_statsfile(statsfile:str): raise OSError(f"{statsfile} should only match one file, but {len(Lst)} matched.") statsfile = Lst[0] - data = np.fromfile(statsfile, - dtype=[ - ('k', NPCT_REAL_TYPE), - - # 核函数 F(k, w) - ('EXP_q0', NPCT_CMPLX_TYPE), - ('EXP_w0', NPCT_CMPLX_TYPE), - - ('VF_q0', NPCT_CMPLX_TYPE), - ('VF_w0', NPCT_CMPLX_TYPE), - - ('HF_q1', NPCT_CMPLX_TYPE), - ('HF_w1', NPCT_CMPLX_TYPE), - ('HF_v1', NPCT_CMPLX_TYPE), - - ('DC_q0', NPCT_CMPLX_TYPE), - ('DC_w0', NPCT_CMPLX_TYPE), - - ('DC_q1', NPCT_CMPLX_TYPE), - ('DC_w1', NPCT_CMPLX_TYPE), - ('DC_v1', NPCT_CMPLX_TYPE), - - ('DC_q2', NPCT_CMPLX_TYPE), - ('DC_w2', NPCT_CMPLX_TYPE), - ('DC_v2', NPCT_CMPLX_TYPE), - - # =============================== - # 被积函数 F(k, w)*Jm(kr)*k - # 下划线后的两位数字,第一位m代表阶数,但不完全对应Bessel函数的阶数, - # 因为存在Bessel函数的导数的情况,需要使用递推公式,故存在不对应情况; - # 第二位p代表自定义的被积函数类型,基于式(5.6.22),分别为 - # if m==0: - # if p==0: - q0 * J1(kr) * k - # if p==2: w0 * J0(kr) * k - # else if m==1 or m==2: - # if p==0: qm * Jm-1(kr) * k - # if p==1: - (qm + vm) * Jm(kr) * k / (kr) - # if p==2: wm * Jm(kr) * k - # if p==3: - vm * Jm-1(kr) * k - # - # ('EXP_00', NPCT_CMPLX_TYPE), - # ('EXP_02', NPCT_CMPLX_TYPE), - - # ('VF_00', NPCT_CMPLX_TYPE), - # ('VF_02', NPCT_CMPLX_TYPE), - - # ('HF_10', NPCT_CMPLX_TYPE), - # ('HF_11', NPCT_CMPLX_TYPE), - # ('HF_12', NPCT_CMPLX_TYPE), - # ('HF_13', NPCT_CMPLX_TYPE), - # ('DC_00', NPCT_CMPLX_TYPE), - # ('DC_02', NPCT_CMPLX_TYPE), - # ('DC_10', NPCT_CMPLX_TYPE), - # ('DC_11', NPCT_CMPLX_TYPE), - # ('DC_12', NPCT_CMPLX_TYPE), - # ('DC_13', NPCT_CMPLX_TYPE), - # ('DC_20', NPCT_CMPLX_TYPE), - # ('DC_21', NPCT_CMPLX_TYPE), - # ('DC_22', NPCT_CMPLX_TYPE), - # ('DC_23', NPCT_CMPLX_TYPE), - ] - ) + # 确定自定义数据类型 EX_q, EX_w, VF_q, ... + dtype = [('k', NPCT_REAL_TYPE)] + for im in range(SRC_M_NUM): + modr = SRC_M_ORDERS[im] + for c in range(QWV_NUM): + if modr==0 and qwvchs[c] == 'v': + continue + + dtype.append((f"{SRC_M_NAME_ABBR[im]}_{qwvchs[c]}", NPCT_CMPLX_TYPE)) + + + data = np.fromfile(statsfile, dtype=dtype) return data @@ -1395,76 +1336,48 @@ def read_statsfile_ptam(statsfile:str): data1 = read_statsfile(os.path.join(os.path.dirname(os.path.dirname(statsfile)), K_basename)) data2 = read_statsfile(os.path.join(os.path.dirname(statsfile), K_basename)) - ptam_data = np.fromfile(statsfile, - dtype=[ - # 各格林函数数值积分的值(k上限位于不同的波峰波谷) - # 名称中的两位数字的解释和`read_statsfile`函数中的解释相同, - # 开头的sum表示这是波峰波谷位置处的数值积分的值(不含dk), - # 末尾的k表示对应积分值的波峰波谷位置的k值 - # - ('sum_EXP_00_k', NPCT_REAL_TYPE), - ('sum_EXP_00', NPCT_CMPLX_TYPE), - ('sum_EXP_02_k', NPCT_REAL_TYPE), - ('sum_EXP_02', NPCT_CMPLX_TYPE), - - ('sum_VF_00_k', NPCT_REAL_TYPE), - ('sum_VF_00', NPCT_CMPLX_TYPE), - ('sum_VF_02_k', NPCT_REAL_TYPE), - ('sum_VF_02', NPCT_CMPLX_TYPE), - - ('sum_HF_10_k', NPCT_REAL_TYPE), - ('sum_HF_10', NPCT_CMPLX_TYPE), - ('sum_HF_11_k', NPCT_REAL_TYPE), - ('sum_HF_11', NPCT_CMPLX_TYPE), - ('sum_HF_12_k', NPCT_REAL_TYPE), - ('sum_HF_12', NPCT_CMPLX_TYPE), - ('sum_HF_13', NPCT_CMPLX_TYPE), - ('sum_HF_13_k', NPCT_REAL_TYPE), - - ('sum_DC_00_k', NPCT_REAL_TYPE), - ('sum_DC_00', NPCT_CMPLX_TYPE), - ('sum_DC_02_k', NPCT_REAL_TYPE), - ('sum_DC_02', NPCT_CMPLX_TYPE), - - ('sum_DC_10_k', NPCT_REAL_TYPE), - ('sum_DC_10', NPCT_CMPLX_TYPE), - ('sum_DC_11_k', NPCT_REAL_TYPE), - ('sum_DC_11', NPCT_CMPLX_TYPE), - ('sum_DC_12_k', NPCT_REAL_TYPE), - ('sum_DC_12', NPCT_CMPLX_TYPE), - ('sum_DC_13_k', NPCT_REAL_TYPE), - ('sum_DC_13', NPCT_CMPLX_TYPE), - - ('sum_DC_20_k', NPCT_REAL_TYPE), - ('sum_DC_20', NPCT_CMPLX_TYPE), - ('sum_DC_21_k', NPCT_REAL_TYPE), - ('sum_DC_21', NPCT_CMPLX_TYPE), - ('sum_DC_22_k', NPCT_REAL_TYPE), - ('sum_DC_22', NPCT_CMPLX_TYPE), - ('sum_DC_23_k', NPCT_REAL_TYPE), - ('sum_DC_23', NPCT_CMPLX_TYPE), - ] - ) + # 确定自定义数据类型 sum_EX_0_k, sum_EX_0, sum_VF_0_k, ... + # 各格林函数数值积分的值(k上限位于不同的波峰波谷) + # 开头的sum表示这是波峰波谷位置处的数值积分的值(不含dk), + # 末尾的k表示对应积分值的波峰波谷位置的k值 + dtype = [] + for im in range(SRC_M_NUM): + modr = SRC_M_ORDERS[im] + for v in range(INTEG_NUM): + if modr==0 and v!=0 and v!=2: + continue + + dtype.append((f"sum_{SRC_M_NAME_ABBR[im]}_{v}_k", NPCT_REAL_TYPE)) + dtype.append((f"sum_{SRC_M_NAME_ABBR[im]}_{v}", NPCT_CMPLX_TYPE)) + + + ptam_data = np.fromfile(statsfile, dtype=dtype) return data1, data2, ptam_data, dist -def _get_stats_Fname(statsdata:np.ndarray, karr:np.ndarray, dist:float, srctype:str, mtype:str, ptype:str): +def _get_stats_Fname(statsdata:np.ndarray, karr:np.ndarray, dist:float, srctype:str, ptype:str): # 根据ptype获得对应的核函数 - int_sgn = 1 krarr = karr*dist + + # 从数组中找到震源名称的索引 + try: + _idx = SRC_M_NAME_ABBR.index(srctype) + mtype = str(SRC_M_ORDERS[_idx]) + except: + raise ValueError(f"{srctype} is an invalid name.") + if mtype=='0': if ptype=='0': - Fname = r"$F(k,\omega)=q_0(k, \omega)$" - Farr = statsdata[f'{srctype}_q0'] - FJname = rf"$F(k,\omega)J_1(kr)k$" - FJarr = jv(1, krarr) * Farr * karr - int_sgn = -1 + Fname = rf"$F(k,\omega)=q^{{({srctype})}}(k, \omega)$" + Farr = statsdata[f'{srctype}_q'] + FJname = rf"$ - F(k,\omega)J_1(kr)k$" + FJarr = - jv(1, krarr) * Farr * karr elif ptype=='2': - Fname = r"$F(k,\omega)=w_0(k, \omega)$" + Fname = rf"$F(k,\omega)=w^{{({srctype})}}(k, \omega)$" FJname = rf"$F(k,\omega)J_0(kr)k$" - Farr = statsdata[f'{srctype}_w0'] + Farr = statsdata[f'{srctype}_w'] FJarr = jv(0, krarr) * Farr * karr else: raise ValueError(f"source {srctype}, m={mtype}, p={ptype} is not supported.") @@ -1472,37 +1385,35 @@ def _get_stats_Fname(statsdata:np.ndarray, karr:np.ndarray, dist:float, srctype: elif mtype in ['1', '2']: m = int(mtype) if ptype=='0': - Fname = rf"$F(k,\omega)=q_{mtype}(k, \omega)$" - Farr = statsdata[f'{srctype}_q{mtype}'] + Fname = rf"$F(k,\omega)=q^{{({srctype})}}(k, \omega)$" + Farr = statsdata[f'{srctype}_q'] FJname = rf"$F(k,\omega)J_{m-1}(kr)k$" FJarr = jv(m-1, krarr) * Farr * karr elif ptype=='1': - Fname = rf"$F(k,\omega)=q_{mtype}(k, \omega) + v_{mtype}(k, \omega)$" - Farr = (statsdata[f'{srctype}_q{mtype}'] + statsdata[f'{srctype}_v{mtype}']) - FJname = rf"$F(k,\omega) \dfrac{{{m}}}{{kr}} J_{m}(kr)k$" - FJarr = jv(m, krarr) * Farr * m/dist - int_sgn = -1 + Fname = rf"$F(k,\omega)=q^{{({srctype})}}(k, \omega) + v^{{({srctype})}}(k, \omega)$" + Farr = (statsdata[f'{srctype}_q'] + statsdata[f'{srctype}_v']) + FJname = rf"$ - F(k,\omega) \dfrac{{{m}}}{{kr}} J_{m}(kr)k$" + FJarr = - jv(m, krarr) * Farr * m/dist elif ptype=='2': - Fname = rf"$F(k,\omega)=w_{mtype}(k, \omega)$" - Farr = statsdata[f'{srctype}_w{mtype}'] + Fname = rf"$F(k,\omega)=w^{{({srctype})}}(k, \omega)$" + Farr = statsdata[f'{srctype}_w'] FJname = rf"$F(k,\omega)J_{m}(kr)k$" FJarr = jv(m, krarr) * Farr * karr elif ptype=='3': - Fname = rf"$F(k,\omega)=v_{mtype}(k, \omega)$" - Farr = statsdata[f'{srctype}_v{mtype}'] - FJname = rf"$F(k,\omega)J_{m-1}(kr)k$" - FJarr = jv(m-1, krarr) * Farr * karr - int_sgn = -1 + Fname = rf"$F(k,\omega)=v^{{({srctype})}}(k, \omega)$" + Farr = statsdata[f'{srctype}_v'] + FJname = rf"$ - F(k,\omega)J_{m-1}(kr)k$" + FJarr = - jv(m-1, krarr) * Farr * karr else: raise ValueError(f"source {srctype}, m={mtype}, p={ptype} is not supported.") else: raise ValueError(f"source {srctype}, m={mtype}, p={ptype} is not supported.") - return Fname, Farr, FJname, FJarr, int_sgn + return Fname, Farr, FJname, FJarr -def plot_statsdata(statsdata:np.ndarray, dist:float, srctype:str, mtype:str, ptype:str, RorI:Union[bool,int]=True, +def plot_statsdata(statsdata:np.ndarray, dist:float, srctype:str, ptype:str, RorI:Union[bool,int]=True, fig:Union[Figure,None]=None, axs:Union[Axes,None]=None): r''' 根据 :func:`read_statsfile ` 函数函数读取的数据, @@ -1512,8 +1423,7 @@ def plot_statsdata(statsdata:np.ndarray, dist:float, srctype:str, mtype:str, pty :param statsdata: :func:`read_statsfile ` 函数返回值 :param dist: 震中距(km) - :param srctype: 震源类型的缩写,包括EXP、VF、HF、DC - :param mtype: 阶数(0,1,2),不完全对应公式中Bessel函数的阶数,因为存在Bessel函数的导数,需要使用递推公式 + :param srctype: 震源类型的缩写,包括EX、VF、HF、DD、DS、SS :param ptype: 积分类型(0,1,2,3) :param RorI: 绘制实部还是虚部,默认实部,传入2表示实部虚部都绘制 :param fig: 传入自定义的matplotlib.Figure对象,默认为None @@ -1524,7 +1434,6 @@ def plot_statsdata(statsdata:np.ndarray, dist:float, srctype:str, mtype:str, pty - **(ax1,ax2,ax3)** - matplotlib.Axes对象数组 ''' - mtype = str(mtype) ptype = str(ptype) karr = statsdata['k'] @@ -1532,7 +1441,7 @@ def plot_statsdata(statsdata:np.ndarray, dist:float, srctype:str, mtype:str, pty if 0.5*np.pi/dk < dist: # 对于bessel函数这种震荡函数,假设一个周期内至少取4个点 print(f"WARNING! dist ({dist}) > PI/(2*dk) ({0.5*np.pi/dk:.5e}.)") - Fname, Farr, FJname, FJarr, int_sgn = _get_stats_Fname(statsdata, karr, dist, srctype, mtype, ptype) + Fname, Farr, FJname, FJarr = _get_stats_Fname(statsdata, karr, dist, srctype, ptype) if fig is None or axs is None: fig, axs = plt.subplots(3, 1, figsize=(8, 9), gridspec_kw=dict(hspace=0.7)) @@ -1571,7 +1480,7 @@ def plot_statsdata(statsdata:np.ndarray, dist:float, srctype:str, mtype:str, pty ax2.legend(loc='lower left') # 数值积分,不乘系数dk - Parr = np.cumsum(FJarr) * int_sgn + Parr = np.cumsum(FJarr) if isinstance(RorI, int) and RorI==2: ax3.plot(karr, np.real(Parr), lw=0.8, label='Real') @@ -1590,7 +1499,7 @@ def plot_statsdata(statsdata:np.ndarray, dist:float, srctype:str, mtype:str, pty def plot_statsdata_ptam(statsdata1:np.ndarray, statsdata2:np.ndarray, statsdata_ptam:np.ndarray, - dist:float, srctype:str, mtype:str, ptype:str, RorI:Union[bool,int]=True, + dist:float, srctype:str, ptype:str, RorI:Union[bool,int]=True, fig:Union[Figure,None]=None, axs:Union[Axes,None]=None): r''' 根据 :func:`read_statsfile_ptam ` 函数读取的数据, @@ -1601,8 +1510,7 @@ def plot_statsdata_ptam(statsdata1:np.ndarray, statsdata2:np.ndarray, statsdata_ :param statsdata1: DWM或FIM过程中的积分过程数据 :param statsdata2: PTAM过程中的积分过程数据 :param statsdata_ptam: PTAM的峰谷位置及幅值 - :param srctype: 震源类型的缩写,包括EXP、VF、HF、DC - :param mtype: 阶数(0,1,2),不完全对应公式中Bessel函数的阶数,因为存在Bessel函数的导数,需要使用递推公式 + :param srctype: 震源类型的缩写,包括EX、VF、HF、DD、DS、SS :param ptype: 积分类型(0,1,2,3) :param RorI: 绘制实部还是虚部,默认实部,传入2表示实部虚部都绘制 :param fig: 传入自定义的matplotlib.Figure对象,默认为None @@ -1613,15 +1521,14 @@ def plot_statsdata_ptam(statsdata1:np.ndarray, statsdata2:np.ndarray, statsdata_ - **(ax1,ax2,ax3)** - matplotlib.Axes对象数组 ''' - mtype = str(mtype) ptype = str(ptype) karr1 = statsdata1['k'] dk1 = karr1[1] - karr1[0] - Fname, Farr1, FJname, FJarr1, int_sgn = _get_stats_Fname(statsdata1, karr1, dist, srctype, mtype, ptype) + Fname, Farr1, FJname, FJarr1 = _get_stats_Fname(statsdata1, karr1, dist, srctype, ptype) karr2 = statsdata2['k'] dk2 = karr2[1] - karr2[0] - Fname, Farr2, FJname, FJarr2, int_sgn = _get_stats_Fname(statsdata2, karr2, dist, srctype, mtype, ptype) + Fname, Farr2, FJname, FJarr2 = _get_stats_Fname(statsdata2, karr2, dist, srctype, ptype) # 将两个过程的结果拼起来 Farr = np.hstack((Farr1, Farr2)) @@ -1665,12 +1572,12 @@ def plot_statsdata_ptam(statsdata1:np.ndarray, statsdata2:np.ndarray, statsdata_ ax2.legend(loc='lower left') # 波峰波谷位置,用红十字标记 - ptKarr = statsdata_ptam[f'sum_{srctype}_{mtype}{ptype}_k'] - ptFJarr = statsdata_ptam[f'sum_{srctype}_{mtype}{ptype}'] + ptKarr = statsdata_ptam[f'sum_{srctype}_{ptype}_k'] + ptFJarr = statsdata_ptam[f'sum_{srctype}_{ptype}'] # 数值积分,不乘系数dk - Parr1 = np.cumsum(FJarr1) * int_sgn - Parr2 = np.cumsum(FJarr2) * int_sgn + Parr1 = np.cumsum(FJarr1) + Parr2 = np.cumsum(FJarr2) Parr = np.hstack([Parr1, Parr2*dk2/dk1+Parr1[-1]]) if isinstance(RorI, int) and RorI==2: From 2230cdcdefe61abf358e9b5e3eeb53e581250a62 Mon Sep 17 00:00:00 2001 From: Dengda98 Date: Sat, 26 Apr 2025 20:39:50 +0800 Subject: [PATCH 05/25] DOC: update function calling in examples --- .../Advanced/integ_converg/integ_converg.rst | 12 +++--- docs/source/Advanced/integ_converg/run/run.py | 39 ++++++++---------- docs/source/Advanced/integ_converg/run/run.sh | 2 + docs/source/Advanced/kernel/run/run.py | 4 +- docs/source/Advanced/kernel/run/run.sh | 2 + docs/source/Tutorial/dynamic/run/run.sh | 3 ++ docs/source/Tutorial/dynamic/run_upar/run.sh | 1 + docs/source/Tutorial/static/run/run.sh | 2 + docs/source/Tutorial/static/run_upar/run.sh | 2 + example/kernel_freq_response/imag_G.png | Bin 63899 -> 63776 bytes example/kernel_freq_response/run.py | 2 +- example/view_integ_stats/view.py | 4 +- example/view_integ_stats/view_dynamic.py | 2 +- example/view_integ_stats/view_stats.png | Bin 94473 -> 94769 bytes 14 files changed, 41 insertions(+), 34 deletions(-) diff --git a/docs/source/Advanced/integ_converg/integ_converg.rst b/docs/source/Advanced/integ_converg/integ_converg.rst index 3b176d2d..a95e76d8 100644 --- a/docs/source/Advanced/integ_converg/integ_converg.rst +++ b/docs/source/Advanced/integ_converg/integ_converg.rst @@ -77,7 +77,7 @@ C和Python导出的核函数文件是一致的,底层调用的是相同的函 :start-after: BEGIN plot stats :end-before: END plot stats -.. image:: run/DC_20.png +.. image:: run/SS_0.png :align: center @@ -88,7 +88,7 @@ C和Python导出的核函数文件是一致的,底层调用的是相同的函 :start-after: BEGIN plot stats RI :end-before: END plot stats RI -.. image:: run/DC_20_RI.png +.. image:: run/SS_0_RI.png :align: center @@ -118,7 +118,7 @@ C和Python导出的核函数文件是一致的,底层调用的是相同的函 :end-before: END DEPSRC 0.0 DGRN -.. image:: run/DC_20_0.0_RI.png +.. image:: run/SS_0_0.0_RI.png :align: center 从图中可以清晰地看到,相比震源深度2km时,积分收敛速度明显变慢,积分值振荡,这要求增加波数积分上限,但这必然降低计算效率。 @@ -167,7 +167,7 @@ C和Python导出的核函数文件是一致的,底层调用的是相同的函 :start-after: BEGIN plot ptam :end-before: END plot ptam -.. image:: run/DC_20_0.0_ptam_RI.png +.. image:: run/SS_0_0.0_ptam_RI.png :align: center @@ -206,7 +206,7 @@ C和Python导出的核函数文件是一致的,底层调用的是相同的函 + **只使用离散波数积分** -.. image:: run/DC_20_0.1_static.png +.. image:: run/SS_0_0.1_static.png :align: center ---------------------------------- @@ -214,6 +214,6 @@ C和Python导出的核函数文件是一致的,底层调用的是相同的函 + **使用峰谷平均法** -.. image:: run/DC_20_0.1_ptam_static.png +.. image:: run/SS_0_0.1_ptam_static.png :align: center diff --git a/docs/source/Advanced/integ_converg/run/run.py b/docs/source/Advanced/integ_converg/run/run.py index b714dd66..22fbdff0 100644 --- a/docs/source/Advanced/integ_converg/run/run.py +++ b/docs/source/Advanced/integ_converg/run/run.py @@ -35,12 +35,11 @@ # BEGIN plot stats ir = 2 dist=distarr[ir] -srctype="DC" -mtype="2" +srctype="SS" ptype="0" -fig, ax = pygrt.utils.plot_statsdata(statsdata, dist=dist, srctype=srctype, mtype=mtype, ptype=ptype) +fig, ax = pygrt.utils.plot_statsdata(statsdata, dist=dist, srctype=srctype, ptype=ptype) fig.tight_layout() -fig.savefig(f"{srctype}_{mtype}{ptype}.png", dpi=100) +fig.savefig(f"{srctype}_{ptype}.png", dpi=100) # END plot stats # ------------------------------------------------------------------- @@ -48,12 +47,11 @@ # BEGIN plot stats RI ir = 2 dist=distarr[ir] -srctype="DC" -mtype="2" +srctype="SS" ptype="0" -fig, ax = pygrt.utils.plot_statsdata(statsdata, dist=dist, srctype=srctype, mtype=mtype, ptype=ptype, RorI=2) +fig, ax = pygrt.utils.plot_statsdata(statsdata, dist=dist, srctype=srctype, ptype=ptype, RorI=2) fig.tight_layout() -fig.savefig(f"{srctype}_{mtype}{ptype}_RI.png", dpi=100) +fig.savefig(f"{srctype}_{ptype}_RI.png", dpi=100) # END plot stats RI # ------------------------------------------------------------------- @@ -73,12 +71,11 @@ statsdata = pygrt.utils.read_statsfile(f"pygrtstats_{depsrc}_{deprcv}/K_0050_*") dist=10 -srctype="DC" -mtype="2" +srctype="SS" ptype="0" -fig, ax = pygrt.utils.plot_statsdata(statsdata, dist=dist, srctype=srctype, mtype=mtype, ptype=ptype, RorI=2) +fig, ax = pygrt.utils.plot_statsdata(statsdata, dist=dist, srctype=srctype, ptype=ptype, RorI=2) fig.tight_layout() -fig.savefig(f"{srctype}_{mtype}{ptype}_{depsrc}_RI.png", dpi=100) +fig.savefig(f"{srctype}_{ptype}_{depsrc}_RI.png", dpi=100) # END DEPSRC 0.0 DGRN # ------------------------------------------------------------------- @@ -88,12 +85,11 @@ ir = 2 statsdata1, statsdata2, ptamdata, dist = pygrt.utils.read_statsfile_ptam(f"pygrtstats_{depsrc}_{deprcv}/PTAM_{ir:04d}_*/PTAM_0050_*") -srctype="DC" -mtype="2" +srctype="SS" ptype="0" -fig, ax = pygrt.utils.plot_statsdata_ptam(statsdata1, statsdata2, ptamdata, dist=dist, srctype=srctype, mtype=mtype, ptype=ptype, RorI=2) +fig, ax = pygrt.utils.plot_statsdata_ptam(statsdata1, statsdata2, ptamdata, dist=dist, srctype=srctype, ptype=ptype, RorI=2) fig.tight_layout() -fig.savefig(f"{srctype}_{mtype}{ptype}_{depsrc}_ptam_RI.png", dpi=100) +fig.savefig(f"{srctype}_{ptype}_{depsrc}_ptam_RI.png", dpi=100) # END plot ptam # ------------------------------------------------------------------- @@ -117,18 +113,17 @@ ir = 0 statsdata1, statsdata2, ptamdata, dist = pygrt.utils.read_statsfile_ptam(f"static_pygrtstats_{depsrc}_{deprcv}/PTAM_{ir:04d}_*/PTAM") -srctype="DC" -mtype="2" +srctype="SS" ptype="0" # 只使用离散波数积分的积分变化 -fig, ax = pygrt.utils.plot_statsdata(statsdata1, dist=dist, srctype=srctype, mtype=mtype, ptype=ptype, RorI=True) +fig, ax = pygrt.utils.plot_statsdata(statsdata1, dist=dist, srctype=srctype, ptype=ptype, RorI=True) fig.tight_layout() -fig.savefig(f"{srctype}_{mtype}{ptype}_{depsrc}_static.png", dpi=100) +fig.savefig(f"{srctype}_{ptype}_{depsrc}_static.png", dpi=100) # 使用了峰谷平均法的积分变化 -fig, ax = pygrt.utils.plot_statsdata_ptam(statsdata1, statsdata2, ptamdata, dist=dist, srctype=srctype, mtype=mtype, ptype=ptype, RorI=True) +fig, ax = pygrt.utils.plot_statsdata_ptam(statsdata1, statsdata2, ptamdata, dist=dist, srctype=srctype, ptype=ptype, RorI=True) fig.tight_layout() -fig.savefig(f"{srctype}_{mtype}{ptype}_{depsrc}_ptam_static.png", dpi=100) +fig.savefig(f"{srctype}_{ptype}_{depsrc}_ptam_static.png", dpi=100) # END SGRN # ------------------------------------------------------------------- diff --git a/docs/source/Advanced/integ_converg/run/run.sh b/docs/source/Advanced/integ_converg/run/run.sh index adc3dd24..ed0af789 100755 --- a/docs/source/Advanced/integ_converg/run/run.sh +++ b/docs/source/Advanced/integ_converg/run/run.sh @@ -1,6 +1,8 @@ #!/bin/bash set -eu +rm -rf GRN* syn* stats* ptam* pygrtstats* static* *.png + # ------------------------------------------------------------------- # BEGIN DGRN # -S,,...表示输出对应频率点索引值的核函数文件 diff --git a/docs/source/Advanced/kernel/run/run.py b/docs/source/Advanced/kernel/run/run.py index eb40688e..bf53996d 100644 --- a/docs/source/Advanced/kernel/run/run.py +++ b/docs/source/Advanced/kernel/run/run.py @@ -42,7 +42,7 @@ def plot_kernel(kerDct:dict, RorI:bool, out:Union[str,None]=None): continue ktypes.append(key) - srctypes = ['EXP0', 'VF0', 'HF1', 'DC0', 'DC1', 'DC2'] + srctypes = ['EX', 'VF', 'HF', 'DD', 'DS', 'SS'] vels = kerDct['_vels'] freqs = kerDct['_freqs'] @@ -51,7 +51,7 @@ def plot_kernel(kerDct:dict, RorI:bool, out:Union[str,None]=None): gs = fig.add_gridspec(len(srctypes), 3) qwvLst = ['q', 'w', 'v'] for ik, key in enumerate(ktypes): - srctype = key.split("_")[0]+key.split("_")[1][1:] + srctype = key.split("_")[0] qwv = key.split("_")[1][0] ax = fig.add_subplot(gs[srctypes.index(srctype), qwvLst.index(qwv)]) diff --git a/docs/source/Advanced/kernel/run/run.sh b/docs/source/Advanced/kernel/run/run.sh index 4ec7393a..47135b76 100755 --- a/docs/source/Advanced/kernel/run/run.sh +++ b/docs/source/Advanced/kernel/run/run.sh @@ -1,5 +1,7 @@ #!/bin/bash +rm -rf GRN* syn* pygrtstats* *.png + # ----------------------------------------------------------------- # BEGIN GRN # -S-1 表示输出所有频率点的核函数 diff --git a/docs/source/Tutorial/dynamic/run/run.sh b/docs/source/Tutorial/dynamic/run/run.sh index 46b4e745..9d2a34f2 100755 --- a/docs/source/Tutorial/dynamic/run/run.sh +++ b/docs/source/Tutorial/dynamic/run/run.sh @@ -1,5 +1,8 @@ #!/bin/bash set -eu + +rm -rf GRN* syn* HFZ HFZ_head travt *.png + # ----------------------------------------------------------------------------------- # BEGIN GRN # 不同震源深度、接收点深度和震中距的格林函数会在 diff --git a/docs/source/Tutorial/dynamic/run_upar/run.sh b/docs/source/Tutorial/dynamic/run_upar/run.sh index fcdb5370..ad0551ab 100755 --- a/docs/source/Tutorial/dynamic/run_upar/run.sh +++ b/docs/source/Tutorial/dynamic/run_upar/run.sh @@ -1,6 +1,7 @@ #!/bin/bash set -eu +rm -rf GRN* syn* *.png # -------------------------------------------------------------------------------------- # BEGIN GRN diff --git a/docs/source/Tutorial/static/run/run.sh b/docs/source/Tutorial/static/run/run.sh index 87204404..cfc4a2fd 100755 --- a/docs/source/Tutorial/static/run/run.sh +++ b/docs/source/Tutorial/static/run/run.sh @@ -1,6 +1,8 @@ #!/bin/bash set -eu +rm -rf grn* syn* *.png + # --------------------------------------------------------------------------------- # BEGIN gmt function gmtplot_static(){ diff --git a/docs/source/Tutorial/static/run_upar/run.sh b/docs/source/Tutorial/static/run_upar/run.sh index 9b19899a..00d0176c 100755 --- a/docs/source/Tutorial/static/run_upar/run.sh +++ b/docs/source/Tutorial/static/run_upar/run.sh @@ -1,6 +1,8 @@ #!/bin/bash set -eu +rm -rf grn* syn* strain stress rotation *.png + depsrc=2 deprcv=0 diff --git a/example/kernel_freq_response/imag_G.png b/example/kernel_freq_response/imag_G.png index 676be3eedf508a334107b4ae07066d8ebddfbd50..f85f067160586518363f481ceb7f1fae9d331dc6 100644 GIT binary patch delta 61654 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 A5dZ)H diff --git a/example/kernel_freq_response/run.py b/example/kernel_freq_response/run.py index e1b988f7..3ff3362b 100644 --- a/example/kernel_freq_response/run.py +++ b/example/kernel_freq_response/run.py @@ -16,7 +16,7 @@ kerDct = pygrt.utils.read_kernels_freqs("pygrtstats", vels) -Type = "HF_v1" +Type = "HF_v" vels = kerDct['_vels'] freqs = kerDct['_freqs'] data = kerDct[Type].copy() diff --git a/example/view_integ_stats/view.py b/example/view_integ_stats/view.py index 01269c03..c25a5fb8 100644 --- a/example/view_integ_stats/view.py +++ b/example/view_integ_stats/view.py @@ -6,11 +6,11 @@ data = pygrt.utils.read_statsfile("stgrtstats/halfspace2_0.1_0/K") dist = 3 -fig, ax = pygrt.utils.plot_statsdata(data, dist, "DC", "2", "2") +fig, ax = pygrt.utils.plot_statsdata(data, dist, "SS", "2") data1, data2, ptamdata, dist = pygrt.utils.read_statsfile_ptam("stgrtstats/halfspace2_0.1_0/PTAM_0090_*/PTAM") -fig, ax = pygrt.utils.plot_statsdata_ptam(data1, data2, ptamdata, dist, "DC", "2", "2") +fig, ax = pygrt.utils.plot_statsdata_ptam(data1, data2, ptamdata, dist, "SS", "2") # fig.tight_layout() # fig.savefig("view_stats.png", dpi=100, bbox_inches='tight') # plt.show() diff --git a/example/view_integ_stats/view_dynamic.py b/example/view_integ_stats/view_dynamic.py index e5877cb1..c655a668 100644 --- a/example/view_integ_stats/view_dynamic.py +++ b/example/view_integ_stats/view_dynamic.py @@ -4,7 +4,7 @@ data1, data2, ptamdata, dist = pygrt.utils.read_statsfile_ptam("GRN_grtstats/halfspace2_0.01_0/PTAM_0000_1.00000e+00/PTAM_0142_*") -fig, ax = pygrt.utils.plot_statsdata_ptam(data1, data2, ptamdata, dist, "DC", "2", "2") +fig, ax = pygrt.utils.plot_statsdata_ptam(data1, data2, ptamdata, dist, "SS", "2") # fig.tight_layout() # fig.savefig("view_stats.png", dpi=100, bbox_inches='tight') # plt.show() diff --git a/example/view_integ_stats/view_stats.png b/example/view_integ_stats/view_stats.png index a6cc0d6c7c94201fd3cf536ecd6828f7928138e7..f8b4c5432b652f74817d8792fc16545bee8d1bd0 100644 GIT binary patch delta 87440 zcmb@ucRZGT_&uIHCpp6$pdR1pwSeByeH`^hG`75hTkRSvvzu7OU}8h-03`DV@IVHsEz3 z_3e`we-##p9uuZS@G}e!=QUh6+5}ZC>le0+KRqV0u(Xs@ z%?%DdS#KB{Y=N<~u&8}@{*K*JQD0#3;gT&Z|^wq1d$w^~fr(QLqz7WT<8_BgF zN=8HRPS9*_>771{U5kG7y8Bdwpxv+OI4Q0;9L#Iv$gOhq(+St(!yO}mSNTTu__~jf z=JUyiCVJj*@W}|lQJSadIo2d@M@k<3Ew?HHagA_-uRsKFsBS3V<_-y?MJlYWJ%58<@+C3 zOR_%bl-!_}31^k4?%4Nkxm;4a;Z%9^x1zic#wo{F0XJyn0D+f~eX+05&DM%zltZ3kEc91IONqEC|B7q*a7 zk<+yG(9#lvp<tJwspFc%?IEFGKcel2 ztV@zhOX*5RoEe90N`ACBI5>3m_MUQP6cv~L#x8v}g`{*MknwY6rD)g6j_io}3S3=I7@ZE8h1Mx1Z}yOSzd!Ip(=> zw>i$hdBAisMJDXi_Vn7BljW(qiSaoU~W_lCw!)jvk$uJD;|WPQAC^xps{Y z+IW~3S4`zT3m}%3mN)96`xY98%N*=y5?zcZJ_Wc!JV~XFPq~fz5{x@ntj(rI-K?y9 z^9EyTYP!2zvEr^PVEUEXbAPFXGIwUp)qS|cLZXRWLHK!>#p7N}(!&)yq1CS!bFU{W zy(uWTTIjVl+3=;gxsFtD7=tN=9kA9WIEKNnAP4r@h+YK^OB8{6)~Vyev18I#ZGkP^ zHM-r?ckkY{c=)isnLUZAyz0ms!syr#y&IeT?WI*$QO!aN%FxizPu_k5wTU7w*qA^P z`tGScQc_a%Q?Ng~Mn@yH3d|;!O2!(y)9#?ba(lTcSt@9C@L{e|d%`siF0ROO0~tgH z&+_3z4=Yw-M~-6KF_tyqG4FlrsC}BH^qd^7d27aqn?g*HO4s+l>)1*rD~%s)bdcj^ zdDpO_57wsom)VaWKQI{Y_2{JWdUA=!9Wzq0vII7z6ZkLW*}|EworGZ0ta9gvYsH*i zo?fZkAVc4KJxwKGuXikpoD$h$4V8EC304rTQ=ZPPITHTb(o)aG2oKArc1|zg2BpBQ z+1-T`em<%S*YG%Fi68dmG^|e4Q_VL`HiS*Axvusk9q|>mEjicEY)EGH1{Pn4m4gdr z=@X2Xw-aK@8(Qj|b2N&(`;w0cf;0MCRCjlGMjU;_&EOP5SnOeBSXcD;V54-Yc*t(N z)>kR7+;L8YNyrXUGUn|u>pnd_T{@c*wh9m3xXurcmwhYBsSJVz9@6ks_2$l$l=LA1 zq^fy`SAw>Ia%rEo`V7be&aRatkKfuTbC{WgbkYdP(~ysW%4ViVQ9?#pnev@NBEz8b z;Z|S0aXvD>(IG)@{qW&KDM?AmsD-eRb8Y8(M_$Um%h*Z?Aspq->J4psC724?h7~#B zMPsJ0un>dM_gs@na2a(=zAiEQYbHtY*Y+u5nc21H?HF=An56|+h8Ft01WZXPZ@s)eh9L`_YNhmK@+aZ%dK zOY8{J??k)Eiu^9`Eg3`tauI?iK=BgOmgg+z8lq@hPu_ellbxAa_oF#_4S{!FPwg6q z?ee&1PCkR2CJav@{puq1!Oj>Gbxt<&u_;y@w*gsFM^OA#^KFaN;$j+;#_*8-qxWiA zO6uxtb2FXEQp)@Ei!G21R_h2@4VQ<@Fcie<25!@*Vq#*(Kelk)nLSE>U&Hzz3-dld zpR%p3&ECIv4(Un9!9ZDv3ZY^TM6=#ve?AVafhR9SEPAx@)~g+#VG~7a7NOnsnnIIxb~N77}xpCbRN%L zJM>XuuGmWEgM&6( z?{hRXG@MC^ zh?Pt0@9gZ%@(K=Y3JTuCMuS=v>MsRW@KA|uRK*Ge@8$U|_b!`~pyH~XQIE42`=MfM zqy16)Cgv2COzN70^*hjTbQ$LdV?IC3trD=@*D1E5OqY*8`@YxG{%g#I$(Q^OKex9l ztU(f?`uEcSy~y*aQc z&^y|hUuyaUd(KOeLWV0rUV0!C;#4Y#ticcOgx$i25;n(?^LL()KfA+K2c@Z}TD+=d z`i7GezxPhX*hEgnvfRU=Ln6pJTXUY9#9PK#BnvW#$Qdo$LVpn&0#Nkb0DfI0~xpf>MeTn5GRTX+7x9q zHNI1!L&oT*SHIQN8O|0Ms-^cp5GLd)mRdEL#2mVY?-8)1FE*KclUNmEKA(0!8YeqA zx?PwS>7_0c65moqR#;P{EM-BpsWww5DlVeOIIRBa2jm3XG3; z1epSRrds|U<#CK(FZ2+!8$a9XrO3q|BN2>(#@%mkzu&vhceXuk@&txU&)js)RCr#6UP1 z_k{RZh||7~9ikGO-)EaNDRM-oygk7?&+3}+ku^&BxOOV0--}jSnL4`c>E53Ey?gfz zd*7?Q5chJo*!S8Q3F59fI0@x9!tKy$;k(gb;RDSI=gSIWTi-gjA-fR>Cz448lGIgu z?b|_bE0x=4vNhlPq-9!c&~0}jXzk0nsLlQ(w2MH}d(J!bsccJrAfX|*+qlJb5*FGf+;oZ3_T=4R}hQ1pfbi{-w?qQ8X<3f5UX7mYHK0$~QR;m7L>_z*d zUo$%v=0^v=UI^Oi&msi_;qTvbwkBM=x}2y;5Y^-lMQ6hA1ecFWCN3uYVaZg=Of}LF zbG1VzQ?h5l>rMYz=5t@Ues3$)?Wx~u5&4=Z?(CdlQC=R!qcWzucPFw0pkyW&7V`ac zvKC+*b(>)p-J4Cdw>6*bOy;GNon$2t5g%OVELqVgu^G?jsLMIRGeTi4qx?etoY zUB0u{RTbRa(PHH&uJ%??nsi0}b7LlaX}a)qKXDUtF;*@hQ#IZA*ZOp_HFQ@kaopq= zPXzxs+!+gMnf`>f?K{q7tm5It#R4(0vFC?+!(TWwQdAZdNA_sKcB4!?oi>1hoEH?Q z?@omFQO=9~zC*S(%mS}S9e%cAVTK)h?i%6b`RThM)2DRp8%~Mg-_`n{KJ2klrCDG` zO2#DQ12e$XdJA_G^jEwOzh~boADmHORrg8J0Ic|)^}**w|MZN&YxU7 zxUuo3{A*GAB(H6HXxA|qCnu*T&7Yql3SdlB7g+zpf+Ly(lZ@X6!!=EFXiH*iK|NaoKm*$Vm5;S*kl*h#Bq|Fv`Uds`2 zqR{_khWyDu-?(`Z%_Y;41pSEI?LuSQg7bg2-@FT5_V&k<{`ea5Tuo!u#?GI!zD_=FTTORxFmJ8 zDfY&PCllwm>g3?He~94C|HKiM9u6DrCdGP8Y{=?2grPSYX`DCM1WRyIp@jT+bnwZa zlbVXbCCaBgnTVSqtKT>tI3ZDxg`Sj`SF;WAVNKEv5O~Gd;v!)F=UTKP>MZdsVjdk# zE+)GkNqC$NZOuWSfK0t1zf?|=0HM>8vu9O0|DUz`s!gJPRXSZ|+}xbB0S^B6Moll{ zXVGs)&-v#UbcL&V#Os}hG#UCBj!e%dcW|(nyu0ynBwO!1g1+oiXBjy1sFC7Z@!;z8 z@^g8Y0Cc?O%KgzxY*_Ho6O#{p&2Bm)Z=Te!|_dIWyz7<+uH<#J6s5m?`;TKh!V!uNxNG}k$1HIM-q+X^5`t@v4_7jBbDN;mdLgH=Pbx{l zbDYAvJEXDSW$9#EE`r7mecG+7ORIJ&r|FavOW=-+Ny^Nu0SSU6K3{*_%r@X??-#3XS$!ze&{j-k-2s@Z>8ykIf3` z)etqc7uOuvNbse;dPO!(tr|tIp22PL27zoB*VTh4w)CPAs=Kx<=j6y) zQjdI_F6^(-ZIO#A$aXxw^VBg*QTP;EmaI4S4>hYj-88rPXkaQsPhu#1{|iOT z^XGv@4*=J5Uea#1Ci|xWpY-QzLF_2ckIdp+_2^b+e-mSd^Fk1@Wzlz^JC7Cvh*JWa znnUM)D*NfPbsEw^x!)gn`_}(Q&+Z$VSS<gsizad%Ng{yeDiTF&c6q<&0C04*D8Q?2ZZeUx+1>xD8TmIATF|NqnKgV#x2Z ztlOF>A~^Uu3_^_xBmMIl7>!e~-k!*W1`J6RR&lB_K#*6kqv= z;YGMzVO}U8vPWZhsd=e&;ph3E(%w1^FEdy`i96>ejGSLi62p%=ddPUGoysLd0R4nL ze8LxSd{V zb)Wp<_{>*z^m2XR^>lBqQ9{0WJ=ceNfBXJ#58>3R+ObT?!2~WM`fDZ8V)oJfKWU}P zug+4!x&6!8Rwj+mI6^ju*XhiQ_AcvNfg^TW64~$5 zFkEu=7)kzHvrOULFGLehD(Z<59Usm)Gg%bMtW!pVWXb(lhgBI>Q;WVM^`umXnA*+Tv z1}o_4(et1DWVnUsy)6^@qJM%s(E4j;p$9j-2Tc?C;z8b{=Q7j4YKKOyOm)dkxGW_TSt|Z}p z8DO2NOKe!BTdikaC_N1-v$g$kkcFV}!~K>zyBbDsXxmv>+-J{N4VO|zv)%oatyR!D zJj`T&9D7k?vV0+@9wu^h1Og=A=x1v@3K{f!!>o7acd@jE+`&2W*2eGjcqXgjje>yy zc8Q_*KP%P{tCF_|@c9(%==y|f4m{3_nwPW-35AhFvM^fi$kJnIPeVkOOL3yv6&rzN zScBfTer3l5dT^ut%w9`0p?S-*slo|NW_yV%9ebKxcPgZIEqb2rYM>kH>uH&f8jcks z{dq<>KRc3G2ic;Vc}yBfvh}O9RT!Nsm|+I{_3M|>kVcMf2#_VPJ}3@^X09V2KR>@< z>r%A-<@_!SnDI4N_&HgnLv&*Fropg!`Mn>RtF2M&lNu{ljfTwgdRzjHJchWvf5;FK5Ne!SY++RDhts0Cz<$7^r1a~p*=47`7x|DL1ASQ3HWY7%mE z4Jo!B!jHI#gK-78`%TXr4bgc_<{$E3Sn3HoM%*@_h?!!0Xh05HW)8~h{NbYyEkSf5M*gIHS)_5g}95Y=($SA zu{mN7FHTn6qPFjY{cDuPm^&(Z%Cez0fhk3THI)kQzqJFY=AY7T32R=ybm_4!m#nI) zYXA1TcWm$=8!MMp6~zMBU%O%(Af9V@(DTqai~$^;0%IPO%Luw`0I4#1=UIkgr zvG(@1yQe$)J1*-!qLn#{g#FZaWnJyA|I^WF<# zC(HivjB&$ElNRjA62m%d(d~Yd-Nk|qyY*)FrmDpHAcQ>i!v|8J5}KW3jXN``U4Q+I z&Mz)z?(oiM{{tTpM|Zo8xo!NMNQ=||1T%3YvxxKf_K@f0N0R7)$lsvY!k9GLNI}EtEnw#n<5-;`=1$&!5Nml$Q&C zxi3340b39YdO;06CpAqGaBmV=;y3P@~hq6q;1|ktS$x z=}&{7I8K+XLS7?|2ywmE3}n>T4>K!3uKr%-6e>D@wRxbQMD5lz6I2qT;Dcm|&MxmN zAf~0+Iq4;w$B|eUp+Ie2fKO>eY9qcHGYQyHil0B^UNwX}NT~*% z^`BvdO(`y%K*Hpjf!SJQb3iQ>p>5NmZ*6kN4>U_|FbPwNOO)gj=t#(pJ!B?Kb zuD<2rwGXGzV{_tX#pD^*YA0khMj7ZvG;(n+UEyMgFi5yc-FIY7 zdQ?zw;m>_yJ+9+SYk=W6klmXP%VBJfCD%*m)$iQfg-QP6NMJEudf)ik*9h%{gOvs4 zAt3#xPM%8g{#WNLQD;~REVX3xa^4?fx6W#4n7ZR(M zcR{D|k7!6a#3|;~rq_s{fRj$F&(t)u-*osBH(H@}oTi_VH`vTaYb|pxc#G*YE*;Qx z9GjC@qQk!oT!0qaw4oDFkQq5Sfj3j@3Lo_3*^HFG*snQ0+D9o&J_b@Y`4>KbazEDN z3O&o>xhe^G5HMfHjp6kD1?GzHN8Vm~8`EO9lHKLHGt;xy_0C=QmqgYJQ#8_eF5qRY zAl3U^C{h%};!cQm*TC`cJp6u%Pf$>H7y-nubh&&11=A<@S8AG0Y3TZ1%qhjzDX}44 zDnQd25DF;!2sI@vA%Us&CI1NpcG)N7_oCm2@BYv*pUkEVC^eoa*4>E8UES%-UWCkV_m;V3c%p!Tv7TQa%lh}dCiVtU}~*)YOai{s%c76RTZIPA`99SVf5z+<+yxV2Jp^Y zyhj5!vU*d1!j?<>*k@y6^?*!#cbf0O>n^kR_MS_rp**j*$HXn_`QFRTS2=wzduc2KM&t+x^?mo}FAAF1tGE#K6dSZh5S~pRQcA^zxv1lLvCJ*7OIC zt%ezE*0G#r=#HG+o4$poNlD}ZekWXSPXo;Z{PAU-;y0O@J2ST~?-KLO{{=r)_%U_AWa#|L&`N3%x`3t++sv-MfB&Ax;io(u zNnoCr9v4D8KR?f7(fKCW*XoM2^5X_$NgJDGpN?z>68vwyy+#MSYf4$s9gb|1?ihom z2Mq}KK)}j}v&*mePtHVe%FX6)|3`D+r{6}by8hpp4lyb&8NdXLjL!UcFM^%+d z?#`Wa`spZwdsH`e7rA?vog%YH8I}(kDIN7 z(>nzC*hGF$iUkVP^32qdl{V+X77p@Fg*@&NjcREG?MnZ{dLTHuae2* zG=J}sK{biQUypuIjZW_rlOj=I76woBAj=WDNRt$wTG&PB9Yq2lD^ zTm_s32LrhU;Yx65zqY%PbQ~VWT}_8-0#E|B2Bbw8?1AQghkG95&x9oOS8&k=2Znno zEZ(ixK=t4yCMG6h*$#YpqilR6V`A5{X?aOEpSB=rpMh49qh4<&>bjGW!n+E%Nv&Jd zGNqN?LSo`VqT)iszGDhe}h{x)>;q|%oK!SK#?u~kCVh)rIuKueVI{-U1Z$d z_we!RVR>%W6Cy2x#uqAi?rr>iZ_?86$i;V0!~WxSTfdK@1<6<{0FNU^>5YnjMOAKn z*V#Q>L82hfvVxST7R_aAQ%ynJWh>SDh6MwwutZF7yF#FOLXir|)Gid>SOG;-9dw0c zr|pERKYlz3JS9Ji*Jc;hdVVI4EHb%=*eGn{-YT5Ab#y|Utd zu5Q`KrsAyJY6iGMr*GTPNu)-Jhsq+XUVObdq(bNvhtk=uqAXVZd02vDo>$>55I^yA zIi~Vz)nq4fUOpCSXO5gH_y4{jOFM-^>$m;o;jf8=p zuL(C%yVt&NZgi(#fRFgv{f~?7|EQFDOEA`kNPkcd!cPX$)(C3r?`q_^etY-OTNKn+ zyF+6~fspx8jSCu~Ipy=57~eWmiQ``#Ye~lk1Q8JtbbJ;R%cWCf!%lsA@s)QTsOr7& zPe()%`eWOl9G8yX(Fj&o(oAu#uZ9%_O|~YJXot*x{;?63S5}oLT$NW|nI}}0SB8z~ zB4z^C-|DiRmOUS&kmjRsSvFD*D^ZSRSNY|! z7{;Q`%<`SNQ4PikBvFpclyifs+ou80oWXL$>7x1v?SMLe0vy6tLFg>@YtVvzGn~#h zw|b9QaMbl2h#&0Qug%l~vkd{ZQgbX$OiY|-*~|GG{{qO{8_0O`-O;y-KoJvg(T5o% z31Zvkhy;&$Df#ObF-31;w>!Ej)%IML{zeWN@R9;~D;amILPyv2?rDSwFTQvRyWQ~3 zKtEd(VtaV<`?8hU6a5c9`X8=GYLivn3>jWN-g;TP;>UCfpLRBKAXj8|@yN@{C-Yg$ z$LjW{_+Nfc`>sF{ zPCP1GZIU>mGyv6%1!5KegWn`dPC@<&hFnAdG{4o_<1^h_Zia-lbZ+~Bw~vNh2My)3`OM100P%A3^wvz!f5H4(DUbd@gw6;5 zh}^0~sJ;YGBKpS_Ec^)UG6qwQyw;_o#8k2ay$lT`2wNfIM(uVRqy4B>v|;zdCsZV& zYQ(Si-g$@BabmJs!idPZmo|nzxVf@D;_trdC9zva4oC`jty#fDy!mTi&{{@$Z=OT3 zYycT(b?qekk6;#KPjpn7JqEtq82IOmtStZf37?^*NMU5@db0W#`(HmEaV!WL&Bh=- zYwdgIN|$XP@&F^1^-g`V`}Xvg4rSBwSJE-2ep~U0WP-v=ERKU>v-3w47v(zLtl0Qo zblv-k_v1k8afOHu+9#Z)SV z1LF$rl>~nB4*B_V?;43hKea3Iy@)hu#te5?Conz@VYDW|#Jf(%YTPKe;0Zk<;1`4y z3U+mmQA!zFP4Xi^Tut^i=f1SHH6$HvvI89=kSxAwo_fb&ZA?R<_F%wdb?u$|!Nz|5 zZhiWY{c?u!frT8NH%~d8Wq@eU$UiB3>-#dAy84a-VzM}jvZu$9#gD9q$Nh$dJrj~~ zBRC};yvqDyfujeCHVS5Sqn+gurL109_j**6V}A_T6is@Pw=iUY$j)M~{p~F^ zmx56J54Ffv5B|j71An``wm`%i!9{dGQq>&RFtjpg_=PpbO@vPbC|%H;RgAeT%}e3v z+&?^<=TVNZGU}E`5eef+BsvS0GqLQ-Tt7o)_zllbK2-tFglG2K1!dE2qZyD z@IsLt630v^n-5x5UnoW>v){Zq@+G4V?^>xx$*BSNd}h1zr-hBbrZY~P0IhH&2V zrFNbdfbzzTct)?0;z%h&DNw>qZC4!RP2kt*T)~)FwlIT89m0NTarZgo7r1u5HIv@l2FnE0X{yhbPBTC{(XnSRh zJhdzMg6g~Rqx}^E3@WFpMfGB+iWjgz6gOmc8TLhv_s8g~X$N4)muF6h%Jkn@t37Xm z6QU+E6gCXEB@8w zx)xz8U)9A&@t9}@qG*Lv#Md_*?(xjsqtkwY6Ri+%kZ^rGK8dQIU9iqKQ~KL6Q3~CI z*#4syD}i&|+~j{W4MuU-5*5CEN4^_>d2;4~&Q>$zE-Qh0L!QkC^w-%o8>jkcBXg*) zh)iG+q;MD;gq^zRQe-%tLzA6lEgP@w?;uMvvG`O*s7#pEO`FX4mKtYMaCgh}7T(AB zkvdbJtN|N`)VBH0+f@X~yfi62%cOW|T)C`Quz2P_;j|l4yi7_Z!F&B~xdmBw;{0JL zbVF=pR~r?77&kp^GBJzg0BVz`Qi!%b%wesdAn?=Ab>ppSf$ZUta0$u3lz7Gu+(=gs^Yd^`4LIA`1R`%5u2Hn|cpZQ;8nE~$s5m~RWT$J`6PE{9Hz;!-3Pa0ZU(sX zn?+n~$hJ?zU^|F@M~VmXekrkAMmkPJw{5x3JDeD_vLS)%zW0FZX53F>*L;>Cx@g>~Mii53CF+{5!|7DUSTjkq>oyUGHot3Yh zJ9v=_qXqpBw{q1T6=SJ0rb)p+j5 zNs`0(vIlB?I8g{nQo6@_6Fo`3uIEZT_#Ln$-L_)kjktN&qWM}2x=}K=b zu3T=rcy_z8o~fYvses;T|B>l{HfBQUB^&N+F75;tWY)f$!?ZK&RA(mk4!0GN{0Hnb zH|_9CL}O;198wD<3;e`6nm}yHC}bF_aUpT_7JMmXW%L*T|5d~ff9~v0I9E(K3KJ}f zW~Fd^vMEW0UxM)e(KSUWb3b{uH~nuU^CfYl3C;Zd(hG*Hebd z5F{%S8DA!&^RG+onL2^@)Yq_!m00*Ng|LRMl(dF$SBA2QeHiadUSXO%#pyUAM~q2J^Y!Jf^Wj&6i=ME%p4CgXTYfdQi_ZOk!-L4LlljX9rCx#( zb{4AIuckLta{W`O?kk%8d=329rv$sY_ooQ~29N>`uPBS+*CjVm7SF9-4Wa$T0)ow; zY?aLWH)GG9#Kn4qg~8vB;|I1UoQg}6^jXXF1ET65kFHhfbMrB@`H-mtITn1y$dE=0 z1s}V7P~!`V1k(I9+GykCnDGnQR}EM#M-OedislU=OFXaIvbEY&{-?0Br%UMWS3fBb zixz2K!uY&@U;UyG<>Z2&ndWOgiHoCkV3lMtd}y(E=>4s)@0_4uiQ-Q&{#R`o@85rd zj@FQe&i#MWi>jVZwanL40(8nnISngL%ObYMD889rm7jIMM{5#7JK*Swc!i?kz9+|aT}xJNIU!!`V0<>0@143g46pW?IQDTv0x zI)l9Q`#%(%S4PsP24N-)xWipV4GMd3cd!C`&_DgZNowxDD`3xPVnvwJ6CM#ia&S=A z)eT1hNz~>s)HLTf2?BCyNl7eVuDmx>S(7s}FGz`ruc1bx7ee;Nh{ebCxt{c?vEw6` z*+(o%iyNP*6u}uZ3~HQYYf**xoz;4BDT>E=N#NND;+o-o7FlQcY}9KnJW7F=~r=SU%I+UyY6ma64e)aza6HPCO@^GKrLx5ELZ7TsL1|1uOC#EfbH(W`;-j~qF9esgXkBxLegOFQWRaoMS)0g=uA~^ zwAW9^8AMtS6=RLBH4BV+?J%Pa9cUqWtwf?!o#_N^n0|Ajs9k6F3QH<(a7>J+ z9~F^025EbKWu>ksfPYu}FA`&)J_2-sd#%j(M>RwuV&>-N_Cmm#AxaA$fD6yidD>s$!fkMe$T;sM?*FNIZGxwFwf}0U88pa% zjgyL)fnW+W$J4wEQqU3uuCzNNaU60CGa(?LxB915(-i_#GD$=fARXM$(_@ZO#s78a z4YWE-(j`CwpCG~w^EFpNIc)^G?_KatKzvKv*w|#Wi*T^B6X40eqp9Fsq_wr!T#ezifI%#2X%xB2m{Do2V6BH|eZgt(i z5+a^k_A;g zUnq$Vh8dU^+!|i)ucW0zP*+{d8B{b0gDE?4%5C^;vW$FO|MU8+HAQ%XQOnf0d z!4GnkCz!>AmI`~`^dNI~Xjp@-&`|`v)bAg3JPvr2&Ziu~C`GBvPz9heO5m;jd}TWs z$Y>K>J_f}z9Ido|r!j=MvC!9n+${s_SLm@rLy5CB^Rd&?(*F2U18DVYA<4*QYZnoN z1+jFkk#P+Q<~W2v6RN~vD24##ZC}NeBlrR|dQ>(xp7=oh+6quOb zZa-L&XZxa{r?GefF5lu0kk}w4 zf?fMTrMa|pe8UyY*%UtdYmfd>&(`!sLmVlnTRJRD>VrIv2f-79xg5mXAF!Sbt&Fhnr$ z69dSNtO9H_b$nQJ+&8tZDE> zU}ZFce;S$Mz;%$dyvHxe$Mp%uXOIln&;|PYfy01l+yrX5gZ3;Am9lUBc3o{HqgwgcfL8+S^w=vtYX&UHkDt9Nt#JKk1$pWP~iX3|(%}X*BNtvTfnuo1F zrevjYg3k6ZpFTT(85RN`gR<&8@$z6)1%(tQ&vnh%wMt(XQkqzf0T7tQwg%n*X$YUv zsM$M(D>>Vh3+iS$8}7kF`7Lp|Ide7^iL(qs(5-j*6hX}Y0J$|(Oe4u}`9QNEYP#Uy z?zG?& z3ZQK)RJHv({XvR&13p3sf`%n?VYpS{eAL5_)%-vF-OyoUP~#HD2k=2@E6@kCIT8;o zAX{krPzt?pzTLzPQ5f@{`8N=-xMBb~j}qUr_}p@Wm>A^JfdF^rG?_vtQwMD@B^B&i!Z4KqwWXce$ss_*aZ4S*)m2nY(X!P(haABFT2rbh712I%A9ya2}m zkxnCYO#a|$MdwL0k=E}qE}@|d=ahsNI*^Q+VXOM)y!m@1ij|TQ1qbjmAcQvQLcA-- zFD%_EN&$1(3sJW#=$rs%6J59ISUcfFqOCgP{MtFkz`G-xKrl>wd3w%Bs}XbnU~@-x zuwsK5A3ij|$n>kI4=#J+WC7eA#}*CrUmo&|8Ws- zfV%|6PZO!SfBM(HTm#nP5jb*FB=ZX%BkaH4XG63&fd7$dK1llmJ_ay{pkguDIN&|J z35NCA;@9r;7oc@TJ2A0A)X{=&R*diB^wV>)#^1A+2MP$5mX?g-hi>htBJ*CGzdZY^ zy*!2uxB9)`Ex_Z!MgtQ=ty{*apC=4ajm}mmMc2O#;~IMRexJY;H;FbS=)eR4A#PP`pa7aG-8S;>H=jhG0!rVlf${Yc4d(%A;`#r} z0*(CNJ<$Kd0xexL#vPi%f!f=^V?EUvA-3&QF*4aeYj8;)_7Hqs%AZRegWfN7v}tPp zLXq{^vlnoc7g;{tmUhGjbyYxG z6dq<2u)cjHK{dxtsa(zrg*>JKzJwzW6fY=fgE})H5q?rn5q4cY{YP#7={fh|PR(&d zLA&rpDnOOxK+_M!e-V1zMgmq(pR4UcIM9OJA6EVa#({so;zm0g`fw1vWjCOZ9H4$5 z)i-4d_AdbQ1@_h-KYxOU_>bs4IPzTR*-JDhKxT3#x}iOhtkkdwI!IvtjZS=I!vsB#T=^sh`*A{?%pwHSG8dSlv`p z<5J_W2{VOH*Qp-k`zLq!sU<29_}AHe5})|U9Hso%eEJtobBu}JyLA@XHJmak)YScB zl2)#%H7p`OTmn*TXVmP{-Xnv59gV16@Qx*e-C?1mD{^?|w;B<}4LKITjB!qnj2xvJ z`eq`02n}ruz{7`*RA1duSK=Pd67UR?4_@P^%00@jXnr=wMY*NJYAx)i7vV{YfQ5w+ zj2ll!?y84hIB`h@=n&cpy6kSE+PO7Im4zkyaopSE$5k~%;)wguYw#W%nAA@c7T=bZ z&NRv!l-(}UlOA2R6puRQEhB76?)4vT*)1xjxz0gO5yg-06wa8v&*yqg$8c z;#Wy2jlI_^B8->mVsh&h6|x##2nOL|F_oKJ-oyJxW~Eg}g~fNI9nYfY8ML-}k*H6y z)SmsEfzQt45Ln!9XGX-p3nRkNy1Q~-r29LYGN&`Ywvyfx{}YYR4Q=o2nbq`<+^_rc zOgHA|gDxw?zHaJ{BBr#W*$;$f9DNUct2EH;3N@`1I3h6&GZPfBtR z5%LmWYRQuLzWSXAMu5Ex+O z797kqICgt#mo`!_-}Qg)EQo(4i@1!Wp^Sm=ZDvQ^5zUW`H_uwSpX-fuS=7xUDmd@g zogN(e5o27c3W#d-a;9aw@z#j|*Uf0_2M+~bVD)lL!xE*Xy&hcLd{f;L^7MQe#^)nn;>Vp|GK&w$ z?)#Zu!Af&`S=fuLSn!z0BU)UX;l3XO9D6@#>*+(hP7HZ{c+k;*lG2n4?6u>!%pbQ} zzNU$I@bx2zlZ~bGS^Q3;p*O@xm;KC9gt3)_-vZUAS>5TOWzOx05^GZr=M)pjkU#u2 z+CMEFDHnObr1oZ{aUvFZBS@?ykZx9X*(z4TUniJlITl>?? zxbrW+<~^C4EBxfSKuGXMN^k_*y{-2pR&~t-+4s$YYhp#t9xp%8=`#@$zdzxi)Mul3 zr^3;=zss<({}B%7U2Wj8Chpezqy;WJznb=Q?Brff`;;1Tx3pfclc|z zZqb%A%`svimlMOvz}or}r?Oe;`0592^YyMWFXx#kxhR32`q3Vz+?PoF6OA#`DSV1J zH5@4yNO7J6|M_Dkd;kW0`{Ucxcm>H4mcj?;|^~*OU6g$G*X?JpRPyF}Z%4JuFbIV@HRf2~nQCsgI!OK>z7`jjXy|BoG z_z8URi5zXJIGC>+d=HxWx*D%6)UQ(Nfkc{~L zb)=^=hre>X{}Bh`l#1vXv3j9PD@OHj!O_+-JR2U-v^7T5shc^l?1*Q z=AN*EYKhhe$Cqn+3EYaRt9?ce^^Wq0lGe+2zM)IStLuL2eE$z&e;rok7yXN(i|&w8 z8YQH=LsGht?(P;uYLOz1bV!55BBi@QN^(gnDUE=1c_!cA-skN5+~?l&FQCsG^PO{y z@hNK^!%7z-ilr)zq*M=dz#$bICy8O12nDxLCQ0~h{Yy`3pYb!JygpZ(82NpVMj4r5 zAPpZ~bYj1HeTJ@s8qkP|B(WwDdbuL0x zE2~~G@rzl*YV*uFn>{-7QXJMploS?H(S`pXeUm)EMF}6sSfnZBhhc>e)n`?42iYjC zI>pi;#~BtYMD!i*j#PMCSXfh`ZtYK+d4IX1@~SXxuci7E@Q%^>@X1sputVW+tZh~= z(uH2myUa2n&}_q&Ny=k_*qx6(e%ID6u`f(SebN z4~dGis2EVFN`E-ITCEn;MM98osruUYTQ)F``>e}|p*v5zfM=jMS|o1YHAe>{#pr{M zqeJzCJYVB^c3d(VdjnVmvk_=LyR1m*>QHkT_bM{Q7FIS>69_nR&9CEZM9)t64^%Cg zu%6)fW9#_o*9}BkNKcq)Go?LOgUJ|1QGbZFd8ruZ*ri^rdM%y$bz-npRhiVPf1Vo& zoW?VWC%~klHzY?fiQU;6GGwE(#f|XZz97iwzX{JKLZH|i38|^K%c`jGNAtkC6hOmIh*7^;Au_8h)~kd!fh{0LnAjzqA02w* zuWPVKS3n4q`zAju-17x>2~WO;@M3>;s6C@-*G?!@6+-`VPzN{=s$^DD#R^!Jig98p zKa!W6>RNlbVLdamWw?{kL~o#EUggO=dBOUq$>vKjkFPo&ODDK{Azszbp}NpJi-py0 z0?r7yZIh`MD({!vNl!47z_-jfx0jDA5_RUV>3|r2lIKr}Tg+6~T3dyrg-Ysv@$JQd zv+8||lFUoMBJ8LTlHw$_8qvt79l-0uHM}ZygfPy+G#@yN4m|Uq;~&gl2d9h-CX?3C z;;^JN7{rt7Sr8G>F@g7P6Be9!_^*!~OU?B9Cwz5NVGa?uw(nvb&4q%zo@ifc?A9@QY4_Rkoo-y0#pgjYQU2}nNPa@1;3kjxwAVn~! zWGABfd-sNA^V1^u?y!g??=p{`(eofvai93hEw z)eWyA;u#xCLr5;RCrQ}oG6L+GV(Z@+8bs0=aF0SLYDiFh2I10=H- zBUF!9rxYfn6N*jtdZfXdvhkQWAjoW-nFofXkTs42_#&C*rJ@{Sd{LD{DF|Q=Gca=w zsMp?293%GUn@fi^@ADEcIPHkcmttFILq>27S6dm3uhKe2E4hpFrvE&ha`C+M@&Ef4 zT4tRdoP)H%t0?60=5#VZ;l~M*6pKo0{cHvQTcIf%PfLs9C!l=Lz7_^H5}GbgA-MGm zQ(MP*psf7Ma`B~D<;4j5|9m8*4L0yR?cUGpvx0|1Dv7ud6rkGu4CowyU9$5gSfWx? zCFzn{++GY{R3+P=6K>-vjgJWBD<4wyqIr`wj-nOE%xgSTd-#Q*qHzInW)vmu15QKM z`mS%?3{tLXOnR*fU#V!I8AU?Q*8)3hNZEH2x6+k3%}`VWZ8OZSy^yodq>v!52Iq7m z>wZ8{?~ckIx3^FF_*E$v83vpUWq?N&Q1(2kM}W7^>y^t#;h#R#HX9{r7&&P;jFiWw ze_1>$vf!hQXT?}K_m)Oawzpb5US9|=`S+J)+e>gNY5=PcX;1^wyoJS~v)iWsDB79pfVmooS=@5mjI zCXEC3n_%8#1m3qopr7bZmSh0NFK;sI=hME}*N&;;{nYcs@AAF%a}tKmW`IhQQRq`) zDX;tgtIYWc$Ga9Ix0blTB>pU62)~Esh#|P{n@EEcN5DGt757)+NxW0G2H@~~=g1%b|HO&Egun<$z-27H| zvgF`o06v6h7cMyK@H(HpCCy#B1P2hTLv})kJb7#Q?KTA`9h7cP9JoZxrkQ<>Osfed z?W6Df(>!8?o!NJ^Pd^@d&nH1C8}zd|We=*cDZO>45BakwIqg%#s&Zk8g?*|1ZL!(j zpcwUSuik{(Z`w5pC%Nbny{^|Y=CrpqcTV?6w%hdx>nLIHCC4$wjbR$cF|M92?alWV zp-|P0H&~N7aON!(RYOWq4g&+=$q0=j4Fu`EfBEtKe=4}3|4F#CG|3;OF^_6munowx0~CjPh&Eny+VU27E9KAZ zzA!3$2M7QaLyhNbh{-0TsjT`0C&F#QD7=lbU7}Q3Xvfi*6}P@9vuoDw>R2BB7r7i< zbOL2x(2C@TN(FrGyJ>$7bLnxc=LmETIu~kj49#o5l#47uP=dBLMl>=7c(C3(@R6M+ zv7pQ^FiC{wOmy|dB6`0=*ZWG>!nZ6iJ8X8IC)aj6E@2rV`unfg53a>lQ`BM#y|0@R z^B1)IdE*pqD|(GTMra6uY!UZ^b9Dn`-2H}pG*cS!fIWYEW0GOjO!~C?mhBKRxie?Z zRp>?D3cXn*)D)_DxF{MlRMLG3>+HX<{Hf;8PugkJhLD3Kmunl@nd(iI(6=cVLjQv@ znE!S6cG^Zqym%;=M@ll?z5#M+{Ciep820F#K;LX5-?ePpy=5163Z}$VD|r?k!#~k) z$(_Dkg|oncYuF_%(7RYS6#hmGV4aVm_(y5F9q%Wo-0VcII5hwau^v6uq`j)Z;AZZ2 z=ftN5@LP<4>#RC+UrDF^-33IpT$s!6V)Nr%rSNq4yZz3ggN1DduO+ml1NFdvY*o#h z1yo+{SeKQ(^TV{qp&G9h8pIO%g=IU;&mZ{H8(jx-T|b97nwmsp)CDGJUZ6uB>Ni-% zprVeVUvPwcKde!+k#qXI!LZ5I%y^S^q;mf3Krm#XP7Py;{RgkbpS{p@F+T&%!>WI8 zUzTqo+L#J5JKg5ku$U~?k<{5v?734i4cQHdJE#Nw$-*`+&XUQm-R@k6&OtC(MP6_Z zZ7sUm%Qe(6pS8Ha`w;H@>z73zmWZz00koPZ>!AZ{py1;|om_;oz@cj&^wnbULfwRN z`AXFvT=UW{(mLA++ndE7vujx$&go*eMMaA%Gfv?yqXtIrcgJcDN1gdf8Nc@&cz$5G zH}LhH6G(sm-U5zRi5uzPAL%Ab_-LCa>i;w6}jLqKF$mGsUx} zdFJqcnByRx|9=|*{4f2#mw1B#PDAUquIK-Fw#hfm*<2RTsgXBOU;DDLs&YVyFki=; zX<=r`$>ivuq%ilcCQuMpxIjnZgNL?!ps0(xI_c;}i6(h5zep(7$UB=t%Y75A0~TjUsM?-z=W-LKTzAc;|op?k|(p z6gS*Hzdo7ia+UE4#&x}OBE!!7`Ce^re?mg>d!+wof|g$$WB~x?c|>rW+}^m=%mOY; zp^59Gk<~%%&@qs&t!*Z0{rm8lY23zk77h#Q7KORwQnR~ylthlJs>Mr^Nbc$}6F^LE zFCZ>Z(8}KrK~s~Lgf*OAEk|mV|9zf>Ay~W^_6N7VWHx7EEqrNTuJ-xefs{tn-(7EE z-|ut?$Z{z!#q$Q&&m^jMuiLS0iW37&46;pjX#H#U-*_-uNlo+M=oteiAsVg2>Vd7u z`6`VP%<-Pg7}Yj3S>uVJ=kNiFOg6C+E~JE02us}z7PMrDnqLARy`p|Db6wF7$5=I) znuq?!xPZ12n832~YG<5mN|8^MLzc=LB^M zgJx*=6hJC`Gd*r_9+&Sl$+O9Y25 zUoEWc^Yna_GZ5Oe?h+io3g&AK=Zmu+D|i)iN6(O-jH3HyM9GLOs{0Er;>&3qN`H2^J#q z)^@2DrcT!QRBo3u6T6A#uU!fIpHtTnSm(?@FUgys<#;Jyfx}$dKsP9VtQ*H|o<q9| z@XSVELkVs#n5g>KX8*+*oN@5VU->-F92*;-M>}rTDAwMm|GE3ZB#WdLK)I?3m(Fy7{$eiBF`E zqUrN&rK5vja-k?CxRIiKmM`uCp--NQ-SRQ${$6XJwH>7$VZQh4S0?d%AFu;% zw#tM!d4yTVrUdOhFtBW0Gec9QqVOTi2JZVdj*}&$PDTO*ru{9b8);qjXRzwA-i0qAQRX7glk=UH-!$lD9RUX_wLP?CswHyRI z@cj?cVyx0Be}1%nU1p<0KCYVl%r{ks*& z5CYezX+mMHTZkf!b)LUH(0nTDq%w26_n{Sce%XY=scEAR>CUbsIDBHqWZJ@AlHtsV za>u8v!U9gb#mhd~QEwdug)JO7H(I>0r#U7w{S>jH68sesRaG?}*MlNALxvhl5bo=x zxB$0fVI|(t<`n5TW@xFX8X)b6=}+$c`%(vWHr+~gYU6L;?#U1~a}tJ5K;WYy%Vt4} zS<a`G;~eAb$n+u1~o2VdLmbkbdt_dY2|140m)QImsM^WzwYWQ+0hCzUPZk` z9}1_Vt3!sr*4)pKlM)vCv&XY02mhYGXUc2>vUMJVr2L9*i$)8G` zW*-Yu2A$veaHgX6v!mKfw(mt|-l$n_7?%x_JiVSXugKcz z4QI0m7N7yirtZ`VsO-Doy@^=t)Ru z^hSfGOogl(#S;9W3sD4Wiwyi{pNS$(3WMM&GSF-jbi};qsj7h#A87n5+}eKlv)^9A9TqjH)tX z4e>f$vz8*3WkY_B?^9v{eV2q%sDzUrZiu@7+DTQb<|a3L{89NoV(qh9IGa{WuLwL` zO$gGf=pPE^f@fleJM;}HrqnjbycB)>Ur;FgNT;%EFqb#KN|=5d<3#;d;(BkYUs zB!B9T9#|X87sQsq!w1-i6~Pl~V8i(+Dk2%Dh#RZ9B!GHG(gJ z@~ECxw{YiEHnYH&RDI{B7V{{A3e+zWilQGmMcNZa!%9owo_xdBcb4O|WOf3>s~m%Q zY&7_97|4-_90XEm1Q*R}B-%!b7WqWlCmF5PW%X~Mf(v9mZA)liz;?4mUp!VW=Hc7{ zR6E}k0?mU|+e(I%Arg7mc`LsaeZy-uw)JqB6}ajQ0F-7b6JORi5}TR)lN$0io_5^W5=m2D`RG>2F(f-B;=_6lC zJQV2bb(8M)L~xAbs9ejX0j9R(upzL|SOA|)A#YHy)p@M}W*DJ&jDKwy+B7p-{AAv{ zT1i-OPQrSqa1ZhBU})heOJxkr3-N#t!@H@+=LZ>C6bsrV zh+d}`V%H$H?&~CBhZI`tV4VkF+a%#YL$cVaKK@xL{xFNG2L~sm`Rv72!ILZQECU-a zAP<$sidW6htwL(0_?c|``ccH#7j*^>c*)`fbI@)7`0>RSUfIeo68LXT$Efz$(7(0# z`2+Dz*dTym9^tS^PR(G-_b;ainuctp56xSs2zlUBjTlNhE$4wQFc`CR^2!SR zwti1mZ?NL#M@X&W==FZ>Z#3ucqIa(u>v(QfnQ8Fr>9n*+9pkiV1o6wCa>EpCB?>3P zF_9g0lKlKFQF_Xf_4|GOlLExKL=ZDp?dsC#+N9F^HbR%S;|04h<(*}N;uviyfMO0{ z*3(`vXAP1y#&IR^aYFOPNpukL-+Z#D*#oP0(q^c}l7vfrB#0oC%l zi7*-DaYom0J40B}S^FDe6UR0Hyru^JRV-(v^4qTh7)&XXuv}lohB;S)%|SH=Z}H8S z>heF>ri1wCF|Rm4$-;}H)p+gXh{W*fD-lOPgZNfsX6t7tW31a)D7F9a7<9q@68Y<< z#x|Qay;sb5+`OckLqoAUcb-B6`O7P;S}=XF>9run zs8ZpoxB1YKA{8OM75F0~U?T*+IJ>U{6n{VOkMLbyb&%B!rkKfv3T?3-*W$jLPg2BH zzW_Ii<;2dx%3fWR2`}Q2sydn)EdRzAA#u5yMYl)V@k*R*{5zF32%$1pyie9{tZ8X) zzPx9<8d#7%DJgE#r24cpxg}#C#tkVJtr<~;a+4Ny=cVnG>?awUGac=2CUZki7FArL z%JgiXBxYMM|3E~QSgrT{s^vT|I?r%_pSF=-mZ>{&Zu6CE6v9X)$Y5d zT|F1PY|RoGz`OJ*Smx@()*5O7lq|(e?<`_kQ4=RB_zjJYqb>R|nnq_hJ@^d$zqU{T z2w_ajRq#8NMp)AiD&?{c**cy*=yEHHua{uu{+h+Kzd@^Xx5L&C>nQe( zM?In#4dhKEI#V4qk{0^a-TRE*&i35*vAT7cBTf*m_$>aGOfx2M8vaxQY=q4LA8KW9 z`f9UXr89&1O%qp%Gj53foxIsRN$04#UMDe&!A)k%oxl6QYwOBEO$pq7N8=u3Q1_YJ;-tUm-AQA8y~6*x ze`7}eQcKiC$rdsc3M$iHSZMz!FT!xO)U1_vfqHeE;Cgc}uUiOQ&5`W5uq*{g@t($V z45ayK-r7(@jUKoXSCMxj_ue)aeh5UX0P+%**ZX>}rQe<*TQX=r%U8xnDX3)V$;Wc+A=KdcK9@H*VfP-N%5?b2*8BW_6J#1;)tB{Oj7-ejeUJB=(2n>2 z$^lE92uo>WIYlMlQ`b3zfTw#pf(`({yafWWKJWI)h<72>Ur%J^kjkueqF-1+f{t#= zp$O`AduLZQRgILOkwS)i=4!|1ixAN=IA^KBm)RVu$TJW=qNMikz69s)N%&Z=Jgn}0=;vi17L zcJj4E`}<;*j6kam3OdEVyw5;qu_cnJ<-k+Au-+e2($!yK+u3`Av`cCQm7N9zG87ep zl1fBGzLF69Qb`q=_Ngg})BWNmJtK|KD$GKXb0%fCTsD4+gCKwG1F#*?Bx|9a(R{W~D;?{`vKk%R9NT3dFJ$T|UDX(4PS3u;Ud; zqQY-{BvlP1Ly%Fva4H8@!2w$UD7|Au80yM3M!1@3(Au&zp;?|@8$Gzd8RoJJ>&D6do9c?eseGOT`v!vSQY? zC##wxTF}IdZt(r1dv}lBWpbLfDDfvC!g@gT40j&p2u1leD>L#2;ew~L_&M*N>x8SOwzmFs*zf4U- zH#19Pv@h7);SXJA${3xCGnsB|wc)cX$llERqKwEHy+}JbiOm-2$mdDfUmB0#lRqY*P7)Q61Z46oe3E z1$Mk8n`lvIZS~++EyPU*73@&pccaeoV&bP}GEBk2L@(D=CYt_~HNgT@)kA-KFIky5tp?>j}u za~KETdL1WxQ?D(t+Q*sE^2Cr;l}HXlM@5*PS5dz!r&Ey#N$H6yl@<2Vt43D5C9=d@ z?~zijLKgaW&sb38Ypgt~bgbJ?7G zo(Z3C+d#`+Q3xD(CImjw7>!4q(WQU-2-Is(m67n9f+}A5hG+FE95qBXd8f8b=sM2> zP`G?!5#d9u?VvjzOr_5aLpSKC#wo#LLBEF%Y(g>pn|I|$ka~??t>(u!Z9D+0pROj= zK0xV=V2fnBDsXQOK(ZN70NXfCP2*b-ufie1LSQ0yb0n#R(ZIr0s@%+=CpE~QVQ{|c-&wn9PbjWs8Ta=NCvZXW?3&!U z3{ImJM?jJ$uok(7TdFI&KBe?6&cgZ69=8(BZG69P(=(=6Kn(eRs!r0BwN%1G-xn~VIZMjrN0#l6#&=Gc0p>K*@DuY0i|6#ACy=(cMdLoF!{P)@%r ze8NRLb9g6lz(0jHyNqokO`$E5^_jNA zN1p|N7hJsLnr;}_iy>Wox}$x3JrGv1i!oM5cCQBs)+&pvXNj^{elHQ+KMJA9>E687 zRE52qc5zdM>L~ERFzOvIuV|u9md4?9KdMH_ea4G#PjCWBKVH&}uK?rxNm{lx%O3_Mm#e(78XB}L}THZ z^5X&%X5^sm_Vs(xP&lv1tczT+0*k$5P+pOmsp7W^#K>6e#x^AC`r4m0qo?&u6A@_& zP?2~;sbf9RcLPW9!5hx$GNQ?{O^h_ew*x}4n8-ROyNavQ3%@UVI9>#j1_{@4Cz?s5 z5ek$lAMkpW8f*LVH1>EGBlkqkCM!7$Oyy1g>`2tPi}A6Dul~i+yB=j+he;<8pk1=U zc6gm7(^fkI30gIRMWXf8a_0rxSB8Z__W|XymIwB_#i4#-8N;?KbNqYysBc;^enskQ zMg;V7PWvQbl)&ab+)7O?3S3Q1yHI=Mrr|kh{+~fwiIp#j* zTb+T%T_a|E~6x#KJ~(6X?iuMn|$Em1Ezg{k!pF>LO&2W>Kq>R zzhqZSGmiaTLysKKS1xkF!xh>0HEcZEWq4pc0ULn| zDmB>Mdlynf&ueY?YEN}c&GVMqu+7Wal++>6L7h@Y|9TNVV+qApz{k)aVH^I@6 z>6LT?6vD)3JQK*H5CR;{JrUYD7^-$=z2Ik=i$Cge2Ug#qt05E=PD*zb#(-58Jrlhb zlG9VJ$=xaK?u+i9)o&MwilN z=yuXSJ=qBR@}{5>{vm*=N;Fjg2nDkhn_;3Bg|M-#ZK`nX^Da z-Fk1pTT}z(>_#KUvpg*v{Cf4CNr1a>W)bb-4igS`pAQT44SEnd~dlitM99Hj^>Vr&VYqp zkOL>x_#7>!Fvh!jdIOB-sJL1*QmVrx3zdb@f9lOent#YKeeng4tvmC6xH_T1Uykqt z$#1Bc&&kv)M{N&fkOG#{HeHvg%K-BG>H@}pOqR=Q((_D8jm!#4tcO;BqxV2ypWD*o z*N@}} zAiuP0i#(spi@ir7-eE_Q&szZ?u3`(s`7?GMR}T*onDfg#asO4K+}fXNbbfQU15Ov! zW$HHxg|dbrk~PUZ9Ko&d{zc~~Ez|^{VaamX%P5lF{Uf4ILdzL$ZNMw)5QpT=u3zAX9HZ=b z+U&TZeVsHH*WU0AB|j(ecUDhyjvN%q$DO*tNBk&@VT~Mf@c3JycqO6CneZu5pK)}i zd+WTAHj>!FN$q-hE8W**8Yh&U_2(K{2eE zon5FYsHmgPYM+KMD!Z8n`2c8^-ayIDn~p%4UI)gsh4rRavbZ1Ht{~d6-_V+wacZt) z^MS!fcHrP_(8!CGaf*XO)8+$&Ah(s7vssb2DNwwbGw2Paw*bKZN$bn!CEWs5Es&Z* z{@9-U{0G>l^#(;v`zI(rSuEidh~O#8lvF!3Hm|cE8UtqZm9kzy3D56dexO#Ejq2AO z5+-`7_eghL!$lLt_;GaP3g+P&XJ%e{0DPr?#AvO0J`x1XZXc&}BYE@Fbtd!x?k-@d zD$@E>LxH2!GG*`@{$M^bIa9Hr9XNSWE+FvPQ&sEJ!kwwrsb1fe~Y& z>K{eJMEwy}#p2vi6DX{hIhQ00lB7h$fSkFEN+5^-nZ#<=t{4ytLFXuxeKf(cjN)p> zME9p5=Zy;c3S%RA`o=?lS>nYM-h_`Qv;q}8Nk;3;7kRh5ULhs$VylP5GPacDS{2UH zdiit>B>B5@`%g8KkOZUg^5h|bsXC_M?a=zf0-2DJ?hwey5{|NQiiA4T+5sLUoq)m& z?&2w3ts`S>&0MOUt7pU4Eb7=E z3GjSev~uOCB{l(v=Y$Ezwo1-0V(ASloy(?00uwJs08-FK7eY;dV#LhWa@`uTv^V}t zqe3ou*WFz+WhWg!^5zD(gbb>$b&C_1pv`p>G5}pqOyzje!^Wd;WMIhXQ zl~BN@iDQTu74Ob9v?Oc!NIg)u$x3WXWeD?Z(co0)KM zbP(|LV5G72>)S!({e=w6tVuo~>(*ehq9;6XybjJ_UGGXmhJLA1q^o1DTnYKy4`M;s z8pz(1>V_k#GXb)5`rDCaB)n)(J`8vTf0l8=C^Aw1@O&y6fnRlFTL<{uEl^<+p!WaN zs;xn^@gL7!n}HISPVn2F1We3^v>WikWi*tVzk35^3$0>7E)%6zYP7LRYFOy%e=`%& z(=%u!gtLqpFDr?WW8SBR5I{j16RkP?6%a?qBp{HaLxtJbmsQmb`To_U^SmMWDE=Bh z!KZub`SUtV7rmw}Fcd&{Sf(w_x($7zcjwGTakMF`&0tYdWX4xZk7>xtPBd61 zhXeq#un_GCv_U~nPzd4qb17k~CXzy+bbN*BcFtv+GkcMZEL>MgP7-=|@Vp>82PH}Z z9@t`kT-M`rHXC<%fz(u#Qv0l-JZuzV0q_-~QhgN~z1TV$33W+Ti!IR;5@dA6dYguY zb(v2ll<&HYf#OdEqryV_7tr=IMc+PqDg4VDjOJjY+u>#Wqj8kI{C4I4?V5%BsiBBhTMjt-W z--PV}pa|PaXSBdpCxU2GfkB8 zC7`Blk#Nsd~Ixn9@3?U818-o2y7Ox3;LJ zj-yDUahbk)Sseo1qRR`wBY&2@{l=kfntL77=l%r+fho03#B8QEJq49`5&OqE`!pSL zN(wXj^Xnz^%kE@aFo7skv_paMXNkBNGbLO}DC}my`%|Gt&IcZYMh<+8QwSsROS6n>I@UyAV0=7v9=dI71y4kWI*@ z$Z|YR6_rcJ`cnI*_jQa-s2eG{EEQv(6)l&7B-o@=?%Iq=z~u&BLD7%7JNXe*y@Rn( zaxVL6y2pfz@$paFw+0Ok#2`aj_)%1S1w`kMadWG{>8bnCgQpF~r2j4tiMfTlB_jQY z(GNJzuW34Lh#?dNU9^gnG>QY^4P^hkphl&-g)>K={G<4P zYQiL6uUJDglSouZUMkWf!-_xj{~m}F0282Mg|ta0NW>zgdtI&sr(Q}9LS^h%5BSLk z;%z$K0Qk`nL68sW? z{~X@Fj-Qww2n>P#@5B(HM?*CdHUs2r)d)b4lUx4B0lmgzZ$FlLjIVvhV}niQcfh5b z!HoiZi~U{S@zGN|yL1D;RrhV?7&rS}B=RmnDam*tGF_F`;*)VnXqTT= zY2}}%t;JDe_suB1yS&1;YZP?fU~zPxy5b&#cG>YhYJYZKYSsG7@#y?XdetFUVXYId zy^zh7aFhT1oY%Bd6-6U#Q|m$#O%LT|RN7+I?9?xZa0=#dW#7q-GkHvAAg~f*ZaKp) z?T@KcW{{{(H2KHYV57}IC}k^NltA`oq-`k$RJ7#JN)kpB3KNwc5*@sK=~A*ls36oX znR}i-r}UEnD)@~w)6>b_gj5s&t<&SwaNDIMU?hAtPBB2mzvJd;=%@LVsr~NKs9KX( zi52OwnmjmDeDMGDS)b40QPIrC1rIExy;v>J>sj%vR2;AW<68ULsAbQmFB(jn2AHn{ z#5kLoAGQb5r;QHm5_0rceEXp>CtRqyC@SS+eZP^pVW5d!En>D@UcE`)^RL*C@Pc)a zRkZ%!CVqmxq5n@FX#4j)IIQmiEePbBzFrY0KR6&d{!FBZKNLpG`!L4rD#vLiAnvPQuIKNvNcj&?C?BVQp}IAvez|lO@bUI%K#XBC&ra3U@P4R-Hv&6oX!ljvt-7c1Y3}%0}=M1qva! zO=RYq!A0IPFIGjLv`!;I#tI1%tyDaXflzwK7a`~XJLp2yaPLUk%VOLbO(rX#YD(0t zP0Z9E*I)tftnjr(q-2slP-$qCgc&@SF6@`o3ATr=HvwIT1Uq`-Bg%PL$~}Om15|^} z0fD>AhfAH%F%AeK1sOH>Eh3k^-sUIlq*TpTP&($*HwwSL09*bNI7U3zLzY3> zN;pM|(X{g}QE*IFazN<5@iudK^X=2U&0v9KcEjb0;JNLg@2EVo#M}MOmuli<@%yIN zxQe8l6>=QU(GE3nQpTTtw0$`(q&AenjvAa;$ zd(fysVco$bN@KgPLkw6|)9W!6;%gO3WIWT5LRC)0v4x#ocC=68QSi}UEVAPIh=L!D z;o{X3#Bt&Kn0V`DCtmQ0h)yyWHDnd07LIz?uWUf6N7s)fU?2VUi@Zggr*9nH8Ge|S z9WtB>?!Z0X(oI&Wp1LO~y>c=t=rOMjkBlMPyeir_JEiEsWF!iyt|AT zWJkmF68rV;MMtV4wgZKIlSM+N3C=r6W;}mLivWy`5qf{w5q#(~ z!rJQL7%AgBd~0YlacE5FdLt|m~;k4VH?ZW$++Qg7d-qs#P&dza(Y(-ZBgEQ#wUw zN$fdC_A7zU`6B$$YW06o|CFF@+xA5t3L>+684s}|J0>}@83>bz^t#g(3JmaL|psf0FlJ1@U{PPG?97AzlrWR>o z%#pdVke_!pPg$u}>n)ztown8-{Jr^js|qI0+jyM=De&4Z`o=a$$q+PJjJ#8}GVCu# z3%AfKlLt0jlKxjzfluseztwu(GxI76-g#70nEH31vMp^;Z}Ue}@a@m#Im_L7zfPlI z(XEu;uDUvGOy4S9s39?KTW{L;965pSd2#-U`{m-8M!`ou*VFnku+1cb!nE=lH&txy zkR8ZqY@s6HUtCc-`9U|D_G?E^&NI(z4pWW=-;UIt-~L%ms0lJ~ZP@ohUTjbTA)K_e z-d&0FzrNrKH7YpG{YmaSiuM0o(BPQnwk%Tut|9;o)>FgQ}fS?mgQWfvSPMKR4^O1KZ+8{r=P7K1z>+CDy|Lx$U$yQ!6^Gl3ubJHdbcg<^dd z6Fa(VmRLQZbf#c?rMc?u3-uwP(^G-VtedW%j`_N@6 zl}^w?2~Jc?E@M=)?aI^UtB^WQJ*oQ*aP#Jq_=GlU@%O?P*RStvpyS*|!hg|96V$6) ziW~{cQAxROWA@T-TiOHXb)ms5?4sgFr5=#0<*%gHTc~5NSiBW7;9KF2=TJBJz|*r* z$M`b?0~eU2f;+BFE)TCw8-Slh9d*_-m23woA;=I@;iiJg(w>9AABL76IT`MUbInJm zSoA6_%_DV`?+u{zHWL(2Ji7we_)7(<2EEcIl6g(6LYoP>5rE+7?btn#;D^}n%NluJ zqqsXtAeh1Y1;$i4z#<{{>~g(q$oKf=ZRE9}pJ)*gkQq?wTxWi95XrS>>b#-( zbb8nQ784Tt996=SOA0c>md+E zL2F_Q@<>1gw$Kqsu$^qQ9!)jBIs1ktS*askd34PHa=f)LsR&c{4!6ALLKN)#j!ydW zv=kPbXatU>Jg<>A2T1ds+^;qAbd@@(i5b{3E03CQ|2Ta$_YbetjT_Q0R9roA9=Mca zg@Rn}3H#cRy+g#oWHP$Td~VYS)H;@~Bw z_hztKjsJJ4+25;;#{ILa)sslhUA{yrtWX`4wlMGiIN*3+jLHs~%`ZQSU5Gt+5g8fG zr%OO7pDc=*BX2cb|3sr!`WDgq$*dAPZM0m7D)TMQHqfA1Di3j9aW zjX;b%B=cgPU)t#UB?Mx&!~%()6*V}HX!Nb04y?=p>G=j>o9R=6pa0Gr(z8#N_zaDY zqa_qf;)>=BKS_q-g00%n2^SqvJ+UNIN-9AovE+4|*u$-~TnQF)I5sr=!_MD)D!-T! z6=8)xa5jFC7-9NTkD`uT?X7K43ekeJdlH_J)A~vKb+iKrXOVn-W}mV9lGyC76quRL z?p-wuLO2U%gE$%m2AtnPvycF^ny;zg_|CuhNp+<#e$$Gv3V#g81lAJA569i2p6jck zFI+BdhI?%32F{6h&};9-niqEyX$=XZ#0of=YH2bSAtwLtdY-Vy;Jb^i{i?SAWKR>& z2OjUE<;cf8-Tk@hc(P?&BH!4v^C3dgX9e0L`3V?_QC&+;F6ngGoal+d3uleKbw!I4 zR*cXs?y(&8C^ddLc0zPv3nbYgJ+4h3V%f@~^D-n_j}6;bp@>*W@~}%S7OP45t5sw~ zKA0wI7)mahCfc4nW!_T?rrddn(yPM{sU)d_)iow;&cQe(LwLES$*=Gg*C8xzB9o?N zNU25aEe>9O&lQaWuENR{crRYF0A_N{H4BZ$InY5}Af(=}l3Rgv(T)tU{ z6zM++I%?6O$1b&RYRL!ppsnE7p-U*S)1{N|OB5+PN$DvXMDPA;oF^$hl4tKU zs!Sv_@Xw+!pEi?B!in*6@!l8?ujAZ( z_St)_x#s-lH`iPrX_4>r{S_we!Km>kZxigXPS7n9l27G~ZOZZk*0mi-GBX^TYdGBc z(Wb0V#0UkHD;*;Q8ovokkgyxssMyEo#c%4#Ff|y2U3at+*eF*%iu?>ui&wLCX;%8^ zH0hf&m#Y{I{fKyuu3`{51WV?N(2Fq&EqJQlEE&30rmlpEsCAfH1&7#1^sP;QenAW` z6<&Gnw-zIG08U)BX}JZ5(+S+85f1bci(P2)v;?PI6F(eM4lP*cP|eVj@}c~g<8p@w z`}nT>7EMo+!7HD<2&V5J^s=9YYbVz?WUn?fvo30~LH9Ih671(9m3D`}lfQka2ru|- z|K8}#xZCFai4@U$14}(Q`xgafT-ed-7YPYgT9oA7wc}skYvSv5`cWE@p>~yNF{fvB z7!a{!{5@BR;fpRaFW56hbUz-vSqWz-ULCO+SFy)gj%H$>kRh$2E)ehbW}c)ab5+@) zVy*2hQG!AZjRq$=-hHM*Fj!ayTKq+~C`#6BFwLKIlFC9OoL`GmE~(=9zRZ`?N6tC> zJHLxMNw-cVf5uUUFO$P(C-z>*!!ntRmV)oO;X~Q%voy;DmR5QQxVb`7tr;uAMJ%+g zgYVZPIXH@$YcT2)90AOCv$$qlwsj3kr9?Xh6kCvR7%_W4;RC6QglwTs8`L6Cl6|x4 z!Y6^0dSt%^zcV~_(?kdxi?&hm?hHR)eEBS#PETP|H6f6|@K_-sg5*Ugdo5pm#9(QX zuG&0xGCWVao9FNi6Ma>CYlIbbU^iJFBR6Ad}oC8WbQI)kX5TQmj zD-MNlur`|Cul0(SFR*b}Z^fxN)N-r}Y%%h@0N=zEJfmw>U zC*J$Ojs82xsJWp=>H{eXUhYJwm1r<`U(1?_Z(E{8>M+`qtq#LPfiw{`o}!K)iLPnC z(S;E>yt|1eANlV_7T|fkR@6x5UKvXK_;DWXK2`TjqHnqq&SF6BudTMaS1XK(L+Ptj z;`KP&r!jGXt*^WYHik;y39``dtc4!G7HdoF&v-<{Yu6*|Od~Cpq!7*;6cdhd(4TlO zbA?qp7VGz~*A+WO957=(1kv+FyJY_d$!crYkMW1~>ES5LCCtZOSJ#PTS$tTQ7=)`B)d??F_Z?jjRN2C!z?cFLsFmrA!SS<{5fuKM6XCHD6=c_nh_zSr_GqrBi(D`|^bwRcpF*biA;VBh7wy?blT2P>+gG#f4H zd#;HQUSzs zG)i$qpn++lfn56T3OY=Uip2lySf1!xyk3)*K3_GJMgd{6tBLTCkr$2t1_cgl_EeGC z_bT}x^EUS}?xy#ZS|j8*qCXq&+LlT|4BC#5vL!*1(e&&S9ysnPuQPY>1-eqfBRgtb z%dofWK2l#Jzb0ALRq_*QJkkvPB zSumob4!Wa74Y@+jlh#^N2TEkB#s?v5E{{lh$h3-ukzX=1eU0%`j#WPc_p^P@@+%2W zn8OT5yhXg;!!O-bsR`dH=n1TklJ9&^h&BL&Be1Q?mTW;br7g$oV2LMXWEn_r$wcw4 z4qA^|w!r5top=CiFIu@9Faml8G8>u5=#2|;yy5Ga0ke^vuUBE2YqM z?P>>TVMWzsC!Hr47S%6ddT>-PdS~rvR}HiwessN-N1h3K;X*jEYoqO>_OAro9UQ0U z#3jr(rJM=e?SEp*kUgFzd|T+^aS%c(%z;AbiZutrMh{bRU8ycd;CHFy<5sM3rklztc^*1)g>Mg!a z0_FU>VW;b}FqoNi%l)P=)eh~u?+kUy=Lr%@-E8wg^sQ!K?I}SyV^B6YruyZ^q+KF` zW}!SyNn{U8{%X1@Zw@ z{ZXW8-v8V|Fmc88B^!gUVao%Jr(0du4?e>`SSw1A3r<%tDk7k<>lTz5Wlb2cQC9`a z*Zkv|dobbHF11uGvv}2wspVix+L!wWIg$j#34SR_EJoh15!BGtpVaBITYoH55l?vUjL{+;d9&R!+69(836Pa;WDG^P!~W ztuJut3>Qi;YlX&8L8!Xw6HXnbPf&UkP0PNHFlb4GnZ?uJ$hg*Zb4wWs35#sR=POmd zO~PlN02GH%6f?Y6=S6n{r44nUR!q0k`3>ooBSm;t;%SYlXJ*?>S*--4X zT2M0Yq=gEc2o`=^HkmJYVMUplgi(n_=;Fv*9?EO-_KlSRV`r%d_oOI}U!_}ykT zxx7X^du=5`4qUHP3~p1eZg{sn<%5EUf$8h2Wk%=-6P>?7LtvYpz};>1Dh?Z|-h>w~ zMfRYcnKCECwIt%>;VW+aCoP1AS0_#!vZl9W|Dxfs>0c^u=ZmNUBp zz$0H;0!1tkDZdtyHn4{!mvlvgT^NS;47vHsDMD@izw*7%)I_@sFGDX?jf%~E3_JPB zk=>wZTq)HbUFyTw-%L1)LWze0Tk+ZD--O)irqH^#W5u)#6ARbvFU`v4h02GU`uVsj_lhlmrK6y<*~(~pP6VT|;ck{s!2PKJx1BP8I#8#d z7~`G?zvczBV{Wu=)y%*g}m_H%9x>l}m=+iR)c?xMFY8gP^-HABPVBLi?7f7u{OfKvscWP>w+m!E8QS z@&P?+*>FhGl+H4RoiJQWAL_=Scb>Pv4|l8Z&+U_3nr?aXVF$~gKrikMO~AAiSELjd z^Am0T6x+s|2G+O9IOk(+-nF26;cg7^o+5@!wS7*kjcf4zxhH;%l5PH01dmF%s`vF7 zHinA=d$KzcpNUpBal)L1Bk$ViaZu@WXX~w^V{p_nsn=vfJm>~EdR!#R;4u^bf zn6Z5Fw80!+tOCGX6QwH6{PX5(jTsAPzk|}MA3La88)bfHf4;~Dq7#?arodfn=X0E? zniENK_DQ(@4!qmPI7oGv#74# zezOt<6X~{35yC;3Fm5-XwEtCchnsuHzeW$xlkzIkcQ=N25{(=Qf3Nt40fR+T(M*dB z)L+cr1o(NWC*?jw$#MHSL_X44VJZ?reOre|_e>Ws3?^1ks_^+g@8JbsA2&otll)Ns z&Q>t}ogSXl&s=XkFDG04<`uNb-K~zkk#|#qCG&Q#KaQ@&JxKeiu1?Gib3<#KD^&~| zF*R7AQy%!jP99x~LHVpKiiB7v$4dp?U1yN5O%i4!K8Ke-jT3rC)r7^vH5+`$q)YQb z-nuIMO*`cBJ-Ipjt;OK+&Jw0&yeOj8?#{hNi`w?nDQfkvv88{|hwG&&xwYguxO{Ne ziv-@O*pAY@r!y?8rW&QAkaQ~4Z#5-_+2|U&M@?ADnhOm6=4Z}@yMB0{xM2TTh(MMt zQwGsVTDQ)v?l-z8FU;fd$#+dkQbOQaqXBwg+_ws-1FV1Jnp{fBMmK5YUMBT>Ou!

p+@wDA?r;q*Y{?2k0E9LDeTV1BWpS z;pM601;dks5~r!-J#~2Cc=Ys)I``T3{NMl3!y_QdiIRW$it5CA%OaPbL{+*l`H|B~ zsXsJxne(+PP}50m*p>6d->jkv2P=L;<}s}8Z5S-@Kx#LRSk9LCx7!d6)sl{3ruYPFZ zlTFTC06_A-@5%sGW8htY6%pe^~4U zo4*$UXCdeIGkmP6_?C*#a!k*^Wfz4btW({?=wAAgI zY$)N%hz6^^w;Y`1rh?B;5{w%85wk(T{xhn!;g_->OqfkeMTcga{d-!>(I;Ryk%jKAshm&nwosEf&xxI04(?t{xqIBF$(dK0 zp`;p0=@@*@fcVo#x*ZW)cjqtW8WyXzowgY&EW~H-iKt&h;dc-g_Gu_PMSiI25dLC3 za#-ejQB|}Uo8@m|4vhU18PfknSkOvH?Y!WTEloROlZzE_k^Dsl`hSN z-_szu?l9<2-WIec&AhEYa_u9%OEQx9A?=@At8;&!^5UZ@P2?^{dXPzPse^_6ix#2AzsaY--gK}}_p{^lb zwWDf`IS$3?F8*wb!DOkiZiz09 zgeRPscFu$5c78IFIYyl*S+1WRgm02(WKRnoVfC!b_obs7QF0Vl`H1q>_lBKx94N^L z%KA%#@o2DC@P_4>dh<|AaiuEoWhRhH^V?5=#G+YQ(CwlYwWsI(%Zg7Sa%?k%bBQa4 zNt*bOUb$`UL06!d7JC58QY)6+`izXQdL_@#BgH{(baX62O(=Hzy=0mk|IlD;>6dR` z(igwqn9=C*Uzfl}e-E(2^NQTr5EV14kMkVgI|GE!$y!r)WM>06bgA6$?mA6gD462ST>pS+TgTQ!puf(3Ax=Sr7GlKgY*?)+=_Q^1 zHEwi0x_rP<*Idw!Q01q_c)WPI2|63v9kyareyBs($JD1t4>3;DuyZx-8wX#Y`q1qh7en z`CtUQ>VAC-sh|WI43Qru%u%XVXh|b}{fT0SbWKj``%;jE^HS*e9^)4`CYfVQiz4lJSUs*ZRL@yxAUbPw%~=Ae{DRK+6NL7*g>=zd zNzs52v2eYgxwse;E<^(mLb=YTaeCJ+8H?JteA|LptlzyEpSo=`++iK){8@bmmrco7 z__+b#e*g^i@>2hO4!UJY_?}11WRWkoj<2GvR&?MXRI@Z?7)p2CLYQyw##4 z>h1QUd_u+q#hwZsqn|MOehs?*0R&(=n-GB#ZCF3 za!>J(DyboQ;9Xn&2kA;3bWc}V^))wGa<3j#K}HG@s);LdH|tU&*ffFk!Za+7!$yc} z<_5E@E!{cXvz!=$*$;_+{!9F+= zkSljOS<&h5cxE{pH!>JhXvr38t;YmjSh1wJ(&+Pf53)Y$#3fm5b2~+)H(+pMb`B+e z0Wp22oQc=Vc{Y1?&QVJ;F&p!HXw1fgk3=yv$U!$$9=|M2wnFk5)+zeBX9dvE|a=ZaNWlL3CF25(Doq73oFr zVX5T;c?9Pd@7W`-n{E|?YI%(}Z(o@TJn)^Dp*(SuXV#q7W~}G9quH>X%$uOe=X7(; zS%1yLH_yf};?`o+({EDj`iuRcAVm~sHOa*E@$cif)8u<$t3`V6D)Y5ni)yLIcA@Cp zf>pUkaW{e0_Aua4`ByF z2)pHE;wSiJ%2v%Li;sAt2h=_jxTe*vU5s5aD1$MLDpipxSRGv!Na|h!re5N>_UOIu zmDV`N!I#D%Q7^am-G4%eD=7t_>O66{{|ygZB6ZjN&B~n{R%u-v>tz+XViNm?%ycZf za#zcK0gL{(3?ueDb3ta@?=~RJKpX@ust6I9_(}+aw4SAq1w92_O7~*|T{2)~qTwjd zTZv_aNi-giXt0-Hz#?kl8gHBGStA;2;eY`H1T+Tk{%#N5l6_YyGsID;L7+oOgs@h~ zF+#XKA&3MH<0zH58J2N^-{1Ou}IMI%7>ig;Ifh zN=;g*Hnmie9zH}XqxW`Gma-i{@&U^HGhRkfS94pvK)fEz;Neh= z9Yf3;O`3YhF91NNh~lrx#0c6r%qe4cyqAxuY3^Z`x11P-$m9g=-vXhzn3)<|q-=L_ zG4}0=^DRc(5>)-kAerP#{{Z(YcLFDBizG!}(H0Xlwk#0K>%A7o9##5<>mprzR2+xD z4dv(4N}|wrR}mI_`%P>&R?!1ui`oTizZ}-7l=I`&jw%OZ`8MJLK?t<7Qs~a`-b&^u zMuXw9V*UD?%;C%Sy+qID9T8$*3~Tmgyi zUp6&0jV&z1m|m@tPq+9A(fa?@LJH_L0R1zKNs_??nRu3h$AKIOT7OG0l_(`>e1-zT zPk+-SeIQi*w1Uk_;(hd|*7caaiSLrr&(qfN& zwiQvvn}*gW4d3L*ZoknptAd5>T)d&l_$Y?Mf%2Bt^W}n#hH&|`zDQkQ+jlsE0qNrv zBbQ~bAABp)ZZ#fprGXEXbcdm$3Xf9D)jl=-t{r%HYqy%%0ee+ zc45Ik1L>%*hAiWfS#|- zZYNOK$Nws)o8Uo*N-AEqv)WYtV&I>b1~RmG>WmV0r*E(3x8p!eBjL{bRf{5*5Y=5W zludb>jmk!@lPtzCRH1nV8UFd~cArw;#zO06-RD80NVe?$?_+j%Ivf|l@tRu8A8;MG0LWZPpGh+splLQ~+=*U%co zLCvenY(4i6`ng3M(gdu+>^KJto=c%!D-?t!FqbiTa_ItXb5L(>fVN5yOfhSxm*9X) z9GnSIfAhNP?hz)yg258{nG*W1%2ZWD&z`6pH-W>%{NlZa53k11z8R^X?7Mvw_CeKI2g#v!mTHA=X_V2g~zuQW1iyUrAYIqHjM?7Z0$m#fSbosu;8)heNvxAQZ+j_7Y$BB-!aV}YX{0)_4WGS zDT0H8&-yh2v`0l@Fr>0AI7K|xbtWv3{E6^~EtWWuH)XXPp#&iN9}e%j85w z@0*2S$Y84F`Q&u)!))H{UiXoTU<%l5fM#fq6YcioeQmz&V(H>otzwEOlm!#PO#guU z<1`0wUQE@nt}m~)t>W03v>XoNHcUeNbpstn%t`H^icOY1VQ`p_MY$J#sk`>8&O1<6 zR5YMT*C!6KtZ`@C+uUUJq3F+z?4hr8^=&$#me32c=UXn5C$a(ej7&QGo{0RF7b$(_ zDd2E<^5CA*S31zk9L^}dCV6W@9`0gr5;jYiDFxFZ>#Erm4Klzx6ccO3h5Xwxs9AztZF2(OC?-gbMvzXtTA zy*o~K=IZ0Dzow(zK|!iyeh_k|b!xjl3EIEzzz+!g=-eu@T?39}Z2%f-W;GdC>mPvT zG17~zM)Lxd-g*7c>*v>_B_gHgU!fh>ifg}p1;5|Tq1CD%YnJi7svzwoL-5mA^UiytA z>*!}zo!R=8eW~Fhy@T4^%7fHn6*~2ua{g?O^X#mEP9f%wgVxJuXqyos zmag|a57&92#${ilXV0{Bbb@bgZc2BHb#Xx01S*Q?l61Hj&|!R>9~vA%id45A3oe@4 z&Y6l6T6CzL#lF7te(QARsVJZUMEY=gbzDF?4aLC`@_^S~)Wi`~zw4E$n8F+OOJ)0o zYqi>6&s+*4ZazTI$f9a}D|wae$QKmHQ>rD_hZ9YE<0a}qV=54d^HJ+$dg3*4SZAbb z7Jly|7bx|(y07dr<#IHOq69B(o+bloxN@Q0{ON4-ngpFX2X*~`O_1lfpM20EE)C21 zWzMWq5NqEJUbl8p)u5!4Q5hLL7^Bqyqjp$pDO?FB38xhwdQ2b_-Y33WbBO(Rr1z@QT+Jh zT)66LLCvDJx|#?GDa$X_gEP+0{3Kq^RHF|jW5xGt>O?kDi_?%2QJA+1c#Yi=yg5GlYANuu_JIK|qTski}G8!-7D4@ptpC-b9* zBzNQ`?#1HC16ayVR1!E!STYBZ%Zeq1ndB+VnNjFxP2}6D#V3_H&0mZ>2f*YYM(>9z zKMM$8S&6HL8BaWUB>u$5Eq~cA?~=tA4*`oBxvRuI>vCR+Ik3E(r_`i{3c5MULTZFQ zAi!EqQ00+kBI+=``9qF&=S@6;tF<-rxV?9Q>z{b_LRE{G>MV&6P}q&=u}~TuilUS+ zhz#b)kmE|usHJ<$tYxbuTcHx?8xtxo$nw|cPDIbV@Zx?~5EbJ)b%tb~X5P<6j{R{c zDBsFzR{&_*+RXnGxiy) zeCd|kA!>{C$y=i$VKcV(f&H&mt9SGbdQd1#2?ICISF~*g zX#EhSJ}+tYhE_kY2C=045qrauf(?wXsp(2M59njb5~@*8Fz8`}x;s_60+++>L~hXEO(^T>8RG zMwcdX?5^VKir%TQj!sTuNMv?$Z+z*!F82cxvg709@4v0d!v@nb&L%i94?7bJJHj7j zFGQj#9GyC6qK0b)APj@(Suzt@;Gk~-H2hRGSJZ$09Jrw|pAA}pIup%1 zjnV(0_#MwDc6QpK)F*OwIpTb=BYR9s)4rkqJ~6k;8rL>Oh=Z0KmMqwGFq%l*ErUsC zYK*LDB^q~Iqkpa^uOCS4?M^})e$nBbXxbBu{%q=74|?K84=7oe-LFgWvis;{3qVfV$*&~S{rE{|X?|E)gs<9WiT2F@l%Sig zD6o?295Mz=Woza_+--H2qaJOkKu9C*Hc%=}en3SU?!l5+%Z*Bl(LxKnAW}awN#7(g zn&%4^*lkE|GGgTdG?UF|KfmCkiZN*RdU$hl+7{<0k)gge>ripu+aEykGb9Ypfyf`a zauwBBYSh#9g)tPlQ>bbex|J4IH@%Oa;L@U$cVzFaeM^d9rt*Z|+U+0qXl`rX@M$_e zG6UH)7rRF%r`}I03Npk(fQMIJQT3MU7WZ{m%5b-MmXRE%AewZ#fcl_4Y&}+?Ool^T zqFVF-4)C?4v?VOx2VDqo0o}Uex-UNly`d|S)&2D6R5X$R^0^F4WXuSi%wp3J9 z2SBK_a~FEO24vDZfXeGDAc?&CDC_(i+RdwOIX*;hkP<^oR{30b5;MoRiQ^;sbR~RN z$xXm_S%6&vhYgmhYR6}m%+YB0F{DX#iG1a40)(SRO(-@k7=VB`&~#R;=LJc-w<`JM z++oG;bKv1pK2wvxzES*W5244(9e-yKs_6$kA<^i+c*(-((Z6D${Oc2ptcAr^KnAf& zplYoMHu3dE^OgqpSV(gu$%xU0gVg~veB%HX&br>Q^;%ETM+!{9q#PVL7k#$5k+y?; z!OuqANR$_Uh?D^W3ajKAVuxsv6FLMf3Nfh@@ci$TR~zd`D*T@oiXeHg!3niRy43Df zikezuuNU0cZ|r-7UgEt)t&FNK*JBBCQVTXY-S4LdYISon)`WpmF?ZI0fodiNF0)FV zv1Hp~7$~mS@ z0awDgV{G8_Vd1s6i6^IoiGvyXJW@k0pUZW>6$1v{nZWj`JDx9xD&vhyy9PwI4l@EcLJw{wNKTc+0S-eEe~Hcaj0;F8 zW5AZy05ob#^O$$^&e?QVi}IgQ0MRA!~2APAYEi7j&Tf z?9_4$pZ7Z&5(Wyoe|^Mb=_F&pzQ1*vquu(YUXhLTU}yjBXN+^PG$Psw=R}40?ha*M ze=}ZtT;{r@edgPIZz|(KMfyqa!zeM~R_Do?1#^G7=LZk4q+N@6Bi6Zj{z7Lej6o=7 zCoUo0%6Y``a$lJ0&|x3+ZM!l?Fe{H6>aEID<#|liW-fqLJ^fACgiFYPpgd@%Hz0mN zTSBuqsR3R5&_qmlovnl)w(R@kFP#s29u!JmV=Knebbxl+!?~p!GH^{642JXsNR8hV z6CZ3$eA@1~fWM3{A)u%rbIW6~^{A;g3akSfN~|O!k7<76<<8NCPGrYlS3XGwluQVK=cm+)E?wa^{~}vN@jZF?AVG`~ z!KY$eBvr_t@g{2R9p$A&42Hv0d5`$%d~jXeV_gUiUj?neonv{5D=xxF(RO50Ff0&= ztJBWaId<7fUK+a4gd-|isg^D#>w&B>uiAmBqMEf4CzsNvM`!)+mjH{DF;jcOYtgBF zMgC%}g7iW6LlWtpT}DUXkVYuKhK$o+JQD!$-|m~Aaqc! zN}owgAEJhW+Xhp;udnwZING6xY;X$x{^fk?1R2;Ca^-f7QhI&xEg=S> z?P@S?)))1{NuWuUwHzDV>+szj4jm7B($y{t!G|v~!OcmNqGU6$4ftCyY*UKX$Y2oI zRVdJ?R{2}-?8@*dGc`Gk_Iki@)ZuqC6IPJ$45-`b0RFWzl0-WdH(?VO*F%R%-L+NV zQH+LvslY;=!jUt=)*>LIEWZw2N-2y13yE+*nFVZ_2=(F*wqwA{Fp>{#j?|&8mu71) zwU?+Z&H0IRm;}UqFNy>CQ=uyP>;e2dcnt1H7qxokd+G+7Pn`jb;67NZxxo5mBEs&rs7iQMN%XMj`vJyU(Pt`x=pGf($9Kg>7~_@9 z%*3>X1d#6(HPQ8#cE=7%{%5_ZvDP{zu zvwpZ$(P$wi0ET5I|M}l{LWOs`Ibbd{m}T&1M6ShfM7&CY86SoEiz*fHKm=$HDM#=4 z@Fb!v+=tu-yg}^4gaK@feeU0HMHH`u_C_jD3}KCPKkrX??AUlSN*!FW!YEQBq~2c1`HG!x-R=#b*0n-keLAG zdJhkecAJ`vze|dhvVBEYIhF!~*=w@8H=_^Js776h7)rn$UcGuHzg?f@7LV-Z2@8wd zM|Y~3QJ>?T*L@SK^*>Kh{O_y63voJC5hYm6284;y(A&k)qc6(COM-cS~k<*%7~Pl zAD@_bvnGt}0T}Sf*zmprodK-&4i4r5RIY$PTLF^oiH~M}yl>k3a@RJ~o23-a2}mIq zfEHHU-=G@qNA_4Wtb|c7ziu+GGB^O-5D|z^i2`ds;*hc_(PR)e6+65Y01KpwI%CC; zLv~5fpX3DG&_|~)FRZBV7xr(Q%sFHBxfTY8Q92MCIXyi+f}P<}KRyuSr6DeZ4@#c@ zOk~`jsduKs4}?w^JXsym3dPk669IVyY4jC-!@>x@0>gO@0Yc~q0WVv1Za!4V+}IT3 zAa?>CZvls^JtC%gmfaZgaO-zUOqJGyWX2w2@{DsJQ1g8G&Cq>!$m_ezGkeN1j~=zyb%?@4%45(r?ATEj*O^2oo%6k93wd9-=YGW?e8nociVY zYmkl&cx}9fo$A5rSWKx6EfJ(>Jutc)&;^d9-T@4_7Z^*(nbx1#u50DuLa^yU1>|)M z=MV@)6?A)}oJOh@vAAdg`|ACzdnzK5IkA8F(?_RHK-EX1-z9?)#3rg226wG|_2Io= z7->CK{@kF^joG4#f{W~Krq33{{_Ud>{#?Ct;hGMM*v;A6^p{thVAjO;1V!Tpf=M~y z%VUakJv%csV?TZbKiO+Q-N=F@UhgkH?TY~Q8h{jVz`UV?4>HzQ7zTnt!Ncn&MMl9x5`ww3sHeYmH(^&>Ds{rPd>bhb_dzna=!*UWWyVoXah!z#Kd=3Q0?Pm?(Ji618KyB z&HX}D%zMjchie{CI!nA7OR$%idS9U$QegA-?ri8T;5DzFfmX%x#$Rdiw}orE0U>cfTIRwD4_)p;=Sf0^>67S#NeU3!1(`V1m?Cfz*&*rteo}F8vkj3{r#Z< zymzcu&Ccs5ZxtB9-^kJy@@HKdjVotfo+0a7Nu2ttpjj*P=S&vu)iS1JyQ1WU7HA@V zK!Lkj)koV!?cDqZc%{f#ja0K*BSpVO2Adj6r+QzjCrHNzz&S*Vbg}|MLU~P1)b$Im zsmJXF%Udt(MNObjr0I4zAA-+6>T@7_-6BMND~tq zxx0=C_?t&}2$lxYHRxBE4ABX@n7Og~r^Rod!ItT~f5yk3%H?U@JX^XT+xHOlPVDbC zeKldK=cl1D^7HA1z#78znqz5x{@b>PXlr$Kf+?7c+dqT6am`?A#3-MCiQ3o{PC`W{ zgXgoeMka+n4v&wIuaKbe=3u1@`0j@Z_xg^+B$Y)||3$X9>tftWBa|MCft3jkaFV(uKz#~V=Oa+&&I=Hkeuj2~N==B&zf)2?emsrpJ6}9) z4d<+A);<*GGWJ>t1vw1y#S`#V1A1gEf2a)R+q458I_rwhs&`(BeKag=`G-Z008J~* zj>Y#52=;{#Bk&m`;-@s3(9LwZqNVF8;4V0gNE&uO}hM_;J~) z!JV}%z~$bcdHf2{3`3Who{Qd?fYd|=Iaqd04Kb*7Fvja;jf4YvR2m?^NbBS4JGQuZ zFLvz!Bxb1O#x5wpY=*^-)F2wk02-vI>afJ+%MWTSNPxH$|f_xp+qGGI5o-t7dRM_yd` zG~Zlo7Zn$G#NK}bgW*e@(FdH=WUTj-d>eXBjuhtrmE=DV}C zXJE==L9Zy!_N$b^P^8qSOVa`@5F~6XW%Y}lApV*0r@~;!(eibwSN1swm3L8Toe1D=0RPuD=kM{77c(%0&LISMMQ6A1mdmvgQD zPmm3%NU{^;xpb@)o;%ZTfU=ssT+yBO!?nJ{nUR3kaz#;dyU-a9&yh#5aKT-*lOQwra2I!!jZoiR&?e6Y^$LarC2Qss>>zh(XFr9Zs zjtm-H%&~9z!F=?GzJwvo!D6!15P5&sl~8ivtd~LeHuY)d4cO9r(1GdoE7ew^Zg;v0 z)xMSrNPc!DFsmZ@DdT|ib+6m&Q!Op6hku|8(7mZ3!RTY~@#Dvux~EwZ_sOEy^KUZ1 z?TNAFk?T<9D~NE1fLU9)z1hD#SlAEnoZlXixa1lZ-R1%@=D#YYzFZ>fDmm$JH8r1FWDAM4DDfV0!L|>^C2|98c(LoCtt%{e(+m$c#kPV2H`05}^g<#I`ZK#J~lm z|L4C_)5Or2+6g!ZnLeKg3k{eF_jV0PyF2(I@s>IpT-PXcp@tDJMa5cS7&q zIpL$@;~`#RCe;r$dY24eW+pb`V+XN0gT6(yhXs5TxJZjxAV z+g*)^A*A0$!Rmi5d3!$MI>=owRWJaxdh9K>P>YRN0=>$pUk}2;`BH;QOhn$N9X~WA z@qi-&kX40h-|9M}=a)$8YZ7e$dX%23LrfrNFunMma$tIUY>JGB z;5Xfd9mjIz6MCN*LWSer>b(+7Sh>v)fUE9)-@Wd(0-RVcSiNzKim}VlrdJFgU*Kul z;r~?ymNs_NLM&L_vBX*o;4Bv`2|&Yjnen~#bp)WTsHjK^;NPQt9&|vP+PVODz6>2t znf8SP_RH1%5mgMpI$`-$>b*;p(LEs5iyC(4KYbuguzq(22Hv0OB5ociIM*7h!phO8G_e(%S%{!>3@bt_%w`J6F)5fiVEG{8s5faEgPg3*#HJlNhVgmVK(_M^)6JVhoAj_B3 zLQdVy-bYaZz@l1|SQ5Q}#Um3g>y|p(5n3e7zC7K>gaIJvIKScRqR5u$RgeV9>gnk%o=!|n<&~8=&Yw(9!mp5N&t#qdC3Ny2 zNk#bt!EycM^73*F09qxcprMaKmc!{H3BL?W{FMm0|68%@*vUN4qXZo$myt5mqoV{j zAbhD1A)a{dp~0>;H6WSi&!0~^tc`rwMz)7==Fn#Z36sVeKicf0?fi!X@ATZ3HV%s_@6kQP!=P0M&_V zE*lmw{b+!2Ef>DLauKHawkCFabyQSZ+Fflur~uXZgEF5YA4NAPdkR!L+Sy?NXgR+D z*o;7~rQP2uutP7JB~acv1mG4NUS$p@9_fxk0cuU&*(X_IOuihD&++D12nVPq?VW8B z@P;G%(5>&)Z$-&FFyy9!GvEMu&uhRyb%S*AE{-0sAz*4|e8PLR(DSC(IgO3p`5e-0 zBo>*HBS(ypnt9#;pjPKbgOf*)v?zcKeK9M?KIZ(X)wz`*#>wdEkphMQFgc^&zX#PX z`rHL)eIZdfz`=h?&%s;*Ba8%Q`nj&|*Y&fbA)U>C!}bpt>ZBEB1^6)e-lV$^cO*g@ z68$6(78>0*8o2&eMX1g;Hs>Ni5v6VV8)S|Nyp#U(SEL}<>oSF*1xo|gs> z_4VN)hX7;Ai)QqKOrPKBEeONkKy7t?UaqZV=4CGgjzBm*$I?^p;(inw*bu!7b4*cp~?LT0purtBkhZ0}W z5uv$Kbpq;8?IC~@y;DkNW$YjJVph!sEM++N#l04=QT)%IlRDGL$y zP4ytp8ib6+wk@WcOYE(-r+W(`8y}oAxsZeYgE)30T;~x0R-a(NoeBehQwiM$d>FE6 zzSu$-R9W;W-?o4iQdU;hu#xHOvRgaF4+VfVem31F5eB?~5)U(TC@8%pCzJWzUM|sX zlAyzoY)Gd6iJ_NRCLz8vOJWCv+yxZUWiEC+t|QXYqH?P~=?w^8lHh+%nzD0+4;fl_ zmfGl$ctzs;X9$)a3>oH6p<7Sn8I)hG_`hXANbK4;;$NOGLkgqy{z+(8J6lRthKh=c z1eXWJ8vY!r?@Yi|zc)A8KZJbxyKj}s3UV|OHVC9i-S1Z%OfRW!fdBe>u>+EdAS4JW z$k0p$aft`{wq5|Hj)A>m$fVvQPxSQ;1&DMYKvx^3v;qhs3>+G(!vH{E@;RT7!G%)v z$rDyz9P1(8fWy20mI#u{Va@bnKsegFyFX%k400CT5C#Mq^xwtSGgYXA)Q zUh-cmfy95+p-8NQ#F5~iNT;hqmAL^}NWgpmh7$l#di6WVi$8q-TwB{=#h+7BVh@N@ zaFcYj|1jB1i?8R{>tgV1-T$-B)5a`n+uG=m98kbtD34Anl?B{h2kpNQE?4!%aqe+C zaP4QmgxVsJFmhSgsk%@B`Cu@694RndHo#B-fq;b2$Xsd#$sX*mgS3-?`CnwvNe1o} zup`;^_2g}!ey>~vrZhe1Kd3s`5sV2S{Tm=7jZ;4lx!nZ|z1!Z? zQ;3S1n$?%;f9^sE!ujavsOEuqVY)%BQ5h^ma`7Jz4ru&C0Cd*C4wW}>g!pD#oLTt) z$8u+{p@Hpf0*@cZ{;rcrceBtlzNnvhNz4L&%0djid_4E!GL+NvH${@9$Jfzbf5s>KxnwfwtHmt8QSNAEeP2paded4^dQYpMqK25Y) zh9(Vus2#E2E#=bvRNUVB_+(!!?7wT=6V0xxlY7LdAiJUcKdgV`t~2kGstZumwcMU8 zn{M{5f$~q01u{^5e*y#xK)wQktcrL`bE#>Y$>hdtuvCS9%n`!-YOQRc^6x&^;WsS8 z#=ZzPZl5?zZr+xV6IEXM`Sk&xr~MDB=|qC=?l%)Vi)I{XWR-iQF_NV1Z{lRAuH)a& zEAIHW{V?L^shily5vwbY8YpC#fg{Es1F-EeLjM@l3A>Ro7hq1_4O=&PI5jo(LlC>n z3lM>_&l8+h@_Z z4DV#i^|AFeusXCBa(eLm@64jLz_qkc+LlapE0XlAUV&)x8`|IR0}xoTuHeUu|HIN* zheh#!Z-18->28pa?(Ptz5s+QFOS%M+aOnMK=wwu5Fkdw6lhn>G6tt5;VVo9Qs`JV7)rP-2Dxfm6 znpKs&7d`61f9!?E=Q#&jx5QN|KGg0vhX)%8AKZSmUs%@m;0?!m3Z9Kj zcFr2VR(=vKfJrDs^toUFJ)MS_2=kJ=1_6t`o}veHvO!GLdUZ)aAVPNe?V0WEz}I)- zsBiAc?GUd?Aq+2dpw0{ZGDjx?NB?f{gb+J47E5l`eM=#Kb>NJKIOA`CI3iK{n)mkC zAM?Vyqnq!Zr+--ARngQkHfFyt>-CA5e+%Nw=|Fz}YjhPt~^^A45U9}N2CakF|+R@G* z#oe;upY{gjD9-l|AVKX*P$g?9Mb_~%dCC7w8L_5D$H+F%X&Vrlq5;ol;W2lTR1;D=94_p9`U z0&cV^aJ4Kg17Ey&q`1ik)JpE-&d;~M-XUfQe&p*ZY0YEwWE#3aAqVW?Sai!@{XYic z%Kn{=hXh@=9dpjzgRY1e>603X=+}QfmDGJCKp=6oh+6|DRC5SD<^^eV0y^D75tZ69 zuKu=8s*L$k;~UMaAw!1TCjrMdzLG^sjKyD^jG2?V!J<@aONIN2KRF(d(ij^_*ZMu~EdPe?6RWmw6Q2V9UH-=M38^sVZ(cLCTsRq@Z3S!^ z#7rJt$-7(Y9cj8vYw!l+le6+B+NB}}Yw5d$am56hMXVlhH0S|f#7uKNnQ+t3_{waJ z7q$+V2qhmEu(zdUpM8f#x3ff5(p@Qn1)epLeK6YRujq~g20wipf0h{%5Sy@r5mD#He^W=8WTzZK@giKMXl8unL|nB4qEc2^o?I!_Uu)Vfc}%kq)GG2S;#MbTJW=t|1N_f zL%IT3hgGT^bc}X}EOoHC-Y)nAtbbhzX3b&ymf2f6KGDVZAI#wSyUGUY?=M3*NUfQW z(<0J;)fny*660snRrC@Xpn41H!mhqW2tq6dMd!A_;%GGL21mUy$KbWkvcWCIgg5@A zG9`EmkMAWd2EJJOcllRRb|$m1lqQ03{RDLRQ+h4f@YAFvjQ%$9hya|2y@snhgG@CC#_x2wwj_l?0->Gs%4fsm6N=ArBjQLqO zyw^^-#aG>QS2q66PU<$sujq*_E99kqKR{ zskpOlxO3w;o-pMja`5VJ(L(x6ad@dlE<}!px37&`-QA;PVN86w5YYEou zB-(YR#$A-I(~WChZ0O#f2n;=5@Y{bA<}&pymLW>&e<%7Z+5;$PAnw`TC(l!3r(Z`5 z9DyBOQ3>~>IBaJ}YF(+PI`4pPYJE@+Yo*1P?7pR;j@i0#yB5ku!uo7YOpj(&DEH*m z&siJ*jX6F26j zOvq|G{i0@ZBUZ@Zqv&Z>DSAzX(nyHjRbPW+}b=uCzS4h+(Tg*6FOgoV% zxkM^>G>^{V2Xc@`av;qnz)BF>!E^5VJ>m=%r2OMLt%_IXXdCQk8>QuT48lH4e?$3; zehfKQG~z}~7`9PHv* zShmxWl1V!rVjS$l;8k9H%!+c#k2?Y7uD}<&D>DS^l?nmUx)lD3|0IkUOi+?MNS_+w zhHtbCz{FMxv{57)utj>JRopL5u+=|yBYKBw%r;tyqNkZ2Hr*tigqZr}*P&g80IVGo zYC+POg`{NQ5Pb;`mw0pJHaFzpTwnirOAIfEQ)Ea^1r_Ni~3 z@$qe9VNH3w(d3OTd^iOuC=t})w1*T*qIe&179-TIpd)T(f+|-Gt13|{r-0JN{_r#o zEm-_y>X4jB*-mq+)vDS1*5g0t3)HY_AQ5@c8IM%T@VllAhg}v_uX_M_ zbH`EV;Il>JNDR`OU}b+xX}1nm=R#d$G=9s6GrgT)c7Coo_A|$Ba}y~cHOI|Ho%3Jv zqD9nMK@Zc^J_))S_^)`v@tH&A<$uQ&!!0Wi(*eVKu61TQ3TxV8P2@8UKe~`bLvkH| zjDE+^F`qw&yF7o*=}SR@)$au-CrmC+jb2rh2>q+`$dX5THJ+I;h7-B(pU)d*I6af} z(Rk60hFb4lZfPx=FAF9Q`}|`Ex3~7z373Zn1kXNU#z%i{cXNFLE+$5Iv|Fdd<18-3o-k77J_n^w z%m-AQFwfXLqwu9{jGjl$UQt4y4Ur|U(^ymOO;X5Y(BU5n0?vgUNDW^{oGHRNEBtUc z2o6yT7V#;)v7IUaOwK*a`@4hIB8LWos0g;qQ;;-DgYcGq2&Yx{t@+@Ds#s6yPeW32Ygd*AAD5>LB4H^7JE22tN+4pQ3gA!GZX4 z!JuXi3v)V`D9%e9&WQirJb2)J4jDg3?<-p>fiZLVqXOc|g?9YVP9s&lduF{2dM0z; z!d(1YZ;{*IW$4%2Gd#V?LuJwsxk%9uq|)1Bc=0@ip9T*t_=2&WT$BD&(TgAwZ!cEM z*gsFJ^!(6p60UCUI1FyBLia_JbMLH+m~z=a2k2>J(h-R6v-Y;Tw~FqeFXyhx2k1lL z#Y05hnmoi{{Rl&0NX_@~5YNKw@KMdYk!6=ou@$Ktf+1pA4o5Ho-KUAS%mgj5mK>}R zg}LZC#xnGSFM}xR>7;91%zpR0f9qzd?&e5*!7AKSsLKmfOEr)o>{ z+u=JvsME2)q4^UIy3C9iXHj$+svW}NU`^*gNXq~KQPzHP$ik8R;cUUBm4eshi>;a! zE&PY5J9UH{g3^bHPnj-#N92wdh0bT%kF;P>87R9s((M>56o`WEIK$7~Snxhz(sM|K#@o>^b{-DzxsumQD|vbRqGYi)Q`POw*26a8_nW z$r}z%fc{ecEjD`A{sEkE^y{ZhxSi!n96iHoGp9-^gC~QAR%%>p%met;>i-cUw2Hi9 zEIc~ov%V>Xb}e4mnc7K9VJo`J)a>cb+7!u(En`5i=!{udYWz@jrsfA?SM8cqlMF7D zQ^4cOXRl#%F{`cU(LR@(E5qgJj-`Izw31L}$SpRD)Gh}B_1%8cT8};g4RZ3+20d+_ zF^V6ADKrqK$}u$IYZnu<2u;8Qx_kTSNg6zK{X;C8ByApBKoS~AgCG#~?3`J@kjfr4h#iUcezxIT8NK;kciB(5!gU)%XoP}C z=4(d^070qR6?O!FHN5`;xWhE8iuUKD`U!muNka?->YMe3%?J$%W?jlKTM<-B92QTy zCa_`n3_E=qGvsY03z;+qY23no;x7Bf?9t2PQ^-Oi)VRs&*vk!z8ho+*;h^|^bj|eV zt}MuN+_3{u-1fg}#`YawNG@uiJOG4t=94N;cl))iHQ#jbG(i4grFZdZ;hc8Jz&cGVQ6pO~WSyNHt87ru`ySbskk6(I9cD8n8!QZB^l5 zB5(g0@hg~^E!SYlb0l^*jcnE^8@%5`y^T?W*kD-BG z<>lMEFgvio9rgJatKkKPRmqq~oj#EvVEU{HY?C=)R1lP=rr4xa5p+cL6s24Qj&FyO z0!l{hRyJ>oT5qw1$!Ar}c)wfQjE%5JG;vjUaEV3TLs({zjINMn^Hm>MZ`>gfHr+W@ zJ~t~&jaxWOw3`kib*MmSZy6sx?j?+3;cwegG@YFjhSQuYlCY|~if{Fu*=VSYD_4^Y&dk zu0Ki4bn|fdJ>~gHatEH5Oe;3zw0TXBvvRHI54O+H&QDH+uj8t=hD43t0iuQ4!>xe3(B|`I{{uw+_C3VjTP7G$`fK&24dgA9O8$!KU94q9!BqxEFYE?2A8 zkAIDlLQbZuQ0VX2DsNU?nkPVYDCyP}`g1X)D)5G*z*tceH~+UpwwnB7hAcI9dM6=i zX>G7ZJZSR9)KJebbL2+1rSq&Qqu5{xs1)FpCea357_ogJ4^si40UG|Z{Gj)Ivxx8* zXg&lVR6yhD%Y+v>G@u#F`=?!ULGQa~XRG&sX9v$Og;yt2=e%8cvIHq9athZ6H`L}m zvrd5=s3%{*#OQ|cyxCfOb$bNqz=IEUS2h9~XPxOWPx*5wlqe^CN zJIY531yxeV+Mv1*>cOotB1#Ik(YwybQV zpWcoNbf0MBD)31ojsBBVw3&+ip+A1^+To+ibW?w?1mbV(@FQ)a02%q=xD+j%C z#=Q=?V}Mw+cVO)Hw7;sCi;8fyzR80sT%d&hjK#tK?J6BJjyikyS+?ijj4>oAb27Sl z80Pz)aW;{rEBwuJv}mr@_2(D*LU8u1IB;VSM5{D)rxhFIO8X;3fTjZP>q_DSGT?t& zSs)PqMN3B$qhFcDKj?p4 z45x(Il^affxRREgzvM`-l49lLSH`~a53N3&i%UctBlIL2L1 z|2Kz*M3{wcWlf%>d3~@=6eg^uD+I_iP_1yeyteU%ru3v+o9WRnMsxCx%h0WH=K{zk zFOa(NI4#QhICqzkjy@1aJ*uRCv^)|d6S5xdKCL2MKSUhLgC3eN(*9RK;6m%&su-S= zj6}A>B01ekuprf;ftRcL*iXq7XKL5v?}*XYbQL#W4-IAxdOt|5d<}k+xYk}s2Ojq@ zhmI<#7UH@xuD9dkc})v7?LCQL@GBU9b6IQ)M!Ht75= z_?qQ#oMyNN|NNEwCJnM+123JUmF&cmbglZQbzch$$BVyS9Lo*oP?a0bbP63^BJk)J zF`G6v=-c?V_um}P1)&d=uK{X^>OLkQqR?@?7zE%XTg%mu1`29GqXTB46Tqu$W-mvctV4 zXzfM_Tr+o&e>Y|h!rk<=D9+{EI#gO-_s4$W(^!bOKv}en-H>g2@DKCX z@82%UNyYz1vx1(ahJ<4NoxO5n$ct!O4ZuAKOBvbtYvrJ4SiHM|*7cju`U@5lPVTQ5LRd7%P(JdE^aCN5 zl`3t0yu@nb!uM8pvSsn3o}c>c&G2{o#!+TI;xhl*G<{#mMD88Gqn5qD*1SHts){hI z3T|yAa}>Y%g!pXVdqcHQi)#d#&y|FZR{t)ofVn=}*(Lna`qP}(sXTgyV-sz7MVcip zHcR8_aE8P*dpZRQ#3x0|Omo=%iv^K#nxGV@kU=dzM5b9 zZuS=**BAD=^qY71kR2fot3Q!tLfk>mwh%}Ni7jVNNaV6ib8k5=ApTA@ZG-1uoKQI zF1eNv^1Y#H(NFr}Im;JCMt0HduI41dBG0sBJB<1YKw_KtvHgb}K8oXg)ZDJv5AeourGlX^I``XghLZkCcpJ9~J(oaXFR3Q)LI7;)d^3B2^Y>AGS1mZEE=7E_Y?(tcXMs3n4dWAiXlVI48fUKd^} zYvgOvQlS%@hT%0F;L8s0M*b+vxVWRmCg(|d+B9j_BpV~4{I1X`ekq8K5*M>IkpC5o zLvNdXt@tIiazd_Mwqi_mb-~OIdYjTayM;bAlKZ!2a3*Zb>)o-nlJV+69WS` zWuYv%Nw?F|7>KaG3aLCU2v4hx0(m9t^}qW`bGOirfSyp_!!}uTh}3QPF;m^2(6cI0 zb(Sx+Y?3weK)eU^98^sxB-F@WdQgbgkDT58vLJZRMJBEO;hLk_( zEN?k`q1|9^kB&XX>mC5~1ASHIUV3L$xA#OEaKyvv(0FHx&k;^1pA?=fgY8g}0bIQ* zox-6q<I=!^d5 zkY*l}R<#6!3)1MQwo$*gjLlI771cZZY#Uuo2HX4vGi5nZE=P83jKV&sezs9VcrVZ{ zw5+xMwW{?M%vd7iGUCp~J`gZAavzykO~-Wv-A1{XGdCHyR8+G$CV-{uDDgrnCWyjC z5+Iy9JEoYEaeg3xAMh9pec?hZxMY5H76BXxZ5ohVEXOSg3%cLihkprN^4+X+3iqQV+S4UDqTX4|32NGz^`lco(1YKew5UW&uIU8bU(Sw#I!CI_@ zlj?E{Rnn&OOZYo4H)L`qe7le9i@rqzUzO0np}ex;;CM_-@R-LW;c1bNRrdNTN4`&Q z(Zk2O(BAhXk;MdHI~{nD@=kTpc=qjP`b1MMDEK#jp%6;c;Vttmyb*Yy(ed88Zvk5Z zgr?nln-boSV<$=j4U`Qk_P$}nKisZ?oZ4|dNyVPPmV~Io3Lmv+hJNNa`{ccjSS^RL zo*(14Zma2`duh~&g=4ZEsi#dddvbhvb-}?Z6&lo_X%d2Af8<3$P!2Jbxnz3k@@9B$==lBk3kYQ1 z&BWZuzw4V-%yZ{qt@6CR-ed<*0jpXGGk7`Ff5)v+3&v&0U8|{^%t$LnP9jRG>*s<; z53yr4GoWsCRGsK`9Ln#=+O)oL{{?7fKL8^9^(qz{$N$_$@qI-1X^yB^5;kSuCR4N! z(XK`pR&GxbAa`3i5>rP#8hu2A&KR@aLSVUL&5%bOKE{MJLrp+^IVF;#!j!i5c1h>yv+lU0{_A^g9FZ~w-tSx+cIcI3(#dv3xHs#pNs(DHm z2OX~~E+@Cd><9q%+=)mLIDT&$Q5+e2mw-ZhDERQKaIba>a z$ZFc}{ha^(bZ?oa&e&4JU<0eT^0=%XSiauJTgS9&`RQ%xD-d> zR8L-q9oul`SA~@b1PsmO;!M%V&&!7r%ePzw5!|{?qMwu_u#Nz%I(M4}Bh2QT7JZw6 z^j37fcqF=9(Kp*}e#)e2CR9tY*8yY4)k{U;3*|i%(90c1iJlEPH^{kT#fDin%%!iO zy;2?U1&UtE3_KEqCWhHETbqLcHlP{dHk(H7NNgOBpAxx=?eO_M8RT%PQ zj`8a%LB`Q96Fs~ObpG}q0CU^B`lhFbL7Kd%N`zzK^Ew` z_R?k2T29MGIF)Tj-N!f#i!F9#l$uNcG5vTtZQ3F1{`_4;)For-wS%l!ip>phqBf3H##=vLQ! z@Au{Mr+4$^3Z0^(LFWDMp<~4A-Pf-s$x(-6_GUdjU;T(61it<+9hmgRx<36qO`1l(5TQB3e=@WxNk6*fgFog>Y5vlu zPl#MbETfqi%0PQb;c+VLlyAtR=xod*LywP6%L0N(tCeu&zu~2(3t}i0R8>YQ>fBBb zOBQG0F&IUGQjzLQtNFX$OJEpvo5U-SmFBGgik(>Boo0= zcGfYD1@;PEPS_Gk_fG!gJejbpX>OOdb;K}uC?la%66ok!Fe``QP=VJ-BXgDt3jEpW zuL?jMLyZ#&0_F0l-c$Qwc{#rBf3kC!Uxx`0gQsk3NZl!s{}OqJ^U?` z8e+mD?gJ}t00@uuG-y*y$1{c+yuCSjXpcRb80R;@HR3918jh)?+ruxArRZt-)NVn7 zw9~hGlVJ`o70cUxfEqQg$4OZBxc8 z$%5;>oBj7P9c#f=if6d`FT{c^xL|y>^S=b1WNl5162L}me7nrjnLPAuTq|%R|2|XU zheysX5O;o|LE18^e|Tu?4+uSl06{=s)@1*Ug%Z4R2vLXfrM3!xd$c4>NA!LbX7Jl! zcD0ilbG8ua---$VrPY38*HMSXj~yT0kMO&-=!o7uG$!vqy5-W}tk4Mr64dD%AYrvE z;dy2Iw9hlW9cey<vvqkM&cz6UPoCyihcCe29{g71r$oeD#$;jeP zeu@x38~9SrBkZAWwp(UZ{alVkpO?=eOU;+mNnFy;cc&3!3cCNHPiYODa#M6xi(>wu!v8+gj+UALbXLs_7M9wWw z77}mV`!g{x3dP%|!>{IN`}W$DBi!#tPIX{O_~Vt`;3{$AN;TDCf@gM&Jp@^f!R6+$ z9=@d48bk4n;pr$brbTmp%WvXn@C>oR7a|#7d2W8q2Y`wPbE3m6zmDnlw+JJwn0g%l zF9ulsFM+xZT^d{^muW#3pj{yPUJ85b)D%IRzPBFRtE-II zku=h98h&7}vMe!6{_w`XmeaNt1o9C}`e&rs_i{MW!4zaO&0yvB5~+AfA$94-hWhF_0!?UBXcfxqjBtFY<#dw+L#OM& zJCNlq+%zr;0b~Cb418in*T++wQLA?+25eBH$Pdg|fUO-L%QR4Eq5~_dDal!9NbWKl z6>~I9FaHbC_*q~$H-xbcgso1H1UmT@>@yE|gwUry;r9h|DnSnJ zYBH7NM#}n3QO9yeM3DD?m> zmfPQd0-OIe^wjq6ohcEj7V#Gbb*cjNJ0FTmX?O zC&8XKonp|sXCuU4O+Dufk%=xwX1YLhrIB{rh4wHbn`xJsy69>5(_eBycfm%j_R~So zi1P|y4%7gPv7a6!F+4mSUz!7T?+~-(+LenPg^yX_@R}IttE?E+Sa$naoqIT*B z3@?QY^cT*ObEd-hB2{B8xLCxq!iuSaWIv?JxQapb!EOR0Ppk#+`&Rl0g+3=V)NWzW zhftSsMJ?!FLMno{2m*(%KKlrtgh!T@(GOmnumCH15)_qb!QyQ)QD+oqCu+?3vr*nb z1hO^gm^Z&TF7EdlavTF;L<6tRfLPuUaTI>+>$|(9;k`AJwNWM zslm-PU4D9DF;MI0Dr~l-Y?VfVo{cNl{6wvfT2mPsR0aYv9Pn5$C!-se?zhtr9#|$JW{j zhrydNt*?$MiY007anlTm2ZeWXpB}JKVN6Rh!DSfrieiaP%vO7R7*gyLHgqDVqCgbR zHeVcLA%|ci)x*gHoSXOWZ`tTj*|(*~&wnr>dybQ=qJjAiUGzrlC>XmkPe*Km3}LKH zh*~ZpV@4oz`|VR|Ie}4i2~poXaz-SP6cRL2)=T4l-7UNH<}H$^0>9Uq^=4K^c1n(vwVEnc zHt|}&5?Qv=TqoeWVIOI(YvcX4?y-OCUGh;4sFkl4qyg04^mjXehIelHB>wVPkrHCl zDTiBb6a?2+ZUJ2zO7!P2yqC#+W%4~H!#ZUM&5Ctq|87vczls>?(;N+5`5u7 zgh-q%dD17_k;qB!OZ`)(m2&0ZfY$BVChGO>xxdE*!X*g!WO_M`kGD9#KKxTLyFhE< z_W_-vm&5u`8J+p58U*4Wo%bZ#aGs|QZ^Fjthte#$>Vv=WP!hKU8Gj6`l14P4L8*5* zRK=*49MP2O!7YKSN5jlLhrrxmKlxJcp(!B@OoVh(#sAk7U{P|$H4^?!mBySzru6{K zPgX3}`5Yn7>9VMz;5+!9s7v(KG~e!2ayev8k?K?rgOsQr!2S64AAZsu`sR7Ef$**n z0F)(jpkU!j3M8xP8~&y;z@<_pg$5)sfBIHmG*~vB4`k5@`Oj6?WnDE>umaSz-EWn`1N2`!!#f&C{3Fp!ZWajMb*YTBmo*jFqfU`01#@Z5mtPzVgxiSHdMLZP46wicJ)rd6c|3f! zd~*1lTc)O-?uGM_#or~}zCEG-7>IOmrVw=y0)`LpiHd6TXXR6Paz2G*G_2eLEN~RI zttxb_D0cQFA<$}w?eI;(mfIn*(>_n`I0iyKpk~ByIrV^XXn7{X7(Rp<^^sQ8L$GED zo_s62ZthS);lNW$IaDk%;(p#QtU~>hg@69&5ogaLkqMRT`D1Q?XLA+l4j)i`&&}d48#IP0UpcoK3qeSj-SamW#(;Zd2*2 z)Si(B9ye~t0PZSzxe1>iVsVqG0&?8sU-PApeOKa}2hCWn*^_Tgt!tf-v5$s^^~h{7 z*A`=FQ6MrpnIP(EB$L38JVMZfOEENcq@B-I5;D_LdHB0GQHZAfA}lCJ3WH} zMB>_9!?vp0-rxXCeebkS_DiB}kGZBx9qqNinlCZZ8?04&w5z7kQgW6~KutB*VKgQ-wsdn$9yzt$~s9=Lm zk&6p1`U0Zt4D!LvgXP>YvmY&pH*Yc{lO4)~ndsKEu~$cxG0G0zMYu)0ejGHYl0DPm~UNyy3+pVRovOC`Ahp z0ZOwSvpz;Ri;esxrj^0h&xzk4JZTR_Zn1PA`U(@zK3BT-%(EiZPoTh2&SDfuBP-B; z%m1L~@phzOL8NA)6kUa0JtsdP_vj z6s6JxRoORST~Fo+VS1!m@nC3~X(3Fa*4bx;%BQ|>#WH}wz~03{VK0%$qL2FCU`DHG z*)j}h=nbreqyutYU#ouA(l^Eh84`L5Xj|w(CY|g0|nj0kNkzkj)s{)y#zcu5!|)& z2i=Vu%OS&Z51s~fpW7xzs=qL&sc%iMUfkWGGhu*Q3FJ=c-XBb!zE(*n7l?vICrx*0 zE9lN~5SDW5-{~|SCoGku)#n_f7+{(A7OjB@Yp7J+!`%Lw6p1TmWCJs*OPJVD(_FNQ z4#K9}`T@+>;iweY11!@9q=+Pw)|fdA@UpD-Z7P-7LgQo#0qw)bx)Mx6R2D6HK!{9H z4+`v|4mq4%oN*go?a~qf4tldcweh29ira<4`85wIx4awz29QiEBLBAt|=Wseq2@ybL9J>wM0J|5!@cW%U zK2M(U%XG>+wTG)#{XC4T#~ZcS0Qx0~c@kI0@%Rupkdu2ELrUi^ z%2(b@enZ5S=Y{Q|`=r!+7!uDG&2xoq^pn-3kvQP9vNRZxT9#pS{_hqeAx%T=5=$X( z9Qse0D~o-0mN9pYpTJ7Jx|ULy&v6=^6Zbc!_27xrWHVUVS+-PE4#wI6Cd>^!Om!vB zK3VSNa(6pDcg~x|ibk=iRr5cIdublApbqFFxKLU{C+1md%jcra5M1_r>lO%tQk=v; zII6~se(_Wf82~lr04sO9w=b60!53$p7CTE^;Q2`!q985ZdDvvV<1U%EG8c**cT5$w z6MyMrb@4z`1qh}`$my7}G7gisn`vSI6JYZK$y}YjNch-Gy(ReOle2mVP;1_@PptRt zv{3@>8s9N!pgN1E8*_Cuex>I~=!x9cfvic?c{YgJwHf-b z)t+(43*~;CVQ;uOehh$8_QDw~e9#|=rdF>;>cE>50yrPZA^k8owxxgM@jtiYv5i8G zgB??TyAg`iw6rw?G|ZwQ-p7kW+ov}N=Ey{c(D29|QaykD z=Rl-|4wNO^3sTaR>W@#l$`ECPk0YfQcEP8C%`5&xn4VRHZO=@pqi%2Ap>E&mXVU~LZ0)&-#2XlIm1H>4!+aV|o5&A2G8EG>bi5Kc`>si8-<7m2mtbgOKex#A9t)Q<2%hr5 z?a|XSu&L9mdrKp(doI#6yNA@n(`1&njt3 z(9S^&k)V%$qhh;xYXCytS#lzZx*wYtl{EchL0`^r-RaiYo(jh6o6BPlbwfI|r?Z8I z70u#PL8_y$>+@lH2!yN_H*>cf9gk-9c%LZwY@uS_`Bs!Ih5b^L`r|m}$K&qogrzZj zX|Sk`h9b>*!>n{I20RNQFkkso_!J;Yc~7V>vI79`N~Qw6IVTeNKwR>(E+ zcw;o?>6)DM_)pLghO!+xu^LmI?8*u8f7G-q<@==8Ca`TdGrB&+LF0gCl) z6DqVX38^@kX$lcf+o&;M2LlD8hnT}pj`jtYZ*o;XD;AC-;tMEi1amG9d0wRnuu*EQ z`lk}%9=f8T)YQ3e8=F>BOox~c7-Eo?A09O~Azi!~MKyif#4$+si0b_t`@(Nu$FKTC z+LfH{S~@K*z(gf$s<}k>ysB8Qbew;z2DD*T;Ni!8*tv=lX`&z1l8vy%M$ka=g$AOY z3A?Zj#o_%$B<46hb4Y-8S&YB2KXAS!VDiax-SyO3$#LzkAU;<@RBBLIg^dz-cI??{ zX!|nwZ{QwedOXG!XkZh0bX+%f)Lx7AZ@(hYKw=m*D7=t@UY34V{ODy)aMtwsb@dRix_n?vn0QaaC?tKHNA}B&8n6Kf z?!YquNEg5FhT%6wH2_MaYt`glYN6FJ&lLUc+cvsvoE5rP5%We#Cw{Q)UxSYfYDy1Z zB`(+n2ske^;2%w%3c3wA{$g9-LvNrK>1XKSq`vIZ8M2R>5A0+m^}H?P3e(IU!*YF5 zqJa<%O-vZ(d+JMt<5iG&?_m@Xz)}r>=v^*DivrF|lPEA#rIBH$+#s_j1N!F9WK)%9 zJOcy99o;8rOxB+rHwSUSvD@tfyF4MN;`c2cf*KyrRrgJTjCclSMn7I$o3zUZZIWDX zN4zMAJ;z%=Y93pzYFfLY>lof4k&D_mL9Bt_L=)eH8+2~!TdW+>icR-0=Za#vFXiwK zL$yAl+`K`=578yCokzbwmsz|P|FMx1D~slfihZ!qKs$hrQ^scN8E`vCJ{X-6;E8d4 zvs|~Kj-|@sNGUGjvXrnc_Hv#|DkwS0dLeyOrT%DR{Yp|vC4t)<5gSohv!bqrn4{RS z73ivJd2bv+>yMApP_wYK)G0@3fz||Kj^zs^>7Pq_E3=OMI2?JcYkx&A=};yYjm4{` zn3nGe&Qmoi&Mqs26!co$r}d~fwOvnYrZdJQXrirsT)=MqHo@6 z>CFefE~YU@%+>ku*kKJ;uVsrM*v9DNBszBEaE#!KH@uK$+RisHPv_a@M{CDvh^T@=WPon1HU z+LxP(x7RMiFi@#HdYEUK zw$wILFO%>baW?dnTqx4VdM)ISv@0>h3^^Y@VavoPIkw*4Zf|5+DiZ?8&ri2DPnVCE z-R2Y5C&V*liy5{KWn^rWlIqCLw_gyy?vT7ww&XA2M~p>fX6U;hdo$~=s|I`>-{@@^ zw4=p4&fy2rILD^MSAZUz~WzZVO0~U;C{ePrthLVzzMZq@M^4sA{;b59Is1n%buV`Ed-Br) zCWJ-`tK2NUM)r=K&*M{l<6muG<}a+eA_k^_Vk83cJ%9_!&u6%#W`LATJC;nFhRPP} z&J~h7*1mp&XiO-@ep*PT2DQx>c3MN??x2n^8Ooz ziLik36iSsJG~h_vbLOgeB7kb-ny_I+BX~6M*elh zmU624?S?F3K}z1{vx8zgkCEwpbCVOo6a9V0liLfp#g7eS%BY8%eZ!6WhFIvTk9uvq z*ve6`# zld%sM_U98AVEcR5>Rj?@9Py3_JDlF(dnd>B3s2CZryUX#99jKhytf?X9D# z+S*6|1qeuYcXtX1h@^lZC@n~*fPgfDz@kw=Qc9$|Q$V`ALy#^}P`cAQx9>ZC<9EmS z-oNfW!*R}WkGg}P< z%E1A!AKG08*kgdFVoekm(b^9*9e)Q({|URh6MF_kfQ$1*mi0|w#)mRl?u892;i z_gg;Ws=02o?yZRyS2SzJ!nbbP<`&}ni9h6epuHuaMs~2`R?~{ZDz~grC?9-dy>>g( zA`~D17}>s-(=1T;7_&nMWV;$5)B8 zj5xUmqtD&i$#%(Z(*$!;P@jBr=R1_=t{4~{3;2Ow?bkZJiG=>{MLjCSLW)vkMm#4q zxh7lbx1+|V^U1ucKcq~!lFN4f5y@;+P0Fh~y-1-C?9ChM8b~^;j^V7!lImch5R*w$ zF61vi{o}cus@6UpYrK2)4T@u1_bA?NAH6-LhD>hh(vVr7ZNlG52xc6NX!&g>g6aJJ zdaON~4Z$NLgL)gHNVsArb;6Xt4s9d4uDb8M0F8HO6|xCVPP|Kpj*nffzpUxtPAlVT4p@4l)l4tuKGL@5YQ?FZ^-5*YyPR#eby*8eUZjYB)zv>dUVPf@ zk01HD&fHl&5B}v2xZ!0qsUL z5~GN&>Lh#Pa7pb~6ch5hWqgU2YHZwwZe_zC0)|>({hV+5w2hU-7vi|-)KzO=9Jt zw!tN9^tY}Qq2^R|faRL}1KDLiqb64MKrmw!rW^1(E&hn5BNiEc;R2dsogtPiuZI(V z$Tk0e)x!R8y zQLc9{Wq;lNG)=zjY9xK1iq^JgoGx0;x%ot~Z76zLGHU<=s58cOx)A z+Y;w&Dl32+9HA2QW zL}ar}?OS9as@c7aU{;!uTK8eUZ?&HMS{;dhbtfUfkY7C#i6Ek7R2P51r6b?ZrZMZ{ zs^PN=-x>)U5})eoE71`a6Hw_`m{=u68Ts;c^}zT|tK`h4|0LBTo3ff6;d0vKU>Y_) zJB)_Eb}2a=kg384!fM5zE4h5|xrU*K3K#K-c=%x(O55$t^(fWr{obWF>m8Now9#+A zWnf!lW|@46dY4vR^xKzGy72+M^;uB`_rt$3_*Wm|ws2=-`m0^< zC{VFjkB86GV7*{t2fjC>|C+w}Cp+@xCkI ze4=it*Wa%dz3CGSOTnVr3x8cbi5}u#utEs|FQf8j!dz3W!4huh5>1@5dxDP?yD0tWrt6s6r?7BNlS!B94@hhTjs~@CZPj6z- z%RQQh{>rGm-n*1p*+(1O#eMwA+^vw(R3M{j{QD1-)~az1aoy=cVt!jP<0-R zQ|Xs_k)wWL*g8b0HfHlXN_iR!LVgYbuVUJ5J#yQ-YUd60#Nf)@Vr~WDCL~f^Tlgo%fGSx~-&L*0t^w)P<*@Q;9I&JN-O8`Qd2<{)IT2pQ+Wu zg0x4pIMDk9~^L~cJgSRR9z5QBW!mlCpbG!iEgT zzyq3#pk)RXf-;FNQC;9_;j_RC_gyzb7Dc=bk9q zAWuyR37b3ZTYzWGPuwF$gq4jdgqmj~UP@jdwamFhgU+O)d$b=8?nfp}0Vq$KZFjkg zn4K9F1U;XBb)M-Z?JaPvTlZVSH61%J!-8m4-3sjZ;SxdYKq1w&O!Z1j59l_K{@Ysc zk^RK05~HFiOfg`S_XC9+Zg*@jlC_~e)tR1B4vt!w((ijlNQBH#m24?5oscqxE9a{5 z31;W zuUq=?B33emAMeuR5>oOMd?HMz@CV^cd5a3pL;-%PDeH)Fhww>0+di_Dd&RiM{8lU& zb;b*-sUoC?Qv)@)U%+nE)7`*!EOfDRj zq>1z*)tCJTc7&}{Htlz(ybz%Wxt7vIswnu4W^}*EZ{8D>=-h8q`^+L)Ff`uBC@}9TJ>^$K?H5_?u^N}0S* zL@+ZCFP$!KR)9AB?XIrbPdFagTdkk}dhDP(g}$cYI$8k##Q*iT;uX9qkkvO7`3ig# zDy_R!)PI)B<_V3hpP!qXYH?-64vwuIdtAKjEZ3_%>gRFVEDZq_S~wbOmO3e^zUrE? z9nKR%h6+?r3-QN~(DinPY>C@d z)ALuOatA%>cjM}G zlO_Ol;T89k#06fm6}{ph68LO4#SU`L0->$BciKU2-!_QNdsTJF<7)pxwJ0 zQLsFZXE^2gwBFbCDGwxS`i=Vaa2m4+SAR+=ixk7j$eaEki($NWC@5s@fxdET+-DS8 zr`-JJiDqUGj#AWIqtUkabj2F?!y09=BE0mFKlevX3SQjDC_a4<@;iPq-|RsDF9xJ` z9icN5*X|!MEs2kPkjz*q_XOc>`8#q^=jlGEOyP_JC}lY;+14_4>Nv??!l|5Vs5GMR|`WAR8=T%D9yB7}ai z>1MSPADSU-cCt(R^|g&a$lw{805G|J&DnoG{t_$3uoVmW+5P@TO^d^#Z*)v+#V+4d zpVt`w#GNmU4)j2e=oZdr{ zvu>SA!;rB2?Mf?9&Z}Zh9s6&cyziTq8(fHAN=>nQA0x&Otn1k3sa$EaOfg|1YTp!x zX?UC-PGU+-Rq!HzHSIJ{Dk+7Kcub+D^1u={TAeCofZLUA<&o<>x+dj?v$CNVv`)vw5Xr-^tq#5EE6wQ3b2M;G4OIkE5 z<~C%N2wPO5D#+WMscj?E6xR6?rGX7C2sL=N0(365pU;0V>)X% z#j3DvrwnRVRBiEN>?3H7A1|UjG>YzdP7#fNy=9)5OsJ1R&uvsXEz;la_D97r{K?#J zSaOj3LH*{Hs`ozGQunsm&$%3JNT7hEPoyZjma)vnEt_7G%k!?ctHbfzsbo^J5Eceq z?LNzTZay3~ytGFnPg*-Ws1KBa?}Dw(yalv4idkJ6_Mi&?%P)ExPeoEcP{f90yOC|$ z(}=z9O!D4p%re*(QWpEh*Ni#JOC5Rzmvbm7r^usLS2AfWAF0deE=wM^mTpr<)ijNtQdbCMYSoN6ED*4w0CtLkz+i@gOGL(m zZJbExcQdW*?jMR7nm+0v=@NRMeajOKVsgP2oqofh`*40cq3JH>FLsjWucK5{1qy7R zKCQrnqK?e85^}PbYhIl-o4jx1f?ma8(_2($oZpu`)cl-n{wnVMm9&sWA z)t6{w?G@c8V!NN+kE%2%i#I%#xc3x^1O6;@(7Bu^N}*pUlPmTV-!8u1!>5T4MT2a? zlHxojX(aq&q|Vc1iv7`OF&Ml~< z%^aqQ7J_lwa-RFI;|mXGEo}xXGsJ1VBw6v06`w3D`TS*(>+3QEzW%lE_JSF;m_nQc z#33WpVyM6QZc%dW2y5+k$;<8=y0D}f{3V3wcYbPNhDEmr0ew&JMhW@VH|{Z;Q$o-$ zEzG7fX)%%8YulVB*M2N(g~Wm%b&o~WNAYrbY0EuKES?ey7Jnaae?Pq$FSJLnQp{lS z>tn&I)(SN?i5yp*6ME9Z1uT?8?9QHuDPzH`X$P<`wI zTOii<9&9YSsDA2VXj9aMvIpB_0#aBLWON!F?6PPNfzgDF=`>zIFHB`gntHIp` z30mcv`D@P`_3g*o-D=e@E4*TqLO*@`1#|};y5DGtPMra}rF)CvocBrvA(oWE-aZ<* zfav5O1$9FAAY{LE6^byAvu_ZTN0O3r|8Z`{U5aDGKI`u*`E*k0k!s_1X&PJ6`atO+ zu+}EM{Z`&^8I5f&b>a_LnU6_?ao+D95APj0ZqPV`L&qN?ch^doRG0_$yiSKoU1=xSuT$b@_ELMii>Mw|6R_|AmdXT>i7U4m`JF_%@OdrXblTbHRVH`HZtt? zRV-FZN=S+3o`OYYRsZ|M+Rq&k1bVU6zEEpC7Yf=Jds;2wMw6pE{4LU#J$MN3(G`;u zp%1FGO}#5VEky7@#GkSQO$vcZ4M|4)Pdvo9V|8GR)^X&KyK6M9_rBZjl4zRzaNsB@ zrC%9NgWZOBEb~;_4Pj4GDC7J)3J^PdMhY;sA)>p$L1W>mKsF`1Q9EB919YL2;3Ur_0UU6(P4M4WJgJE?`g*74AVfJkPV?nNWY-#B3skarhI}7 zPOij{hM334d-uW)cGj!os*+gk-qg~%^%n8p@|CYp%CU3UlP0^VCr^7dvcVjk%fVJY z$3lM0meS#7mO61HcN8s?nw2;>@}F}>+iR_>RAVit+5jQ#QH$$x2fi+xW~#V(&p)V(2(uR_~@)2Iru|XPmcn05LjH!k0rL}l>&)(B`i6J{=O>Fmxqk>KB3gH zbFnup8?{QH6`#Kg6#WtAfS~k?SMEl-1)AS~$vPz*Z==eSjq<2Y1mwzU?%iqc9P+BE zzpi+DG5lbpwqD)h=~IDg;Dm2SK9{L=W^v%JoOnLtfj#qTFn_%gzNLjsyx%Fy5Xfpg zAF#*d2NWnkJ}Pg0#$48bGsLPx{Jtl@Jd(`0&De|AKeuN6q{WvdAwf3>IKT(q?3C^eLeS8QT3$;GKp#Y3hcg(5oNO zgXEv>Yk{Mk-M`gYV7Ik{ENz-c`ZFpmz;g!-@kgN|lYW+YsJ8xWKvtsZ_6gLMWDt1l zGCZ&bL-gc9gwiJ0Z%h{Iv1Z=8&^`3!v9v^Ly>;uTeY{8hXU_u#^(3yM)u#=;7zXs) z4$x?=k$Snw^PX$N26pF37XYN1(Jt$aw(Xf9ibIrks;TK;ZoD~LAB|ZQu-sWuq6qmV zW;dtBQ@GR4XhdhYJ;lN@)^yGY(Ki=i5Ya)nLY`TgY)pO2Xz*WsJdmH@sx8`c)HC)&=Je3~4+f4yr_cJZUj<4r+LiIUCp zow(JM(X;hr52NndUhrehiYqD>+ww0YpK3va+Gh*ekY58_)>#?02e}@nD7~PWJRVRU zLf#)9Nv*(0Di+r@eu9E=GTz3Ybk)D(?g8iGqDbl*0=_D^O;Y$`(E-#pj%C&Zh-6Fx zYqO-K2eLne=*9-fO0tE28r~Jz>azscI1Hsr@%EGkU);Pe7w}pmH&E|@rEgjrnv=xb z*f$f$)$|z`PsTHx_vtIVgnMp}^V_=KE7=Iv<AVp^ zXI*}HI@7koQ`=?o&GE{X>5@omi|LDG0sR?D179~_OY8Ap*pKF_=DgYYx6pTp3=3L( zpXM;5{*8UkN$fY(n`O@X#}x_}E`|KYPvX_6ci97(&43Rg`AIFwKk&iX%6AWAxnIVl z%%yu}v^MP{Q7v8DXWyjX&NFW9xJ%$#Lc8A%qvQ%fy$41V3OIO-?k^vH{N=Ay@dVv!}Dv_`-TvN8pEc~liv zB1|l-tAn8~8~028&gl4$wIB=Vn6-oi71+9i1ZA1`~op=um&Pk+e zV=QB9sh`Jq()A97vnrN~jYUs)tkOi0gFO6*<{gYn%Gki=5N}v~u1;5BK%M+>O`8_g z@aDj*>E?9)##Luc7_g3BIG*ou?V!QJ>!Ea15968kU#s+AbY3&R6*n6e%}! zb7ov`V3${=*~rw<3y^nSjXp6*xf*K!9bd27O8&IHg;?mpO$B+ZCYGB;EmFMdQ=mh^ zzds>M^Qtz-!-dp+6k`@vT^I}&eo9|WPBaL?yC;{cxCA{Op)Clvz{U-c6^ILutw_Jm z&>uZCWc=EalLJNhE&~c7u+jz7KhS%TtbCj|<2g43Rmea2m-bRt{C2%Zn|x1@V~3ED z!t(abu_(Um;|UgzBPYV#{#CgK9gKKJPrM`5^`m{bm+zTexemx_EtNApdEB~Ps={I^ z4JOk@UXwhn#{Ti6{Rr5P#F(f}MtrhlI|AQrJ=Uu1Z~*3a;|im(Why9enxfv+&S6TV zx>>bQOO}`H#fKRD_g-9@N)&3ccPaSM3@ZklsJDOr9$#8Yt2uRcaZ%UTpSQGZ86oQm zjDsiD3{w|&)aa5d?yM+#H7@q|^+`K8@M_c32Z2eaQ@FOY4qz^^a+GB9=IGS!&Xgj0Yb zi?h@NY;bF#PrU7%>!z9Nf@9XPns7srl+73Kwnfm0?#~~)PlVEU8G@oE1qw)YgMSum zyEe3ZZN*2=y`J!V*BPZRxOqt^3%+pNl}n_AG4|Yr7lq+87E{NjjPu_G=fKCg^pe%e zNVJH*ztbfyIVDV3$G1S&u{uF8Z~+_X>PiTVfG^94_LNz;4Zb7GO&;PeoA7yP8<0G4 zLQLEEu|F!agoTG6Adtv~!UhQ>A$??gC%~Rp@djiMg=qCdkXkAT7aveE@>&&)gR* z1S;q7@Nhpa{TexECQ-o{i4O*-G{1HeX@2q`&>&QWwX?Xq1ry+n5diA*wQxQ)BO_dh zor9x&B=te1)i5Q3psk#XfcQq#Xd4(rEH-+qgYKExCh_>-0da%}XhTnp@z>Lq7Ji<+ zJ>U9mI>r9h`{q@7GiiDADWw4~nUU8P3p+99g8RI^sMj$&yx?#j6xLC>`GAgv?}^wH zd=UidCGR8Esi`RdiEP_DGw%q(=)ZLN&r(DNXzx>ubUriY+pgsv>{xYdvldbiEC&6w z-ZZ1I=%E$FAN(w(oa&(U1;9E2CItvWjD;v12ZS=Lo=6%jXtv&oDFmB>(2eTL3mg^* z!K*t!U?)M>sYjlkVgTQ4^kx+mkZ~2q#1JMWub-D>1B#nI)m_YqE6)1k7&`AT4nd3=0)v$F#bpt}tHveS?k$koY~MxVUMpgdit z`%CWpmHO4Ul6K%uhZ$e5k-Y&VX*E5)_kaMl0vLKs{~>)Mp6KgkN$=Z>pQ4_J%y63b zp^`V4ZL^o}zkxNt>l?B+C=Avg4~<&sf@S>y*$x3oR&;X{2Aq2xaP$M5Pq47CFqz0v zdUJiyiv;0G>_fP;67K*5lm@u-kq>s;0`Vl@J(IernHh~k%=QsCrp{XcQVe*Sx?pkw zs_i2^uMuc!^C)o+YmvaS3a3Csoi>mc5g1?SHovC^LXo zTns#^3e(Pvach2`OV>Y(jdiWh3Ki{OTB!-QwE+`?f0wc5peQNRufs(&B@810uXWpy z5KlRT%0b%P++1VsrzkJSj=|6lUI&p$3~!aytD@hfy&n*hVNUyqtpfwT-a3FPcOuxm z2tpzPtPX&$2x(E;;f(jj-*Rt^bNZwX3SD2Fb(pEiFu>3HL$#~+*GYY;|EUHq{Q(}m zv#T3~9!TIbrWIq2>*s$t0$zDEHx8coNYZ&r8gFq9wQzr0pEX@!nETlp6Q5xLZ-{Gx-`G{o3O* zj%Ww9e^)4sy0kVSAG%>?u1tiT+l$l&6Zv`pg_N;%e#ae~Mw}Rc#UFy1t}XErV=|Cq zE2o80V51=*fQVx;YV2s&ofJf!{A%pP(Szt#Vr3w-02eR;z*(VS2KoQo#lLH0_%`qp zE)j8%8CqIe%J3#;XJ#^Nzmbze0d}j=z_?ULt`yes5G&K-B$7mmJ=s7kDOw=FCkLKl z+*flw`%Hg>m}-Wvvd@$vN~g=^3-^o~ZMR+5CLAOL7miuF`+BS4x!1NutbLkJQ6 z#Eb@SH710RA%H9uupA%;oLU@2^IV{*0820JR#NysUkud{gms&NpE3?;&WM(~CnqOK z{HDkN5?;+4UiMF*`*L|$0<|GsP@xIHvz+JdtEif?th>qtckisYH=5SXqwh4uX({@A zyex=9L)*@uQuGnxSCcY)H|bS1_Rum=yOJ6g9Wnt<`HeU0zwN+G5ZdW~e0&@3RuvCBk96fuS{p$++Ea-{l^tW%U-0||4cqi)rb$vDHfXgp^)Adq|1{eMC=%}&u zE!=OZV<||1iHUi6?K?R!fwn{BkdYzzZ>3O9H2?h&?X8qsqB_o#uM_{-h(ST>6~Na4 zv(O+#Eha3Swk?5mD;YO=UoZ=+(dA11?{aA1j8*dAB?uHO{?F7c|NjI04<8Yh7&TJ@ z7;~UPcKh+xWTnU6(ye5!jD2q;jc$br5}0~BKei;GkQNMzMRsaFdk6##D z==o1mx6|Wjau7PMP&2>7T8Qz%11c;s-Y#H6vdY#^yecjF34z%o$3{b#8f$CoU-|cF zy^TQeSOlGvq((_oQxkQ%@1@O#^LF~w(SpmUzbU!IVINbB`P8$Uy{-Iov`&6?DL`_M zGc0VUD$?ZpD&v^u{o;nVs!JS^+(V zN1Uja*_3l*-vZ)1(~KBEe4_i!H^23OQ#Ugblau>z0C4pF$+IvgQR)R?%D#e)?+6-i zZ_xUln?|nxa{I`sQ=;1r3}tsy#N}i1fs(M5v#Uw~Oa%{^%~^#t&J^JBwF-5Hu6_<6)R+=O2 z-{fc%M#sbuxEXHex450}n}Vx${yyn2;a};*lj;Hh^vJL<%0Gd4} zsDVVdjk-;51i-^sTF#djN6^k!L+N@zfDer4<(2DWYH++J{2IPKKS+}F5eGlpUwXSI zQ#^gTo{S?Qgd-hPQo`N$YRL~M31Q>ul9e^(}d5QoCJV8W?#ZXAY%dc z($q_zck80uh7H7YzUK@r*N0Dt$;cE9B|Q%<*y9HZe8rvC?%3Me7NlPi3|8%5cuz@j zn4SLlF6w>G&&kQjD5VL~uBjeN6c~J!^o{t=w z{PuG~P1lEm2yiRl^}?4|Q)oQ@W32p77QTaHP~f4d1Fsm-8~)J-a+d5P~fpBW)^3TqsOjg1Wgo(??jNUpN_tn^V|M_rJu z0Ueh^J33@VsbO5i7{)#)B$9uxU4ST=3Q;m0HFW~$<&c%jhUkgr-?zu(ij^kq$iyTh znPp|TKvDS_@b=PpEXb6zWL`E>w@aV)O5MhAadU5Iagy8z_qPi?!JR!#%BfoW`5vTS zht(h)k6b@L)CS~W=ES(TPN4Z6!0Ii$CxY27&vMX{b#GAo-u^DFW1Km7Be4Ly$39Cd zD`)Z4Nc|dXf|p-jTlx%i9P5^SA9!3IZ}t6{QheC!NZos)`B~+kS$Qlg^fDesIB!8Yz(4)xemx$@ z`cKgDfBTUIK4RvA_wF5J)7=!bJ`2W|HTyR-S|zBbCx>r-8~=+PVP;;$r5|O1{K9IC zB5lmV2*Q5{ft|90;ydtRyS32imJgxqJAC32LfOYsz<+qV-$nH7k#BiHL0b?8(dAwc za6eHwF0by~Ww7AK43?d(Fhv0es>sFMe~mE!krpaEyJy;Q=T2ZdZ}0urOA*)C*EvgM zAOt}hD1pJ4vG#y?y0x`+ezp9U_Dmdb&jU0HyMQi3g1{jrITsff=IXhnrAUymH|dF> zC@3%QO}_UMgth=|ev6Jk+t$3`$$Od__URL)H#p#g0CNM%Ise;JJJ35;aW_9J3mHV1 zTZeM~oD3Ej8Hg2*wceTg0&uhNgZ;DCzchez{Bq&94+tj^W|}+%sSQ1zf`Wn^Ah&Vp zBqM+|HtUOKn60&^0=w1;+!oXZ!oLtiKsgJ*1whX@&KP>Eg2h3^nqfe_tb)^4Z-7Ky zZoFm*if)lc#0Shuh=#z%e=ldwH{zc0yKD{x!83-fz7IkCnA^8ULPEmM#nn0Yc3pYp*FBe>c+;)>n>^cUgF}? zh~G&Z3=RlDZUT^Vc0N9`!By1~XY}WUfFS`4#Me=GidN0*7M!0%ja~r~?ymzk z42B%3F(F9yu2KMSQ98^jSBCE|-|2P2D8D-Br85T}@tCzxj5)ZmdXQdNJ@Lxk{OsQ1 z4Yq@NFPLl)R~cN-c-T1eyBqu*xE`!KQ6ShNmTdwqQ5>!;z zJFUl_Clbg${tMJ0$Y(HTD}3kx+JPSiUGPEVj?jpPWs@LpgYZDsqog9K9{_m#hO-zi zplhgn79~KWC;(W#!eh_K!qQTnmku2H+z?q6E0LF%SMLqMqr(ksA1j905Rvr&Vy6(s zCnT(aAgl|x8F<%+iLHN}FAy$}&14<}7Z;av36RQcMK~(tMJXE81n}X&RCbrvEn$M3 zfm|qVW=)Nd?Oa=?TxeDmSau;)KYZsx)B0W3=O9#6`jqmzh2oyoP+Ph0N%5^D3CNA% zvsVM(*2fy`5Clf~5|J6QXv-M-mrS~=r1w#e<)6cfNN4eRL}| XQ!KKnMK~o0fq#_bpFS#+H3|4%BSgg$ delta 87100 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 Date: Sun, 27 Apr 2025 13:39:33 +0800 Subject: [PATCH 06/25] DOC: use `EX` instead `EXP` to represent Explosion --- docs/source/Advanced/integ_converg/run/run.py | 2 +- docs/source/Advanced/kernel/run/run.py | 2 +- docs/source/Tutorial/dynamic/run/run.py | 6 +++--- docs/source/Tutorial/dynamic/syn.rst | 8 ++++---- docs/source/Tutorial/static/run/run.py | 6 +++--- docs/source/Tutorial/static/static_syn.rst | 8 ++++---- example/compare_c_py/run_pygrt.py | 4 ++-- example/convolve_signals/run_pygrt.py | 2 +- pygrt/C_extension/include/dynamic/propagate.h | 2 +- .../include/static/static_propagate.h | 1 - pygrt/C_extension/src/dynamic/grt_main.c | 16 ++++++++-------- pygrt/pymod.py | 4 ++-- pygrt/utils.py | 18 +++++++++--------- 13 files changed, 39 insertions(+), 40 deletions(-) diff --git a/docs/source/Advanced/integ_converg/run/run.py b/docs/source/Advanced/integ_converg/run/run.py index 22fbdff0..d4fc269d 100644 --- a/docs/source/Advanced/integ_converg/run/run.py +++ b/docs/source/Advanced/integ_converg/run/run.py @@ -26,7 +26,7 @@ # 返回的是自定义类型的numpy数组 statsdata = pygrt.utils.read_statsfile(f"pygrtstats_{depsrc}_{deprcv}/K_0050_*") print(statsdata.dtype) -# [('k', '[///]\n" " Designed to choose which kind of source's Green's \n" -" functions will be computed, default is all (%d/%d/%d/%d). \n", (int)doEXP, (int)doVF, (int)doHF, (int)doDC); printf( +" functions will be computed, default is all (%d/%d/%d/%d). \n", (int)doEX, (int)doVF, (int)doHF, (int)doDC); printf( " Four bool type (0 or 1) options are\n" -" : Explosion (EXP)\n" +" : Explosion (EX)\n" " : Vertical Force (VF)\n" " : Horizontal Force (HF)\n" " : Shear (DC)\n" @@ -521,7 +521,7 @@ static void getopt_from_command(int argc, char **argv){ // 选择要计算的格林函数 -G1/1/1/1 case 'G': G_flag = 1; - doEXP = doVF = doHF = doDC = false; + doEX = doVF = doHF = doDC = false; { int i1, i2, i3, i4; i1 = i2 = i3 = i4 = 0; @@ -529,14 +529,14 @@ static void getopt_from_command(int argc, char **argv){ fprintf(stderr, "[%s] " BOLD_RED "Error in -G.\n" DEFAULT_RESTORE, command); exit(EXIT_FAILURE); }; - doEXP = (i1!=0); + doEX = (i1!=0); doVF = (i2!=0); doHF = (i3!=0); doDC = (i4!=0); } // 至少要有一个真 - if(!(doEXP || doVF || doHF || doDC)){ + if(!(doEX || doVF || doHF || doDC)){ fprintf(stderr, "[%s] " BOLD_RED "Error! At least set one true value in -G.\n" DEFAULT_RESTORE, command); exit(EXIT_FAILURE); } @@ -792,7 +792,7 @@ static void print_parameters(){ printf("| %-*s | ", nlen1-3, "sources"); tmp[0] = '\0'; - if(doEXP) snprintf(tmp+strlen(tmp), sizeof(tmp)-strlen(tmp), "EX,"); + if(doEX) snprintf(tmp+strlen(tmp), sizeof(tmp)-strlen(tmp), "EX,"); if(doVF) snprintf(tmp+strlen(tmp), sizeof(tmp)-strlen(tmp), "VF,"); if(doHF) snprintf(tmp+strlen(tmp), sizeof(tmp)-strlen(tmp), "HF,"); if(doDC) snprintf(tmp+strlen(tmp), sizeof(tmp)-strlen(tmp), "DC,"); @@ -1149,7 +1149,7 @@ int main(int argc, char **argv) { strcpy(hd.kt1, "S"); for(int im=0; im=3) continue; diff --git a/pygrt/pymod.py b/pygrt/pymod.py index d35189d1..7c32a766 100755 --- a/pygrt/pymod.py +++ b/pygrt/pymod.py @@ -203,7 +203,7 @@ def compute_grn( delayT0:float=0.0, delayV0:float=0.0, calc_upar:bool=False, - gf_source=['EXP', 'VF', 'HF', 'DC'], + gf_source=['EX', 'VF', 'HF', 'DC'], statsfile:Union[str,None]=None, statsidxs:Union[np.ndarray,List[int],None]=None, print_runtime:bool=True): @@ -243,7 +243,7 @@ def compute_grn( depsrc = self.depsrc deprcv = self.deprcv - calc_EXP:bool = 'EXP' in gf_source + calc_EX:bool = 'EX' in gf_source calc_VF:bool = 'VF' in gf_source calc_HF:bool = 'HF' in gf_source calc_DC:bool = 'DC' in gf_source diff --git a/pygrt/utils.py b/pygrt/utils.py index 7bc08aa0..cf9f9e9a 100755 --- a/pygrt/utils.py +++ b/pygrt/utils.py @@ -38,7 +38,7 @@ __all__ = [ "gen_syn_from_gf_DC", "gen_syn_from_gf_SF", - "gen_syn_from_gf_EXP", + "gen_syn_from_gf_EX", "gen_syn_from_gf_MT", "compute_strain", @@ -71,7 +71,7 @@ def _gen_syn_from_gf(st:Stream, calc_upar:bool, compute_type:str, M0:float, az:f :param st: 计算好的时域格林函数, :class:`obspy.Stream` 类型 :param calc_upar: 是否计算位移u的空间导数 :param compute_type: 计算类型,应为以下之一: - 'COMPUTE_EXP'(爆炸源), 'COMPUTE_SF'(单力源), + 'COMPUTE_EX'(爆炸源), 'COMPUTE_SF'(单力源), 'COMPUTE_DC'(剪切源), 'COMPUTE_MT'(矩张量源) :param M0: 标量地震矩, 单位dyne*cm :param az: 方位角(度) @@ -144,7 +144,7 @@ def _gen_syn_from_static_gf(grn:dict, calc_upar:bool, compute_type:str, M0:float :param grn: 计算好的静态格林函数, 字典类型 :param calc_upar: 是否计算位移u的空间导数 :param compute_type: 计算类型,应为以下之一: - 'COMPUTE_EXP'(爆炸源), 'COMPUTE_SF'(单力源), + 'COMPUTE_EX'(爆炸源), 'COMPUTE_SF'(单力源), 'COMPUTE_DC'(剪切源), 'COMPUTE_MT'(矩张量源) :param M0: 标量地震矩, 单位dyne*cm :param ZNE: 是否以ZNE分量输出? @@ -332,7 +332,7 @@ def _set_source_radi( :param par_theta: 是否求对theta的偏导 :param coef: 比例系数 :param compute_type: 计算类型,应为以下之一: - 'COMPUTE_EXP'(爆炸源), 'COMPUTE_SF'(单力源), + 'COMPUTE_EX'(爆炸源), 'COMPUTE_SF'(单力源), 'COMPUTE_DC'(剪切源), 'COMPUTE_MT'(矩张量源) :param M0: 地震矩 :param azrad: 方位角(弧度) @@ -355,7 +355,7 @@ def _set_source_radi( mult = 1e-20 * M0 * coef # 根据不同计算类型处理 - if compute_type == 'COMPUTE_EXP': + if compute_type == 'COMPUTE_EX': # 爆炸源情况 src_coef[0, 0] = src_coef[0, 1] = 0.0 if par_theta else mult # Z/R分量 src_coef[0, 2] = 0.0 # T分量 @@ -491,7 +491,7 @@ def gen_syn_from_gf_SF(st:Union[Stream,dict], S:float, fN:float, fE:float, fZ:fl raise NotImplementedError -def gen_syn_from_gf_EXP(st:Union[Stream,dict], M0:float, az:float=-999, ZNE=False, calc_upar:bool=False): +def gen_syn_from_gf_EX(st:Union[Stream,dict], M0:float, az:float=-999, ZNE=False, calc_upar:bool=False): ''' 爆炸源 @@ -507,9 +507,9 @@ def gen_syn_from_gf_EXP(st:Union[Stream,dict], M0:float, az:float=-999, ZNE=Fals if isinstance(st, Stream): if az > 360 or az < -360: raise ValueError(f"WRONG azimuth ({az})") - return _gen_syn_from_gf(st, calc_upar, "COMPUTE_EXP", M0, az, ZNE) + return _gen_syn_from_gf(st, calc_upar, "COMPUTE_EX", M0, az, ZNE) elif isinstance(st, dict): - return _gen_syn_from_static_gf(st, calc_upar, "COMPUTE_EXP", M0, ZNE) + return _gen_syn_from_static_gf(st, calc_upar, "COMPUTE_EX", M0, ZNE) else: raise NotImplementedError @@ -1241,7 +1241,7 @@ def read_kernels_freqs(statsdir:str, vels:np.ndarray, ktypes:Union[List[str],Non :param statsdir: 存储积分过程文件的目录 :param vels: 待插值的速度数组(km/s),必须正序 - :param ktype: 指定返回一系列的核函数名称,如EXP_q0,DC_w2等,默认返回全部 + :param ktype: 指定返回一系列的核函数名称,如EX_q,DS_w等,默认返回全部 :return: - **kerDct** - 字典格式的核函数插值结果 From 0826396e475239fcb3a0dae9cdd3163e1d459cfc Mon Sep 17 00:00:00 2001 From: Dengda98 Date: Sun, 27 Apr 2025 13:42:54 +0800 Subject: [PATCH 07/25] DOC: set `gettext_uuid=False` --- .../en/LC_MESSAGES/API/C_extension/common.po | 6 +- .../API/C_extension/common/attenuation.po | 8 +- .../API/C_extension/common/bessel.po | 7 +- .../API/C_extension/common/colorstr.po | 6 +- .../API/C_extension/common/const.po | 11 +- .../API/C_extension/common/coord.po | 8 +- .../LC_MESSAGES/API/C_extension/common/dwm.po | 11 +- .../LC_MESSAGES/API/C_extension/common/fim.po | 11 +- .../API/C_extension/common/integral.po | 8 +- .../API/C_extension/common/iostats.po | 11 +- .../API/C_extension/common/kernel.po | 6 +- .../API/C_extension/common/logo.po | 6 +- .../API/C_extension/common/matrix.po | 12 +- .../API/C_extension/common/model.po | 16 +- .../API/C_extension/common/progressbar.po | 8 +- .../API/C_extension/common/prtdbg.po | 6 +- .../API/C_extension/common/ptam.po | 14 +- .../API/C_extension/common/quadratic.po | 9 +- .../API/C_extension/common/radiation.po | 8 +- .../API/C_extension/common/recursion.po | 10 +- .../API/C_extension/common/sacio.po | 9 +- .../API/C_extension/common/sacio2.po | 8 +- .../API/C_extension/common/search.po | 10 +- .../API/C_extension/common/version.po | 6 +- .../en/LC_MESSAGES/API/C_extension/dynamic.po | 6 +- .../API/C_extension/dynamic/grt.po | 8 +- .../API/C_extension/dynamic/layer.po | 9 +- .../API/C_extension/dynamic/propagate.po | 7 +- .../API/C_extension/dynamic/signals.po | 17 +- .../API/C_extension/dynamic/source.po | 7 +- .../en/LC_MESSAGES/API/C_extension/static.po | 6 +- .../API/C_extension/static/static_layer.po | 8 +- .../C_extension/static/static_propagate.po | 6 +- .../API/C_extension/static/static_source.po | 7 +- .../API/C_extension/static/stgrt.po | 7 +- .../en/LC_MESSAGES/API/C_extension/travt.po | 6 +- .../API/C_extension/travt/travt.po | 7 +- docs/locales/en/LC_MESSAGES/API/api.po | 14 +- docs/locales/en/LC_MESSAGES/API/c_api.po | 14 +- docs/locales/en/LC_MESSAGES/API/py_api.po | 14 +- .../en/LC_MESSAGES/API/pygrt/c_interfaces.po | 65 ++--- .../en/LC_MESSAGES/API/pygrt/c_structures.po | 114 +++----- .../locales/en/LC_MESSAGES/API/pygrt/pygrn.po | 85 +++--- .../locales/en/LC_MESSAGES/API/pygrt/pymod.po | 130 ++++----- .../en/LC_MESSAGES/API/pygrt/signals.po | 59 ++-- .../locales/en/LC_MESSAGES/API/pygrt/utils.po | 254 +++++++----------- .../en/LC_MESSAGES/Advanced/filon_linear.po | 58 ++-- docs/locales/en/LC_MESSAGES/Advanced/index.po | 12 +- .../Advanced/integ_converg/integ_converg.po | 42 --- .../en/LC_MESSAGES/Advanced/k_integ.po | 80 +++--- .../en/LC_MESSAGES/Advanced/kernel/kernel.po | 40 +-- .../en/LC_MESSAGES/Tutorial/dynamic/gfunc.po | 191 ++++++------- .../Tutorial/dynamic/strain_stress.po | 52 ---- .../en/LC_MESSAGES/Tutorial/dynamic/syn.po | 74 +++-- docs/locales/en/LC_MESSAGES/Tutorial/index.po | 24 +- .../en/LC_MESSAGES/Tutorial/prepare.po | 30 +-- .../Tutorial/static/static_gfunc.po | 13 - .../Tutorial/static/static_strain_stress.po | 9 - .../LC_MESSAGES/Tutorial/static/static_syn.po | 29 +- docs/locales/en/LC_MESSAGES/copyright.po | 16 +- docs/locales/en/LC_MESSAGES/index.po | 59 ++-- docs/locales/en/LC_MESSAGES/install.po | 4 +- docs/source/conf.py | 2 +- 63 files changed, 669 insertions(+), 1131 deletions(-) diff --git a/docs/locales/en/LC_MESSAGES/API/C_extension/common.po b/docs/locales/en/LC_MESSAGES/API/C_extension/common.po index 27633087..1a6f5b7c 100644 --- a/docs/locales/en/LC_MESSAGES/API/C_extension/common.po +++ b/docs/locales/en/LC_MESSAGES/API/C_extension/common.po @@ -6,9 +6,9 @@ #, fuzzy msgid "" msgstr "" -"Project-Id-Version: PyGRT 0.6.1.dev1+g4641a40.d20250422\n" +"Project-Id-Version: PyGRT 0.7.1.dev5+g2230cdc.d20250427\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-04-22 15:39+0800\n" +"POT-Creation-Date: 2025-04-27 12:43+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: en\n" @@ -19,7 +19,7 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 2.16.0\n" -#: ../../source/API/C_extension/common.rst:2 870e7fb944a44610b42417abadce1a8c +#: ../../source/API/C_extension/common.rst:2 msgid "common" msgstr "" diff --git a/docs/locales/en/LC_MESSAGES/API/C_extension/common/attenuation.po b/docs/locales/en/LC_MESSAGES/API/C_extension/common/attenuation.po index e6bb4e5c..2d68b6fe 100644 --- a/docs/locales/en/LC_MESSAGES/API/C_extension/common/attenuation.po +++ b/docs/locales/en/LC_MESSAGES/API/C_extension/common/attenuation.po @@ -6,9 +6,9 @@ #, fuzzy msgid "" msgstr "" -"Project-Id-Version: PyGRT 0.6.1.dev1+g4641a40.d20250422\n" +"Project-Id-Version: PyGRT 0.7.1.dev5+g2230cdc.d20250427\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-04-22 15:39+0800\n" +"POT-Creation-Date: 2025-04-27 12:43+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: en\n" @@ -20,22 +20,18 @@ msgstr "" "Generated-By: Babel 2.16.0\n" #: ../../source/API/C_extension/common/attenuation.rst:2 -#: 0251ca0310a34a66b744200a9a5d1424 msgid "attenuation.h" msgstr "" #: ../../source/API/C_extension/common/attenuation.rst -#: 53c5119e5f6843d39fc635310cf4974a msgid "Functions" msgstr "" #: ../../source/API/C_extension/common/attenuation.rst -#: 5ea715280fea4eeb8d26818cf309ca46 msgid "参数" msgstr "" #: ../../source/API/C_extension/common/attenuation.rst -#: ed792cbd6fa748329938d2878d719676 msgid "返回" msgstr "" diff --git a/docs/locales/en/LC_MESSAGES/API/C_extension/common/bessel.po b/docs/locales/en/LC_MESSAGES/API/C_extension/common/bessel.po index f655a6a6..99c6f3e8 100644 --- a/docs/locales/en/LC_MESSAGES/API/C_extension/common/bessel.po +++ b/docs/locales/en/LC_MESSAGES/API/C_extension/common/bessel.po @@ -6,9 +6,9 @@ #, fuzzy msgid "" msgstr "" -"Project-Id-Version: PyGRT 0.6.1.dev1+g4641a40.d20250422\n" +"Project-Id-Version: PyGRT 0.7.1.dev5+g2230cdc.d20250427\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-04-22 15:39+0800\n" +"POT-Creation-Date: 2025-04-27 12:43+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: en\n" @@ -20,17 +20,14 @@ msgstr "" "Generated-By: Babel 2.16.0\n" #: ../../source/API/C_extension/common/bessel.rst:2 -#: 9401f023fdd3450f8aaac956587666c2 msgid "bessel.h" msgstr "" #: ../../source/API/C_extension/common/bessel.rst -#: 341c415d95e94b0ba50f272590430d55 msgid "Functions" msgstr "" #: ../../source/API/C_extension/common/bessel.rst -#: 60950234710749688b0043a633eccad0 c2c3e2ced4d24434bf61d8dcd47972a6 msgid "参数" msgstr "" diff --git a/docs/locales/en/LC_MESSAGES/API/C_extension/common/colorstr.po b/docs/locales/en/LC_MESSAGES/API/C_extension/common/colorstr.po index f77dbd72..e92c74f1 100644 --- a/docs/locales/en/LC_MESSAGES/API/C_extension/common/colorstr.po +++ b/docs/locales/en/LC_MESSAGES/API/C_extension/common/colorstr.po @@ -6,9 +6,9 @@ #, fuzzy msgid "" msgstr "" -"Project-Id-Version: PyGRT 0.6.1.dev1+g4641a40.d20250422\n" +"Project-Id-Version: PyGRT 0.7.1.dev5+g2230cdc.d20250427\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-04-22 15:39+0800\n" +"POT-Creation-Date: 2025-04-27 12:43+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: en\n" @@ -20,12 +20,10 @@ msgstr "" "Generated-By: Babel 2.16.0\n" #: ../../source/API/C_extension/common/colorstr.rst:2 -#: 40cbf7ce17ed4b7a96024947c64b970b msgid "colorstr.h" msgstr "" #: ../../source/API/C_extension/common/colorstr.rst -#: 6580f266f2904b7180a6023d4ddebf66 msgid "Defines" msgstr "" diff --git a/docs/locales/en/LC_MESSAGES/API/C_extension/common/const.po b/docs/locales/en/LC_MESSAGES/API/C_extension/common/const.po index 510ff5d9..5101c73e 100644 --- a/docs/locales/en/LC_MESSAGES/API/C_extension/common/const.po +++ b/docs/locales/en/LC_MESSAGES/API/C_extension/common/const.po @@ -6,9 +6,9 @@ #, fuzzy msgid "" msgstr "" -"Project-Id-Version: PyGRT 0.6.1.dev1+g4641a40.d20250422\n" +"Project-Id-Version: PyGRT 0.7.1.dev5+g2230cdc.d20250427\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-04-22 15:39+0800\n" +"POT-Creation-Date: 2025-04-27 12:43+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: en\n" @@ -20,17 +20,18 @@ msgstr "" "Generated-By: Babel 2.16.0\n" #: ../../source/API/C_extension/common/const.rst:2 -#: 5ee0a6dc0c324f108ae23edafb2e4494 msgid "const.h" msgstr "" #: ../../source/API/C_extension/common/const.rst -#: b9877214f7e742dfabb5fa33565832ef msgid "Defines" msgstr "" #: ../../source/API/C_extension/common/const.rst -#: 1fff5e2dd9a444719b696ad1638cdeaf msgid "Typedefs" msgstr "" +#: ../../source/API/C_extension/common/const.rst +msgid "Variables" +msgstr "" + diff --git a/docs/locales/en/LC_MESSAGES/API/C_extension/common/coord.po b/docs/locales/en/LC_MESSAGES/API/C_extension/common/coord.po index c99af011..6c91a005 100644 --- a/docs/locales/en/LC_MESSAGES/API/C_extension/common/coord.po +++ b/docs/locales/en/LC_MESSAGES/API/C_extension/common/coord.po @@ -6,9 +6,9 @@ #, fuzzy msgid "" msgstr "" -"Project-Id-Version: PyGRT 0.6.1.dev1+g4641a40.d20250422\n" +"Project-Id-Version: PyGRT 0.7.1.dev5+g2230cdc.d20250427\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-04-22 15:39+0800\n" +"POT-Creation-Date: 2025-04-27 12:43+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: en\n" @@ -20,18 +20,14 @@ msgstr "" "Generated-By: Babel 2.16.0\n" #: ../../source/API/C_extension/common/coord.rst:2 -#: acbced41c9ea49b78fc10ad2057032c3 msgid "coord.h" msgstr "" #: ../../source/API/C_extension/common/coord.rst -#: f3f1a7a8ef4c4505a1e06a14037d3d4a msgid "Functions" msgstr "" #: ../../source/API/C_extension/common/coord.rst -#: a73e1ce765844ab0b9f34ca2015d97ba d96cda1b752a44799f17964b66016233 -#: f0b2f9625133417696b6930c1392f010 msgid "参数" msgstr "" diff --git a/docs/locales/en/LC_MESSAGES/API/C_extension/common/dwm.po b/docs/locales/en/LC_MESSAGES/API/C_extension/common/dwm.po index f92a907a..000a7533 100644 --- a/docs/locales/en/LC_MESSAGES/API/C_extension/common/dwm.po +++ b/docs/locales/en/LC_MESSAGES/API/C_extension/common/dwm.po @@ -6,9 +6,9 @@ #, fuzzy msgid "" msgstr "" -"Project-Id-Version: PyGRT 0.6.1.dev1+g4641a40.d20250422\n" +"Project-Id-Version: PyGRT 0.7.1.dev5+g2230cdc.d20250427\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-04-22 15:39+0800\n" +"POT-Creation-Date: 2025-04-27 12:43+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: en\n" @@ -20,19 +20,18 @@ msgstr "" "Generated-By: Babel 2.16.0\n" #: ../../source/API/C_extension/common/dwm.rst:2 -#: 97ffb9698c354a498a81447cd9782d99 msgid "dwm.h" msgstr "" -#: ../../source/API/C_extension/common/dwm.rst 063a8d193c0642be808bc594ff188c25 +#: ../../source/API/C_extension/common/dwm.rst msgid "Functions" msgstr "" -#: ../../source/API/C_extension/common/dwm.rst e830564cd48548dba988ec10e9c17eb9 +#: ../../source/API/C_extension/common/dwm.rst msgid "参数" msgstr "" -#: ../../source/API/C_extension/common/dwm.rst f94f2a07d8ea47a48c159ea9d102533e +#: ../../source/API/C_extension/common/dwm.rst msgid "返回" msgstr "" diff --git a/docs/locales/en/LC_MESSAGES/API/C_extension/common/fim.po b/docs/locales/en/LC_MESSAGES/API/C_extension/common/fim.po index 01eb678c..a9234537 100644 --- a/docs/locales/en/LC_MESSAGES/API/C_extension/common/fim.po +++ b/docs/locales/en/LC_MESSAGES/API/C_extension/common/fim.po @@ -6,9 +6,9 @@ #, fuzzy msgid "" msgstr "" -"Project-Id-Version: PyGRT 0.6.1.dev1+g4641a40.d20250422\n" +"Project-Id-Version: PyGRT 0.7.1.dev5+g2230cdc.d20250427\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-04-22 15:39+0800\n" +"POT-Creation-Date: 2025-04-27 12:43+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: en\n" @@ -20,19 +20,18 @@ msgstr "" "Generated-By: Babel 2.16.0\n" #: ../../source/API/C_extension/common/fim.rst:2 -#: 7d0834d8663142efa312e3b6047152a8 msgid "fim.h" msgstr "" -#: ../../source/API/C_extension/common/fim.rst 09c08107d58f4cf49a0b60fa3ceb02b8 +#: ../../source/API/C_extension/common/fim.rst msgid "Functions" msgstr "" -#: ../../source/API/C_extension/common/fim.rst 29269d4539fe401db85dd0f93b302981 +#: ../../source/API/C_extension/common/fim.rst msgid "参数" msgstr "" -#: ../../source/API/C_extension/common/fim.rst c2d5ac81671a443c963319699b28ce8e +#: ../../source/API/C_extension/common/fim.rst msgid "返回" msgstr "" diff --git a/docs/locales/en/LC_MESSAGES/API/C_extension/common/integral.po b/docs/locales/en/LC_MESSAGES/API/C_extension/common/integral.po index 2d68257b..bd404459 100644 --- a/docs/locales/en/LC_MESSAGES/API/C_extension/common/integral.po +++ b/docs/locales/en/LC_MESSAGES/API/C_extension/common/integral.po @@ -6,9 +6,9 @@ #, fuzzy msgid "" msgstr "" -"Project-Id-Version: PyGRT 0.6.1.dev1+g4641a40.d20250422\n" +"Project-Id-Version: PyGRT 0.7.1.dev5+g2230cdc.d20250427\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-04-22 15:39+0800\n" +"POT-Creation-Date: 2025-04-27 12:43+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: en\n" @@ -20,18 +20,14 @@ msgstr "" "Generated-By: Babel 2.16.0\n" #: ../../source/API/C_extension/common/integral.rst:2 -#: 6abb4c7e6aed4a6289bd62fdf292aee8 msgid "integral.h" msgstr "" #: ../../source/API/C_extension/common/integral.rst -#: 51503e516b144c04bd8d0e7b34f5ec2c msgid "Functions" msgstr "" #: ../../source/API/C_extension/common/integral.rst -#: 07edee11f98f48a0b7512b6107204aec 9af82f7b94484cbbac2cd245cb4d31ad -#: f04cc646e9414e0ba935b8d1e31d89cf msgid "参数" msgstr "" diff --git a/docs/locales/en/LC_MESSAGES/API/C_extension/common/iostats.po b/docs/locales/en/LC_MESSAGES/API/C_extension/common/iostats.po index 295dfe39..fad0e809 100644 --- a/docs/locales/en/LC_MESSAGES/API/C_extension/common/iostats.po +++ b/docs/locales/en/LC_MESSAGES/API/C_extension/common/iostats.po @@ -6,9 +6,9 @@ #, fuzzy msgid "" msgstr "" -"Project-Id-Version: PyGRT 0.6.1.dev1+g4641a40.d20250422\n" +"Project-Id-Version: PyGRT 0.7.1.dev5+g2230cdc.d20250427\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-04-22 15:39+0800\n" +"POT-Creation-Date: 2025-04-27 12:43+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: en\n" @@ -20,17 +20,18 @@ msgstr "" "Generated-By: Babel 2.16.0\n" #: ../../source/API/C_extension/common/iostats.rst:2 -#: 4aeb82999f584dddba2a712941c0b80d msgid "iostats.h" msgstr "" #: ../../source/API/C_extension/common/iostats.rst -#: 87752904fe3440b7abe32882c8587cab msgid "Functions" msgstr "" #: ../../source/API/C_extension/common/iostats.rst -#: 27ee2d300235486ba9db07b9353b6ad8 916270ce181844829b2a53c8552cbb00 msgid "参数" msgstr "" +#: ../../source/API/C_extension/common/iostats.rst +msgid "返回" +msgstr "" + diff --git a/docs/locales/en/LC_MESSAGES/API/C_extension/common/kernel.po b/docs/locales/en/LC_MESSAGES/API/C_extension/common/kernel.po index 3bf5e435..12a6a108 100644 --- a/docs/locales/en/LC_MESSAGES/API/C_extension/common/kernel.po +++ b/docs/locales/en/LC_MESSAGES/API/C_extension/common/kernel.po @@ -6,9 +6,9 @@ #, fuzzy msgid "" msgstr "" -"Project-Id-Version: PyGRT 0.6.1.dev1+g4641a40.d20250422\n" +"Project-Id-Version: PyGRT 0.7.1.dev5+g2230cdc.d20250427\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-04-22 15:39+0800\n" +"POT-Creation-Date: 2025-04-27 12:43+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: en\n" @@ -20,12 +20,10 @@ msgstr "" "Generated-By: Babel 2.16.0\n" #: ../../source/API/C_extension/common/kernel.rst:2 -#: 2c4982cdebd64035b7af2ade4f94342c msgid "kernel.h" msgstr "" #: ../../source/API/C_extension/common/kernel.rst -#: 8d3ccf76599c428ca2d7123a8c2b40bf msgid "Typedefs" msgstr "" diff --git a/docs/locales/en/LC_MESSAGES/API/C_extension/common/logo.po b/docs/locales/en/LC_MESSAGES/API/C_extension/common/logo.po index 0eaa2f37..debf4636 100644 --- a/docs/locales/en/LC_MESSAGES/API/C_extension/common/logo.po +++ b/docs/locales/en/LC_MESSAGES/API/C_extension/common/logo.po @@ -6,9 +6,9 @@ #, fuzzy msgid "" msgstr "" -"Project-Id-Version: PyGRT 0.6.1.dev1+g4641a40.d20250422\n" +"Project-Id-Version: PyGRT 0.7.1.dev5+g2230cdc.d20250427\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-04-22 15:39+0800\n" +"POT-Creation-Date: 2025-04-27 12:43+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: en\n" @@ -20,12 +20,10 @@ msgstr "" "Generated-By: Babel 2.16.0\n" #: ../../source/API/C_extension/common/logo.rst:2 -#: 6c4269b957bf49409b960418a160f36d msgid "logo.h" msgstr "" #: ../../source/API/C_extension/common/logo.rst -#: 2be646264a7c459aa53cb1f7cd3b6428 msgid "Functions" msgstr "" diff --git a/docs/locales/en/LC_MESSAGES/API/C_extension/common/matrix.po b/docs/locales/en/LC_MESSAGES/API/C_extension/common/matrix.po index 36cbdf14..a26a0fdc 100644 --- a/docs/locales/en/LC_MESSAGES/API/C_extension/common/matrix.po +++ b/docs/locales/en/LC_MESSAGES/API/C_extension/common/matrix.po @@ -6,9 +6,9 @@ #, fuzzy msgid "" msgstr "" -"Project-Id-Version: PyGRT 0.6.1.dev1+g4641a40.d20250422\n" +"Project-Id-Version: PyGRT 0.7.1.dev5+g2230cdc.d20250427\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-04-22 15:39+0800\n" +"POT-Creation-Date: 2025-04-27 12:43+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: en\n" @@ -20,22 +20,14 @@ msgstr "" "Generated-By: Babel 2.16.0\n" #: ../../source/API/C_extension/common/matrix.rst:2 -#: 2ae830bb56444baf9184e19ae0a066e6 msgid "matrix.h" msgstr "" #: ../../source/API/C_extension/common/matrix.rst -#: 89717d215f8e46c091f148677f5d210e msgid "Functions" msgstr "" #: ../../source/API/C_extension/common/matrix.rst -#: 00b9d2d8ad4444daabc1147e137c4c7f 4709575009054192983c6891190404f0 -#: 4725f2a9aabb47e898afb50939995468 4f564625073e4458ba8ea9edebed4dca -#: 95566b7a64e345aea80a725e6fb3c1b2 9a28af2f73d04b4e8df968b10fcb0e4f -#: b84ee6a06d5442aa9130692298f2a5f4 c9e66e4430ab4f898b595aae21d78aaa -#: dc72ac49fe1a4d54b10747cd58e4877e e04955e63e6e4301b582df6f490cc288 -#: e8f85992964a4d6aaca224251e27c073 msgid "参数" msgstr "" diff --git a/docs/locales/en/LC_MESSAGES/API/C_extension/common/model.po b/docs/locales/en/LC_MESSAGES/API/C_extension/common/model.po index 7a00f6c9..47f73e66 100644 --- a/docs/locales/en/LC_MESSAGES/API/C_extension/common/model.po +++ b/docs/locales/en/LC_MESSAGES/API/C_extension/common/model.po @@ -6,9 +6,9 @@ #, fuzzy msgid "" msgstr "" -"Project-Id-Version: PyGRT 0.6.1.dev1+g4641a40.d20250422\n" +"Project-Id-Version: PyGRT 0.7.1.dev5+g2230cdc.d20250427\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-04-22 15:39+0800\n" +"POT-Creation-Date: 2025-04-27 12:43+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: en\n" @@ -20,38 +20,26 @@ msgstr "" "Generated-By: Babel 2.16.0\n" #: ../../source/API/C_extension/common/model.rst:2 -#: 146ff1af716e42c9bd73f991c9f858f5 msgid "model.h" msgstr "" #: ../../source/API/C_extension/common/model.rst -#: e5e50fa4065a4957810c7abf37fcbd08 msgid "Typedefs" msgstr "" #: ../../source/API/C_extension/common/model.rst -#: 4462b341925045f6990db9375e727bc9 msgid "Functions" msgstr "" #: ../../source/API/C_extension/common/model.rst -#: 13d7765d0b8b4497b85dff1a53ab8c35 1d21676c4f1f4aa7b47182e8808d465e -#: 2bb39a37140645a1a5c4e569cf4db19d 612dfe1179a44fd0b74cbe678258bc14 -#: 73cc787b40374b34b1892a748ca40d3b 754a89f5c1264a468c2ebe8a0a351fcb -#: 9cd6ce0c05b94294a229d939a1872bad a0dbb59ff77949489ca73de345331d1d -#: bd6443bc36a04878be00174700703aca d75b08ead0104866b491cacab8374f09 msgid "参数" msgstr "" #: ../../source/API/C_extension/common/model.rst -#: 355f3746cdda4d49b4a1737d59cf3070 6f0cf1bb9a2942aa8f9af7e94ba44f93 -#: cbbfc9cab15c4f8b943d28fd2db3539d msgid "返回" msgstr "" #: ../../source/API/C_extension/common/model.rst -#: 6c773f15b1834fdb933b4442c8ce29c6 b1efe8de57ec49dcaf64dabd0b6c02fb -#: b92f0b97869f4b109c6c5c28d82e00a1 e1e701639e014dc5a7089f3e13fc13ee msgid "Public Members" msgstr "" diff --git a/docs/locales/en/LC_MESSAGES/API/C_extension/common/progressbar.po b/docs/locales/en/LC_MESSAGES/API/C_extension/common/progressbar.po index 58628154..fea40a89 100644 --- a/docs/locales/en/LC_MESSAGES/API/C_extension/common/progressbar.po +++ b/docs/locales/en/LC_MESSAGES/API/C_extension/common/progressbar.po @@ -6,9 +6,9 @@ #, fuzzy msgid "" msgstr "" -"Project-Id-Version: PyGRT 0.6.1.dev1+g4641a40.d20250422\n" +"Project-Id-Version: PyGRT 0.7.1.dev5+g2230cdc.d20250427\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-04-22 15:39+0800\n" +"POT-Creation-Date: 2025-04-27 12:43+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: en\n" @@ -20,22 +20,18 @@ msgstr "" "Generated-By: Babel 2.16.0\n" #: ../../source/API/C_extension/common/progressbar.rst:2 -#: ea253215ce7142e3baa37704861c5bbd msgid "progressbar.h" msgstr "" #: ../../source/API/C_extension/common/progressbar.rst -#: 861b719d4efe4caea98f4f3a1dd85019 msgid "Defines" msgstr "" #: ../../source/API/C_extension/common/progressbar.rst -#: ff00755045ac48229df7d4297d14ee33 msgid "Functions" msgstr "" #: ../../source/API/C_extension/common/progressbar.rst -#: 316ca105279d4ec2bb9a84d185b193e9 msgid "参数" msgstr "" diff --git a/docs/locales/en/LC_MESSAGES/API/C_extension/common/prtdbg.po b/docs/locales/en/LC_MESSAGES/API/C_extension/common/prtdbg.po index b9a34602..600c4a55 100644 --- a/docs/locales/en/LC_MESSAGES/API/C_extension/common/prtdbg.po +++ b/docs/locales/en/LC_MESSAGES/API/C_extension/common/prtdbg.po @@ -6,9 +6,9 @@ #, fuzzy msgid "" msgstr "" -"Project-Id-Version: PyGRT 0.6.1.dev1+g4641a40.d20250422\n" +"Project-Id-Version: PyGRT 0.7.1.dev5+g2230cdc.d20250427\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-04-22 15:39+0800\n" +"POT-Creation-Date: 2025-04-27 12:43+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: en\n" @@ -20,12 +20,10 @@ msgstr "" "Generated-By: Babel 2.16.0\n" #: ../../source/API/C_extension/common/prtdbg.rst:2 -#: a3e53b286ddc474eb1fd21ae60cb2749 msgid "prtdbg.h" msgstr "" #: ../../source/API/C_extension/common/prtdbg.rst -#: f3dca077c33e4ae5bedb8c7ae18ef9e7 msgid "Defines" msgstr "" diff --git a/docs/locales/en/LC_MESSAGES/API/C_extension/common/ptam.po b/docs/locales/en/LC_MESSAGES/API/C_extension/common/ptam.po index 372d676c..ef2335d3 100644 --- a/docs/locales/en/LC_MESSAGES/API/C_extension/common/ptam.po +++ b/docs/locales/en/LC_MESSAGES/API/C_extension/common/ptam.po @@ -6,9 +6,9 @@ #, fuzzy msgid "" msgstr "" -"Project-Id-Version: PyGRT 0.6.1.dev1+g4641a40.d20250422\n" +"Project-Id-Version: PyGRT 0.7.1.dev5+g2230cdc.d20250427\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-04-22 15:39+0800\n" +"POT-Creation-Date: 2025-04-27 12:43+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: en\n" @@ -20,28 +20,18 @@ msgstr "" "Generated-By: Babel 2.16.0\n" #: ../../source/API/C_extension/common/ptam.rst:2 -#: 8c2db2c3c7344a59ab4263002792a311 msgid "ptam.h" msgstr "" #: ../../source/API/C_extension/common/ptam.rst -#: 513ae3f0daee41ad810c5f0820b743f9 -msgid "Defines" -msgstr "" - -#: ../../source/API/C_extension/common/ptam.rst -#: 187269ad75ca440d9f321afaba582d36 msgid "Functions" msgstr "" #: ../../source/API/C_extension/common/ptam.rst -#: 7fc4f1fe41bc473f9f00507d6ae0798a a304cb6d2535418a8cc11efce4790553 -#: c0cf6f45fea54402913b32a579ead583 msgid "参数" msgstr "" #: ../../source/API/C_extension/common/ptam.rst -#: 1a1048cf8d0a4562bd9b36db3ea8fae0 msgid "返回" msgstr "" diff --git a/docs/locales/en/LC_MESSAGES/API/C_extension/common/quadratic.po b/docs/locales/en/LC_MESSAGES/API/C_extension/common/quadratic.po index 838baafc..de9abaa3 100644 --- a/docs/locales/en/LC_MESSAGES/API/C_extension/common/quadratic.po +++ b/docs/locales/en/LC_MESSAGES/API/C_extension/common/quadratic.po @@ -6,9 +6,9 @@ #, fuzzy msgid "" msgstr "" -"Project-Id-Version: PyGRT 0.6.1.dev1+g4641a40.d20250422\n" +"Project-Id-Version: PyGRT 0.7.1.dev5+g2230cdc.d20250427\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-04-22 15:39+0800\n" +"POT-Creation-Date: 2025-04-27 12:43+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: en\n" @@ -20,23 +20,18 @@ msgstr "" "Generated-By: Babel 2.16.0\n" #: ../../source/API/C_extension/common/quadratic.rst:2 -#: 317610a82ddf417fa3d7a09267219584 msgid "quadratic.h" msgstr "" #: ../../source/API/C_extension/common/quadratic.rst -#: 5f3692dcb60a4c30ac9d8197667f1c44 msgid "Functions" msgstr "" #: ../../source/API/C_extension/common/quadratic.rst -#: 55b77a3d1dbc46ef9fc4e26063c66167 bfc1a8378e4e4a69b6cec24d47055f42 -#: cb982c5f51964c918feb785cb9aa7ab1 msgid "参数" msgstr "" #: ../../source/API/C_extension/common/quadratic.rst -#: 6b1617b423a24e80b530fe2e384eb5dc afbb5a5bd8fa4075b64c0fa028b99e85 msgid "返回" msgstr "" diff --git a/docs/locales/en/LC_MESSAGES/API/C_extension/common/radiation.po b/docs/locales/en/LC_MESSAGES/API/C_extension/common/radiation.po index 179679de..65d10084 100644 --- a/docs/locales/en/LC_MESSAGES/API/C_extension/common/radiation.po +++ b/docs/locales/en/LC_MESSAGES/API/C_extension/common/radiation.po @@ -6,9 +6,9 @@ #, fuzzy msgid "" msgstr "" -"Project-Id-Version: PyGRT 0.6.1.dev1+g4641a40.d20250422\n" +"Project-Id-Version: PyGRT 0.7.1.dev5+g2230cdc.d20250427\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-04-22 15:39+0800\n" +"POT-Creation-Date: 2025-04-27 12:43+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: en\n" @@ -20,22 +20,18 @@ msgstr "" "Generated-By: Babel 2.16.0\n" #: ../../source/API/C_extension/common/radiation.rst:2 -#: b216c433530044aaa2f40987a9690df1 msgid "radiation.h" msgstr "" #: ../../source/API/C_extension/common/radiation.rst -#: a8dd09a80185487ebbdd5073b2eeb3c4 msgid "Defines" msgstr "" #: ../../source/API/C_extension/common/radiation.rst -#: 715dbff82dfc4cd09fd67febdde977be msgid "Functions" msgstr "" #: ../../source/API/C_extension/common/radiation.rst -#: f0ac2e80a4ab412f95e0163f2c039467 msgid "参数" msgstr "" diff --git a/docs/locales/en/LC_MESSAGES/API/C_extension/common/recursion.po b/docs/locales/en/LC_MESSAGES/API/C_extension/common/recursion.po index ceafbdc1..fef4528f 100644 --- a/docs/locales/en/LC_MESSAGES/API/C_extension/common/recursion.po +++ b/docs/locales/en/LC_MESSAGES/API/C_extension/common/recursion.po @@ -6,9 +6,9 @@ #, fuzzy msgid "" msgstr "" -"Project-Id-Version: PyGRT 0.6.1.dev1+g4641a40.d20250422\n" +"Project-Id-Version: PyGRT 0.7.1.dev5+g2230cdc.d20250427\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-04-22 15:39+0800\n" +"POT-Creation-Date: 2025-04-27 12:43+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: en\n" @@ -20,20 +20,14 @@ msgstr "" "Generated-By: Babel 2.16.0\n" #: ../../source/API/C_extension/common/recursion.rst:2 -#: a88c6e433e6d49408a2853a204f82aed msgid "recursion.h" msgstr "" #: ../../source/API/C_extension/common/recursion.rst -#: ddb8ffbf91ae482a941cdfe9ebec2937 msgid "Functions" msgstr "" #: ../../source/API/C_extension/common/recursion.rst -#: 9f3595a7eee640fc8b3946b06f5d2def a85f9438e3954e53b67f0d95eafdd9d2 -#: bed37774600e427aa047f9e6e52818bb dacdbbabe6e74212b4f9d28d251f5a98 -#: ebc66f8634654faea722142559cb1e05 f4625a2a5ee344e7bfeac958d99151d7 -#: fc22ed367a97485cbecbbe3c17629131 msgid "参数" msgstr "" diff --git a/docs/locales/en/LC_MESSAGES/API/C_extension/common/sacio.po b/docs/locales/en/LC_MESSAGES/API/C_extension/common/sacio.po index e79ad654..30777437 100644 --- a/docs/locales/en/LC_MESSAGES/API/C_extension/common/sacio.po +++ b/docs/locales/en/LC_MESSAGES/API/C_extension/common/sacio.po @@ -6,9 +6,9 @@ #, fuzzy msgid "" msgstr "" -"Project-Id-Version: PyGRT 0.6.1.dev1+g4641a40.d20250422\n" +"Project-Id-Version: PyGRT 0.7.1.dev5+g2230cdc.d20250427\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-04-22 15:39+0800\n" +"POT-Creation-Date: 2025-04-27 12:43+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: en\n" @@ -20,27 +20,22 @@ msgstr "" "Generated-By: Babel 2.16.0\n" #: ../../source/API/C_extension/common/sacio.rst:2 -#: 6da4b0d7ad674f878e8ff70d32a1b800 msgid "sacio.h" msgstr "" #: ../../source/API/C_extension/common/sacio.rst -#: 7fd9710ce00e42efa4c1fe0e96ef651c msgid "Defines" msgstr "" #: ../../source/API/C_extension/common/sacio.rst -#: e3562ab288204e35ba80e176f8364a36 msgid "Typedefs" msgstr "" #: ../../source/API/C_extension/common/sacio.rst -#: ec46016ca4244ec186333c6f7765df43 msgid "Functions" msgstr "" #: ../../source/API/C_extension/common/sacio.rst -#: 62d9d7be941d4cb08211749777656ca3 msgid "Public Members" msgstr "" diff --git a/docs/locales/en/LC_MESSAGES/API/C_extension/common/sacio2.po b/docs/locales/en/LC_MESSAGES/API/C_extension/common/sacio2.po index fecf4c77..03205881 100644 --- a/docs/locales/en/LC_MESSAGES/API/C_extension/common/sacio2.po +++ b/docs/locales/en/LC_MESSAGES/API/C_extension/common/sacio2.po @@ -6,9 +6,9 @@ #, fuzzy msgid "" msgstr "" -"Project-Id-Version: PyGRT 0.6.1.dev1+g4641a40.d20250422\n" +"Project-Id-Version: PyGRT 0.7.1.dev5+g2230cdc.d20250427\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-04-22 15:39+0800\n" +"POT-Creation-Date: 2025-04-27 12:43+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: en\n" @@ -20,22 +20,18 @@ msgstr "" "Generated-By: Babel 2.16.0\n" #: ../../source/API/C_extension/common/sacio2.rst:2 -#: d98e4e5ff1d44aabb066a0066cb89934 msgid "sacio2.h" msgstr "" #: ../../source/API/C_extension/common/sacio2.rst -#: f79d55115f184aef84a1d021e6707f6a msgid "Functions" msgstr "" #: ../../source/API/C_extension/common/sacio2.rst -#: 458412aabe4d4b81aa04d5a1e840ecf3 71e47891304142668823c11ade6bf705 msgid "参数" msgstr "" #: ../../source/API/C_extension/common/sacio2.rst -#: e7afe3c9ab6f4a1fb72592db9d17b587 msgid "返回" msgstr "" diff --git a/docs/locales/en/LC_MESSAGES/API/C_extension/common/search.po b/docs/locales/en/LC_MESSAGES/API/C_extension/common/search.po index 256aa224..b3be4c16 100644 --- a/docs/locales/en/LC_MESSAGES/API/C_extension/common/search.po +++ b/docs/locales/en/LC_MESSAGES/API/C_extension/common/search.po @@ -6,9 +6,9 @@ #, fuzzy msgid "" msgstr "" -"Project-Id-Version: PyGRT 0.6.1.dev1+g4641a40.d20250422\n" +"Project-Id-Version: PyGRT 0.7.1.dev5+g2230cdc.d20250427\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-04-22 15:39+0800\n" +"POT-Creation-Date: 2025-04-27 12:43+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: en\n" @@ -20,24 +20,18 @@ msgstr "" "Generated-By: Babel 2.16.0\n" #: ../../source/API/C_extension/common/search.rst:2 -#: fac7f3a2d07b475eb0de58e0657a9d88 msgid "search.h" msgstr "" #: ../../source/API/C_extension/common/search.rst -#: 71a4b5c981ec475da5728dcbf9ad2f8a msgid "Functions" msgstr "" #: ../../source/API/C_extension/common/search.rst -#: 59ea4278efa84b709e0e5f606cfcf7a7 b37ef3cffda448bba823597fa607fe80 -#: ed62817de316410b843bf7415ea27ad7 ee7f08f0b9754987934c87974e6f5b1b msgid "参数" msgstr "" #: ../../source/API/C_extension/common/search.rst -#: 0f7dd64d8caa491689360e3c423773fe 50644d9fd6a9446f8ff9f141dae8693f -#: daee8a5abc5848ef9895212636efb614 e5f2e1c285c64411a9dd015a409a8a08 msgid "返回" msgstr "" diff --git a/docs/locales/en/LC_MESSAGES/API/C_extension/common/version.po b/docs/locales/en/LC_MESSAGES/API/C_extension/common/version.po index a8194d14..d951c07c 100644 --- a/docs/locales/en/LC_MESSAGES/API/C_extension/common/version.po +++ b/docs/locales/en/LC_MESSAGES/API/C_extension/common/version.po @@ -6,9 +6,9 @@ #, fuzzy msgid "" msgstr "" -"Project-Id-Version: PyGRT 0.6.1.dev1+g4641a40.d20250422\n" +"Project-Id-Version: PyGRT 0.7.1.dev5+g2230cdc.d20250427\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-04-22 15:39+0800\n" +"POT-Creation-Date: 2025-04-27 12:43+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: en\n" @@ -20,12 +20,10 @@ msgstr "" "Generated-By: Babel 2.16.0\n" #: ../../source/API/C_extension/common/version.rst:2 -#: 4473e4797fa9496582dc10bf4cdfec64 msgid "version.h" msgstr "" #: ../../source/API/C_extension/common/version.rst -#: 99f618860563447d95f894d351b7cb36 msgid "Defines" msgstr "" diff --git a/docs/locales/en/LC_MESSAGES/API/C_extension/dynamic.po b/docs/locales/en/LC_MESSAGES/API/C_extension/dynamic.po index 88967a27..7e5f11d1 100644 --- a/docs/locales/en/LC_MESSAGES/API/C_extension/dynamic.po +++ b/docs/locales/en/LC_MESSAGES/API/C_extension/dynamic.po @@ -6,9 +6,9 @@ #, fuzzy msgid "" msgstr "" -"Project-Id-Version: PyGRT 0.6.1.dev1+g4641a40.d20250422\n" +"Project-Id-Version: PyGRT 0.7.1.dev5+g2230cdc.d20250427\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-04-22 15:39+0800\n" +"POT-Creation-Date: 2025-04-27 12:43+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: en\n" @@ -19,7 +19,7 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 2.16.0\n" -#: ../../source/API/C_extension/dynamic.rst:2 c571a4cae2c14b7781953971f3a2fae3 +#: ../../source/API/C_extension/dynamic.rst:2 msgid "dynamic" msgstr "" diff --git a/docs/locales/en/LC_MESSAGES/API/C_extension/dynamic/grt.po b/docs/locales/en/LC_MESSAGES/API/C_extension/dynamic/grt.po index b9eec543..0dc328a7 100644 --- a/docs/locales/en/LC_MESSAGES/API/C_extension/dynamic/grt.po +++ b/docs/locales/en/LC_MESSAGES/API/C_extension/dynamic/grt.po @@ -6,9 +6,9 @@ #, fuzzy msgid "" msgstr "" -"Project-Id-Version: PyGRT 0.6.1.dev1+g4641a40.d20250422\n" +"Project-Id-Version: PyGRT 0.7.1.dev5+g2230cdc.d20250427\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-04-22 15:39+0800\n" +"POT-Creation-Date: 2025-04-27 12:43+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: en\n" @@ -20,18 +20,14 @@ msgstr "" "Generated-By: Babel 2.16.0\n" #: ../../source/API/C_extension/dynamic/grt.rst:2 -#: feb09f2a0cde423689070c32ac6e1566 msgid "grt.h" msgstr "" #: ../../source/API/C_extension/dynamic/grt.rst -#: 96332fca0b3d4ef9811fcfefb5e10ccb msgid "Functions" msgstr "" #: ../../source/API/C_extension/dynamic/grt.rst -#: 2b2823c594ea48cfb926e432b0e9a77e 4c81273412a74b779be02c9bbc3ec94b -#: 4d0d619870134815bd3c31c16762fa32 msgid "参数" msgstr "" diff --git a/docs/locales/en/LC_MESSAGES/API/C_extension/dynamic/layer.po b/docs/locales/en/LC_MESSAGES/API/C_extension/dynamic/layer.po index 26d34987..3a304ac5 100644 --- a/docs/locales/en/LC_MESSAGES/API/C_extension/dynamic/layer.po +++ b/docs/locales/en/LC_MESSAGES/API/C_extension/dynamic/layer.po @@ -6,9 +6,9 @@ #, fuzzy msgid "" msgstr "" -"Project-Id-Version: PyGRT 0.6.1.dev1+g4641a40.d20250422\n" +"Project-Id-Version: PyGRT 0.7.1.dev5+g2230cdc.d20250427\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-04-22 15:39+0800\n" +"POT-Creation-Date: 2025-04-27 12:43+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: en\n" @@ -20,19 +20,14 @@ msgstr "" "Generated-By: Babel 2.16.0\n" #: ../../source/API/C_extension/dynamic/layer.rst:2 -#: 8b5e4b1ab1c74a1c9c9f3dc809ad73ee msgid "layer.h" msgstr "" #: ../../source/API/C_extension/dynamic/layer.rst -#: 5f929b25a3124c84a1bcb6dc40a14350 msgid "Functions" msgstr "" #: ../../source/API/C_extension/dynamic/layer.rst -#: 11dd34b03e9b406296a85e92fb5fc337 35d502a7e7b04210ae2392de4136af52 -#: 448d7960db5e4a71ac02ac99b178cbe1 52c54f8c3ea842388adefba4adae16b5 -#: e79933dce6f144c4810c0e0e63180581 msgid "参数" msgstr "" diff --git a/docs/locales/en/LC_MESSAGES/API/C_extension/dynamic/propagate.po b/docs/locales/en/LC_MESSAGES/API/C_extension/dynamic/propagate.po index d4403814..28df31f4 100644 --- a/docs/locales/en/LC_MESSAGES/API/C_extension/dynamic/propagate.po +++ b/docs/locales/en/LC_MESSAGES/API/C_extension/dynamic/propagate.po @@ -6,9 +6,9 @@ #, fuzzy msgid "" msgstr "" -"Project-Id-Version: PyGRT 0.6.1.dev1+g4641a40.d20250422\n" +"Project-Id-Version: PyGRT 0.7.1.dev5+g2230cdc.d20250427\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-04-22 15:39+0800\n" +"POT-Creation-Date: 2025-04-27 12:43+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: en\n" @@ -20,17 +20,14 @@ msgstr "" "Generated-By: Babel 2.16.0\n" #: ../../source/API/C_extension/dynamic/propagate.rst:2 -#: 0d4cafe43d37485b9e13ef22c4304649 msgid "propagate.h" msgstr "" #: ../../source/API/C_extension/dynamic/propagate.rst -#: 870aed9fdef74926ba9a1babba449f56 msgid "Functions" msgstr "" #: ../../source/API/C_extension/dynamic/propagate.rst -#: 9a8656e7683e44968513fc29efdb5fc7 msgid "参数" msgstr "" diff --git a/docs/locales/en/LC_MESSAGES/API/C_extension/dynamic/signals.po b/docs/locales/en/LC_MESSAGES/API/C_extension/dynamic/signals.po index 832d070e..b9163ca7 100644 --- a/docs/locales/en/LC_MESSAGES/API/C_extension/dynamic/signals.po +++ b/docs/locales/en/LC_MESSAGES/API/C_extension/dynamic/signals.po @@ -6,9 +6,9 @@ #, fuzzy msgid "" msgstr "" -"Project-Id-Version: PyGRT 0.6.1.dev1+g4641a40.d20250422\n" +"Project-Id-Version: PyGRT 0.7.1.dev5+g2230cdc.d20250427\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-04-22 15:39+0800\n" +"POT-Creation-Date: 2025-04-27 12:43+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: en\n" @@ -20,35 +20,22 @@ msgstr "" "Generated-By: Babel 2.16.0\n" #: ../../source/API/C_extension/dynamic/signals.rst:2 -#: 42b45528df244c0f9934a860ce7de834 msgid "signals.h" msgstr "" #: ../../source/API/C_extension/dynamic/signals.rst -#: 4dcb6efcf9fb417fa0f6bfcd5cbeb404 msgid "Defines" msgstr "" #: ../../source/API/C_extension/dynamic/signals.rst -#: f189e9f1dbf74ac49729e5cffbe9aaa5 msgid "Functions" msgstr "" #: ../../source/API/C_extension/dynamic/signals.rst -#: 01e335c8960b408dbca88f326ba0c659 139760cee5ef40f6b3038d0dde5a4d42 -#: 2474707145c645d7a75d719b2ea14b1f 2a1dd1f71ad04d3ab18bd0450a34fde8 -#: 37404d4055ce47edb9b2552114775f81 5d2afddeeccb46ebaa6e29b6aebee8d0 -#: 672fee9a3fc447cf9e3d347fa313a274 8c5a9782fec24633b8df2626afc96a74 -#: 95378626a99a40fa821e3a631b448a86 b9007a9f3b0d40edbd1346bc9cff343f -#: c6f8a1dba70c42849ffff2166273737d f1c829bd7f4e4bbb9b1f24aec1551dd0 msgid "参数" msgstr "" #: ../../source/API/C_extension/dynamic/signals.rst -#: 07db9503c9e747da81ad86639cb1ca5d 1a562b1162414eeeb901a7132572d47a -#: 617c79a5877b49c7a77a870ac1422777 7b4af30c65144895b602f19eb82d9da4 -#: bb8176727e2b40f1a29029eeb0f59b36 e6668e1311684d61a9796921119ec228 -#: f23c6f075f8c40f28b3c5162f0029de8 msgid "返回" msgstr "" diff --git a/docs/locales/en/LC_MESSAGES/API/C_extension/dynamic/source.po b/docs/locales/en/LC_MESSAGES/API/C_extension/dynamic/source.po index d4295c1f..5e0a59fd 100644 --- a/docs/locales/en/LC_MESSAGES/API/C_extension/dynamic/source.po +++ b/docs/locales/en/LC_MESSAGES/API/C_extension/dynamic/source.po @@ -6,9 +6,9 @@ #, fuzzy msgid "" msgstr "" -"Project-Id-Version: PyGRT 0.6.1.dev1+g4641a40.d20250422\n" +"Project-Id-Version: PyGRT 0.7.1.dev5+g2230cdc.d20250427\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-04-22 15:39+0800\n" +"POT-Creation-Date: 2025-04-27 12:43+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: en\n" @@ -20,17 +20,14 @@ msgstr "" "Generated-By: Babel 2.16.0\n" #: ../../source/API/C_extension/dynamic/source.rst:2 -#: db1f7139e70841dbb223796cbab47964 msgid "source.h" msgstr "" #: ../../source/API/C_extension/dynamic/source.rst -#: dda037bd65ff4f28ab247985e00a50e4 msgid "Functions" msgstr "" #: ../../source/API/C_extension/dynamic/source.rst -#: 0cc31a0e8a414fc39136054589442960 msgid "参数" msgstr "" diff --git a/docs/locales/en/LC_MESSAGES/API/C_extension/static.po b/docs/locales/en/LC_MESSAGES/API/C_extension/static.po index 71afe72c..5c99a0b9 100644 --- a/docs/locales/en/LC_MESSAGES/API/C_extension/static.po +++ b/docs/locales/en/LC_MESSAGES/API/C_extension/static.po @@ -6,9 +6,9 @@ #, fuzzy msgid "" msgstr "" -"Project-Id-Version: PyGRT 0.6.1.dev1+g4641a40.d20250422\n" +"Project-Id-Version: PyGRT 0.7.1.dev5+g2230cdc.d20250427\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-04-22 15:39+0800\n" +"POT-Creation-Date: 2025-04-27 12:43+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: en\n" @@ -19,7 +19,7 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 2.16.0\n" -#: ../../source/API/C_extension/static.rst:2 29b4059c990b4a8b9683e557f9c56544 +#: ../../source/API/C_extension/static.rst:2 msgid "static" msgstr "" diff --git a/docs/locales/en/LC_MESSAGES/API/C_extension/static/static_layer.po b/docs/locales/en/LC_MESSAGES/API/C_extension/static/static_layer.po index cd9710f3..31ea07ed 100644 --- a/docs/locales/en/LC_MESSAGES/API/C_extension/static/static_layer.po +++ b/docs/locales/en/LC_MESSAGES/API/C_extension/static/static_layer.po @@ -6,9 +6,9 @@ #, fuzzy msgid "" msgstr "" -"Project-Id-Version: PyGRT 0.6.1.dev1+g4641a40.d20250422\n" +"Project-Id-Version: PyGRT 0.7.1.dev5+g2230cdc.d20250427\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-04-22 15:39+0800\n" +"POT-Creation-Date: 2025-04-27 12:43+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: en\n" @@ -20,18 +20,14 @@ msgstr "" "Generated-By: Babel 2.16.0\n" #: ../../source/API/C_extension/static/static_layer.rst:2 -#: 8f219523eb8c4ab3ae838290b2a5362b msgid "static_layer.h" msgstr "" #: ../../source/API/C_extension/static/static_layer.rst -#: 4a38c345ff0741e191394f0b06bae481 msgid "Functions" msgstr "" #: ../../source/API/C_extension/static/static_layer.rst -#: 1a67a3358550415fb8f1bdc7b58317d8 3862ffb5dfac4de4b3d8e9eb11e77f3a -#: 4b86cd980ede4f7d830d5ec5efd65fe6 e19f605279254c20a29878e2e57a8a05 msgid "参数" msgstr "" diff --git a/docs/locales/en/LC_MESSAGES/API/C_extension/static/static_propagate.po b/docs/locales/en/LC_MESSAGES/API/C_extension/static/static_propagate.po index 187f2450..5c754fa5 100644 --- a/docs/locales/en/LC_MESSAGES/API/C_extension/static/static_propagate.po +++ b/docs/locales/en/LC_MESSAGES/API/C_extension/static/static_propagate.po @@ -6,9 +6,9 @@ #, fuzzy msgid "" msgstr "" -"Project-Id-Version: PyGRT 0.6.1.dev1+g4641a40.d20250422\n" +"Project-Id-Version: PyGRT 0.7.1.dev5+g2230cdc.d20250427\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-04-22 15:39+0800\n" +"POT-Creation-Date: 2025-04-27 12:43+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: en\n" @@ -20,12 +20,10 @@ msgstr "" "Generated-By: Babel 2.16.0\n" #: ../../source/API/C_extension/static/static_propagate.rst:2 -#: 470428e5443a41649dba48cbb2af3eb5 msgid "static_propagate.h" msgstr "" #: ../../source/API/C_extension/static/static_propagate.rst -#: 99dbbaf4f92e447d96159bb199467c5d msgid "Functions" msgstr "" diff --git a/docs/locales/en/LC_MESSAGES/API/C_extension/static/static_source.po b/docs/locales/en/LC_MESSAGES/API/C_extension/static/static_source.po index b2a54204..4c20b757 100644 --- a/docs/locales/en/LC_MESSAGES/API/C_extension/static/static_source.po +++ b/docs/locales/en/LC_MESSAGES/API/C_extension/static/static_source.po @@ -6,9 +6,9 @@ #, fuzzy msgid "" msgstr "" -"Project-Id-Version: PyGRT 0.6.1.dev1+g4641a40.d20250422\n" +"Project-Id-Version: PyGRT 0.7.1.dev5+g2230cdc.d20250427\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-04-22 15:39+0800\n" +"POT-Creation-Date: 2025-04-27 12:43+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: en\n" @@ -20,17 +20,14 @@ msgstr "" "Generated-By: Babel 2.16.0\n" #: ../../source/API/C_extension/static/static_source.rst:2 -#: cdff0d3ec34945ccb66251ed4abfc723 msgid "static_source.h" msgstr "" #: ../../source/API/C_extension/static/static_source.rst -#: 1432cf12a87244cc9d107aad55b26a54 msgid "Functions" msgstr "" #: ../../source/API/C_extension/static/static_source.rst -#: 0ae4f10b683a4471aee3b62c4ae436aa msgid "参数" msgstr "" diff --git a/docs/locales/en/LC_MESSAGES/API/C_extension/static/stgrt.po b/docs/locales/en/LC_MESSAGES/API/C_extension/static/stgrt.po index 5e52752d..c4a1cfd0 100644 --- a/docs/locales/en/LC_MESSAGES/API/C_extension/static/stgrt.po +++ b/docs/locales/en/LC_MESSAGES/API/C_extension/static/stgrt.po @@ -6,9 +6,9 @@ #, fuzzy msgid "" msgstr "" -"Project-Id-Version: PyGRT 0.6.1.dev1+g4641a40.d20250422\n" +"Project-Id-Version: PyGRT 0.7.1.dev5+g2230cdc.d20250427\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-04-22 15:39+0800\n" +"POT-Creation-Date: 2025-04-27 12:43+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: en\n" @@ -20,17 +20,14 @@ msgstr "" "Generated-By: Babel 2.16.0\n" #: ../../source/API/C_extension/static/stgrt.rst:2 -#: 2eb911ae24084926b04b5b66b8e4b4fd msgid "stgrt.h" msgstr "" #: ../../source/API/C_extension/static/stgrt.rst -#: a6b1d6d90c5c4a0fa106e54b720a6795 msgid "Functions" msgstr "" #: ../../source/API/C_extension/static/stgrt.rst -#: 3e753bf44a11437bb7b6268e74bee09d msgid "参数" msgstr "" diff --git a/docs/locales/en/LC_MESSAGES/API/C_extension/travt.po b/docs/locales/en/LC_MESSAGES/API/C_extension/travt.po index bc5328af..16d6fc78 100644 --- a/docs/locales/en/LC_MESSAGES/API/C_extension/travt.po +++ b/docs/locales/en/LC_MESSAGES/API/C_extension/travt.po @@ -6,9 +6,9 @@ #, fuzzy msgid "" msgstr "" -"Project-Id-Version: PyGRT 0.6.1.dev1+g4641a40.d20250422\n" +"Project-Id-Version: PyGRT 0.7.1.dev5+g2230cdc.d20250427\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-04-22 15:39+0800\n" +"POT-Creation-Date: 2025-04-27 12:43+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: en\n" @@ -19,7 +19,7 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 2.16.0\n" -#: ../../source/API/C_extension/travt.rst:2 cec25f51688f41759991f6177269a91d +#: ../../source/API/C_extension/travt.rst:2 msgid "travt" msgstr "" diff --git a/docs/locales/en/LC_MESSAGES/API/C_extension/travt/travt.po b/docs/locales/en/LC_MESSAGES/API/C_extension/travt/travt.po index 6a7b9e38..235f285c 100644 --- a/docs/locales/en/LC_MESSAGES/API/C_extension/travt/travt.po +++ b/docs/locales/en/LC_MESSAGES/API/C_extension/travt/travt.po @@ -6,9 +6,9 @@ #, fuzzy msgid "" msgstr "" -"Project-Id-Version: PyGRT 0.6.1.dev1+g4641a40.d20250422\n" +"Project-Id-Version: PyGRT 0.7.1.dev5+g2230cdc.d20250427\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-04-22 15:39+0800\n" +"POT-Creation-Date: 2025-04-27 12:43+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: en\n" @@ -20,17 +20,14 @@ msgstr "" "Generated-By: Babel 2.16.0\n" #: ../../source/API/C_extension/travt/travt.rst:2 -#: f257dc831f804cb9bbbfe669ef6dfa87 msgid "travt.h" msgstr "" #: ../../source/API/C_extension/travt/travt.rst -#: 011ff5f0c1434ada87064a9231ddd252 msgid "Functions" msgstr "" #: ../../source/API/C_extension/travt/travt.rst -#: 2d4bb4d4e7d2486aa203c4ef93ee9395 msgid "参数" msgstr "" diff --git a/docs/locales/en/LC_MESSAGES/API/api.po b/docs/locales/en/LC_MESSAGES/API/api.po index 65b27fa5..a3eebda9 100644 --- a/docs/locales/en/LC_MESSAGES/API/api.po +++ b/docs/locales/en/LC_MESSAGES/API/api.po @@ -6,9 +6,9 @@ #, fuzzy msgid "" msgstr "" -"Project-Id-Version: PyGRT 0.6.1.dev1+g4641a40.d20250422\n" +"Project-Id-Version: PyGRT 0.7.1.dev5+g2230cdc.d20250427\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-04-22 15:39+0800\n" +"POT-Creation-Date: 2025-04-27 12:43+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: en\n" @@ -19,23 +19,23 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 2.16.0\n" -#: ../../source/API/api.rst:2 7abc91b4ae5d4cd0a51c3bd90d6e6521 +#: ../../source/API/api.rst:2 msgid "Application Programming Interface" msgstr "" -#: ../../source/API/api.rst 670a8aa99daf42edb471cceaca2c7d68 +#: ../../source/API/api.rst msgid "Author" msgstr "" -#: ../../source/API/api.rst:4 62129516dcf44320b6545c63f5ce2e46 +#: ../../source/API/api.rst:4 msgid "Zhu Dengda" msgstr "" -#: ../../source/API/api.rst b0a304df385e4fee892e3c4c58012020 +#: ../../source/API/api.rst msgid "Email" msgstr "" -#: ../../source/API/api.rst:5 4f2222f561274c01909b783b1259c8c2 +#: ../../source/API/api.rst:5 msgid "zhudengda@mail.iggcas.ac.cn" msgstr "" diff --git a/docs/locales/en/LC_MESSAGES/API/c_api.po b/docs/locales/en/LC_MESSAGES/API/c_api.po index a35e506c..5746e965 100644 --- a/docs/locales/en/LC_MESSAGES/API/c_api.po +++ b/docs/locales/en/LC_MESSAGES/API/c_api.po @@ -6,9 +6,9 @@ #, fuzzy msgid "" msgstr "" -"Project-Id-Version: PyGRT 0.6.1.dev1+g4641a40.d20250422\n" +"Project-Id-Version: PyGRT 0.7.1.dev5+g2230cdc.d20250427\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-04-22 15:39+0800\n" +"POT-Creation-Date: 2025-04-27 12:43+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: en\n" @@ -19,23 +19,23 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 2.16.0\n" -#: ../../source/API/c_api.rst:2 c7c6e42948b84c5ba50538fc0242c79d +#: ../../source/API/c_api.rst:2 msgid "C extension API" msgstr "" -#: ../../source/API/c_api.rst 5e866a32e9dc4151854ed5c8ff2e4450 +#: ../../source/API/c_api.rst msgid "Author" msgstr "" -#: ../../source/API/c_api.rst:4 26f6e008b21f40108b5b5ee2e1a29e00 +#: ../../source/API/c_api.rst:4 msgid "Zhu Dengda" msgstr "" -#: ../../source/API/c_api.rst b76fc6593d04446b9f1a2063de5dd616 +#: ../../source/API/c_api.rst msgid "Email" msgstr "" -#: ../../source/API/c_api.rst:5 8365ab0099ca4cee9fff0d2d8c864a8e +#: ../../source/API/c_api.rst:5 msgid "zhudengda@mail.iggcas.ac.cn" msgstr "" diff --git a/docs/locales/en/LC_MESSAGES/API/py_api.po b/docs/locales/en/LC_MESSAGES/API/py_api.po index 12731f43..abe4ad0e 100644 --- a/docs/locales/en/LC_MESSAGES/API/py_api.po +++ b/docs/locales/en/LC_MESSAGES/API/py_api.po @@ -6,9 +6,9 @@ #, fuzzy msgid "" msgstr "" -"Project-Id-Version: PyGRT 0.6.1.dev1+g4641a40.d20250422\n" +"Project-Id-Version: PyGRT 0.7.1.dev5+g2230cdc.d20250427\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-04-22 15:39+0800\n" +"POT-Creation-Date: 2025-04-27 12:43+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: en\n" @@ -19,23 +19,23 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 2.16.0\n" -#: ../../source/API/py_api.rst:2 ab55187afc624c248cc23562c7b5f7ab +#: ../../source/API/py_api.rst:2 msgid "**PyGRT** package API" msgstr "" -#: ../../source/API/py_api.rst ee513f9c98654a85bae243507b43816c +#: ../../source/API/py_api.rst msgid "Author" msgstr "" -#: ../../source/API/py_api.rst:4 3e64819eeae04d659a42b9d4a67eeb91 +#: ../../source/API/py_api.rst:4 msgid "Zhu Dengda" msgstr "" -#: ../../source/API/py_api.rst f9f01d8700924cd691642e0c713fcbc3 +#: ../../source/API/py_api.rst msgid "Email" msgstr "" -#: ../../source/API/py_api.rst:5 08f538ca09844cf392dd651e63868f42 +#: ../../source/API/py_api.rst:5 msgid "zhudengda@mail.iggcas.ac.cn" msgstr "" diff --git a/docs/locales/en/LC_MESSAGES/API/pygrt/c_interfaces.po b/docs/locales/en/LC_MESSAGES/API/pygrt/c_interfaces.po index 46d1fe06..6f784423 100644 --- a/docs/locales/en/LC_MESSAGES/API/pygrt/c_interfaces.po +++ b/docs/locales/en/LC_MESSAGES/API/pygrt/c_interfaces.po @@ -6,9 +6,9 @@ #, fuzzy msgid "" msgstr "" -"Project-Id-Version: PyGRT 0.6.1.dev1+g4641a40.d20250422\n" +"Project-Id-Version: PyGRT 0.7.1.dev5+g2230cdc.d20250427\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-04-22 15:39+0800\n" +"POT-Creation-Date: 2025-04-27 12:43+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: en\n" @@ -19,112 +19,99 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 2.16.0\n" -#: ../../source/API/pygrt/c_interfaces.rst:2 c392e8f1eba74dc492760c0320c62bfd +#: ../../source/API/pygrt/c_interfaces.rst:2 msgid "pygrt.c_interfaces" msgstr "" -#: a4cf2b596478429ebe2b7d625ef889a4 of pygrt.c_interfaces +#: of pygrt.c_interfaces msgid "file" msgstr "" -#: 33ebf2a2cead447c8344ffe3dba111da of pygrt.c_interfaces:1 +#: of pygrt.c_interfaces:1 msgid "c_interfaces.py" msgstr "" -#: 414ef6de14834748bb00501639a42618 of pygrt.c_interfaces +#: of pygrt.c_interfaces msgid "author" msgstr "" -#: 7c29551586584112848664dbd9a5a1a3 of pygrt.c_interfaces:2 +#: of pygrt.c_interfaces:2 msgid "Zhu Dengda (zhudengda@mail.iggcas.ac.cn)" msgstr "" -#: 71f96ccdf4f3414497186d2134f8ac9c of pygrt.c_interfaces +#: of pygrt.c_interfaces msgid "date" msgstr "" -#: 089947839a5d4cd49cf197ee96e1e3aa of pygrt.c_interfaces:3 +#: of pygrt.c_interfaces:3 msgid "2024-07-24" msgstr "" -#: bae85e44a35448b9b06370676f8c1706 of pygrt.c_interfaces:5 +#: of pygrt.c_interfaces:5 msgid "该文件包括 C库的调用接口" msgstr "" -#: ../../docstring 4966d725b96a46f6bf165e593ea66368 of -#: pygrt.c_interfaces.libgrt:1 +#: ../../docstring of pygrt.c_interfaces.libgrt:1 msgid "libgrt库" msgstr "" -#: ../../docstring 61b75a54e8c84df7be938091f0c5e460 of -#: pygrt.c_interfaces.C_integ_grn_spec:1 +#: ../../docstring of pygrt.c_interfaces.C_integ_grn_spec:1 msgid "C库中计算格林函数的主函数 integ_grn_spec, 详见C API同名函数" msgstr "" -#: ../../docstring db3d882ca7d349c0a1a597640cc95f49 of -#: pygrt.c_interfaces.C_integ_static_grn:1 +#: ../../docstring of pygrt.c_interfaces.C_integ_static_grn:1 msgid "计算静态格林函数" msgstr "" -#: ../../docstring dec045f3e8ff45119ed3d4fb4ab96dc5 of -#: pygrt.c_interfaces.C_set_num_threads:1 +#: ../../docstring of pygrt.c_interfaces.C_set_num_threads:1 msgid "设置多线程数" msgstr "" -#: 242f92caba4840ba97013af03da1f81d of pygrt.c_interfaces.set_num_threads:1 +#: of pygrt.c_interfaces.set_num_threads:1 msgid "定义计算使用的多线程数" msgstr "" -#: ../../source/API/pygrt/c_interfaces.rst ddd2351a2b9449728f62070c3a609d20 +#: ../../source/API/pygrt/c_interfaces.rst msgid "参数" msgstr "" -#: 011b5ac2e947425bb3d15f2d66170110 of pygrt.c_interfaces.set_num_threads:3 +#: of pygrt.c_interfaces.set_num_threads:3 msgid "线程数" msgstr "" -#: ../../docstring 64efd0c792ae4db6bd3d6b2b444dc4db of -#: pygrt.c_interfaces.C_compute_travt1d:1 +#: ../../docstring of pygrt.c_interfaces.C_compute_travt1d:1 msgid "计算1D层状半空间的初至波走时" msgstr "" -#: ../../docstring bd7063369bf04db3976545757262b086 of -#: pygrt.c_interfaces.C_free:1 +#: ../../docstring of pygrt.c_interfaces.C_free:1 msgid "释放在C中申请的内存" msgstr "" -#: ../../docstring 84ae91e084364a6b90ec7aa9205905fd of -#: pygrt.c_interfaces.C_get_trap_wave:1 +#: ../../docstring of pygrt.c_interfaces.C_get_trap_wave:1 msgid "梯形波" msgstr "" -#: ../../docstring ad801dfe029a4640b8c59a64cc12ab0f of -#: pygrt.c_interfaces.C_get_parabola_wave:1 +#: ../../docstring of pygrt.c_interfaces.C_get_parabola_wave:1 msgid "抛物波" msgstr "" -#: ../../docstring 3fe8311407c5467fb642ea75d11a7afe of -#: pygrt.c_interfaces.C_get_ricker_wave:1 +#: ../../docstring of pygrt.c_interfaces.C_get_ricker_wave:1 msgid "雷克子波" msgstr "" -#: ../../docstring 90efa74bfb5349619288f7a5d7615348 of -#: pygrt.c_interfaces.C_rot_zxy2zrt_vec:1 +#: ../../docstring of pygrt.c_interfaces.C_rot_zxy2zrt_vec:1 msgid "直角坐标zxy到柱坐标zrt的矢量旋转" msgstr "" -#: ../../docstring 0f2c8f21e12d41fb8cec0089f541c076 of -#: pygrt.c_interfaces.C_rot_zxy2zrt_symtensor2odr:1 +#: ../../docstring of pygrt.c_interfaces.C_rot_zxy2zrt_symtensor2odr:1 msgid "直角坐标zxy到柱坐标zrt的二阶对称张量旋转" msgstr "" -#: ../../docstring 3a91987dfb06461084883ce48f054c83 of -#: pygrt.c_interfaces.C_rot_zrt2zxy_upar:1 +#: ../../docstring of pygrt.c_interfaces.C_rot_zrt2zxy_upar:1 msgid "柱坐标下的位移偏导 ∂u(z,r,t)/∂(z,r,t) 转到 直角坐标 ∂u(z,x,y)/∂(z,x,y)" msgstr "" -#: ../../docstring e0efdbe9990e41629b836c0eb8bf9df1 of -#: pygrt.c_interfaces.C_py_attenuation_law:1 +#: ../../docstring of pygrt.c_interfaces.C_py_attenuation_law:1 msgid "品质因子Q 对 波速的影响" msgstr "" diff --git a/docs/locales/en/LC_MESSAGES/API/pygrt/c_structures.po b/docs/locales/en/LC_MESSAGES/API/pygrt/c_structures.po index 81a6bcbc..8d5d188d 100644 --- a/docs/locales/en/LC_MESSAGES/API/pygrt/c_structures.po +++ b/docs/locales/en/LC_MESSAGES/API/pygrt/c_structures.po @@ -6,9 +6,9 @@ #, fuzzy msgid "" msgstr "" -"Project-Id-Version: PyGRT 0.6.1.dev1+g4641a40.d20250422\n" +"Project-Id-Version: PyGRT 0.7.1.dev5+g2230cdc.d20250427\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-04-22 15:39+0800\n" +"POT-Creation-Date: 2025-04-27 12:43+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: en\n" @@ -19,157 +19,147 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 2.16.0\n" -#: ../../source/API/pygrt/c_structures.rst:2 0767e69a63ba449286e76b7a2181b88a +#: ../../source/API/pygrt/c_structures.rst:2 msgid "pygrt.c_structures" msgstr "" -#: f625debcf928481baefdd851b7e377be of pygrt.c_structures +#: of pygrt.c_structures msgid "file" msgstr "" -#: cb340b06f33e433483e4ed29e33e472a of pygrt.c_structures:1 +#: of pygrt.c_structures:1 msgid "c_structures.py" msgstr "" -#: 7b152176aed2440d928964b5d33e69b2 of pygrt.c_structures +#: of pygrt.c_structures msgid "author" msgstr "" -#: 699dfc3374bd4ca386f2b36f9173248d of pygrt.c_structures:2 +#: of pygrt.c_structures:2 msgid "Zhu Dengda (zhudengda@mail.iggcas.ac.cn)" msgstr "" -#: 23081209834d494ebeb2c4350a365ef5 of pygrt.c_structures +#: of pygrt.c_structures msgid "date" msgstr "" -#: 4d496799cb67414dbaa4028b1c8a6d37 of pygrt.c_structures:3 +#: of pygrt.c_structures:3 msgid "2024-07-24" msgstr "" -#: 5df5fdebd02e49f4892afdfc0dc9eb24 of pygrt.c_structures:6 +#: of pygrt.c_structures:6 msgid "该文件包括" msgstr "" -#: b4dc1551d9f34d55abcef293a6bb0f3e of pygrt.c_structures:6 +#: of pygrt.c_structures:6 msgid "1、模型结构体的C接口 c_PyModel1D 2、格林函数结构体的C接口 c_GRN" msgstr "" -#: 0cb833b971394b8fbce6f3f2a4ee3934 a3f995397a2e4972a2c3c974680c4924 of -#: pygrt.c_structures.c_GRN:1 pygrt.c_structures.c_PyModel1D:1 +#: of pygrt.c_structures.c_PyModel1D:1 msgid "基类::py:class:`~_ctypes.Structure`" msgstr "" -#: a8b1d26a5b994e3c94d5ddea15a9dbda of pygrt.c_structures.c_PyModel1D:1 +#: of pygrt.c_structures.c_PyModel1D:1 msgid "和C结构体PYMODEL1D作匹配" msgstr "" -#: 34ca3ff9b9d740268f13a7bebf391a3c of pygrt.c_structures.c_PyModel1D +#: of pygrt.c_structures.c_PyModel1D msgid "field n" msgstr "" -#: e0e1939fdb2a40a088bb79bd4001c67e of pygrt.c_structures.c_PyModel1D:3 +#: of pygrt.c_structures.c_PyModel1D:3 msgid "层数" msgstr "" -#: 6097f127304e470b8697ef1c5dbc54a6 of pygrt.c_structures.c_PyModel1D +#: of pygrt.c_structures.c_PyModel1D msgid "filed depsrc" msgstr "" -#: 6af3b0e52e7b4f8ea9c1d8ea7cb56554 of pygrt.c_structures.c_PyModel1D:4 +#: of pygrt.c_structures.c_PyModel1D:4 msgid "震源深度 km" msgstr "" -#: bd80a9b1ddda4c638806132bc96e24f0 of pygrt.c_structures.c_PyModel1D +#: of pygrt.c_structures.c_PyModel1D msgid "filed deprcv" msgstr "" -#: dfaefbc85eb848309aeea9bd12f69e33 of pygrt.c_structures.c_PyModel1D:5 +#: of pygrt.c_structures.c_PyModel1D:5 msgid "接收点深度 km" msgstr "" -#: c867def132894191b7599166e255ad58 of pygrt.c_structures.c_PyModel1D +#: of pygrt.c_structures.c_PyModel1D msgid "field isrc" msgstr "" -#: d92352993dbf4a25b8c02f6c356daf8b of pygrt.c_structures.c_PyModel1D:6 +#: of pygrt.c_structures.c_PyModel1D:6 msgid "震源所在层位" msgstr "" -#: b05fdc874a3541138ccd4e3d0ff64fbb of pygrt.c_structures.c_PyModel1D +#: of pygrt.c_structures.c_PyModel1D msgid "field ircv" msgstr "" -#: 6f1116ff67ae46959875360b919cce47 of pygrt.c_structures.c_PyModel1D:7 +#: of pygrt.c_structures.c_PyModel1D:7 msgid "台站所在层位" msgstr "" -#: a8159a07dd3440798520bf671495cbf3 of pygrt.c_structures.c_PyModel1D +#: of pygrt.c_structures.c_PyModel1D msgid "field ircvup" msgstr "" -#: 6dc27f1f9d8b46518a80769ce187c633 of pygrt.c_structures.c_PyModel1D:8 +#: of pygrt.c_structures.c_PyModel1D:8 msgid "台站层位是否高于震源" msgstr "" -#: 66dfa444313045578d5b2c230eb3c5b1 of pygrt.c_structures.c_PyModel1D +#: of pygrt.c_structures.c_PyModel1D msgid "field thk" msgstr "" -#: de647f3fab044d0aaf3301dea8220144 of pygrt.c_structures.c_PyModel1D:9 +#: of pygrt.c_structures.c_PyModel1D:9 msgid "数组, 每层层厚(km)" msgstr "" -#: 5b3d218a8bd84915a0d7bee237295ca7 of pygrt.c_structures.c_PyModel1D +#: of pygrt.c_structures.c_PyModel1D msgid "field Va" msgstr "" -#: 657c864d5bcf48bc85046e437ff541a0 of pygrt.c_structures.c_PyModel1D:10 +#: of pygrt.c_structures.c_PyModel1D:10 msgid "数组, 每层P波速度(km/s)" msgstr "" -#: 8b4c52e85ab44e338131b06ebcf728a0 of pygrt.c_structures.c_PyModel1D +#: of pygrt.c_structures.c_PyModel1D msgid "field Vb" msgstr "" -#: 513dc1dd870d42dba313c0da77875c20 of pygrt.c_structures.c_PyModel1D:11 +#: of pygrt.c_structures.c_PyModel1D:11 msgid "数组, 每层S波速度(km/s)" msgstr "" -#: 2aef02276b044897ae2cd00993327eb0 of pygrt.c_structures.c_PyModel1D +#: of pygrt.c_structures.c_PyModel1D msgid "field Rho" msgstr "" -#: 6e9f4ce025204b36a7fda17359ef8534 of pygrt.c_structures.c_PyModel1D:12 +#: of pygrt.c_structures.c_PyModel1D:12 msgid "数组, 每层密度(g/cm^3)" msgstr "" -#: 7124d49feb664c9882756be9435a37fa of pygrt.c_structures.c_PyModel1D +#: of pygrt.c_structures.c_PyModel1D msgid "field Qa" msgstr "" -#: 96fcbadec96149d2a25e4358bcea6f18 of pygrt.c_structures.c_PyModel1D:13 +#: of pygrt.c_structures.c_PyModel1D:13 msgid "数组, 每层P波品质因子Q_P" msgstr "" -#: 94bdb40e142f4bfe9f37bc30b582b7e4 of pygrt.c_structures.c_PyModel1D +#: of pygrt.c_structures.c_PyModel1D msgid "field Qb" msgstr "" -#: f6902e6d8b764c2aa9b8dabc538f205e of pygrt.c_structures.c_PyModel1D:14 +#: of pygrt.c_structures.c_PyModel1D:14 msgid "数组, 每层S波品质因子Q_S" msgstr "" -#: ../../docstring 0650583e9c37401498d0e3103e9cba2e -#: 0da91f4c94604a219a70064c8175f886 2e17782f73024a4bb05be51121d76bbc -#: 4814b967051b4465bd34f2801618a00f 6d24ac5928cf4df58c7dac80ed3d5fab -#: 7382b49a5b974a2cb9e8b606da21bca9 857e1fe697334efd9b4362232152791c -#: 8d3f87733e31481c8921343d7e6886c0 8ef68e1991c9406c8e4bbd6247088b18 -#: a20cbb295a624e25b856e71dba363e3b c159019efae449519057831aaec12fe1 -#: d29221a4ac254b37be6eb806e6d4bb9e e310b3d05aa04177bd0f3f2fac71f2d4 -#: f57503eb7166497a82a12944571d9087 fd8dac208e69414ea1c8591b2e43dd02 of -#: pygrt.c_structures.c_GRN.Im:1 pygrt.c_structures.c_GRN.Re:1 -#: pygrt.c_structures.c_GRN.nf:1 pygrt.c_structures.c_PyModel1D.Qa:1 +#: ../../docstring of pygrt.c_structures.c_PyModel1D.Qa:1 #: pygrt.c_structures.c_PyModel1D.Qb:1 pygrt.c_structures.c_PyModel1D.Rho:1 #: pygrt.c_structures.c_PyModel1D.Thk:1 pygrt.c_structures.c_PyModel1D.Va:1 #: pygrt.c_structures.c_PyModel1D.Vb:1 pygrt.c_structures.c_PyModel1D.deprcv:1 @@ -180,31 +170,3 @@ msgstr "" msgid "Structure/Union member" msgstr "" -#: b3185042c9634330bd9910e4f49bf05c of pygrt.c_structures.c_GRN:1 -msgid "和C结构体GRN作匹配" -msgstr "" - -#: 844211e16ba1496996dd14c3c194c85b of pygrt.c_structures.c_GRN -msgid "field nf" -msgstr "" - -#: 36cbc079f337455c943301649960eed1 of pygrt.c_structures.c_GRN:3 -msgid "频率点数" -msgstr "" - -#: ec86790f0e824564a7cc8d8727b68c95 of pygrt.c_structures.c_GRN -msgid "field Re" -msgstr "" - -#: 3bb5efd27dd240abafd9af29c9836b98 of pygrt.c_structures.c_GRN:4 -msgid "频谱实部" -msgstr "" - -#: a268ad0b582749f880f8902fcd550993 of pygrt.c_structures.c_GRN -msgid "field Im" -msgstr "" - -#: 8c35a9197e734890b27cabbfd21a75f1 of pygrt.c_structures.c_GRN:5 -msgid "频谱虚部" -msgstr "" - diff --git a/docs/locales/en/LC_MESSAGES/API/pygrt/pygrn.po b/docs/locales/en/LC_MESSAGES/API/pygrt/pygrn.po index 8bda291d..9c1dfd50 100644 --- a/docs/locales/en/LC_MESSAGES/API/pygrt/pygrn.po +++ b/docs/locales/en/LC_MESSAGES/API/pygrt/pygrn.po @@ -6,9 +6,9 @@ #, fuzzy msgid "" msgstr "" -"Project-Id-Version: PyGRT 0.6.1.dev1+g4641a40.d20250422\n" +"Project-Id-Version: PyGRT 0.7.1.dev5+g2230cdc.d20250427\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-04-22 15:39+0800\n" +"POT-Creation-Date: 2025-04-27 12:43+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: en\n" @@ -19,126 +19,103 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 2.16.0\n" -#: ../../source/API/pygrt/pygrn.rst:2 8ba56ba3398c44e885ac316875865e96 +#: ../../source/API/pygrt/pygrn.rst:2 msgid "pygrt.pygrn" msgstr "" -#: f3b8c6e05736417ab689a218695f64ec of pygrt.pygrn +#: of pygrt.pygrn msgid "file" msgstr "" -#: 16985e4fd6f6497eb34fcfddc1c84098 of pygrt.pygrn:1 +#: of pygrt.pygrn:1 msgid "pygrn.py" msgstr "" -#: 9ab8b226c3ce4a958f1d5e6c42d7c7df of pygrt.pygrn +#: of pygrt.pygrn msgid "author" msgstr "" -#: 282565e5095147a1a73c149bae45c079 of pygrt.pygrn:2 +#: of pygrt.pygrn:2 msgid "Zhu Dengda (zhudengda@mail.iggcas.ac.cn)" msgstr "" -#: 4dfb82bc0026404f9a3b51a236b15474 of pygrt.pygrn +#: of pygrt.pygrn msgid "date" msgstr "" -#: 42efb523b2a2486a9d6ff63004d9377f of pygrt.pygrn:3 +#: of pygrt.pygrn:3 msgid "2024-07-24" msgstr "" -#: e5b81239c94c457a83d9c4cd6c592b9c of pygrt.pygrn:5 +#: of pygrt.pygrn:5 msgid "该文件包括 Python端使用的格林函数 :class:`pygrt.pygrn.PyGreenFunction`" msgstr "" -#: a8501fb127b149adab26e3330ea426fe of pygrt.pygrn.PyGreenFunction:1 +#: of pygrt.pygrn.PyGreenFunction:1 msgid "基类::py:class:`object`" msgstr "" -#: 51440fae77c8462099e4937e53b6f7fe of pygrt.pygrn.PyGreenFunction.__init__:1 -msgid "Python端使用的格林函数类,包括和C库计算得到的 :class:`c_GRN` 结构体数据作对接" +#: of pygrt.pygrn.PyGreenFunction.__init__:1 +msgid "Python端使用的格林函数类" msgstr "" -#: ../../source/API/pygrt/pygrn.rst a6cc55e7d0fc4078b24ab3edafdaa6a1 -#: b59b19166a9c456e849282a9683498f1 d9cc4c43d45e45f5b342c664c959e1cc +#: ../../source/API/pygrt/pygrn.rst msgid "参数" msgstr "" -#: 69e53c36433b490faf4b129096d13db7 of pygrt.pygrn.PyGreenFunction.__init__:3 +#: of pygrt.pygrn.PyGreenFunction.__init__:3 msgid "格林函数名称,震源类型(EX,VF,HF,DD,DS,SS)+三分量(Z,R,T)" msgstr "" -#: 7b70cc91360d4915a7b92ee32dc514d1 of pygrt.pygrn.PyGreenFunction.__init__:4 +#: of pygrt.pygrn.PyGreenFunction.__init__:4 msgid "时间点数" msgstr "" -#: 32c3f5844d4e481d9e935e769a332fd3 of pygrt.pygrn.PyGreenFunction.__init__:5 +#: of pygrt.pygrn.PyGreenFunction.__init__:5 msgid "采样间隔(s)" msgstr "" -#: 2afe5e7a3e6f4dc3a4d710c8fccfe5d3 of pygrt.pygrn.PyGreenFunction.__init__:6 +#: of pygrt.pygrn.PyGreenFunction.__init__:6 msgid "频率数组(Hz)" msgstr "" -#: fb922c2048aa43218a1db4c76e2ffe89 of pygrt.pygrn.PyGreenFunction.__init__:7 +#: of pygrt.pygrn.PyGreenFunction.__init__:7 msgid "定义虚频率,omega = w - j*wI, wI = wI" msgstr "" -#: 432ebd6e61f14aaab4a6b4249d2cda4c of pygrt.pygrn.PyGreenFunction.__init__:8 +#: of pygrt.pygrn.PyGreenFunction.__init__:8 msgid "震中距(km)" msgstr "" -#: 48fe244a230642a3878f0bcc11a22b28 of pygrt.pygrn.PyGreenFunction.__init__:9 +#: of pygrt.pygrn.PyGreenFunction.__init__:9 msgid "震源深度(km)" msgstr "" -#: 42535685b05b468ba7af7f7d227fc841 of pygrt.pygrn.PyGreenFunction.__init__:10 +#: of pygrt.pygrn.PyGreenFunction.__init__:10 msgid "台站深度(km)" msgstr "" -#: 0b86ab3ee061483a930ad40c7389d997 of -#: pygrt.pygrn.PyGreenFunction.fill_grn_cmplx_numpy:1 -msgid "以numpy.ndarray的形式整理复数数组" -msgstr "" - -#: 170d0a3c7740481fb1d0795253f659cb of -#: pygrt.pygrn.PyGreenFunction.fill_grn_cmplx_numpy:3 -msgid "将最终结果乘上系数mult" -msgstr "" - -#: ../../source/API/pygrt/pygrn.rst c8af659827284a45a68a5c5990d53c5f -#: cb3be221678341fa88b4c65d56724fd9 -msgid "返回" -msgstr "" - -#: 29197a9ce75a48b5b111cce6cfedb4df of -#: pygrt.pygrn.PyGreenFunction.fill_grn_cmplx_numpy:5 -msgid "- **self** - 整理好数据的实例本身" -msgstr "" - -#: e6bb6d77981549168f20c10fde9202f9 of -#: pygrt.pygrn.PyGreenFunction.fill_grn_cmplx_numpy:6 -msgid "**self** - 整理好数据的实例本身" -msgstr "" - -#: 8b6eacd6f4e342bfbbefff9dc32b08e2 of -#: pygrt.pygrn.PyGreenFunction.plot_response:1 +#: of pygrt.pygrn.PyGreenFunction.plot_response:1 msgid "绘制频率响应图,包括幅度响应和相位响应" msgstr "" -#: 68095be71bcc4019b5dad609d2c38083 of pygrt.pygrn.PyGreenFunction.freq2time:1 +#: of pygrt.pygrn.PyGreenFunction.freq2time:1 msgid "将格林函数从频域转为时域,以 :class:`obspy.Trace` 的形式返回" msgstr "" -#: 70bc36616d074b189fbe5963e17cfdcb of pygrt.pygrn.PyGreenFunction.freq2time:3 +#: of pygrt.pygrn.PyGreenFunction.freq2time:3 msgid "时域信号的起始时刻相对发震时刻的偏移量(s),例如T0=5表示发震后5s开始记录波形" msgstr "" -#: e5d75127e9ca4fe1be7c1942e391894b of pygrt.pygrn.PyGreenFunction.freq2time:5 +#: ../../source/API/pygrt/pygrn.rst +msgid "返回" +msgstr "" + +#: of pygrt.pygrn.PyGreenFunction.freq2time:5 msgid "- **tr**: :class:`obspy.Trace` 类型的格林函数时间序列" msgstr "" -#: e7ab57fdd85942c7bf90470c2dd248f5 of pygrt.pygrn.PyGreenFunction.freq2time:6 +#: of pygrt.pygrn.PyGreenFunction.freq2time:6 msgid "**tr**: :class:`obspy.Trace` 类型的格林函数时间序列" msgstr "" diff --git a/docs/locales/en/LC_MESSAGES/API/pygrt/pymod.po b/docs/locales/en/LC_MESSAGES/API/pygrt/pymod.po index 9db95e27..65541551 100644 --- a/docs/locales/en/LC_MESSAGES/API/pygrt/pymod.po +++ b/docs/locales/en/LC_MESSAGES/API/pygrt/pymod.po @@ -6,9 +6,9 @@ #, fuzzy msgid "" msgstr "" -"Project-Id-Version: PyGRT 0.6.1.dev1+g4641a40.d20250422\n" +"Project-Id-Version: PyGRT 0.7.1.dev5+g2230cdc.d20250427\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-04-24 18:17+0800\n" +"POT-Creation-Date: 2025-04-27 12:43+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: en\n" @@ -19,114 +19,111 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 2.16.0\n" -#: ../../source/API/pygrt/pymod.rst:2 c5c865636ae5496c9d2063b5e09ee66c +#: ../../source/API/pygrt/pymod.rst:2 msgid "pygrt.pymod" msgstr "" -#: a1e52108d0ee47ed9c2cd4ce8859ca7f of pygrt.pymod +#: of pygrt.pymod msgid "file" msgstr "" -#: 49d66c5682784f70961e60d5f829024a of pygrt.pymod:1 +#: of pygrt.pymod:1 msgid "pymod.py" msgstr "" -#: 48e4b14106a44b48a6b095d5f3205782 of pygrt.pymod +#: of pygrt.pymod msgid "author" msgstr "" -#: 05d7f891333442f0af79997d3370dc51 of pygrt.pymod:2 +#: of pygrt.pymod:2 msgid "Zhu Dengda (zhudengda@mail.iggcas.ac.cn)" msgstr "" -#: 6339cca2fdf7497793cd91ecea2497a9 of pygrt.pymod +#: of pygrt.pymod msgid "date" msgstr "" -#: f667fea53734432fadd11fb7549bc34d of pygrt.pymod:3 +#: of pygrt.pymod:3 msgid "2024-07-24" msgstr "" -#: 0c7bd6dd1a44451882669d6f270802c8 of pygrt.pymod:5 +#: of pygrt.pymod:5 msgid "该文件包括 Python端使用的模型 :class:`pygrt.c_structures.c_PyModel1D`" msgstr "" -#: d46459a48742475d9119928e98cd6e56 of pygrt.pymod.PyModel1D:1 +#: of pygrt.pymod.PyModel1D:1 msgid "基类::py:class:`object`" msgstr "" -#: efb9a64979ff4dc8852f5387fa182c30 of pygrt.pymod.PyModel1D.__init__:1 +#: of pygrt.pymod.PyModel1D.__init__:1 msgid "将震源和台站插入定义模型的数组,转为 :class:`PyModel1D ` 实例的形式" msgstr "" -#: ../../source/API/pygrt/pymod.rst 00f273f5f307446d8ff93f63865f56b4 -#: 0faea18c0e5648299b9da1e6b609096c e0b0748d57ee471c9c11a5b200d9ff60 -#: e63156842d424154b0cd310a4c5a3156 +#: ../../source/API/pygrt/pymod.rst msgid "参数" msgstr "" -#: dc20fb797b184216bd0f3d312d9e04ed of pygrt.pymod.PyModel1D.__init__:3 +#: of pygrt.pymod.PyModel1D.__init__:3 msgid "模型数组,每行格式为[thickness(km), Vp(km/s), Vs(km/s), Rho(g/cm^3), Qp, Qs]" msgstr "" -#: 68bf2f6134304816bb9f5e49824c4c25 of pygrt.pymod.PyModel1D.__init__:4 +#: of pygrt.pymod.PyModel1D.__init__:4 msgid "震源深度(km)" msgstr "" -#: ded9d835ddac4b248e088028f7c93246 of pygrt.pymod.PyModel1D.__init__:5 +#: of pygrt.pymod.PyModel1D.__init__:5 msgid "台站深度(km)" msgstr "" -#: bd3e1578b90440d2a08da56ad5b93b61 of pygrt.pymod.PyModel1D.compute_travt1d:1 +#: of pygrt.pymod.PyModel1D.compute_travt1d:1 msgid "调用C程序,计算初至P波和S波的走时" msgstr "" -#: d4b71727c8cf41db9a9cb1f9d81d33a0 of pygrt.pymod.PyModel1D.compute_travt1d:3 +#: of pygrt.pymod.PyModel1D.compute_travt1d:3 msgid "震中距" msgstr "" -#: ../../source/API/pygrt/pymod.rst 5660d9be95354f2187d677e7eef63f1f -#: a2fd30283e964f43aecce7960dfdb87b cdb8a50a02b845138db3d7b5ba5f93b9 +#: ../../source/API/pygrt/pymod.rst msgid "返回" msgstr "" -#: 3ff18a25edfd4b2cb094d7ca6842d384 of pygrt.pymod.PyModel1D.compute_travt1d:5 +#: of pygrt.pymod.PyModel1D.compute_travt1d:5 msgid "- **travtP** - 初至P波走时(s) - **travtS** - 初至S波走时(s)" msgstr "" -#: e486be005c6b46a4b7e33b970e6d8526 of pygrt.pymod.PyModel1D.compute_travt1d:6 +#: of pygrt.pymod.PyModel1D.compute_travt1d:6 msgid "**travtP** - 初至P波走时(s)" msgstr "" -#: 30f6484e6a834a99affe0ad7205452e3 of pygrt.pymod.PyModel1D.compute_travt1d:7 +#: of pygrt.pymod.PyModel1D.compute_travt1d:7 msgid "**travtS** - 初至S波走时(s)" msgstr "" -#: fddd6d25bc904158a7c8638591c460fc of pygrt.pymod.PyModel1D.gen_gf_spectra:1 +#: of pygrt.pymod.PyModel1D.gen_gf_spectra:1 msgid "Bad function name, has already been removed. Use 'compute_grn' instead." msgstr "" -#: 4d1eba9a8610450988c3850a80e3d00f of pygrt.pymod.PyModel1D.compute_grn:1 +#: of pygrt.pymod.PyModel1D.compute_grn:1 msgid "调用C库计算格林函数的主函数,以列表的形式返回,其中每个元素为对应震中距的格林函数 :class:`obspy.Stream` 类型。" msgstr "" -#: bafd97d3163a462b8734f42bf4005c1a of pygrt.pymod.PyModel1D.compute_grn:4 +#: of pygrt.pymod.PyModel1D.compute_grn:4 msgid "多个震中距(km) 的数组, 或单个震中距的浮点数" msgstr "" -#: 5b370033819f47b18fd4541c7cc7a426 of pygrt.pymod.PyModel1D.compute_grn:5 +#: of pygrt.pymod.PyModel1D.compute_grn:5 msgid "时间点数,借助于 `SciPy`,nt不再要求是2的幂次" msgstr "" -#: 0e74b7963c9947c2842a39c73ed6eb62 of pygrt.pymod.PyModel1D.compute_grn:6 +#: of pygrt.pymod.PyModel1D.compute_grn:6 msgid "采样间隔(s)" msgstr "" -#: 33055c6f62424e219ba48ac00b885e99 of pygrt.pymod.PyModel1D.compute_grn:7 +#: of pygrt.pymod.PyModel1D.compute_grn:7 msgid "频率范围(Hz),以此确定待计算的离散频率点" msgstr "" -#: 52a11230f22b4d48948605fe85a3c5bb of pygrt.pymod.PyModel1D.compute_grn:8 +#: of pygrt.pymod.PyModel1D.compute_grn:8 msgid "" "定义虚频率的系数 :math:`\\zeta` , 虚频率 :math:`\\tilde{\\omega} = \\omega - j*w_I, " "w_I = \\zeta*\\pi/T, T=nt*dt` , T为时窗长度。 使用离散波数积分时为了避开附加源以及奇点的影响, " @@ -134,130 +131,103 @@ msgid "" "2021) `" msgstr "" -#: 0021ce7eee8249e2b0a9aa3ea050d6ba of pygrt.pymod.PyModel1D.compute_grn:11 +#: of pygrt.pymod.PyModel1D.compute_grn:11 msgid "" "最小参考速度,默认vmin=max(minimum velocity, 0.1),用于定义波数积分上限,小于0则在达到积分上限后使用峰谷平均法 " "(默认当震源和场点深度差<=1km时自动使用峰谷平均法)" msgstr "" -#: 76dbb9a8011040519559009608db9e1f f700cc4267804f2b94b825c6a551117c of -#: pygrt.pymod.PyModel1D.compute_grn:13 +#: of pygrt.pymod.PyModel1D.compute_grn:13 #: pygrt.pymod.PyModel1D.compute_static_grn:7 msgid "" "波数k积分收敛条件,见 :ref:`(Yao and Harkrider, 1983) ` " ":ref:`(初稿) `, 为负数代表不提前判断收敛,按照波数积分上限进行积分" msgstr "" -#: 68470abb73644bffb4188d900668289d of pygrt.pymod.PyModel1D.compute_grn:15 +#: of pygrt.pymod.PyModel1D.compute_grn:15 msgid "影响波数k积分上限的系数,见下方" msgstr "" -#: cbfe80d8ef6342b1b9d0aceca4c14c0c of pygrt.pymod.PyModel1D.compute_grn:16 +#: of pygrt.pymod.PyModel1D.compute_grn:16 msgid "" "波数k积分的上限 :math:`\\tilde{k_{max}}=\\sqrt{(k_{0}*\\pi/hs)^2 + " "(ampk*w/vmin_{ref})^2}` , 波数k积分循环必须退出, hs=max(震源和台站深度差,1.0)" msgstr "" -#: 19185cb4f9204dd68b97e06590cff60a of pygrt.pymod.PyModel1D.compute_grn:17 +#: of pygrt.pymod.PyModel1D.compute_grn:17 msgid "" "定义波数k积分的间隔 `dk=2\\pi / (L*rmax)`, 选取要求见 :ref:`(Bouchon, 1981) " "` :ref:`(张海明, 2021) `,默认自动选择" msgstr "" -#: bc3a82fe9c304353b1344df5b6dcfbd2 e1b962a45a4c429bb636ffa032943c8c of -#: pygrt.pymod.PyModel1D.compute_grn:19 +#: of pygrt.pymod.PyModel1D.compute_grn:19 #: pygrt.pymod.PyModel1D.compute_static_grn:11 msgid "Filon积分的间隔 filonLength, 和波数积分和Filon积分的分割点filonCut, k*=/rmax" msgstr "" -#: 8ff689fbcc81451d814cf14b42728c92 fd5bf22ac2594bd1bd1ec601ec0a4684 of -#: pygrt.pymod.PyModel1D.compute_grn:20 +#: of pygrt.pymod.PyModel1D.compute_grn:20 #: pygrt.pymod.PyModel1D.compute_static_grn:12 msgid "是否计算位移u的空间导数" msgstr "" -#: 8325f19427e246388992a9f70bdb2782 of pygrt.pymod.PyModel1D.compute_grn:21 +#: of pygrt.pymod.PyModel1D.compute_grn:21 msgid "待计算的震源类型" msgstr "" -#: 44ca9359c4914d88bc64faabbb334efd d3bd5bf31c7c49fc8e813e0350e4bbf7 of -#: pygrt.pymod.PyModel1D.compute_grn:22 +#: of pygrt.pymod.PyModel1D.compute_grn:22 #: pygrt.pymod.PyModel1D.compute_static_grn:13 msgid "" "波数k积分(包括Filon积分和峰谷平均法)的过程记录文件,常用于debug或者观察积分过程中 :math:`F(k,\\omega)` 和 " ":math:`F(k,\\omega)J_m(kr)k` 的变化" msgstr "" -#: 1636ba0210894c39b35a13fa7fb35556 of pygrt.pymod.PyModel1D.compute_grn:23 +#: of pygrt.pymod.PyModel1D.compute_grn:23 msgid "仅输出特定频点的过程记录文件,建议给定频点,否则默认所有频率点的记录文件都输出,很占空间" msgstr "" -#: 03ee508b418a40b9b41c6e76107f10f5 of pygrt.pymod.PyModel1D.compute_grn:24 +#: of pygrt.pymod.PyModel1D.compute_grn:24 msgid "是否打印运行时间" msgstr "" -#: be94abff6e024b209726b86f3a881d7c of pygrt.pymod.PyModel1D.compute_grn:26 +#: of pygrt.pymod.PyModel1D.compute_grn:26 msgid "- **dataLst** - 列表,每个元素为 :class:`obspy.Stream` 类型 )" msgstr "" -#: b19bbe652b20401c9e0cbc89ebeacb94 of pygrt.pymod.PyModel1D.compute_grn:27 +#: of pygrt.pymod.PyModel1D.compute_grn:27 msgid "**dataLst** - 列表,每个元素为 :class:`obspy.Stream` 类型 )" msgstr "" -#: be5c5b5e256e42138b55d63d9cdcc1d2 of -#: pygrt.pymod.PyModel1D.compute_static_grn:1 +#: of pygrt.pymod.PyModel1D.compute_static_grn:1 msgid "调用C库计算静态格林函数,以字典的形式返回" msgstr "" -#: 17950d388a3d403c8538d9d2b8aa1402 of -#: pygrt.pymod.PyModel1D.compute_static_grn:3 +#: of pygrt.pymod.PyModel1D.compute_static_grn:3 msgid "北向坐标数组,或单个浮点数" msgstr "" -#: 8b75a8705b0e4aa691ffa6436c220038 of -#: pygrt.pymod.PyModel1D.compute_static_grn:4 +#: of pygrt.pymod.PyModel1D.compute_static_grn:4 msgid "东向坐标数组,或单个浮点数" msgstr "" -#: 98919ce775504040b0121614e2ac2b3d of -#: pygrt.pymod.PyModel1D.compute_static_grn:5 +#: of pygrt.pymod.PyModel1D.compute_static_grn:5 msgid "最小参考速度(具体数值不使用),小于0则在达到积分上限后使用峰谷平均法 (默认当震源和场点深度差<=0.5km时自动使用峰谷平均法)" msgstr "" -#: b4a776378c2845638e458d78e8c0f20f of -#: pygrt.pymod.PyModel1D.compute_static_grn:9 +#: of pygrt.pymod.PyModel1D.compute_static_grn:9 msgid "" "波数k积分的上限 :math:`\\tilde{k_{max}}=(k_{0}*\\pi/hs)^2` , 波数k积分循环必须退出, " "hs=max(震源和台站深度差,1.0)" msgstr "" -#: 23e13c83e5e145bbaa7ddb3b7f20ded8 of -#: pygrt.pymod.PyModel1D.compute_static_grn:10 +#: of pygrt.pymod.PyModel1D.compute_static_grn:10 msgid "定义波数k积分的间隔 `dk=2\\pi / (L*rmax)`, 默认15;负数表示使用Filon积分" msgstr "" -#: 92a1dbf5500b4f5a911d9d9006d0fb99 of -#: pygrt.pymod.PyModel1D.compute_static_grn:15 +#: of pygrt.pymod.PyModel1D.compute_static_grn:15 msgid "- **dataDct** - 字典形式的格林函数" msgstr "" -#: 6f1b955e85ea4a878a20731884441a2f of -#: pygrt.pymod.PyModel1D.compute_static_grn:16 +#: of pygrt.pymod.PyModel1D.compute_static_grn:16 msgid "**dataDct** - 字典形式的格林函数" msgstr "" -#~ msgid "k0是否取随频率变化的线性关系,即 :math:`k_{0} = k_{0} * f/f_{max}`" -#~ msgstr "" - -#~ msgid "" -#~ "定义波数k积分的间隔 `dk=2\\pi / (L*rmax)`, 选取要求见 " -#~ ":ref:`(Bouchon, 1981) ` :ref:`(张海明," -#~ " 2021) `,默认自动选择;负数表示使用Filon积分" -#~ msgstr "" - -#~ msgid "" -#~ "波数k积分(包括Filon积分和峰谷平均法)的过程记录文件,常用于debug或者观察积分过程中 " -#~ ":math:`F_m(k,\\omega)` 和 :math:`F_m(k,\\omega)J_m(kr)k`" -#~ " 的变化" -#~ msgstr "" - diff --git a/docs/locales/en/LC_MESSAGES/API/pygrt/signals.po b/docs/locales/en/LC_MESSAGES/API/pygrt/signals.po index 23e7e1bb..f80b7a9f 100644 --- a/docs/locales/en/LC_MESSAGES/API/pygrt/signals.po +++ b/docs/locales/en/LC_MESSAGES/API/pygrt/signals.po @@ -6,9 +6,9 @@ #, fuzzy msgid "" msgstr "" -"Project-Id-Version: PyGRT 0.6.1.dev1+g4641a40.d20250422\n" +"Project-Id-Version: PyGRT 0.7.1.dev5+g2230cdc.d20250427\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-04-22 15:39+0800\n" +"POT-Creation-Date: 2025-04-27 12:43+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: en\n" @@ -19,105 +19,94 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 2.16.0\n" -#: ../../source/API/pygrt/signals.rst:2 826ae4f989d945cdb713bf50d96f78b9 +#: ../../source/API/pygrt/signals.rst:2 msgid "pygrt.signals" msgstr "" -#: 1a688c60139c47e88edf1ef33fe8e842 of pygrt.signals +#: of pygrt.signals msgid "file" msgstr "" -#: 77a86239cee948dc8a0c381fe12228ab of pygrt.signals:1 +#: of pygrt.signals:1 msgid "signals.py" msgstr "" -#: 8f46bd1e94d44ea0be3f08196431e674 of pygrt.signals +#: of pygrt.signals msgid "author" msgstr "" -#: 307e8661b3dc4675adfc192d20067a40 of pygrt.signals:2 +#: of pygrt.signals:2 msgid "Zhu Dengda (zhudengda@mail.iggcas.ac.cn)" msgstr "" -#: 2462e3983d2a418685fe9684710157ae of pygrt.signals +#: of pygrt.signals msgid "date" msgstr "" -#: 5ede04d129804ab1a5cab3454f0444ee of pygrt.signals:3 +#: of pygrt.signals:3 msgid "2024-07-24" msgstr "" -#: 4bb8292c4311475b8e62109a980c5508 of pygrt.signals:5 +#: of pygrt.signals:5 msgid "该文件包括一些常见的时间信号,最高幅值均为1" msgstr "" -#: ab72cecd5a2143f199c075b595f64e1a of pygrt.signals.gen_triangle_wave:1 +#: of pygrt.signals.gen_triangle_wave:1 msgid "生成三角信号" msgstr "" -#: ../../source/API/pygrt/signals.rst 24f135aa18b641698bc0916924f72d38 -#: 2be25b17260d45609876e730e266b6b5 316336503c354e29b54bb8d3c7dd9ab6 -#: aee3ce5579194c979e331902b0498c57 +#: ../../source/API/pygrt/signals.rst msgid "参数" msgstr "" -#: 44cdf0371f1b44a29130cc6f429fe4a5 4b593fba00d44022bfb11bfcdfb80eb9 of -#: pygrt.signals.gen_parabola_wave:3 pygrt.signals.gen_triangle_wave:3 +#: of pygrt.signals.gen_parabola_wave:3 pygrt.signals.gen_triangle_wave:3 msgid "信号时长(s)" msgstr "" -#: 81a9b15456e2413db4657599ab3e2e07 bb8754dda35f4d0b95345cbc9a833d8a -#: d50a99bd25774ffb8ab2d34a2ec2ea95 f3d55f32a0964610b8636e629f340a2c of -#: pygrt.signals.gen_parabola_wave:4 pygrt.signals.gen_ricker_wave:4 +#: of pygrt.signals.gen_parabola_wave:4 pygrt.signals.gen_ricker_wave:4 #: pygrt.signals.gen_trap_wave:6 pygrt.signals.gen_triangle_wave:4 msgid "采样间隔(s)" msgstr "" -#: ../../source/API/pygrt/signals.rst 385567215d574c4998266bebfa2c0d28 -#: 98b95fd8652d4178936e03bf72116f8b d137595837dd4cd99833302e38b9ac06 -#: da50e0e2f1ea4edf8659e7d1f544b66b +#: ../../source/API/pygrt/signals.rst msgid "返回" msgstr "" -#: 33a36f6d52304c8eafc2deb357be0aed 6060ed206def41caa88018afc9197151 -#: 75dbcc8392924852be92a1b7f739c84b a9d35fdfc9df4be98937b367b0d8e32f of -#: pygrt.signals.gen_parabola_wave:6 pygrt.signals.gen_ricker_wave:6 +#: of pygrt.signals.gen_parabola_wave:6 pygrt.signals.gen_ricker_wave:6 #: pygrt.signals.gen_trap_wave:8 pygrt.signals.gen_triangle_wave:6 msgid "- **wave** - 波形幅值序列" msgstr "" -#: 03eaccd252444fc1853f41c9cb7f44e8 4517016889fc4047b5f9feb7b1316673 -#: d0243c533d3b43b888e537ece69b69c2 d9741f7463e7439d8c6e39d406506087 of -#: pygrt.signals.gen_parabola_wave:7 pygrt.signals.gen_ricker_wave:7 +#: of pygrt.signals.gen_parabola_wave:7 pygrt.signals.gen_ricker_wave:7 #: pygrt.signals.gen_trap_wave:9 pygrt.signals.gen_triangle_wave:7 msgid "**wave** - 波形幅值序列" msgstr "" -#: 76e0bf9cc01b4d59ba039c6e53a6896c of pygrt.signals.gen_parabola_wave:1 +#: of pygrt.signals.gen_parabola_wave:1 msgid "生成抛物线信号" msgstr "" -#: 5f94146b22db4fb8b04104644be1e336 of pygrt.signals.gen_trap_wave:1 +#: of pygrt.signals.gen_trap_wave:1 msgid "生成梯形信号" msgstr "" -#: a7a4eeec403b46d4a748f111cb2785f7 of pygrt.signals.gen_trap_wave:3 +#: of pygrt.signals.gen_trap_wave:3 msgid "上坡截止时刻(s)" msgstr "" -#: b64077affd5d433bb2d191d6b64835b0 of pygrt.signals.gen_trap_wave:4 +#: of pygrt.signals.gen_trap_wave:4 msgid "平台截止时刻(s)" msgstr "" -#: e61a03db386f4844a59924706a557c00 of pygrt.signals.gen_trap_wave:5 +#: of pygrt.signals.gen_trap_wave:5 msgid "下坡截止时刻(s)" msgstr "" -#: b8f3abdfb16c4f88947d71d28e3a92a0 of pygrt.signals.gen_ricker_wave:1 +#: of pygrt.signals.gen_ricker_wave:1 msgid "生成Ricker子波" msgstr "" -#: cdccd3cbe4bf453f97992227b91ab612 of pygrt.signals.gen_ricker_wave:3 +#: of pygrt.signals.gen_ricker_wave:3 msgid "中心频率(Hz)" msgstr "" diff --git a/docs/locales/en/LC_MESSAGES/API/pygrt/utils.po b/docs/locales/en/LC_MESSAGES/API/pygrt/utils.po index 560f3f6a..43b00aa7 100644 --- a/docs/locales/en/LC_MESSAGES/API/pygrt/utils.po +++ b/docs/locales/en/LC_MESSAGES/API/pygrt/utils.po @@ -6,9 +6,9 @@ #, fuzzy msgid "" msgstr "" -"Project-Id-Version: PyGRT 0.6.1.dev1+g4641a40.d20250422\n" +"Project-Id-Version: PyGRT 0.7.1.dev5+g2230cdc.d20250427\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-04-24 18:17+0800\n" +"POT-Creation-Date: 2025-04-27 12:43+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: en\n" @@ -19,357 +19,326 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 2.16.0\n" -#: ../../source/API/pygrt/utils.rst:2 8324f60eb6e644b1bca00787f9769533 +#: ../../source/API/pygrt/utils.rst:2 msgid "pygrt.utils" msgstr "" -#: 9044f9ea6272402c90c13c25a501b5be of pygrt.utils +#: of pygrt.utils msgid "file" msgstr "" -#: a8128809ee124d8c8c7accd5bfe6814a of pygrt.utils:1 +#: of pygrt.utils:1 msgid "utils.py" msgstr "" -#: 28188270f03b4651aa81358f1bd10665 of pygrt.utils +#: of pygrt.utils msgid "author" msgstr "" -#: 32d8e11a9f0347498a33e95c494f466b of pygrt.utils:2 +#: of pygrt.utils:2 msgid "Zhu Dengda (zhudengda@mail.iggcas.ac.cn)" msgstr "" -#: 4ca09d813ce64ec0bf8b9c6ba7b834e6 of pygrt.utils +#: of pygrt.utils msgid "date" msgstr "" -#: 4c9c3cb810f84f2a9613c1757b5125c6 of pygrt.utils:3 +#: of pygrt.utils:3 msgid "2024-07-24" msgstr "" -#: c1c6b4dffc9a4e0d8eb207f083e90bfa of pygrt.utils:11 +#: of pygrt.utils:11 msgid "该文件包含一些数据处理操作上的补充:" msgstr "" -#: ae18e7fecc8d422f8b3dab9fd754480a of pygrt.utils:6 +#: of pygrt.utils:6 msgid "1、剪切源、单力源、爆炸源、矩张量源 通过格林函数合成理论地震图的函数" msgstr "" -#: 4698ff529395475d90340bba280e28c2 of pygrt.utils:8 +#: of pygrt.utils:8 msgid "2、Stream类型的时域卷积、微分、积分 (基于numpy和scipy)" msgstr "" -#: 45bb29a7a7c84bdeb7c90436cbf21bc1 of pygrt.utils:10 +#: of pygrt.utils:10 msgid "3、Stream类型写到本地sac文件,自定义名称" msgstr "" -#: 7a08521279334c24a62b0511cda313a6 of pygrt.utils:12 +#: of pygrt.utils:12 msgid "4、读取波数积分和峰谷平均法过程文件" msgstr "" -#: 5961fb2684c64bc1b2fa782842897613 of pygrt.utils.gen_syn_from_gf_DC:1 +#: of pygrt.utils.gen_syn_from_gf_DC:1 msgid "剪切源,角度单位均为度" msgstr "" -#: ../../source/API/pygrt/utils.rst 130dfba759a242048b92911da0f5ac72 -#: 235d06b35e744a019d1d9cb3da596822 37902489063f4554b8c0aa8b897daa42 -#: 8a5275ea97624a8784edfb13d570a6b8 924070289a8a4d9c92141de48e01da3d -#: a7b5275265424e54848c13bdb2efb6ad b99b1d94c94a404a8f2372e2b31bedc8 -#: ca5878ab51d846bda73d9ee625157133 ce3de2785e1442419aac296171a038ac -#: d8adfd894baf48b1b52328f9251c72bc da289be8000148bbad569791f0d1db2f -#: e6e296427e10432394882080eb719539 e6faa5cf5a234df6be36c18670fd224c -#: f12bdf6c9c5c45eaafcd35cd56efbbfb f61160af862c40c5a2410b538e8f306b -#: ffb1dd2846f64c13bfe39596aac3c81f +#: ../../source/API/pygrt/utils.rst msgid "参数" msgstr "" -#: 04e35c918710487a89b6ef78ee971a75 5810e6004f8a445896048e3608897785 -#: adbc22ea9fb04f0c973b34b316b047c1 bfa634290e424d4492e470fe39dfcd5a of -#: pygrt.utils.gen_syn_from_gf_DC:3 pygrt.utils.gen_syn_from_gf_EXP:3 +#: of pygrt.utils.gen_syn_from_gf_DC:3 pygrt.utils.gen_syn_from_gf_EX:3 #: pygrt.utils.gen_syn_from_gf_MT:3 pygrt.utils.gen_syn_from_gf_SF:3 msgid "计算好的时域格林函数, :class:`obspy.Stream` 类型,或者静态格林函数(字典类型)" msgstr "" -#: 9831d0377ce24ee88a7540df27980866 de51e577d60349819e3f4a4e33153a1c of -#: pygrt.utils.gen_syn_from_gf_DC:4 pygrt.utils.gen_syn_from_gf_EXP:4 +#: of pygrt.utils.gen_syn_from_gf_DC:4 pygrt.utils.gen_syn_from_gf_EX:4 msgid "标量地震矩, 单位dyne*cm" msgstr "" -#: e2ac648a9a13480b894d4342ed244e4e of pygrt.utils.gen_syn_from_gf_DC:5 +#: of pygrt.utils.gen_syn_from_gf_DC:5 msgid "走向,以北顺时针为正,0<=strike<=360" msgstr "" -#: 50e479a7c63f4d7882e80e1f3bfba399 of pygrt.utils.gen_syn_from_gf_DC:6 +#: of pygrt.utils.gen_syn_from_gf_DC:6 msgid "倾角,以水平面往下为正,0<=dip<=90" msgstr "" -#: ee3b70751e0143a19fbbd2692965d144 of pygrt.utils.gen_syn_from_gf_DC:7 +#: of pygrt.utils.gen_syn_from_gf_DC:7 msgid "滑动角,在断层面相对于走向方向逆时针为正,-180<=rake<=180" msgstr "" -#: d63052efb0bb4b26939e6246224aa115 of pygrt.utils.gen_syn_from_gf_DC:8 +#: of pygrt.utils.gen_syn_from_gf_DC:8 msgid "台站方位角,以北顺时针为正,0<=az<=360(静态情况不需要)" msgstr "" -#: 0331d96cfb33444196cba56811c4a720 1d50334dccb542b2abce8fc25d229e35 -#: a2a3a7b4094e4413b0dbb944ce852391 d78b386176cd46f785f91b36b3e6a49b of -#: pygrt.utils.gen_syn_from_gf_DC:9 pygrt.utils.gen_syn_from_gf_EXP:6 +#: of pygrt.utils.gen_syn_from_gf_DC:9 pygrt.utils.gen_syn_from_gf_EX:6 #: pygrt.utils.gen_syn_from_gf_MT:7 pygrt.utils.gen_syn_from_gf_SF:9 msgid "是否以ZNE分量输出?" msgstr "" -#: 238b4e1f9510427a95835a26742525d3 2465d75c090944e98f18864172c1fbb5 -#: 2b46bed5f30f4a469c36478f5a852d8b 86e1833278854939a3dc047bb1abe201 of -#: pygrt.utils.gen_syn_from_gf_DC:10 pygrt.utils.gen_syn_from_gf_EXP:7 +#: of pygrt.utils.gen_syn_from_gf_DC:10 pygrt.utils.gen_syn_from_gf_EX:7 #: pygrt.utils.gen_syn_from_gf_MT:8 pygrt.utils.gen_syn_from_gf_SF:10 msgid "是否计算位移u的空间导数" msgstr "" -#: ../../source/API/pygrt/utils.rst 07f4c51c1e65475bae7e0ff456edb4d8 -#: 6c6de927e67849d9a1fdcfbd81fce07f 6d1546f968fa41639afa6aa1d272becb -#: 6f7433213a224693b6f395ccac074b53 703a125055d7477291b13306b85b8e21 -#: 80ea0e9b43a241aeaabdc1d1efbfe05e 8ecc84cc59a0473f9e220db8adc4def7 -#: 9ee5c09b8ec840e09e95408a34c71b5c a2d300a4681c4d6682e0d6633a131652 -#: ad5be957f0804097981ee71707a967a4 b2c8bce6ce1a4edd8e0ff3fef29755ac -#: b56b0b9ef4094215b86a839067f9e376 c1b3728e698c4470843428f82227d68d -#: ca32944b23d94e30866d80adff3f8a7f d045eedd8c5242fdbc012a3990387b40 +#: ../../source/API/pygrt/utils.rst msgid "返回" msgstr "" -#: 3787663dd868481bac8de31cd6b88d85 of pygrt.utils.gen_syn_from_gf_DC:12 +#: of pygrt.utils.gen_syn_from_gf_DC:12 msgid "- **stream** - 三分量地震图, :class:`obspy.Stream` 类型" msgstr "" -#: a668a533128d437897a9cf9e328d7e88 of pygrt.utils.gen_syn_from_gf_DC:13 +#: of pygrt.utils.gen_syn_from_gf_DC:13 msgid "**stream** - 三分量地震图, :class:`obspy.Stream` 类型" msgstr "" -#: 53a2951e955a43ce906aea1d1e155d10 of pygrt.utils.gen_syn_from_gf_SF:1 +#: of pygrt.utils.gen_syn_from_gf_SF:1 msgid "单力源,力分量单位均为dyne" msgstr "" -#: 55a7c70c56bb4e5abeb8b43faafabfad of pygrt.utils.gen_syn_from_gf_SF:4 +#: of pygrt.utils.gen_syn_from_gf_SF:4 msgid "力的放大系数" msgstr "" -#: 0ee8b9463c3a4303a712eea5ae2104d0 of pygrt.utils.gen_syn_from_gf_SF:5 +#: of pygrt.utils.gen_syn_from_gf_SF:5 msgid "北向力,向北为正" msgstr "" -#: e6704b70e5224f2694a9b341e9f6d119 of pygrt.utils.gen_syn_from_gf_SF:6 +#: of pygrt.utils.gen_syn_from_gf_SF:6 msgid "东向力,向东为正" msgstr "" -#: a585ba05a652433ca426ce82171fb252 of pygrt.utils.gen_syn_from_gf_SF:7 +#: of pygrt.utils.gen_syn_from_gf_SF:7 msgid "垂向力,向下为正" msgstr "" -#: 3ec53eee35b64dfb863c9ff5325049af f603fad51e9e4e6c832da3190921ee28 of -#: pygrt.utils.gen_syn_from_gf_MT:6 pygrt.utils.gen_syn_from_gf_SF:8 +#: of pygrt.utils.gen_syn_from_gf_MT:6 pygrt.utils.gen_syn_from_gf_SF:8 msgid "台站方位角,以北顺时针为正,0<=az<=360 (静态情况不需要)" msgstr "" -#: c1735a008e5e46618527c26a49551ee7 of pygrt.utils.gen_syn_from_gf_SF:12 +#: of pygrt.utils.gen_syn_from_gf_SF:12 msgid "- **stream** - 三分量地震图, :class:`obspy.Stream` 类型" msgstr "" -#: 7a312de71a1a40d3bb7fe12c386d0ffa of pygrt.utils.gen_syn_from_gf_SF:13 +#: of pygrt.utils.gen_syn_from_gf_SF:13 msgid "**stream** - 三分量地震图, :class:`obspy.Stream` 类型" msgstr "" -#: 86530da246a745c6a925f233f5cf0035 of pygrt.utils.gen_syn_from_gf_EXP:1 +#: of pygrt.utils.gen_syn_from_gf_EX:1 msgid "爆炸源" msgstr "" -#: 81a0e16872c04b1eb8300e1e6a7abe73 of pygrt.utils.gen_syn_from_gf_EXP:5 +#: of pygrt.utils.gen_syn_from_gf_EX:5 msgid "台站方位角,以北顺时针为正,0<=az<=360 [不用于计算] (静态情况不需要)" msgstr "" -#: 346ac3233e26410aa705b6781debf751 43722c31cd6c4b0f940e3ee72b96a5dd of -#: pygrt.utils.gen_syn_from_gf_EXP:9 pygrt.utils.gen_syn_from_gf_MT:10 +#: of pygrt.utils.gen_syn_from_gf_EX:9 pygrt.utils.gen_syn_from_gf_MT:10 msgid "- **stream** - 三分量地震图, :class:`obspy.Stream` 类型" msgstr "" -#: 94f14593212245578766f2755024d3c4 9e4aeb68ff444335b5d120881f3fdaf6 of -#: pygrt.utils.gen_syn_from_gf_EXP:10 pygrt.utils.gen_syn_from_gf_MT:11 +#: of pygrt.utils.gen_syn_from_gf_EX:10 pygrt.utils.gen_syn_from_gf_MT:11 msgid "**stream** - 三分量地震图, :class:`obspy.Stream` 类型" msgstr "" -#: e56995b67bb3493c98ffc46004f98e0e of pygrt.utils.gen_syn_from_gf_MT:1 +#: of pygrt.utils.gen_syn_from_gf_MT:1 msgid "矩张量源,单位为dyne*cm" msgstr "" -#: 792e44320526438fb858e6eda37dd9d8 of pygrt.utils.gen_syn_from_gf_MT:4 +#: of pygrt.utils.gen_syn_from_gf_MT:4 msgid "标量地震矩" msgstr "" -#: 71935962329d4727a20e0f5a00a20add of pygrt.utils.gen_syn_from_gf_MT:5 +#: of pygrt.utils.gen_syn_from_gf_MT:5 msgid "矩张量 (M11, M12, M13, M22, M23, M33),下标1,2,3分别代表北向,东向,垂直向下" msgstr "" -#: 3c63f5db0756412594d115ab0c37921c of pygrt.utils.compute_strain:1 +#: of pygrt.utils.compute_strain:1 msgid "Compute dynamic/static strain tensor from synthetic spatial derivatives." msgstr "" -#: 350c7482974a46d5b4de0aacb5b53b43 c4663baf3b50420abdc61374f86ad56c -#: f1ded1ace57c487c8ae05719b6a74da1 of pygrt.utils.compute_rotation:3 -#: pygrt.utils.compute_strain:3 pygrt.utils.compute_stress:3 +#: of pygrt.utils.compute_rotation:3 pygrt.utils.compute_strain:3 +#: pygrt.utils.compute_stress:3 msgid "" "synthetic spatial derivatives :class:`obspy.Stream` class for dynamic " "case, dict class for static case." msgstr "" -#: 811a7ea5eb734d3198eee66b76cece2e of pygrt.utils.compute_strain:6 +#: of pygrt.utils.compute_strain:6 msgid "" "- **stres** - dynamic/static strain tensor, in :class:`obspy.Stream` " "class or dict class." msgstr "" -#: 43adb80ee0324bce8a17081d73d32575 of pygrt.utils.compute_strain:7 +#: of pygrt.utils.compute_strain:7 msgid "" "**stres** - dynamic/static strain tensor, in :class:`obspy.Stream` class" " or dict class." msgstr "" -#: f873a32ccc8d46089c1162bdff6ef07d of pygrt.utils.compute_rotation:1 +#: of pygrt.utils.compute_rotation:1 msgid "Compute dynamic/static rotation tensor from synthetic spatial derivatives." msgstr "" -#: d3fa58abd1864be9941682d2fb5fb670 of pygrt.utils.compute_rotation:6 +#: of pygrt.utils.compute_rotation:6 msgid "" "- **stres** - dynamic/static rotation tensor, in :class:`obspy.Stream` " "class or dict class." msgstr "" -#: 4d7f4168fa104561ace965966711ce61 of pygrt.utils.compute_rotation:7 +#: of pygrt.utils.compute_rotation:7 msgid "" "**stres** - dynamic/static rotation tensor, in :class:`obspy.Stream` " "class or dict class." msgstr "" -#: a716cf4cbf6545d485d3c9d940ceb3e8 of pygrt.utils.compute_stress:1 +#: of pygrt.utils.compute_stress:1 msgid "Compute dynamic/static stress tensor from synthetic spatial derivatives." msgstr "" -#: 147453ad90a7448e97f168f7680e4478 of pygrt.utils.compute_stress:6 +#: of pygrt.utils.compute_stress:6 msgid "" "- **stres** - dynamic/static stress tensor (unit: dyne/cm^2 = 0.1 Pa), " "in :class:`obspy.Stream` class or dict class." msgstr "" -#: a9209b291fc248a7bc8f97ffcaca9fd0 of pygrt.utils.compute_stress:7 +#: of pygrt.utils.compute_stress:7 msgid "" "**stres** - dynamic/static stress tensor (unit: dyne/cm^2 = 0.1 Pa), in " ":class:`obspy.Stream` class or dict class." msgstr "" -#: b85765de572b4864aed1f1065ff11f40 of pygrt.utils.stream_convolve:1 +#: of pygrt.utils.stream_convolve:1 msgid "对stream中每一道信号做线性卷积" msgstr "" -#: 76c50a6e9574470db5076b2e348be384 a0d725be30464de1aa8fe63d31dcffde -#: bc03c548c0644263b5c3605b6c4487e2 eb4252d74db4443da888f9b27536be1a of -#: pygrt.utils.stream_convolve:3 pygrt.utils.stream_diff:3 +#: of pygrt.utils.stream_convolve:3 pygrt.utils.stream_diff:3 #: pygrt.utils.stream_integral:3 pygrt.utils.stream_write_sac:3 msgid "记录多个Trace的 :class:`obspy.Stream` 类型" msgstr "" -#: ed86a638405d48fba601a2a176d7220c of pygrt.utils.stream_convolve:4 +#: of pygrt.utils.stream_convolve:4 msgid "卷积信号" msgstr "" -#: 320b05c954d84e83888942f2d318dfa6 35607b18659a45fd9907fec99c1984e6 -#: d2fb2c7a7d99491b86054381b0d40876 of pygrt.utils.stream_convolve:5 -#: pygrt.utils.stream_diff:4 pygrt.utils.stream_integral:4 +#: of pygrt.utils.stream_convolve:5 pygrt.utils.stream_diff:4 +#: pygrt.utils.stream_integral:4 msgid "是否做原地更改" msgstr "" -#: 6872304a1c9547ceb9ca215b57d1c4e8 9106afe9afca4c738c4ebc2ad56990b0 -#: 9a1d4120dce24f71b15023773aa2dbbc of pygrt.utils.stream_convolve:7 -#: pygrt.utils.stream_diff:6 pygrt.utils.stream_integral:6 +#: of pygrt.utils.stream_convolve:7 pygrt.utils.stream_diff:6 +#: pygrt.utils.stream_integral:6 msgid "- **stream** - 处理后的结果, :class:`obspy.Stream` 类型" msgstr "" -#: 42cd0aca85f346c4b6fd3949743c4081 a2d9ab98dc894bad91b0441b7f2ce32a -#: b8efce350a7349ca8c6d924946215fca of pygrt.utils.stream_convolve:8 -#: pygrt.utils.stream_diff:7 pygrt.utils.stream_integral:7 +#: of pygrt.utils.stream_convolve:8 pygrt.utils.stream_diff:7 +#: pygrt.utils.stream_integral:7 msgid "**stream** - 处理后的结果, :class:`obspy.Stream` 类型" msgstr "" -#: e0dc97703b024566aa0fdc55799a59f0 of pygrt.utils.stream_integral:1 +#: of pygrt.utils.stream_integral:1 msgid "对stream中每一道信号做梯形积分" msgstr "" -#: 66dc60f2d30e477f8e1c9d883cf7b78d of pygrt.utils.stream_diff:1 +#: of pygrt.utils.stream_diff:1 msgid "对stream中每一道信号做中心差分" msgstr "" -#: fd786a4d502a4e45a308475d8c48a273 of pygrt.utils.stream_write_sac:1 +#: of pygrt.utils.stream_write_sac:1 msgid "将一系列Trace以SAC形式保存到本地,以发震时刻作为参考0时刻" msgstr "" -#: 6041fe6868aa4161b766533eb2914bb7 of pygrt.utils.stream_write_sac:4 +#: of pygrt.utils.stream_write_sac:4 msgid "" "保存文件名,不要加后缀, 例如path=\"GRN/out\"表明sac文件将保存在GRN文件中, 文件名分别为outR.sac, " "outT.sac, outZ.sac, 若通道名前缀有\"r\",\"z\"或\"t\"(表示位移空间导数),则该前缀 " "也会加到SAC文件名中,例如GRN/routR.sac" msgstr "" -#: 9b45759a1e7f4ab187eddb6e74e6c3cb of pygrt.utils.read_kernels_freqs:1 +#: of pygrt.utils.read_kernels_freqs:1 msgid "读取statsdir目录下所有频率(除了零频)的积分过程文件(K_开头),再将核函数线性插值到指定的速度数组vels" msgstr "" -#: e8538b307b0645a186a98587ef4a419f of pygrt.utils.read_kernels_freqs:3 +#: of pygrt.utils.read_kernels_freqs:3 msgid "存储积分过程文件的目录" msgstr "" -#: 1daa9dc1b9e04435a10fde35cd45e1c5 of pygrt.utils.read_kernels_freqs:4 +#: of pygrt.utils.read_kernels_freqs:4 msgid "待插值的速度数组(km/s),必须正序" msgstr "" -#: a9b07d9aad464058b95c4b8ad08095cc of pygrt.utils.read_kernels_freqs:5 -msgid "指定返回一系列的核函数名称,如EXP_q0,DC_w2等,默认返回全部" +#: of pygrt.utils.read_kernels_freqs:5 +msgid "指定返回一系列的核函数名称,如EX_q,DS_w等,默认返回全部" msgstr "" -#: d3baac93a06043fa8bde825b66a28a2d of pygrt.utils.read_kernels_freqs:7 +#: of pygrt.utils.read_kernels_freqs:7 msgid "- **kerDct** - 字典格式的核函数插值结果" msgstr "" -#: df74305a1c814bb7b3428d8b365eb1bb of pygrt.utils.read_kernels_freqs:8 +#: of pygrt.utils.read_kernels_freqs:8 msgid "**kerDct** - 字典格式的核函数插值结果" msgstr "" -#: 5c2d9ea92fac4066a46a20c914ac92ab of pygrt.utils.read_statsfile:1 +#: of pygrt.utils.read_statsfile:1 msgid "读取单个频率下波数积分(或Filon积分)的记录文件" msgstr "" -#: 126a0d69f07449f2a4c2d67bd8dd229c of pygrt.utils.read_statsfile:3 +#: of pygrt.utils.read_statsfile:3 msgid "文件路径(可使用通配符简化输入)" msgstr "" -#: c5b279662f454133a4be4f4c1eb45347 of pygrt.utils.read_statsfile:5 +#: of pygrt.utils.read_statsfile:5 msgid "" "- **data** - `numpy.ndarray " "`_ " "自定义类型数组" msgstr "" -#: 71100763e1414917ae9e8518ab74bd6b of pygrt.utils.read_statsfile:6 +#: of pygrt.utils.read_statsfile:6 msgid "" "**data** - `numpy.ndarray " "`_ " "自定义类型数组" msgstr "" -#: bc724e8c92d041bea0ea682ec81c4f80 of pygrt.utils.read_statsfile_ptam:1 +#: of pygrt.utils.read_statsfile_ptam:1 msgid "读取单个频率下峰谷平均法的记录文件" msgstr "" -#: 0f4bf32518184b078de526429ab5cdc6 of pygrt.utils.read_statsfile_ptam:3 +#: of pygrt.utils.read_statsfile_ptam:3 msgid "PTAM文件路径(可使用通配符简化输入)" msgstr "" -#: ac444538b4d24a1fa7021ed39f6e8f23 of pygrt.utils.read_statsfile_ptam:5 +#: of pygrt.utils.read_statsfile_ptam:5 msgid "" "- **data1** - `numpy.ndarray " "`_ " @@ -380,120 +349,99 @@ msgid "" "自定义类型数组,PTAM的峰谷位置及幅值 - **dist** - 文件对应的震中距(km)" msgstr "" -#: 3953d4787e8d4c06867d2e190f67b4a5 of pygrt.utils.read_statsfile_ptam:6 +#: of pygrt.utils.read_statsfile_ptam:6 msgid "" "**data1** - `numpy.ndarray " "`_ " "自定义类型数组,DWM或FIM过程中的积分过程数据" msgstr "" -#: 9e4809344337451981a2f2f5ba6357a0 of pygrt.utils.read_statsfile_ptam:7 +#: of pygrt.utils.read_statsfile_ptam:7 msgid "" "**data2** - `numpy.ndarray " "`_ " "自定义类型数组,PTAM过程中的积分过程数据" msgstr "" -#: a17f9ada0f104cbc914c7b0569327072 of pygrt.utils.read_statsfile_ptam:8 +#: of pygrt.utils.read_statsfile_ptam:8 msgid "" "**ptam_data** - `numpy.ndarray " "`_ " "自定义类型数组,PTAM的峰谷位置及幅值" msgstr "" -#: 6cb99861aff64d70804920b1749d6107 of pygrt.utils.read_statsfile_ptam:9 +#: of pygrt.utils.read_statsfile_ptam:9 msgid "**dist** - 文件对应的震中距(km)" msgstr "" -#: 862bad65279d4d0995eaa80d917a9dea of pygrt.utils.plot_statsdata:1 +#: of pygrt.utils.plot_statsdata:1 msgid "" "根据 :func:`read_statsfile ` 函数函数读取的数据, 绘制核函数 " ":math:`F(k,\\omega)`、被积函数 :math:`F(k,\\omega)J_m(kr)k`,以及简单计算累积积分 " ":math:`\\sum F(k,\\omega)J_m(kr)k` 并绘制。" msgstr "" -#: be5c145f722347dbbd60a7f92ef4f23e d7e4d8eaf58b499da40e693abd5d801f of -#: pygrt.utils.plot_statsdata:4 pygrt.utils.plot_statsdata_ptam:4 +#: of pygrt.utils.plot_statsdata:4 pygrt.utils.plot_statsdata_ptam:4 msgid "并不是每个震源类型对应的每一阶每种积分类型都存在,详见 :ref:`grn_types`。" msgstr "" -#: 112d5a31bcf14f48adcc5340d6fe6437 of pygrt.utils.plot_statsdata:6 +#: of pygrt.utils.plot_statsdata:6 msgid ":func:`read_statsfile ` 函数返回值" msgstr "" -#: b693f21a0a1f4e95b484991340a2b18d of pygrt.utils.plot_statsdata:7 +#: of pygrt.utils.plot_statsdata:7 msgid "震中距(km)" msgstr "" -#: 3c29d7b233af4bd1b50daaf5b0218e84 ef5fc11dca98418a87a7183c26a0bc05 of -#: pygrt.utils.plot_statsdata:8 pygrt.utils.plot_statsdata_ptam:9 -msgid "震源类型的缩写,包括EXP、VF、HF、DC" +#: of pygrt.utils.plot_statsdata:8 pygrt.utils.plot_statsdata_ptam:9 +msgid "震源类型的缩写,包括EX、VF、HF、DD、DS、SS" msgstr "" -#: 45fd38fa64c74ee48f2c4d39f86eb59f d3cd8000875546acbdeca3a22494a071 of -#: pygrt.utils.plot_statsdata:9 pygrt.utils.plot_statsdata_ptam:10 -msgid "阶数(0,1,2),不完全对应公式中Bessel函数的阶数,因为存在Bessel函数的导数,需要使用递推公式" -msgstr "" - -#: 77525acd634f4936996bb20f640d914a 919603b9963e48de9c01594809a14b1e of -#: pygrt.utils.plot_statsdata:10 pygrt.utils.plot_statsdata_ptam:11 +#: of pygrt.utils.plot_statsdata:9 pygrt.utils.plot_statsdata_ptam:10 msgid "积分类型(0,1,2,3)" msgstr "" -#: 9172e6803b73465795e087a2ec0f3911 d4ffe2779bce42dd8a502c8aa36f7944 of -#: pygrt.utils.plot_statsdata:11 pygrt.utils.plot_statsdata_ptam:12 +#: of pygrt.utils.plot_statsdata:10 pygrt.utils.plot_statsdata_ptam:11 msgid "绘制实部还是虚部,默认实部,传入2表示实部虚部都绘制" msgstr "" -#: 8fbc9924cad1471ea4e57a877e018b89 cd60dbe44ebc41b2801598e1cf855c28 of -#: pygrt.utils.plot_statsdata:12 pygrt.utils.plot_statsdata_ptam:13 +#: of pygrt.utils.plot_statsdata:11 pygrt.utils.plot_statsdata_ptam:12 msgid "传入自定义的matplotlib.Figure对象,默认为None" msgstr "" -#: 6d61c391c9674cf18521628c1bb0b26b dbd55da8ea1f43c4b21027d5eb9edb32 of -#: pygrt.utils.plot_statsdata:13 pygrt.utils.plot_statsdata_ptam:14 +#: of pygrt.utils.plot_statsdata:12 pygrt.utils.plot_statsdata_ptam:13 msgid "传入自定义的matplotlib.Axes对象数组(三个),默认为None" msgstr "" -#: 13259fac833a4fcda4e2d52a4f9bf215 1667c1d4841a40738cbf1b0a57638642 of -#: pygrt.utils.plot_statsdata:15 pygrt.utils.plot_statsdata_ptam:16 +#: of pygrt.utils.plot_statsdata:14 pygrt.utils.plot_statsdata_ptam:15 msgid "" "- **fig** - matplotlib.Figure对象 - " "**(ax1,ax2,ax3)** - matplotlib.Axes对象数组" msgstr "" -#: 123922c58cde48329e18a53999b5471c b36871dc55044263818de9de196cb8e6 of -#: pygrt.utils.plot_statsdata:16 pygrt.utils.plot_statsdata_ptam:17 +#: of pygrt.utils.plot_statsdata:15 pygrt.utils.plot_statsdata_ptam:16 msgid "**fig** - matplotlib.Figure对象" msgstr "" -#: 09790fa351aa42d3ae1823fabf0fb16d e5ce3621d25041918524b47071bb42a4 of -#: pygrt.utils.plot_statsdata:17 pygrt.utils.plot_statsdata_ptam:18 +#: of pygrt.utils.plot_statsdata:16 pygrt.utils.plot_statsdata_ptam:17 msgid "**(ax1,ax2,ax3)** - matplotlib.Axes对象数组" msgstr "" -#: 521bd32e7dab4e0fa476befd41ebea67 of pygrt.utils.plot_statsdata_ptam:1 +#: of pygrt.utils.plot_statsdata_ptam:1 msgid "" "根据 :func:`read_statsfile_ptam ` 函数读取的数据," " 简单计算并绘制累积积分以及峰谷平均法使用的波峰波谷的位置。" msgstr "" -#: d42eefababa146fca20898bfcbfa412f of pygrt.utils.plot_statsdata_ptam:6 +#: of pygrt.utils.plot_statsdata_ptam:6 msgid "DWM或FIM过程中的积分过程数据" msgstr "" -#: c6ff97a76e8f4a6591437bac8e795207 of pygrt.utils.plot_statsdata_ptam:7 +#: of pygrt.utils.plot_statsdata_ptam:7 msgid "PTAM过程中的积分过程数据" msgstr "" -#: 5b761f43302041d2936f23f04813dd57 of pygrt.utils.plot_statsdata_ptam:8 +#: of pygrt.utils.plot_statsdata_ptam:8 msgid "PTAM的峰谷位置及幅值" msgstr "" -#~ msgid "" -#~ "根据 :func:`read_statsfile ` " -#~ "函数函数读取的数据, 绘制核函数 :math:`F_m(k,\\omega)`、被积函数 " -#~ ":math:`F_m(k,\\omega)J_m(kr)k`,以及简单计算累积积分 :math:`\\sum " -#~ "F_m(k,\\omega)J_m(kr)k` 并绘制。" -#~ msgstr "" - diff --git a/docs/locales/en/LC_MESSAGES/Advanced/filon_linear.po b/docs/locales/en/LC_MESSAGES/Advanced/filon_linear.po index eb385da0..4ef0845f 100644 --- a/docs/locales/en/LC_MESSAGES/Advanced/filon_linear.po +++ b/docs/locales/en/LC_MESSAGES/Advanced/filon_linear.po @@ -19,27 +19,27 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 2.16.0\n" -#: ../../source/Advanced/filon_linear.rst:2 8d6246fc47cf412a895160abe9aadf32 +#: ../../source/Advanced/filon_linear.rst:2 msgid "Filon积分法" msgstr "Filon's Integration Method" -#: ../../source/Advanced/filon_linear.rst 4bbb4bf9ad084a93ae45b593136b355f +#: ../../source/Advanced/filon_linear.rst msgid "Author" msgstr "" -#: ../../source/Advanced/filon_linear.rst:4 ec9d87b6890f4943a41a4f2f6e09f5fc +#: ../../source/Advanced/filon_linear.rst:4 msgid "Zhu Dengda" msgstr "" -#: ../../source/Advanced/filon_linear.rst c5d0558aaa4b4bfa8e424d8abe1682ed +#: ../../source/Advanced/filon_linear.rst msgid "Email" msgstr "" -#: ../../source/Advanced/filon_linear.rst:5 d323f38759e24ccc9550f8d65bc14d1b +#: ../../source/Advanced/filon_linear.rst:5 msgid "zhudengda@mail.iggcas.ac.cn" msgstr "" -#: ../../source/Advanced/filon_linear.rst:11 e2009788c8944845a18f4712a18e272d +#: ../../source/Advanced/filon_linear.rst:11 msgid "" "谨慎使用固定间隔的Filon积分法,除非你很清楚原理以及误差来源。后期会考虑加入 **自适应Filon积分法** :ref:`(张海明, 2021) " "` 以减少固定积分间隔的影响。" @@ -48,7 +48,7 @@ msgstr "" "In the future, **Self-Adaptive Filon's Integration Method** :ref:`(Zhang Haiming, 2021) ` " "may be considered to mitigate the impact of fixed integration intervals." -#: ../../source/Advanced/filon_linear.rst:14 6eb088fc43f04478a91373cb2fb527f5 +#: ../../source/Advanced/filon_linear.rst:14 msgid "" "以下介绍程序中使用的 **基于两点线性插值的Filon积分** :ref:`(纪晨, 姚振兴, 1995) ` " ":ref:`(初稿) ` ,主要介绍思路,具体公式推导详见对应论文。" @@ -57,25 +57,25 @@ msgstr "" ":ref:`(Ji Chen, Yao Zhenxing, 1995) ` :ref:`(初稿) ` " "used in the program, mainly explaining the idea. For detailed formula derivations, refer to the corresponding paper." -#: ../../source/Advanced/filon_linear.rst:16 01d56ee3f5e3407a9bc0a519df5271b2 +#: ../../source/Advanced/filon_linear.rst:16 msgid "对于以下积分," msgstr "For the following integral," -#: ../../source/Advanced/filon_linear.rst:18 28eb781747fd4a70b9f1fac3fbc2fd7b +#: ../../source/Advanced/filon_linear.rst:18 msgid "P_m(\\omega,r) = \\int_0^{k_{\\text{max}}} F_m(k, \\omega)J_m(kr)kdk" msgstr "" -#: ../../source/Advanced/filon_linear.rst:22 6e7ad2bd12494b49aef8420293843a24 +#: ../../source/Advanced/filon_linear.rst:22 msgid "分成两个部分," msgstr "It is divided into two parts," -#: ../../source/Advanced/filon_linear.rst:24 c751a3bbaed64e3caea38bf528cebdd4 +#: ../../source/Advanced/filon_linear.rst:24 msgid "" "P_m(\\omega,r) = \\int_0^{k^*} F_m(k, \\omega)J_m(kr)kdk + " "\\int_{k^*}^{k_{\\text{max}}} F_m(k, \\omega)J_m(kr)kdk" msgstr "" -#: ../../source/Advanced/filon_linear.rst:28 97a62e7c22b747fe94de689648d8eea5 +#: ../../source/Advanced/filon_linear.rst:28 msgid "" "其中积分第一部分仍然使用离散波数积分求解 (见 :ref:`k_integ_rst` " "部分),积分第二部分将Bessel函数取渐近表达式,可将其转为以下形式" @@ -83,7 +83,7 @@ msgstr "" "The first part of the integral still uses discrete wavenumber integration to solve (see :ref:`k_integ_rst` section), " "and the second part of the integral takes the asymptotic expression of the Bessel function, which can be transformed into the following form." -#: ../../source/Advanced/filon_linear.rst:30 71452cef25294a0c8e413c4945806945 +#: ../../source/Advanced/filon_linear.rst:30 msgid "" "\\begin{align}\n" "P_m(\\omega,r) &= \\sqrt{\\dfrac{2}{\\pi r}}\n" @@ -93,7 +93,7 @@ msgid "" "\\end{align}" msgstr "" -#: ../../source/Advanced/filon_linear.rst:38 cdebd4ae800a454d96cb12051469e7f1 +#: ../../source/Advanced/filon_linear.rst:38 msgid "" "其中高亮部分的积分是Filon积分的关键。在每一个区间 :math:`[k_i, k_{i+1}], k_i=(i-1) \\Delta k` " "内,使用两点线性插值公式,:math:`\\bar{F}` 可表示为" @@ -101,13 +101,13 @@ msgstr "" "The highlighted part of the integral is the key to Filon's integration. In each interval :math:`[k_i, k_{i+1}], k_i=(i-1) \\Delta k`, " "using the two-point linear interpolation formula, :math:`\\bar{F}` can be expressed as" -#: ../../source/Advanced/filon_linear.rst:40 a46cac27c72c4365b58d0dceaf3def59 +#: ../../source/Advanced/filon_linear.rst:40 msgid "" "\\bar{F} = \\bar{F}_i + \\dfrac{\\bar{F}_{i+1} - \\bar{F}_i}{\\Delta k} " "(k - k_i)" msgstr "" -#: ../../source/Advanced/filon_linear.rst:44 4996c5f9de9949bcaf0a929f1941416e +#: ../../source/Advanced/filon_linear.rst:44 msgid "" "将此式代回积分公式中,可得到 " "**该区间内的积分解析解**,而最终的解即为多个区间内解析解的和。可进一步推导,将相邻区间的解析解中的部分式子两两相消,得到更简化的整个区间的解析解。由于相比于Bessel函数," @@ -119,15 +119,15 @@ msgstr "" "Further derivation can simplify the analytical solution for the entire interval by canceling out parts of the formulas in adjacent intervals. " "Since :math:`\\bar{F}` often changes more slowly compared to the Bessel function, Filon's integration can achieve good accuracy even with relatively large step sizes :math:`\\Delta k`." -#: ../../source/Advanced/filon_linear.rst:50 c56e55eda1b44df89be60e118ece0d8f +#: ../../source/Advanced/filon_linear.rst:50 msgid "从以上推导可看出,该方法的精度取决于以下两个方面:" msgstr "From the above derivation, it can be seen that the accuracy of this method depends on the following two aspects:" -#: ../../source/Advanced/filon_linear.rst:52 ac21a2033ce242198b5c60368705fd10 +#: ../../source/Advanced/filon_linear.rst:52 msgid "**Bessel函数渐近表达式与真实值的误差:** 通过将积分分为两个部分计算,可大幅减少该误差。" msgstr "**Error between the asymptotic expression of the Bessel function and the true value:** Dividing the integral into two parts can significantly reduce this error." -#: ../../source/Advanced/filon_linear.rst:54 c31f02fdb01d414e986e050b2f5d7816 +#: ../../source/Advanced/filon_linear.rst:54 msgid "" "**区间内核函数线性拟合与真实值的误差:** 该误差受人为设定的Filon积分间隔控制。当 **区间过大** " "时,线性拟合效果很差,计算结果偏差较大。" @@ -135,15 +135,15 @@ msgstr "" "**Error between the linear fitting of the kernel function within the interval and the true value:** This error is controlled by the manually set Filon's integration interval. " "When the **interval is too large**, the linear fitting effect is poor, and the calculation result deviates significantly." -#: ../../source/Advanced/filon_linear.rst:57 41818569315f47b78336bef70d2624cd +#: ../../source/Advanced/filon_linear.rst:57 msgid "通过以下可选参数,可使用Filon积分。" msgstr "Filon's integration can be used through the following optional parameters." -#: ../../source/Advanced/filon_linear.rst:61 4a786d3828764929b1b374c267d9ad3e +#: ../../source/Advanced/filon_linear.rst:61 msgid "C" msgstr "" -#: ../../source/Advanced/filon_linear.rst:63 dee77885e33245c38d566f571fe86a22 +#: ../../source/Advanced/filon_linear.rst:63 msgid "" ":command:`grt` 和 :command:`stgrt` 程序支持以下可选参数来使用Filon积分,具体说明详见 " ":command:`grt -h` 或 :command:`stgrt -h`。" @@ -151,27 +151,27 @@ msgstr "" "The :command:`grt` and :command:`stgrt` programs support the following optional parameters to use Filon's integration. " "For detailed explanations, see :command:`grt -h` or :command:`stgrt -h`." -#: ../../source/Advanced/filon_linear.rst:65 2a1aa2be881845f6abbd5bf339403cfe +#: ../../source/Advanced/filon_linear.rst:65 msgid "``-L[//]``" msgstr "" -#: ../../source/Advanced/filon_linear.rst:67 dd40fc0537b740ba9908efb73fbed0c0 +#: ../../source/Advanced/filon_linear.rst:67 msgid "```` 定义离散波数积分的积分间隔 (见 :ref:`k_integ_rst` 部分)" msgstr "```` defines the integration interval for discrete wavenumber integration (see :ref:`k_integ_rst` section)." -#: ../../source/Advanced/filon_linear.rst:68 3f709a78baca4ffbb08dbac8681b8b61 +#: ../../source/Advanced/filon_linear.rst:68 msgid "```` 定义Filon积分间隔,公式和离散波数积分使用的一致。" msgstr "```` defines the Filon's integration interval, consistent with the formula used for discrete wavenumber integration." -#: ../../source/Advanced/filon_linear.rst:69 5a4a70deda4f4bf198ee4501055d9049 +#: ../../source/Advanced/filon_linear.rst:69 msgid "```` 定义了两个积分的分割点, :math:`k^*=` ```` :math:`/r_{\\text{max}}`" msgstr "```` defines the division point of the two integrals, :math:`k^*=` ```` :math:`/r_{\\text{max}}`." -#: ../../source/Advanced/filon_linear.rst:71 7970f3518caa46619b25d9ea0ae51c7e +#: ../../source/Advanced/filon_linear.rst:71 msgid "Python" msgstr "" -#: ../../source/Advanced/filon_linear.rst:73 a0a886c49b3241408071fe745984f923 +#: ../../source/Advanced/filon_linear.rst:73 msgid "" ":func:`compute_grn() ` 函数和 " ":func:`compute_static_grn() ` " @@ -181,7 +181,7 @@ msgstr "" ":func:`compute_static_grn() ` function " "support the following optional parameters to use Filon's integration. For detailed explanations, see the API." -#: ../../source/Advanced/filon_linear.rst:75 b6b49209453a449fb38a5a8ee36b10ca +#: ../../source/Advanced/filon_linear.rst:75 msgid "``filonLC:List[float]`` 需给定两个量,分别对应C选项卡中的 ```` 参数和 ```` 参数。" msgstr "``filonLC:List[float]`` requires two values, corresponding to the ```` and ```` parameters in the C tab." diff --git a/docs/locales/en/LC_MESSAGES/Advanced/index.po b/docs/locales/en/LC_MESSAGES/Advanced/index.po index 8e209a15..e76192cb 100644 --- a/docs/locales/en/LC_MESSAGES/Advanced/index.po +++ b/docs/locales/en/LC_MESSAGES/Advanced/index.po @@ -19,27 +19,27 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 2.16.0\n" -#: ../../source/Advanced/index.rst:2 d1c66ef87384434696f244d8b6ef22ec +#: ../../source/Advanced/index.rst:2 msgid "进阶教程" msgstr "Advanced Tutorial" -#: ../../source/Advanced/index.rst 2c15e09c24da41c0bbaf822ea0dc632d +#: ../../source/Advanced/index.rst msgid "Author" msgstr "" -#: ../../source/Advanced/index.rst:4 38b4e3d42a5c450d9c59c99a38c95196 +#: ../../source/Advanced/index.rst:4 msgid "Zhu Dengda" msgstr "" -#: ../../source/Advanced/index.rst 4bc4c1eaa6ae41d48a6f182a4022a9dc +#: ../../source/Advanced/index.rst msgid "Email" msgstr "" -#: ../../source/Advanced/index.rst:5 0b13dd0abd00491d8cc6fba892eaa751 +#: ../../source/Advanced/index.rst:5 msgid "zhudengda@mail.iggcas.ac.cn" msgstr "" -#: ../../source/Advanced/index.rst:9 ad9b71e9809440c8b072f7a0dbfb2ee9 +#: ../../source/Advanced/index.rst:9 msgid "以下介绍更多的细节控制及用法。" msgstr "The following introduces more detailed controls and usage." diff --git a/docs/locales/en/LC_MESSAGES/Advanced/integ_converg/integ_converg.po b/docs/locales/en/LC_MESSAGES/Advanced/integ_converg/integ_converg.po index 92ecd9eb..c59af50c 100644 --- a/docs/locales/en/LC_MESSAGES/Advanced/integ_converg/integ_converg.po +++ b/docs/locales/en/LC_MESSAGES/Advanced/integ_converg/integ_converg.po @@ -20,32 +20,26 @@ msgstr "" "Generated-By: Babel 2.16.0\n" #: ../../source/Advanced/integ_converg/integ_converg.rst:4 -#: 66608262db6341ea89878a796cb2a972 msgid "积分收敛性与峰谷平均法" msgstr "Convergency of Integral and Peak-Trough Averaging Method" #: ../../source/Advanced/integ_converg/integ_converg.rst -#: e40552831abf413d8712ebb5e41b35a9 msgid "Author" msgstr "" #: ../../source/Advanced/integ_converg/integ_converg.rst:6 -#: ce35f66a47ef4d13b8091562cdc996cc msgid "Zhu Dengda" msgstr "" #: ../../source/Advanced/integ_converg/integ_converg.rst -#: 57fdc95f71bb436f9cf551c24402774b msgid "Email" msgstr "" #: ../../source/Advanced/integ_converg/integ_converg.rst:7 -#: dae6643c67ef4f11b009f8b070f6d6e9 msgid "zhudengda@mail.iggcas.ac.cn" msgstr "" #: ../../source/Advanced/integ_converg/integ_converg.rst:11 -#: def273595da2403fb880c24137ac26bf msgid "" "通过输出核函数文件,观察源点和场点深度接近时,积分收敛性的变化,以及峰谷平均法的作用。 **具体积分表达式以及分类详见** " ":ref:`gfunc_rst`。" @@ -56,12 +50,10 @@ msgstr "" "expressions and types, see** :ref:`gfunc_rst`." #: ../../source/Advanced/integ_converg/integ_converg.rst:14 -#: 01dc414c3b654166ac5dea0c397c78da msgid "核函数文件" msgstr "Kernel function file" #: ../../source/Advanced/integ_converg/integ_converg.rst:15 -#: 29549dd647cf4373acdb3b6a1a3e07c4 msgid "该文件记录了波数积分过程中不同波数对应的核函数值。以下用法展示了如何输出该文件。" msgstr "" "This file records the kernel function values corresponding to different " @@ -72,13 +64,10 @@ msgstr "" #: ../../source/Advanced/integ_converg/integ_converg.rst:42 #: ../../source/Advanced/integ_converg/integ_converg.rst:106 #: ../../source/Advanced/integ_converg/integ_converg.rst:190 -#: 10a3128472cb45f18d0377c779a4c93f 5671de61dabb4e8783a929780d77b8f1 -#: 77f7e55f93804f95a488e99f2079028e 8bec1a9270a24f7a85bf9f8f331ce02f msgid "C" msgstr "" #: ../../source/Advanced/integ_converg/integ_converg.rst:26 -#: 4dc0c8440c924b4abe9fd50bc540ca00 msgid "输出的核函数文件会在 :rst:dir:`GRN_grtstats/milrow_{depsrc}_{deprcv}/` 路径下。" msgstr "" "The output kernel function files will be under the " @@ -88,18 +77,14 @@ msgstr "" #: ../../source/Advanced/integ_converg/integ_converg.rst:58 #: ../../source/Advanced/integ_converg/integ_converg.rst:113 #: ../../source/Advanced/integ_converg/integ_converg.rst:197 -#: 097f5a35e7374798acf2c10af4a4eb85 12add9cbdad74756be2d27b2e79fff21 -#: 65eb6eaf3f7b46fa86d92975943beae1 74bf3a9ee21a4be9b3dd162f397f89b5 msgid "Python" msgstr "" #: ../../source/Advanced/integ_converg/integ_converg.rst:35 -#: a417303ad09742be9b7a35a0adcb9472 msgid "输出的核函数文件会在自定义路径下。" msgstr "The output kernel function files will be in a custom path." #: ../../source/Advanced/integ_converg/integ_converg.rst:38 -#: b46c62c8209042e8b03e84b91286a557 msgid "" "C和Python导出的核函数文件是一致的,底层调用的是相同的函数。文件名称格式为 ``K_{iw}_{freq}``,其中 ``{iw}`` " "表示频率索引值, ``{freq}`` 表示对应频率(Hz)。文件为自定义的二进制文件, " @@ -114,7 +99,6 @@ msgstr "" "provided." #: ../../source/Advanced/integ_converg/integ_converg.rst:44 -#: 9bcd5c8d284f419fbba0502bf6d46b51 msgid ":command:`grt.k2a` 程序可将单个核函数文件转为文本格式。" msgstr "" "The :command:`grt.k2a` program can convert a single kernel function file " @@ -122,19 +106,16 @@ msgstr "" #: ../../source/Advanced/integ_converg/integ_converg.rst:51 #: ../../source/Advanced/integ_converg/integ_converg.rst:155 -#: 65d25eb501324795bf332d359e54d881 c5ac1b35456c470a8209b3cb4941e815 msgid "输出的文件如下," msgstr "The output files are as follows," #: ../../source/Advanced/integ_converg/integ_converg.rst:56 -#: 3a714d5065614082bf0b43d37db9b018 msgid "后续你可以选择习惯的方式读取和处理。" msgstr "" "Subsequently, you can choose your preferred method for reading and " "processing." #: ../../source/Advanced/integ_converg/integ_converg.rst:65 -#: 2acdff4a78264692bd99ea6853a89bd0 msgid "" "其中除了波数 ``k`` 外,每条结果的命名格式均为 ``{srcType}_{q/w/v}{m}``,与 :ref:`gfunc_rst` " "部分介绍的积分公式中的核函数 :math:`q_m, w_m, v_m` 保持一致。" @@ -145,7 +126,6 @@ msgstr "" ":ref:`gfunc_rst` section." #: ../../source/Advanced/integ_converg/integ_converg.rst:69 -#: 949bdef2d51d467e83880c6ed89664d5 msgid "" "核函数文件中记录的值非最终核函数值。对于动态解,还需乘 :math:`\\left(-\\dfrac{\\Delta " "k}{4\\pi\\rho\\omega^2}\\right)`。" @@ -155,12 +135,10 @@ msgstr "" ":math:`\\left(-\\dfrac{\\Delta k}{4\\pi\\rho\\omega^2}\\right)`." #: ../../source/Advanced/integ_converg/integ_converg.rst:72 -#: 0fc77363663745769a22326b4825bcf4 msgid "可视化" msgstr "Visualization" #: ../../source/Advanced/integ_converg/integ_converg.rst:73 -#: 82c13b0b4c6941e4952ab24f1fadb23b msgid "" "以下将使用Python进行图件绘制。 " "**在Python函数中指定震源类型、阶数、积分类型,可自动绘制核函数、被积函数和积分值随波数的变化**,其中积分类型对应 " @@ -173,28 +151,24 @@ msgstr "" " the four types introduced in the :ref:`gfunc_rst` section." #: ../../source/Advanced/integ_converg/integ_converg.rst:84 -#: ec1355e099f34060ac349700cb0a65b8 msgid "可以通过指定 ``RorI=False`` 参数来指定绘制虚部,传入 ``RorI=2`` 表示实虚部都绘制。" msgstr "" "You can specify the ``RorI=False`` parameter to plot the imaginary part, " "or pass ``RorI=2`` to plot both the real and imaginary parts." #: ../../source/Advanced/integ_converg/integ_converg.rst:95 -#: aef5685403794de0a6197ae4f586aa19 msgid "从图中可以看到,当波数增加到一定范围以上,积分收敛良好,无振荡现象。" msgstr "" "From the figure, it can be seen that when the wavenumber increases beyond" " a certain range, the integral converges well without oscillation." #: ../../source/Advanced/integ_converg/integ_converg.rst:100 -#: a7eb8ce8b29946868e4955f6447f4ea0 msgid "当震源和场点深度接近/相等时,积分收敛速度变慢" msgstr "" "Integral converge slowly when source and receiver depths are close or " "equal." #: ../../source/Advanced/integ_converg/integ_converg.rst:102 -#: e6a7ecf2a76343c5815cb684c4b2ff85 msgid "假设其它参数不变,我们调整 **震源深度为0.1km**,再计算格林函数,读取核函数文件,绘制图像。" msgstr "" "Assuming other parameters remain unchanged, we adjust the **source depth " @@ -202,7 +176,6 @@ msgstr "" " file, and plot the image." #: ../../source/Advanced/integ_converg/integ_converg.rst:124 -#: 337ceb25b3c04ee992d437c0eb18601f msgid "从图中可以清晰地看到,相比震源深度2km时,积分收敛速度明显变慢,积分值振荡,这要求增加波数积分上限,但这必然降低计算效率。" msgstr "" "From the figure, it can be clearly seen that compared to a source depth " @@ -212,7 +185,6 @@ msgstr "" "efficiency." #: ../../source/Advanced/integ_converg/integ_converg.rst:126 -#: be23e106c00d4657992ed63ad0e89c6b msgid "" "你可以尝试 " "**当震源和场点位于同一深度**,收敛振荡现象也很明显。要注意的是这和是否在地表无关,即使震源和场点都在地下,深度接近时积分收敛也会变慢。" @@ -224,12 +196,10 @@ msgstr "" "their depths are close." #: ../../source/Advanced/integ_converg/integ_converg.rst:130 -#: 278ac92d1aa44e0d837f6c6280002965 msgid "峰谷平均法" msgstr "Peak-Trough averaging method" #: ../../source/Advanced/integ_converg/integ_converg.rst:131 -#: 6477c4c8047842398c94952e45f480c0 msgid "" "具体原理很简洁易懂,从以下图像中你也能了解大概。详见 :ref:`(Zhang et al., 2003) ` " ":ref:`(张海明, 2021) `。" @@ -239,7 +209,6 @@ msgstr "" "` :ref:`(Zhang Haiming, 2021) ` for details." #: ../../source/Advanced/integ_converg/integ_converg.rst:133 -#: d847dd7a10994a9797cc5fd5ed8f6ba6 msgid "" "在以上示例中,当震源和场点深度接近时,你会注意到输出的核函数文件增加了,这是因为程序内部设定 " "**当震源和场点深度差小于1km时,自动使用峰谷平均法(PTAM)**。具体流程为,程序中在进行完离散波数积分后,继续增加k(不同震中距使用不同dk),使用PTAM寻找足够数量的波峰和波谷(内部设定为36个),再对这些波峰波谷取缩减序列" @@ -260,7 +229,6 @@ msgstr "" "for the reduction sequence is as follows," #: ../../source/Advanced/integ_converg/integ_converg.rst:144 -#: 415e097454b64cafbe18a04198b95d1d msgid "" "在 ``K_{iw}_{freq}`` 文件同级目录下,程序把 **PTAM过程中的核函数以及积分峰谷位置分为两个文件** 保存在 " "``PTAM_{ir}_{dist}/`` 目录下( ``{ir}`` 为震中距索引, ``{dist}`` 为震中距),其中 " @@ -277,21 +245,18 @@ msgstr "" "records the peaks and troughs of the integral values." #: ../../source/Advanced/integ_converg/integ_converg.rst:148 -#: 53bc22d888bd422fb5c766696abb5a9f msgid ":command:`grt.k2a` 程序也支持将 ``PTAM_{ir}_{dist}/PTAM_{iw}_{freq}`` 文件转为文本格式," msgstr "" "The :command:`grt.k2a` program also supports converting the " "``PTAM_{ir}_{dist}/PTAM_{iw}_{freq}`` file into text format." #: ../../source/Advanced/integ_converg/integ_converg.rst:160 -#: cd259ed7968945958e3c1abf0b96f0a1 msgid "记录了不同震源、不同积分类型的峰谷位置。" msgstr "" "Records the peak-trough positions for different sources and integral " "types." #: ../../source/Advanced/integ_converg/integ_converg.rst:163 -#: d977291e151a4f57b94d3c560dd09ff6 msgid "" "故为了绘制完整的波数积分+PTAM过程,涉及三个文件。不过Python函数已经做了优化,由于程序输出的目录结构固定,文件命名格式固定,只需传入 " "``PTAM_{ir}_{dist}/PTAM_{iw}_{freq}`` 文件,Python函数会自动读取对应的三个文件。" @@ -304,7 +269,6 @@ msgstr "" "automatically read the corresponding three files." #: ../../source/Advanced/integ_converg/integ_converg.rst:174 -#: 2ec69cfec0b64ac7bdb938156a47b148 msgid "红十字为选取的波峰波谷,再取缩减序列即可得到估计的积分收敛值。" msgstr "" "The red crosses represent the selected peaks and troughs, and the " @@ -312,12 +276,10 @@ msgstr "" "reduction sequence." #: ../../source/Advanced/integ_converg/integ_converg.rst:179 -#: 3f2ee24207844b0596f51150b875939e msgid "静态解的积分收敛性" msgstr "Integral convergence of static solutions" #: ../../source/Advanced/integ_converg/integ_converg.rst:180 -#: f6b1a03c70be4910bff29ae1664c9f66 msgid "以上部分是以动态解为例,静态解从积分类型、收敛特征、文件格式、绘图完全类似,只是不再有频率索引值。" msgstr "" "The above section uses dynamic solutions as an example. Static solutions " @@ -326,7 +288,6 @@ msgstr "" "frequency index." #: ../../source/Advanced/integ_converg/integ_converg.rst:184 -#: a4559764a2de45c2931d082fc377f79b msgid "" "核函数文件中记录的值非最终核函数值。对于静态解,还需乘 :math:`\\left(\\dfrac{\\Delta " "k}{4\\pi\\mu}\\right)`。" @@ -336,7 +297,6 @@ msgstr "" ":math:`\\left(\\dfrac{\\Delta k}{4\\pi\\mu}\\right)`." #: ../../source/Advanced/integ_converg/integ_converg.rst:186 -#: 9b0645ba48404d1793eddb498cecb384 msgid "假设震源深度0.1km,场点位于地表,场点仅定义一个点(2,2)做示例,这里直接给出脚本。" msgstr "" "Assume the source depth is 0.1km, the field point is on the surface, and " @@ -344,12 +304,10 @@ msgstr "" "directly here." #: ../../source/Advanced/integ_converg/integ_converg.rst:207 -#: 2401fffa26974696a6de399dc3c96de5 msgid "**只使用离散波数积分**" msgstr "**Only use discrete wavenumber integration**" #: ../../source/Advanced/integ_converg/integ_converg.rst:215 -#: f16724d784f6468fb1cacffe39c2fce8 msgid "**使用峰谷平均法**" msgstr "**Use Peak-Trough averaging method**" diff --git a/docs/locales/en/LC_MESSAGES/Advanced/k_integ.po b/docs/locales/en/LC_MESSAGES/Advanced/k_integ.po index 2c5ef9c5..63d02661 100644 --- a/docs/locales/en/LC_MESSAGES/Advanced/k_integ.po +++ b/docs/locales/en/LC_MESSAGES/Advanced/k_integ.po @@ -19,37 +19,37 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 2.16.0\n" -#: ../../source/Advanced/k_integ.rst:4 87ff0fdc29dc4cd39864a536298db4af +#: ../../source/Advanced/k_integ.rst:4 msgid "控制波数积分" msgstr "Control the Wavenumber Integral" -#: ../../source/Advanced/k_integ.rst 1cc7529328c0437a9ee3779312e50261 +#: ../../source/Advanced/k_integ.rst msgid "Author" msgstr "" -#: ../../source/Advanced/k_integ.rst:6 ab49adb6873342a2addfb308b639b375 +#: ../../source/Advanced/k_integ.rst:6 msgid "Zhu Dengda" msgstr "" -#: ../../source/Advanced/k_integ.rst bd299ca0a3a14a8abaf25fb8dbef4e44 +#: ../../source/Advanced/k_integ.rst msgid "Email" msgstr "" -#: ../../source/Advanced/k_integ.rst:7 d03c97fba0b540bdab1f7d73296e5b15 +#: ../../source/Advanced/k_integ.rst:7 msgid "zhudengda@mail.iggcas.ac.cn" msgstr "" -#: ../../source/Advanced/k_integ.rst:11 0985b725ebd841acaa02977538ff4c37 +#: ../../source/Advanced/k_integ.rst:11 msgid "在 :ref:`gfunc_rst` 部分介绍了程序将按以下形式从数值上计算波数积分," msgstr "In the :ref:`gfunc_rst` section, the program numerically computes the wavenumber integral in the following form," -#: ../../source/Advanced/k_integ.rst:13 fa7c8f44d77943a188ca9302a333bdde +#: ../../source/Advanced/k_integ.rst:13 msgid "" "P_m(\\omega) = \\Delta k \\sum_{j=0}^{\\infty} F_m(k_j,\\omega)J_m(k_j " "r)k_j" msgstr "" -#: ../../source/Advanced/k_integ.rst:17 a6406b12738a4648b50d639a7ee8d25c +#: ../../source/Advanced/k_integ.rst:17 msgid "" "其中 :math:`\\Delta k = 2\\pi/L, k_j=j\\Delta k`,:math:`L` 为特征长度,即 " ":math:`L` 控制波数积分的积分间隔,默认根据 :ref:`gfunc_rst` 部分介绍的约束条件自动确定。" @@ -59,21 +59,21 @@ msgstr "" "By default, it is automatically determined based on the constraints introduced " "in the :ref:`gfunc_rst` section." -#: ../../source/Advanced/k_integ.rst:19 adacd157fad2498f981ac3a08fcbc9b3 +#: ../../source/Advanced/k_integ.rst:19 msgid "程序会取一个较大值 :math:`k_{\\text{max}}` 作为波数积分的上限,经验公式为" msgstr "The program will take a relatively large value :math:`k_{\\text{max}}` as the upper limit of the wavenumber integral, with the empirical formula being" -#: ../../source/Advanced/k_integ.rst:21 1064e89ab8af4d71a4f2a277acdd7a06 +#: ../../source/Advanced/k_integ.rst:21 msgid "" "k_{\\text{max}} = \\sqrt{k_0^2 + s \\cdot " "\\left(\\dfrac{\\omega}{v_{\\text{min}}}\\right)^2}" msgstr "" -#: ../../source/Advanced/k_integ.rst:25 32b42b13b6514f99a373bda326af464d +#: ../../source/Advanced/k_integ.rst:25 msgid "其中" msgstr "in which" -#: ../../source/Advanced/k_integ.rst:27 77134b08c32f4ae587af3c890ca8d53f +#: ../../source/Advanced/k_integ.rst:27 msgid "" ":math:`k_0` 为零频的波数积分上限,默认为 :math:`\\dfrac{5\\pi}{h_s}`, :math:`h_s` " "为震源和场点的深度差(绝对值),限制最小为1km,若实际深度差小于该值,则自动使用峰谷平均法;" @@ -84,21 +84,21 @@ msgstr "" "with a minimum limit of 1 km. If the actual depth difference is less than this " "value, the peak-trough averaging method is automatically used;" -#: ../../source/Advanced/k_integ.rst:28 5b27979ba29f4cefa238c6ed9079a9ae +#: ../../source/Advanced/k_integ.rst:28 msgid ":math:`\\omega` 为角频率;" msgstr ":math:`\\omega` is angular frequency; " -#: ../../source/Advanced/k_integ.rst:29 c1bc940666894d15ab48ec781ae73ace +#: ../../source/Advanced/k_integ.rst:29 msgid "" ":math:`v_{\\text{min}}` " "为参考最小速度,默认取自模型中的最小速度,且限制在0.1km/s以上;若传入负值,表明使用峰谷平均法(负号不参与计算)。" msgstr ":math:`v_{\\text{min}}` is the reference minimum velocity, which defaults to the minimum velocity in the model and is constrained to be above 0.1 km/s. If a negative value is passed, it indicates the use of the peak-trough averaging method (the negative sign is not involved in the calculation)." -#: ../../source/Advanced/k_integ.rst:30 9c96af014f994d7cbeed5af1f023bc90 +#: ../../source/Advanced/k_integ.rst:30 msgid ":math:`s` 为放大系数,默认为1.15;" msgstr ":math:`s` is the amplification factor, with a default value of 1.15." -#: ../../source/Advanced/k_integ.rst:32 50bd4468c26d4ab3b0b56085e59e407c +#: ../../source/Advanced/k_integ.rst:32 msgid "" "程序支持自动判断积分收敛 :ref:`(Yao and Harkrider, 1983) ` " "。当所有积分满足如下表达式时,自动退出波数循环(若达到 :math:`k_{\\text{max}}` 则强制退出 )," @@ -106,109 +106,109 @@ msgstr "" "The program supports automatic determination of integral convergence :ref:`(Yao and Harkrider, 1983) `. " "When all integrals satisfy the following expression, the wavenumber loop automatically exits (or forcibly exits if :math:`k_{\\text{max}}` is reached)." -#: ../../source/Advanced/k_integ.rst:34 ec1e4ad7c431464887daf95ae76773c8 +#: ../../source/Advanced/k_integ.rst:34 msgid "" "\\left | \\dfrac{ k_j F_m(k_j,\\omega) J_m(k_j r) }\n" "{\\sum_{i=1}^j k_i F_m(k_i,\\omega) J_m(k_i r) } \\right | \\le \\epsilon" msgstr "" -#: ../../source/Advanced/k_integ.rst:39 8a0fa6fedad54f259b35beb9cf5562f2 +#: ../../source/Advanced/k_integ.rst:39 msgid "其中 :math:`\\epsilon` 为预先指定的收敛精度。程序默认不使用该功能。" msgstr "where :math:`\\epsilon` is the pre-specified convergence precision. By default, the program does not use this feature." -#: ../../source/Advanced/k_integ.rst:43 1fc743ca959d4603aa4ba69ca169546f +#: ../../source/Advanced/k_integ.rst:43 msgid "通过以下可选参数,可直接控制波数积分, **也将直接影响程序计算结果和运行时长**。" msgstr "The wavenumber integral can be directly controlled through the following optional parameters, **which will also directly affect the program's calculation results and runtime duration**." -#: ../../source/Advanced/k_integ.rst:47 5272f11a07444d5bacc7b53a12e75411 +#: ../../source/Advanced/k_integ.rst:47 msgid "C" msgstr "" -#: ../../source/Advanced/k_integ.rst:49 d67f545bea54451aaca58040f8397be4 +#: ../../source/Advanced/k_integ.rst:49 msgid ":command:`grt` 程序支持以下可选参数来控制波数积分,具体说明详见 :command:`grt -h`。" msgstr "The :command:`grt` program supports the following optional parameters to control the wavenumber integral. For detailed explanations, see :command:`grt -h`." -#: ../../source/Advanced/k_integ.rst:51 2e90e349a51d418d8e98d1d538881307 +#: ../../source/Advanced/k_integ.rst:51 msgid "``-K[//]``" msgstr "" -#: ../../source/Advanced/k_integ.rst:53 05e7d4ce390e4e66ad3219f96c92266b +#: ../../source/Advanced/k_integ.rst:53 msgid "```` 对应公式中的 :math:`k_0` 的系数,默认为5" msgstr "```` corresponds to the coefficient of :math:`k_0` in the formula, with a default value of 5." -#: ../../source/Advanced/k_integ.rst:54 9e8a6ecaf1ea411e93e597bef12a79f4 +#: ../../source/Advanced/k_integ.rst:54 msgid "```` 对应公式中的 :math:`s` ,默认为1.15" msgstr "```` corresponds to :math:`s` in the formula, with a default value of 1.15." -#: ../../source/Advanced/k_integ.rst:55 8c88510577cb43fb92e122ccd4930d5f +#: ../../source/Advanced/k_integ.rst:55 msgid "```` 对应公式中的 :math:`\\epsilon`,默认为-1(不使用)" msgstr "```` corresponds to :math:`\\epsilon` in the formula, with a default value of -1 (not used)." -#: ../../source/Advanced/k_integ.rst:57 8d2c65b110004904b2a1efbcb465a844 +#: ../../source/Advanced/k_integ.rst:57 msgid "``-V``, 对应公式中的 :math:`v_{\\text{min}}`" msgstr "``-V`` corresponds to :math:`v_{\\text{min}}` in the formula." -#: ../../source/Advanced/k_integ.rst:59 eeac188d30b84bb49dcddf1ec821b68d +#: ../../source/Advanced/k_integ.rst:59 msgid "" "``-L``, 对应公式中的 :math:`L` 的系数, :math:`L=` ```` " ":math:`\\cdot r_{\\text{max}}`" msgstr "``-L`` corresponds to the coefficient of :math:`L` in the formula, where :math:`L=` ```` :math:`\\cdot r_{\\text{max}}`." -#: ../../source/Advanced/k_integ.rst:61 f2cda0eaf3fe42929713f5c5eed8eb91 +#: ../../source/Advanced/k_integ.rst:61 msgid ":command:`stgrt` 程序支持以下可选参数来控制波数积分,参数与上面对应,具体说明详见 :command:`stgrt -h`。" msgstr "The :command:`stgrt` program supports the following optional parameters to control the wavenumber integral. The parameters correspond to the above, and detailed explanations can be found in :command:`stgrt -h`." -#: ../../source/Advanced/k_integ.rst:63 de3b285eef554807913934c2148aea69 +#: ../../source/Advanced/k_integ.rst:63 msgid "``-K[/]``" msgstr "" -#: ../../source/Advanced/k_integ.rst:64 797b5b41f6424f198a8fd9abc514a532 +#: ../../source/Advanced/k_integ.rst:64 msgid "``-L``" msgstr "" -#: ../../source/Advanced/k_integ.rst:66 1038c2e13ae345549f351ca0a46713e5 +#: ../../source/Advanced/k_integ.rst:66 msgid "Python" msgstr "" -#: ../../source/Advanced/k_integ.rst:68 0699bee654af41ed8c4e53bc58d6973f +#: ../../source/Advanced/k_integ.rst:68 msgid "" ":func:`compute_grn() ` " "函数支持以下可选参数来控制波数积分,具体说明详见API。" msgstr "The :func:`compute_grn() ` function supports the following optional parameters to control the wavenumber integral. For detailed explanations, see the API." -#: ../../source/Advanced/k_integ.rst:70 1802fc3c1789437090fadc966180c163 +#: ../../source/Advanced/k_integ.rst:70 msgid "``k0:float``, 对应公式中的 :math:`k_0` 的系数,默认为5" msgstr "``k0:float`` corresponds to the coefficient of :math:`k_0` in the formula, with a default value of 5." -#: ../../source/Advanced/k_integ.rst:71 e240b6bd982e4c23902f69f4f81eabbf +#: ../../source/Advanced/k_integ.rst:71 msgid "``ampk:float``, 对应公式中的 :math:`s` ,默认为1.15" msgstr "``ampk:float`` corresponds to :math:`s` in the formula, with a default value of 1.15." -#: ../../source/Advanced/k_integ.rst:72 f4bce5d58e8346fca3393407ad64d939 +#: ../../source/Advanced/k_integ.rst:72 msgid "``keps:float`` 对应公式中的 :math:`\\epsilon`,默认为-1(不使用)" msgstr "``keps:float`` corresponds to :math:`\\epsilon` in the formula, with a default value of -1 (not used)." -#: ../../source/Advanced/k_integ.rst:73 3776ee56a0a040eca108a14a217fd6e4 +#: ../../source/Advanced/k_integ.rst:73 msgid "" "``Length:float`` 对应公式中的 :math:`L` 的系数, :math:`L=` ```` " ":math:`\\cdot r_{\\text{max}}`" msgstr "``Length:float`` corresponds to the coefficient of :math:`L` in the formula, where :math:`L=` ```` :math:`\\cdot r_{\\text{max}}`." -#: ../../source/Advanced/k_integ.rst:75 aee1cf0b2baf4762aa0e46678d9298ae +#: ../../source/Advanced/k_integ.rst:75 msgid "" ":func:`compute_static_grn() ` " "函数支持以下可选参数来控制波数积分,参数与上面对应,具体说明详见API。" msgstr "The :func:`compute_static_grn() ` function supports the following optional parameters to control the wavenumber integral. The parameters correspond to the above, and detailed explanations can be found in the API." -#: ../../source/Advanced/k_integ.rst:77 c35575180a9f4e6b8f6b4b8645d80207 +#: ../../source/Advanced/k_integ.rst:77 msgid "``k0:float``" msgstr "" -#: ../../source/Advanced/k_integ.rst:78 adc2a5b37a084c83b18939c74f29dece +#: ../../source/Advanced/k_integ.rst:78 msgid "``keps:float``" msgstr "" -#: ../../source/Advanced/k_integ.rst:79 ad419c4908d14fbd883312c30f20a4e6 +#: ../../source/Advanced/k_integ.rst:79 msgid "``Length:float``" msgstr "" diff --git a/docs/locales/en/LC_MESSAGES/Advanced/kernel/kernel.po b/docs/locales/en/LC_MESSAGES/Advanced/kernel/kernel.po index ec61ef5d..4dab80c6 100644 --- a/docs/locales/en/LC_MESSAGES/Advanced/kernel/kernel.po +++ b/docs/locales/en/LC_MESSAGES/Advanced/kernel/kernel.po @@ -19,27 +19,27 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 2.16.0\n" -#: ../../source/Tutorial/kernel/kernel.rst:2 0944b5e71b8140728e2b1d29b06c6323 +#: ../../source/Tutorial/kernel/kernel.rst:2 msgid "核函数 :math:`f-v` 谱图" msgstr "Kernel function :math:`f-v` spectrum" -#: ../../source/Tutorial/kernel/kernel.rst 3a31cf7f58fe41fc9fe7e2ce11303237 +#: ../../source/Tutorial/kernel/kernel.rst msgid "Author" msgstr "" -#: ../../source/Tutorial/kernel/kernel.rst:4 ec381742f9a94daebf3a7832088bb061 +#: ../../source/Tutorial/kernel/kernel.rst:4 msgid "Zhu Dengda" msgstr "" -#: ../../source/Tutorial/kernel/kernel.rst 87d078674a734a74a47dea68809bc9be +#: ../../source/Tutorial/kernel/kernel.rst msgid "Email" msgstr "" -#: ../../source/Tutorial/kernel/kernel.rst:5 956a67893d13447ca0b717a22834d7a6 +#: ../../source/Tutorial/kernel/kernel.rst:5 msgid "zhudengda@mail.iggcas.ac.cn" msgstr "" -#: ../../source/Tutorial/kernel/kernel.rst:10 91a1bafce89e4131b5f1558cfa8a336d +#: ../../source/Tutorial/kernel/kernel.rst:10 msgid "" "在 :ref:`integ_converg_rst` 部分介绍了程序可以导出积分过程中不同频率的核函数值,这使得我们可以绘制核函数的 " ":math:`f-v` 谱图 [#]_ ,以观察其中的频散特征 。" @@ -49,21 +49,21 @@ msgstr "" "integration phase, allowing us to plot the kernel function :math:`f-v` spectrum " "[#]_ to observe its dispersion characteristics." -#: ../../source/Tutorial/kernel/kernel.rst:12 e9fb606fe0b64b41b31948d3e11c3022 +#: ../../source/Tutorial/kernel/kernel.rst:12 msgid "以薄层模型为例," msgstr "Taking the thin-layer model as an example," -#: ../../source/Tutorial/kernel/kernel.rst:17 a2223871b25d4c9887bbd74c79b5dc89 +#: ../../source/Tutorial/kernel/kernel.rst:17 msgid "感谢席超强博士 `@xichaoqiang `_ 的建议。" msgstr "" "Thanks to Dr. Chaoqiang Xi `@xichaoqiang " "`_ for the suggestion." -#: ../../source/Tutorial/kernel/kernel.rst:21 470cebdaaebf477e817ffa11a8c0ad80 +#: ../../source/Tutorial/kernel/kernel.rst:21 msgid "生成核函数文件" msgstr "Generate kernel function file" -#: ../../source/Tutorial/kernel/kernel.rst:25 c035761f1e5c4897bdcbb8121743268d +#: ../../source/Tutorial/kernel/kernel.rst:25 msgid "与之前的示例相比,这里添加了控制波数积分的参数,以显式控制核函数的采样间隔和范围。但这并非是计算格林函数的最佳参数,故此时格林函数计算结果很可能是不收敛的。" msgstr "" "Compared to the previous example, parameters for controlling the " @@ -72,19 +72,19 @@ msgstr "" "optimal parameters for calculating the Green's function, so the Green's " "function calculation results may not converge in this case." -#: ../../source/Tutorial/kernel/kernel.rst:30 9c9f200a2da54243a2ecf399be452ef8 +#: ../../source/Tutorial/kernel/kernel.rst:30 msgid "C" msgstr "" -#: ../../source/Tutorial/kernel/kernel.rst:38 844be22aea6a42fb9a7020048672288d +#: ../../source/Tutorial/kernel/kernel.rst:38 msgid "Python" msgstr "" -#: ../../source/Tutorial/kernel/kernel.rst:47 bf659d0f22c34fff9be3c3df24740071 +#: ../../source/Tutorial/kernel/kernel.rst:47 msgid "读取,插值,获得 :math:`f-v` 谱" msgstr "Read, intepolate, and get Kernel function :math:`f-v` spectrum" -#: ../../source/Tutorial/kernel/kernel.rst:48 cc28f265dd444798acfa02d96cac0f59 +#: ../../source/Tutorial/kernel/kernel.rst:48 msgid "" "Python端提供了 :py:func:`pygrt.utils.read_kernels_freqs` 函数来完成所有频率的核函数读取以及从波数" " ``k`` 插值到特定速度点 ``v`` 的工作 ( :math:`v=\\omega/k` ),最后获得保存有核函数的 :math:`f-v`" @@ -96,23 +96,23 @@ msgstr "" ":math:`v=\\omega/k` ), and finally obtaining a dictionary containing the " "Kernel function :math:`f-v` spectra." -#: ../../source/Tutorial/kernel/kernel.rst:56 4c090173925a46969d0a8e1c2177c88d +#: ../../source/Tutorial/kernel/kernel.rst:56 msgid "绘制核函数 :math:`f-v` 谱图" msgstr "Plot kernel function :math:`f-v` spectrum" -#: ../../source/Tutorial/kernel/kernel.rst:57 19d4116898064f7581c73113806a3e6d +#: ../../source/Tutorial/kernel/kernel.rst:57 msgid "以下将使用Python进行图件绘制。" msgstr "The following will use Python for plotting." -#: ../../source/Tutorial/kernel/kernel.rst:66 0030200157164df1a56180c465851485 +#: ../../source/Tutorial/kernel/kernel.rst:66 msgid "**虚部**" msgstr "Imaginary part" -#: ../../source/Tutorial/kernel/kernel.rst:73 1e321f71506b47978d788f430d9d5beb +#: ../../source/Tutorial/kernel/kernel.rst:73 msgid "**实部**" msgstr "Real part" -#: ../../source/Tutorial/kernel/kernel.rst:82 179f3208c47141138ad0ffee329d2c10 +#: ../../source/Tutorial/kernel/kernel.rst:82 msgid "" "从图上可看到, **核函数** :math:`f-v` **谱图的虚部峰值正是频散曲线的位置** ,尽管其中不同震源的核函数幅值不同,但 " ":math:`q_m,w_m` 呈现的频散特征一致,这对应的是 **Rayleigh波频散** ,而 :math:`v_m` 对应的是 " @@ -125,7 +125,7 @@ msgstr "" "w_m` are consistent, which corresponds to **Rayleigh wave dispersion**, " "while :math:`v_m` corresponds to **Love wave dispersion**." -#: ../../source/Tutorial/kernel/kernel.rst:84 849b82c1b53d494da507ca0825e31123 +#: ../../source/Tutorial/kernel/kernel.rst:84 msgid "不同的震源场点深度、不同的虚频率都会导致幅值变化,积分间隔则会影响插值效果。" msgstr "" "Different source/receiver depths and different imaginary frequencies will" diff --git a/docs/locales/en/LC_MESSAGES/Tutorial/dynamic/gfunc.po b/docs/locales/en/LC_MESSAGES/Tutorial/dynamic/gfunc.po index 4d46ffdc..695671a6 100644 --- a/docs/locales/en/LC_MESSAGES/Tutorial/dynamic/gfunc.po +++ b/docs/locales/en/LC_MESSAGES/Tutorial/dynamic/gfunc.po @@ -19,27 +19,27 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 2.16.0\n" -#: ../../source/Tutorial/dynamic/gfunc.rst:4 4312fe3422564999833c02615f9df47f +#: ../../source/Tutorial/dynamic/gfunc.rst:4 msgid "计算动态格林函数" msgstr "Compute Dynamic Green's Functions" -#: ../../source/Tutorial/dynamic/gfunc.rst b57eff1703904bf18c8d85b416e48cfc +#: ../../source/Tutorial/dynamic/gfunc.rst msgid "Author" msgstr "" -#: ../../source/Tutorial/dynamic/gfunc.rst:6 527b881c3490415b8e291edd6379262d +#: ../../source/Tutorial/dynamic/gfunc.rst:6 msgid "Zhu Dengda" msgstr "" -#: ../../source/Tutorial/dynamic/gfunc.rst cf4e9165fd2d454cb96b761f075563d4 +#: ../../source/Tutorial/dynamic/gfunc.rst msgid "Email" msgstr "" -#: ../../source/Tutorial/dynamic/gfunc.rst:7 8b80da9c7e134566bdc072c199a8398c +#: ../../source/Tutorial/dynamic/gfunc.rst:7 msgid "zhudengda@mail.iggcas.ac.cn" msgstr "" -#: ../../source/Tutorial/dynamic/gfunc.rst:12 9288aca0916f4b2ea3b7885a8fccadca +#: ../../source/Tutorial/dynamic/gfunc.rst:12 msgid "" "Python中计算动态格林函数的主函数为 :func:`compute_grn() " "` ,C程序为 :command:`grt`。" @@ -48,7 +48,7 @@ msgstr "" ":func:`compute_grn() `, and the " "corresponding C program is :command:`grt`." -#: ../../source/Tutorial/dynamic/gfunc.rst:14 0e41f3b7ef1a4a77b0581d5bb3bc2e44 +#: ../../source/Tutorial/dynamic/gfunc.rst:14 msgid "" "核心计算逻辑来自 :ref:`初稿 ` ,具体代码可见与C API中对应同名 :file:`*.c`" " 文件,其中计算格林函数频谱的主函数为 :file:`grt.c` 里的 " @@ -61,7 +61,7 @@ msgstr "" ":file:`grt.c`. The coordinate system for the output results is shown in " "the figure below." -#: ../../source/Tutorial/dynamic/gfunc.rst:22 5917a70015914e51a621a95344f74145 +#: ../../source/Tutorial/dynamic/gfunc.rst:22 msgid "" "**推导过程中定义的Z分量与C/Python输出的Z分量方向相反**。因为从Z轴向下为正的坐标系对于 **半无限水平分层均匀介质** " "来讲更便于公式推导;而在结果输出后,会对Z分量取相反数,因为Z轴向上和目前实采数据使用的Z轴方向一致,这更便于后续数据处理。" @@ -75,7 +75,7 @@ msgstr "" " in current real-world data, making subsequent data processing more " "convenient." -#: ../../source/Tutorial/dynamic/gfunc.rst:24 02ac3f22cdc045c89bdef59b7621d44a +#: ../../source/Tutorial/dynamic/gfunc.rst:24 msgid "" "除非特别指明(例如描述震源机制),且一般使用 **PyGRT** 时也不会涉及底层程序内部, **在实际使用过程中提及的Z轴均以向上为正** " ",仅在讨论代码内部细节和公式推导时对此加以区分。" @@ -86,11 +86,11 @@ msgstr "" " positive upward**, with distinctions made only when discussing internal " "code details and formula derivations." -#: ../../source/Tutorial/dynamic/gfunc.rst:29 f9c5c8ca0bd94c14b15a466fbf1bffbd +#: ../../source/Tutorial/dynamic/gfunc.rst:29 msgid "示例程序" msgstr "Simple run" -#: ../../source/Tutorial/dynamic/gfunc.rst:31 202fb73ffcff4b08b298c6a80d80dacd +#: ../../source/Tutorial/dynamic/gfunc.rst:31 msgid "" "假设在 :file:`milrow` " "模型中,震源深度2km,接收点位于地表,震中距为5km,8km和10km,计算格林函数,要求采样点数500个点,采样间隔0.02s。" @@ -100,11 +100,11 @@ msgstr "" "and 10km. Compute the Green's functions with 500 sampling points and a " "sampling interval of 0.02s." -#: ../../source/Tutorial/dynamic/gfunc.rst:35 f2915d95710c45c782f6bbf04b9777c4 +#: ../../source/Tutorial/dynamic/gfunc.rst:35 msgid "C" msgstr "" -#: ../../source/Tutorial/dynamic/gfunc.rst:42 b48a54370e6b43649fde13649edebbc6 +#: ../../source/Tutorial/dynamic/gfunc.rst:42 msgid "" "不同震源深度、接收点深度和震中距的格林函数会在 :rst:dir:`GRN/milrow_{depsrc}_{deprcv}_{dist}/` " "路径下,使用SAC格式保存。" @@ -113,7 +113,7 @@ msgstr "" "epicentral distances are saved in SAC format under the path " ":rst:dir:`GRN/milrow_{depsrc}_{deprcv}_{dist}/`." -#: ../../source/Tutorial/dynamic/gfunc.rst:44 b597d6560c994c0bbe1aee78d1648581 +#: ../../source/Tutorial/dynamic/gfunc.rst:44 msgid "" "一些基本信息(包括源点和场点的物性参数)保存在SAC头段变量中,其中 :c:var:`t0` 和 :c:var:`t1` " "分别代表初至P波和初至S波的到时。在不设定其它参数时,程序中使用0(发震时刻)作为参考时间,故其等价于走时。" @@ -125,17 +125,17 @@ msgstr "" "0 (the origin time) as the reference time, so they are equivalent to " "travel times." -#: ../../source/Tutorial/dynamic/gfunc.rst:46 56024a2dfccb495ca114e8850c8cfcd9 +#: ../../source/Tutorial/dynamic/gfunc.rst:46 msgid ":command:`grt.travt` 命令可以显式地再计算初至波走时," msgstr "" "The :command:`grt.travt` command can explicitly recalculate the travel " "times of the first waves." -#: ../../source/Tutorial/dynamic/gfunc.rst:53 3443b5bfe79740f49f05448e787ba96c +#: ../../source/Tutorial/dynamic/gfunc.rst:53 msgid "走时结果会输出到终端," msgstr "The travel time results will be output to the terminal." -#: ../../source/Tutorial/dynamic/gfunc.rst:58 9c6238af11194bbdab885ec745aad1fa +#: ../../source/Tutorial/dynamic/gfunc.rst:58 msgid "" "如果你没有安装SAC软件,可以使用Python的ObsPy库读取生成的SAC数据,或者使用 :command:`grt.b2a` " "工具临时将SAC格式文件转为如下的文本文件:" @@ -145,18 +145,18 @@ msgstr "" "tool to temporarily convert SAC format files into the following text " "files:" -#: ../../source/Tutorial/dynamic/gfunc.rst:65 b0b8e733036d4d93b908e63c2447c44f +#: ../../source/Tutorial/dynamic/gfunc.rst:65 msgid "输出的文本文件如下,两列分别为时间点和幅值。这种输出仅保留波形信息,缺失SAC文件中的头段变量。" msgstr "" "The output text file is as follows, with two columns representing time " "points and amplitudes, respectively. This output retains only waveform " "information and lacks the header variables in the SAC file." -#: ../../source/Tutorial/dynamic/gfunc.rst:70 4a3d766721f44e80a4c5e43e08e65fa2 +#: ../../source/Tutorial/dynamic/gfunc.rst:70 msgid "Python" msgstr "" -#: ../../source/Tutorial/dynamic/gfunc.rst:77 17dbc428ce2243f2af35b831cd2b4311 +#: ../../source/Tutorial/dynamic/gfunc.rst:77 msgid "" "多个震中距的格林函数以列表形式返回,其中每个元素为 |Stream| 类。:class:`Trace.stats.sac` " "中保存了SAC头段变量,与C程序输出保持一致。" @@ -166,11 +166,11 @@ msgstr "" ":class:`Trace.stats.sac` contains the SAC header variables, consistent " "with the output of the C program." -#: ../../source/Tutorial/dynamic/gfunc.rst:82 dbaed76ef7f34ed2a2d7a385465fb840 +#: ../../source/Tutorial/dynamic/gfunc.rst:82 msgid "格林函数计算结果的单位:" msgstr "Units of the computed Green's function results:" -#: ../../source/Tutorial/dynamic/gfunc.rst:84 9ca8ff2eea1a4d23993eff54cd7e1536 +#: ../../source/Tutorial/dynamic/gfunc.rst:84 msgid "" "爆炸源: :math:`10^{-20} \\, \\frac{\\text{cm}}{\\text{dyne} \\cdot " "\\text{cm}}`" @@ -178,11 +178,11 @@ msgstr "" "Explosion: :math:`10^{-20} \\, \\frac{\\text{cm}}{\\text{dyne} \\cdot " "\\text{cm}}`" -#: ../../source/Tutorial/dynamic/gfunc.rst:85 ff19f184111f421897dfd37fe3659c15 +#: ../../source/Tutorial/dynamic/gfunc.rst:85 msgid "单力源: :math:`10^{-15} \\, \\frac{\\text{cm}}{\\text{dyne}}`" msgstr "Single Force: :math:`10^{-15} \\, \\frac{\\text{cm}}{\\text{dyne}}`" -#: ../../source/Tutorial/dynamic/gfunc.rst:86 3135fe3079a049348aa334888cf87f13 +#: ../../source/Tutorial/dynamic/gfunc.rst:86 msgid "" "剪切源: :math:`10^{-20} \\, \\frac{\\text{cm}}{\\text{dyne} \\cdot " "\\text{cm}}`" @@ -190,7 +190,7 @@ msgstr "" "Shear: :math:`10^{-20} \\, \\frac{\\text{cm}}{\\text{dyne} \\cdot " "\\text{cm}}`" -#: ../../source/Tutorial/dynamic/gfunc.rst:87 7fb0fb4635f642589c6d7cbfe1295699 +#: ../../source/Tutorial/dynamic/gfunc.rst:87 msgid "" "矩张量源: :math:`10^{-20} \\, \\frac{\\text{cm}}{\\text{dyne} \\cdot " "\\text{cm}}`" @@ -198,21 +198,21 @@ msgstr "" "Moment Tensor: :math:`10^{-20} \\, \\frac{\\text{cm}}{\\text{dyne} \\cdot" " \\text{cm}}`" -#: ../../source/Tutorial/dynamic/gfunc.rst:92 e9b61555602e4c44ad8204b3dd963bf9 +#: ../../source/Tutorial/dynamic/gfunc.rst:92 msgid "离散波数积分" msgstr "Discrete wavenumber integration" -#: ../../source/Tutorial/dynamic/gfunc.rst:94 9d2f9f7ce3864248be1295426fb541f6 +#: ../../source/Tutorial/dynamic/gfunc.rst:94 msgid "格林函数频谱的计算本质转化为求以下积分:" msgstr "" "The essence of calculating the Green's functions spectra is transformed " "into solving the following integrals:" -#: ../../source/Tutorial/dynamic/gfunc.rst:96 7b26addcbf9e47b99eec0ba68d561dc1 +#: ../../source/Tutorial/dynamic/gfunc.rst:96 msgid "P_m(\\omega) = \\int_0^\\infty F_m(k, \\omega)J_m(kr)kdk" msgstr "" -#: ../../source/Tutorial/dynamic/gfunc.rst:100 93a7e16857954427acff5c4229f3eee3 +#: ../../source/Tutorial/dynamic/gfunc.rst:100 msgid "" "其中 :math:`F_m(k,\\omega)` 称为核函数,它是和介质属性相关的量,与震中距无关。我们可以使用离散波数积分法 " ":ref:`(Bouchon, 1981) ` 将上式积分转变为求和:" @@ -223,17 +223,17 @@ msgstr "" ":ref:`(Bouchon, 1981) ` to transform the above integral " "into a summation:" -#: ../../source/Tutorial/dynamic/gfunc.rst:102 1df6a1eece5342fcb3462ff4ae6bdc80 +#: ../../source/Tutorial/dynamic/gfunc.rst:102 msgid "P_m(\\omega) = \\Delta k \\sum_{j=0}^{\\infty} F_m(k_j,\\omega)J_m(k_j r)k_j" msgstr "" -#: ../../source/Tutorial/dynamic/gfunc.rst:106 3675493efafa44dca67e40b40714875d +#: ../../source/Tutorial/dynamic/gfunc.rst:106 msgid "其中 :math:`\\Delta k = 2\\pi/L, k_j=j\\Delta k`,:math:`L` 为特征长度,要求满足:" msgstr "" "where :math:`\\Delta k = 2\\pi/L, k_j=j\\Delta k`, and :math:`L` is the " "characteristic length, which must satisfy:" -#: ../../source/Tutorial/dynamic/gfunc.rst:108 67a4adc517ad4f6b842d99f7a072882f +#: ../../source/Tutorial/dynamic/gfunc.rst:108 msgid "" "\\left\\{\n" "\\begin{aligned}\n" @@ -243,7 +243,7 @@ msgid "" "\\right." msgstr "" -#: ../../source/Tutorial/dynamic/gfunc.rst:117 1de90b5ae5bb4841bbf79c0aaad26146 +#: ../../source/Tutorial/dynamic/gfunc.rst:117 msgid "" "其中 :math:`\\alpha` 为参考P波速度, :math:`T` 为所需计算的理论地震图的总时间长度。常见的保守经验值为 " ":math:`L=20r` ,但也应依具体情况而定 。为了避开附加源以及奇点的影响,:ref:`(Bouchon, 1981) " @@ -259,11 +259,11 @@ msgstr "" "detailed derivation, refer to :ref:`(Bouchon, 1981) ` and " ":ref:`(Zhang Haiming, 2021) `." -#: ../../source/Tutorial/dynamic/gfunc.rst:123 9b1c768c4ef64fda8f88dd5195ac7e73 +#: ../../source/Tutorial/dynamic/gfunc.rst:123 msgid "积分形式分类" msgstr "Types of integral forms" -#: ../../source/Tutorial/dynamic/gfunc.rst:125 53659ddf4d27420db91d4db205c88525 +#: ../../source/Tutorial/dynamic/gfunc.rst:125 msgid "" "通过在面谐矢量坐标系中建立波函数进行公式推导,最终格林函数的三分量频谱 :math:`W_m(\\omega), Q_m(\\omega), " "V_m(\\omega)` (分别为垂向,径向,切向)可以表达为:" @@ -274,7 +274,7 @@ msgstr "" "vertical, radial, and tangential components, respectively) can be " "expressed as:" -#: ../../source/Tutorial/dynamic/gfunc.rst:127 4c45f6a6e95345889ef742ac1a0cc7ff +#: ../../source/Tutorial/dynamic/gfunc.rst:127 msgid "" "\\left\\{\n" "\\begin{aligned}\n" @@ -287,7 +287,7 @@ msgid "" "\\right." msgstr "" -#: ../../source/Tutorial/dynamic/gfunc.rst:139 ab9a0b5b8f75460a881dda0b78c555bd +#: ../../source/Tutorial/dynamic/gfunc.rst:139 msgid "" "初次推导该公式可能会对虚数 :math:`i` 及公式中的正负号感到疑惑,但其实这里的设计是将虚数 :math:`i` 和方向因子 " ":math:`e^{im\\theta}` 合并,所以在后续合成理论地震图时你会发现,:math:`m=0,1,2` 阶的 :math:`W_m," @@ -302,7 +302,7 @@ msgstr "" " directional derivative of :math:`V_m` with respect to " ":math:`(m\\theta)`." -#: ../../source/Tutorial/dynamic/gfunc.rst:142 6162322cf45f4e47ab26b67fbd89a7a5 +#: ../../source/Tutorial/dynamic/gfunc.rst:142 msgid "" "公式来自 :ref:`初稿 ` (5.6.22)式,其中阶数 :math:`m=0,1,2`。核函数 " ":math:`q_m,w_m,v_m` " @@ -316,7 +316,7 @@ msgstr "" " cases where the source is shallower than the field point, which is not " "shown here)." -#: ../../source/Tutorial/dynamic/gfunc.rst:144 d2a9c36abf324391947893b2ae36b80f +#: ../../source/Tutorial/dynamic/gfunc.rst:144 msgid "" "\\begin{aligned}\n" "\\begin{bmatrix} q_m \\\\ w_m \\end{bmatrix} &=\n" @@ -335,7 +335,7 @@ msgid "" "\n" msgstr "" -#: ../../source/Tutorial/dynamic/gfunc.rst:158 439cedb9ce664c4286f68f537c3d77d5 +#: ../../source/Tutorial/dynamic/gfunc.rst:158 msgid "" "为了方便程序实现,根据积分形式,我们对待求积分进行如下分类,其中每一阶都分为4类( :math:`p=0,1,2,3` ),除了0阶只需两类,此时" " :math:`v_0=0` :" @@ -345,11 +345,11 @@ msgstr "" "into four types (:math:`p=0,1,2,3`), except for the 0th order, which " "requires only two types, where :math:`v_0=0`:" -#: ../../source/Tutorial/dynamic/gfunc.rst:160 d5a04a0727cd447ab717c963b086f530 +#: ../../source/Tutorial/dynamic/gfunc.rst:160 msgid ":math:`m=0` [#]_" msgstr "" -#: ../../source/Tutorial/dynamic/gfunc.rst:162 e983f189b2f74a9886a995576090442d +#: ../../source/Tutorial/dynamic/gfunc.rst:162 msgid "" "\\left\\{\n" "\\begin{aligned}\n" @@ -359,11 +359,11 @@ msgid "" "\\right." msgstr "" -#: ../../source/Tutorial/dynamic/gfunc.rst:172 a0d6b32b60b44a84a6cb9ab3f848cdc1 +#: ../../source/Tutorial/dynamic/gfunc.rst:172 msgid ":math:`m=1,2`" msgstr "" -#: ../../source/Tutorial/dynamic/gfunc.rst:174 d7febd670e2149e99202e018efbe9d88 +#: ../../source/Tutorial/dynamic/gfunc.rst:174 msgid "" "\\left\\{\n" "\\begin{aligned}\n" @@ -376,7 +376,7 @@ msgid "" "\\right." msgstr "" -#: ../../source/Tutorial/dynamic/gfunc.rst:186 fde71aca360f42bdbb33c2fa1bf8cb0f +#: ../../source/Tutorial/dynamic/gfunc.rst:186 msgid "" "以上每个积分都形成 :math:`\\int_0^\\infty F_m(k, \\omega)J_m(kr)kdk` " "的形式,便可逐个使用离散波数积分(或Filon积分、峰谷平均法等)求解每个积分。" @@ -386,17 +386,17 @@ msgstr "" "discrete wavenumber integration (or Filon integration, peak-trough " "averaging method, etc.)." -#: ../../source/Tutorial/dynamic/gfunc.rst:188 bcb17948bb50491aa022075c682da123 +#: ../../source/Tutorial/dynamic/gfunc.rst:188 msgid "感谢席超强博士 `@xichaoqiang `_ 的订正。" msgstr "" "Thanks to Dr. Chaoqiang Xi `@xichaoqiang " "`_ for the corrections." -#: ../../source/Tutorial/dynamic/gfunc.rst:194 7f3cffa784a04c6b8844336717d770fe +#: ../../source/Tutorial/dynamic/gfunc.rst:194 msgid "格林函数分类" msgstr "Types of Green's Functions" -#: ../../source/Tutorial/dynamic/gfunc.rst:196 bf831e53ab1542069a8abcde92fb85d8 +#: ../../source/Tutorial/dynamic/gfunc.rst:196 msgid "程序会输出15个格林函数(也可以选择输出哪些震源),但并不是每个震源类型对应的每一阶每种积分类型都存在。以下为15个格林函数定义的名称,以及对应上述的阶数以及积分类型:" msgstr "" "The program will output 15 Green's functions (or you can choose which " @@ -404,27 +404,27 @@ msgstr "" "and every type of integral. Below are the names of the 15 defined Green's" " functions, along with their corresponding orders and integral types:" -#: ../../source/Tutorial/dynamic/gfunc.rst:199 1d24fbc4ee3545ae8a8fffe5a931bfd1 +#: ../../source/Tutorial/dynamic/gfunc.rst:199 msgid "**名称**" msgstr "**Name**" -#: ../../source/Tutorial/dynamic/gfunc.rst:199 5bbefbdccc174a769c40f269c3abb1e0 +#: ../../source/Tutorial/dynamic/gfunc.rst:199 msgid "**格林函数类型**" msgstr "**Green's Function Type**" -#: ../../source/Tutorial/dynamic/gfunc.rst:199 978285963f484daca3583a0ab469bd0a +#: ../../source/Tutorial/dynamic/gfunc.rst:199 msgid "**对应阶数**" msgstr "**Order**" -#: ../../source/Tutorial/dynamic/gfunc.rst:199 1e397a8f49954adca1bfc063e23ae796 +#: ../../source/Tutorial/dynamic/gfunc.rst:199 msgid "**对应积分类型**" msgstr "**Integral Type**" -#: ../../source/Tutorial/dynamic/gfunc.rst:201 002443a4725a4bd497f18f6b1babcd40 +#: ../../source/Tutorial/dynamic/gfunc.rst:201 msgid "EXZ" msgstr "" -#: ../../source/Tutorial/dynamic/gfunc.rst:201 941607e835ad4b82ae86241759067981 +#: ../../source/Tutorial/dynamic/gfunc.rst:201 msgid "爆炸源Z分量" msgstr "Explosion, Vertical Upward" @@ -433,10 +433,7 @@ msgstr "Explosion, Vertical Upward" #: ../../source/Tutorial/dynamic/gfunc.rst:205 #: ../../source/Tutorial/dynamic/gfunc.rst:207 #: ../../source/Tutorial/dynamic/gfunc.rst:215 -#: ../../source/Tutorial/dynamic/gfunc.rst:217 2245b7094eb4435baede91605a41b6a6 -#: 4fa45e2c76a2481a9047e767f2e0fb3c 513a46d37bce4ef2a8f165ef62431c6c -#: 57a711a395724c9da99ed7f0ebf6a89b 9d1b65696de34a5a8ae4ccafd6920001 -#: c737a65691ae4c38abb1a59b9a800949 +#: ../../source/Tutorial/dynamic/gfunc.rst:217 msgid ":math:`m=0`" msgstr "" @@ -445,49 +442,45 @@ msgstr "" #: ../../source/Tutorial/dynamic/gfunc.rst:209 #: ../../source/Tutorial/dynamic/gfunc.rst:215 #: ../../source/Tutorial/dynamic/gfunc.rst:219 -#: ../../source/Tutorial/dynamic/gfunc.rst:225 3c8b49c29d5b4231be8d2164e4dcf483 -#: 4e59777844b5405b8149802abbff0131 874d8e86a80a4f44ad6880b6e3770306 -#: 9d591b2b7f6e4f0dae1997db5f1cc9a6 a4b1b7c2ebcb45fa8bd61ce39ebcc649 -#: c7dd980cba5b431594aa0a24e934827d +#: ../../source/Tutorial/dynamic/gfunc.rst:225 msgid ":math:`p=2`" msgstr "" -#: ../../source/Tutorial/dynamic/gfunc.rst:203 08737e0245d94c85bf886108283b0419 +#: ../../source/Tutorial/dynamic/gfunc.rst:203 msgid "EXR" msgstr "" -#: ../../source/Tutorial/dynamic/gfunc.rst:203 649ccc684f0d46eaab0e73e31a18eef2 +#: ../../source/Tutorial/dynamic/gfunc.rst:203 msgid "爆炸源R分量" msgstr "Explosion, Radial Outward" #: ../../source/Tutorial/dynamic/gfunc.rst:203 #: ../../source/Tutorial/dynamic/gfunc.rst:207 -#: ../../source/Tutorial/dynamic/gfunc.rst:217 038780040e234d3b9fd7851557a52554 -#: 67025985fec14eff9376d529dd3b0314 dd9bf46f572f43d084682ca34b4377ad +#: ../../source/Tutorial/dynamic/gfunc.rst:217 msgid ":math:`p=0`" msgstr "" -#: ../../source/Tutorial/dynamic/gfunc.rst:205 d0ef1050be19449fa6e501d84756bb33 +#: ../../source/Tutorial/dynamic/gfunc.rst:205 msgid "VFZ" msgstr "" -#: ../../source/Tutorial/dynamic/gfunc.rst:205 67cb4489ecc24fd4b5aae64ec1aaf7c6 +#: ../../source/Tutorial/dynamic/gfunc.rst:205 msgid "垂直向下力源Z分量" msgstr "Vertical Downward Force, Vertical Upward" -#: ../../source/Tutorial/dynamic/gfunc.rst:207 144a2801705d43fea9803988f8cadf42 +#: ../../source/Tutorial/dynamic/gfunc.rst:207 msgid "VFR" msgstr "" -#: ../../source/Tutorial/dynamic/gfunc.rst:207 127a0920209c4a6e84fd05057aec3ffd +#: ../../source/Tutorial/dynamic/gfunc.rst:207 msgid "垂直向下力源R分量" msgstr "Vertical Downward Force, Radial Outward" -#: ../../source/Tutorial/dynamic/gfunc.rst:209 8d5a40dd05d94a4eb05faf9ec28903fa +#: ../../source/Tutorial/dynamic/gfunc.rst:209 msgid "HFZ" msgstr "" -#: ../../source/Tutorial/dynamic/gfunc.rst:209 8427d51a82a7465d955ec739c58b66bf +#: ../../source/Tutorial/dynamic/gfunc.rst:209 msgid "水平力源Z分量" msgstr "Horizontal Force, Vertical Upward" @@ -496,111 +489,105 @@ msgstr "Horizontal Force, Vertical Upward" #: ../../source/Tutorial/dynamic/gfunc.rst:213 #: ../../source/Tutorial/dynamic/gfunc.rst:219 #: ../../source/Tutorial/dynamic/gfunc.rst:221 -#: ../../source/Tutorial/dynamic/gfunc.rst:223 11d125ec61bc471ea340647de1823ba8 -#: 2bc22f80fce54f8cac5fea3203c02eb8 6c7efd65d8544569abdf76bdde0ac9e1 -#: b66e1968f47f4b7b9a5699df6e2624c2 c71451f5958f4e14b89170cd9a26b459 -#: d2369e56c2f14b85a50c82b9e6d97559 +#: ../../source/Tutorial/dynamic/gfunc.rst:223 msgid ":math:`m=1`" msgstr "" -#: ../../source/Tutorial/dynamic/gfunc.rst:211 dff8a362f0e74dfab37f3cbfd4702103 +#: ../../source/Tutorial/dynamic/gfunc.rst:211 msgid "HFR" msgstr "" -#: ../../source/Tutorial/dynamic/gfunc.rst:211 35b6af4603c147568484e197aa21ea3e +#: ../../source/Tutorial/dynamic/gfunc.rst:211 msgid "水平力源R分量" msgstr "Horizontal Force, Radial Outward" #: ../../source/Tutorial/dynamic/gfunc.rst:211 #: ../../source/Tutorial/dynamic/gfunc.rst:221 -#: ../../source/Tutorial/dynamic/gfunc.rst:227 26c6824f51994908aaa468cb5f8bf42f -#: b39e19fdbc884004a7c83d31bff1c556 ffe292c19bca40abacb637ce9310131a +#: ../../source/Tutorial/dynamic/gfunc.rst:227 msgid ":math:`(p=0)+(p=1)`" msgstr "" -#: ../../source/Tutorial/dynamic/gfunc.rst:213 34bbcdbf71274dae8d2b4b72906f07d9 +#: ../../source/Tutorial/dynamic/gfunc.rst:213 msgid "HFT" msgstr "" -#: ../../source/Tutorial/dynamic/gfunc.rst:213 0a2a01e24e10442ba836520e3117cafc +#: ../../source/Tutorial/dynamic/gfunc.rst:213 msgid "水平力源T分量" msgstr "Horizontal Force, Transverse Clockwise" #: ../../source/Tutorial/dynamic/gfunc.rst:213 #: ../../source/Tutorial/dynamic/gfunc.rst:223 -#: ../../source/Tutorial/dynamic/gfunc.rst:229 0e54d8e2b1f54c2a996651cd222548c0 -#: 6f7cf6ab278a407383dd00b87ab7de43 ff21b0ea0e2c4fab84306514c30a57a5 +#: ../../source/Tutorial/dynamic/gfunc.rst:229 msgid ":math:`-(p=1)+(p=3)`" msgstr "" -#: ../../source/Tutorial/dynamic/gfunc.rst:215 ef465b4ae7904041b2ebdd7d51414067 +#: ../../source/Tutorial/dynamic/gfunc.rst:215 msgid "DDZ" msgstr "" -#: ../../source/Tutorial/dynamic/gfunc.rst:215 cd1f375690e344f98d1ecc451e25f282 +#: ../../source/Tutorial/dynamic/gfunc.rst:215 msgid "倾角45度倾滑Z分量" msgstr "45° dip slip, Vertical Upward" -#: ../../source/Tutorial/dynamic/gfunc.rst:217 2204d9f0d2774562bc9b282e47585503 +#: ../../source/Tutorial/dynamic/gfunc.rst:217 msgid "DDR" msgstr "" -#: ../../source/Tutorial/dynamic/gfunc.rst:217 d42347c1860643d0bf2f5fa57c4e975f +#: ../../source/Tutorial/dynamic/gfunc.rst:217 msgid "倾角45度倾滑R分量" msgstr "45° dip slip, Radial Outward" -#: ../../source/Tutorial/dynamic/gfunc.rst:219 e07f91f4a07a47dba460e74bfab42f32 +#: ../../source/Tutorial/dynamic/gfunc.rst:219 msgid "DSZ" msgstr "" -#: ../../source/Tutorial/dynamic/gfunc.rst:219 4fe3aaea963c4f66ad76f729c1f161e8 +#: ../../source/Tutorial/dynamic/gfunc.rst:219 msgid "倾角90度倾滑Z分量" msgstr "90° dip slip, Vertical Upward" -#: ../../source/Tutorial/dynamic/gfunc.rst:221 3c23d08da15c412793d829b4a822642a +#: ../../source/Tutorial/dynamic/gfunc.rst:221 msgid "DSR" msgstr "" -#: ../../source/Tutorial/dynamic/gfunc.rst:221 8a8d0df583ec4efa8c79679bb026ead7 +#: ../../source/Tutorial/dynamic/gfunc.rst:221 msgid "倾角90度倾滑R分量" msgstr "90° dip slip, Radial Outward" -#: ../../source/Tutorial/dynamic/gfunc.rst:223 0edac21110884ad882357ed0b184e432 +#: ../../source/Tutorial/dynamic/gfunc.rst:223 msgid "DST" msgstr "" -#: ../../source/Tutorial/dynamic/gfunc.rst:223 98d86d2a0a954da39fb6900c60a44aa2 +#: ../../source/Tutorial/dynamic/gfunc.rst:223 msgid "倾角90度倾滑T分量" msgstr "90° dip slip, Transverse Clockwise" -#: ../../source/Tutorial/dynamic/gfunc.rst:225 f1f911610c1f477ca480c0d78c171743 +#: ../../source/Tutorial/dynamic/gfunc.rst:225 msgid "SSZ" msgstr "" -#: ../../source/Tutorial/dynamic/gfunc.rst:225 1639e3a4277b48d3a4cf71815a273099 +#: ../../source/Tutorial/dynamic/gfunc.rst:225 msgid "倾角90度走滑Z分量" msgstr "Vertical strike slip, Vertical Upward" #: ../../source/Tutorial/dynamic/gfunc.rst:225 #: ../../source/Tutorial/dynamic/gfunc.rst:227 -#: ../../source/Tutorial/dynamic/gfunc.rst:229 0708c2c707054fa58a7395b096a9f097 -#: 15d6638941544f2083c5a91905c0c097 dfb154fe455f452c9f13ebdaec28a13d +#: ../../source/Tutorial/dynamic/gfunc.rst:229 msgid ":math:`m=2`" msgstr "" -#: ../../source/Tutorial/dynamic/gfunc.rst:227 7e5177e8c0e24938b0f9e350fe103e45 +#: ../../source/Tutorial/dynamic/gfunc.rst:227 msgid "SSR" msgstr "" -#: ../../source/Tutorial/dynamic/gfunc.rst:227 fa77e6bb33f2445a8af5603c468d1b4c +#: ../../source/Tutorial/dynamic/gfunc.rst:227 msgid "倾角90度走滑R分量" msgstr "Vertical strike slip, Radial Outward" -#: ../../source/Tutorial/dynamic/gfunc.rst:229 1aa04dbfaa6a48048da39f71e7830f96 +#: ../../source/Tutorial/dynamic/gfunc.rst:229 msgid "SST" msgstr "" -#: ../../source/Tutorial/dynamic/gfunc.rst:229 d933e035278149b6a18a7810d837fc3c +#: ../../source/Tutorial/dynamic/gfunc.rst:229 msgid "倾角90度走滑T分量" msgstr "Vertical strike slip, Transverse Clockwise" diff --git a/docs/locales/en/LC_MESSAGES/Tutorial/dynamic/strain_stress.po b/docs/locales/en/LC_MESSAGES/Tutorial/dynamic/strain_stress.po index 76b388f9..ffcf8ce0 100644 --- a/docs/locales/en/LC_MESSAGES/Tutorial/dynamic/strain_stress.po +++ b/docs/locales/en/LC_MESSAGES/Tutorial/dynamic/strain_stress.po @@ -20,32 +20,26 @@ msgstr "" "Generated-By: Babel 2.16.0\n" #: ../../source/Tutorial/dynamic/strain_stress.rst:4 -#: d93da5013590490ba4ff0c4844fc45ae msgid "计算动态应变、旋转、应力张量" msgstr "Compute Dynamic Strain, Rotation, and Stress Tensors" #: ../../source/Tutorial/dynamic/strain_stress.rst -#: eb5462a879a143e0bf6ac4ecca8e8966 msgid "Author" msgstr "" #: ../../source/Tutorial/dynamic/strain_stress.rst:6 -#: 5e4a9212881f40378346e2057949d897 msgid "Zhu Dengda" msgstr "" #: ../../source/Tutorial/dynamic/strain_stress.rst -#: cc50f3e8bdc74180b4e26b6ecf6e7173 msgid "Email" msgstr "" #: ../../source/Tutorial/dynamic/strain_stress.rst:7 -#: 10953a6e0bb44fe59f51ccf223a98399 msgid "zhudengda@mail.iggcas.ac.cn" msgstr "" #: ../../source/Tutorial/dynamic/strain_stress.rst:12 -#: 6429b528630d46d5837d3cd2523ef2ea msgid "" "计算这些张量需要计算位移的空间导数 :math:`\\partial z,\\partial r,\\partial \\theta` " "[#partial]_ 。 从前文关于格林函数的计算 ( :ref:`gfunc_rst` ) 和位移合成的公式 ( :ref:`syn_rst`" @@ -60,7 +54,6 @@ msgstr "" "based on the geometric and constitutive equations." #: ../../source/Tutorial/dynamic/strain_stress.rst:14 -#: 76fa63d03bde459bbc7f0830a83d0a4d msgid "" ":math:`\\partial z,\\partial r,\\partial \\theta` 为 " ":math:`\\dfrac{\\partial}{\\partial z},\\dfrac{\\partial}{\\partial " @@ -71,12 +64,10 @@ msgstr "" "\\dfrac{\\partial}{\\partial \\theta}`." #: ../../source/Tutorial/dynamic/strain_stress.rst:17 -#: ecfe79aff64c4b5983f87a75bdc249d9 msgid "计算格林函数阶段,求出 :math:`\\partial z,\\partial r`" msgstr "During the Green's function calculation phase, compute :math:`\\partial z,\\partial r`" #: ../../source/Tutorial/dynamic/strain_stress.rst:19 -#: 25bc6d6661d74075ad72b4f050102cf4 msgid "" "假设在 :file:`milrow` " "模型中,震源深度2km,接收点位于地表,震中距为10km,计算格林函数及其空间导数,要求采样点数500个点,采样间隔0.02s。" @@ -92,14 +83,10 @@ msgstr "" #: ../../source/Tutorial/dynamic/strain_stress.rst:136 #: ../../source/Tutorial/dynamic/strain_stress.rst:168 #: ../../source/Tutorial/dynamic/strain_stress.rst:202 -#: 2a4ca14945a948d6a4ecb1897c2ade14 33b9432913a848d4b3be30325d539f1b -#: 53b793963c2348649b6f50bad6b17ac1 91a4e5f3fada4a078e35c0457c738767 -#: d945474ea1d048c08dbea37d471aac31 fc17e5f58a754b5c8ad725d53ae930fc msgid "C" msgstr "" #: ../../source/Tutorial/dynamic/strain_stress.rst:30 -#: 8657a04be89744c5860c76054434f2a7 msgid "" "在 :rst:dir:`GRN/milrow_{depsrc}_{deprcv}_{dist}/` " "路径下,文件名开头有\"r\"和\"z\"就代表 :math:`\\partial r` 和 :math:`\\partial z`。" @@ -113,49 +100,38 @@ msgstr "" #: ../../source/Tutorial/dynamic/strain_stress.rst:145 #: ../../source/Tutorial/dynamic/strain_stress.rst:177 #: ../../source/Tutorial/dynamic/strain_stress.rst:211 -#: 01476087fe4343a2bc8ed6dd86a4cb9e 3b14097e577b4013afc3af9f077ae7f0 -#: 422eed83fd7b4513a9ffef18a8f03019 47818307c3054e48a331f297b80a5596 -#: 496c5d6e4f6845e19d8b7d1cee56b1db 7cd5e233549a4e939945e33296dc049f msgid "Python" msgstr "" #: ../../source/Tutorial/dynamic/strain_stress.rst:39 -#: 537f32d9f0df48b0bdfc46acc253c056 msgid "通道名开头有\"r\"和\"z\"就代表 :math:`\\partial r` 和 :math:`\\partial z`。" msgstr "Channel names starting with \"r\" and \"z\" represent :math:`\\partial r` and :math:`\\partial z`, respectively." #: ../../source/Tutorial/dynamic/strain_stress.rst:44 -#: 4b1febc4c8e14148aebc222bfb4169b9 msgid "计算格林函数阶段求出的空间导数的单位:" msgstr "The unit of spatial derivatives computed during the Green's function calculation phase:" #: ../../source/Tutorial/dynamic/strain_stress.rst:46 -#: 0e600e0ec3134cdca5d50bc0459f4eb8 msgid "爆炸源: :math:`10^{-25} \\, /\\text{dyne} \\cdot \\text{cm}`" msgstr "Explosion: :math:`10^{-25} \\, /\\text{dyne} \\cdot \\text{cm}`" #: ../../source/Tutorial/dynamic/strain_stress.rst:47 -#: f66850d2ebcf45309518dba7580488ff msgid "单力源: :math:`10^{-20} \\, /\\text{dyne}`" msgstr "Single Force: :math:`10^{-20} \\, /\\text{dyne}`" #: ../../source/Tutorial/dynamic/strain_stress.rst:48 -#: 51a1e0224b1442f087f0d8540a5656b2 msgid "剪切源: :math:`10^{-25} \\, /\\text{dyne} \\cdot \\text{cm}`" msgstr "Shear: :math:`10^{-25} \\, /\\text{dyne} \\cdot \\text{cm}`" #: ../../source/Tutorial/dynamic/strain_stress.rst:49 -#: c5368593fb824989b33a79362f3e05ee msgid "矩张量源: :math:`10^{-25} \\, /\\text{dyne} \\cdot \\text{cm}`" msgstr "Moment Tensor: :math:`10^{-25} \\, /\\text{dyne} \\cdot \\text{cm}`" #: ../../source/Tutorial/dynamic/strain_stress.rst:54 -#: f795c22b755443af865aedac6854eac0 msgid "合成位移阶段,求出 :math:`\\partial \\theta / r` 并合成位移空间导数" msgstr "During the displacement synthesis phase, compute :math:`\\partial \\theta / r` and synthesize the spatial derivatives of displacement." #: ../../source/Tutorial/dynamic/strain_stress.rst:56 -#: 17220d19db4f4ecf83c06b61491ab749 msgid "" "假设震源为剪切源,断层走向33°,倾角50°,滑动角120°,标量矩 1e24 dyne·cm,方位角30°。待求项中有 :math:`r` " "是为了保证量纲统一。" @@ -165,7 +141,6 @@ msgstr "" "The inclusion of :math:`r` in the terms to be solved ensures dimensional consistency." #: ../../source/Tutorial/dynamic/strain_stress.rst:67 -#: cb0d4a8cf87c4e22861ead54d6b7a2ed msgid "" "在 :rst:dir:`syn_dc/` 路径下,文件名开头有\"r\",\"z\",\"t\"分别代表 :math:`\\partial r`," " :math:`\\partial z`,:math:`\\partial \\theta / r`。" @@ -173,14 +148,12 @@ msgstr "" "In the :rst:dir:`syn_dc/` path, file names starting with \"r\", \"z\", and \"t\" represent :math:`\\partial r`, :math:`\\partial z`, and :math:`\\partial \\theta / r`, respectively." #: ../../source/Tutorial/dynamic/strain_stress.rst:76 -#: a5a2a538675649ceaf51de154189a5da msgid "" "通道名开头有\"r\",\"z\",\"t\"分别代表 :math:`\\partial r`, :math:`\\partial " "z`,:math:`\\partial \\theta / r`。" msgstr "Channel names starting with \"r\", \"z\", and \"t\" represent :math:`\\partial r`, :math:`\\partial z`, and :math:`\\partial \\theta / r`, respectively." #: ../../source/Tutorial/dynamic/strain_stress.rst:79 -#: 31beefea774642da86d33aa9a58e6dd7 msgid "" "以上计算的空间导数在柱坐标系下,即 :math:`\\dfrac{\\partial " "u(z,r,\\theta)}{\\partial(z,r,\\theta)}`。如果需要 :math:`\\dfrac{\\partial " @@ -195,7 +168,6 @@ msgstr "" "change from \"z/r/t\" to \"z/x/y\"." #: ../../source/Tutorial/dynamic/strain_stress.rst:90 -#: e6c8d59a27d945fca2f8a8672b18b549 msgid "" "在 :rst:dir:`syn_dc_zne/` 路径下,文件名开头有\"z\",\"n\",\"e\"分别代表 :math:`\\partial" " z`, :math:`\\partial x`,:math:`\\partial y`。" @@ -203,34 +175,28 @@ msgstr "" "In the :rst:dir:`syn_dc_zne/` path, file names starting with \"z\", \"n\", and \"e\" represent :math:`\\partial z`, :math:`\\partial x`, and :math:`\\partial y`, respectively." #: ../../source/Tutorial/dynamic/strain_stress.rst:99 -#: eca27f30b57346209d93180a65e3d112 msgid "" "通道名开头有\"z\",\"n\",\"e\"分别代表 :math:`\\partial z`, :math:`\\partial " "x`,:math:`\\partial y`。" msgstr "Channel names starting with \"z\", \"n\", and \"e\" represent :math:`\\partial z`, :math:`\\partial x`, and :math:`\\partial y`, respectively." #: ../../source/Tutorial/dynamic/strain_stress.rst:103 -#: a03c06bcc68d409b950c55b807305e27 msgid "不可以使用ObsPy库中提供的Stream.rotate()函数进行位移空间导数的旋转。" msgstr "The Stream.rotate() function provided by the ObsPy library cannot be used to rotate the spatial derivatives of displacement." #: ../../source/Tutorial/dynamic/strain_stress.rst:108 -#: 3f73c877a519465f8243c0b079e7584d msgid "合成的位移空间导数单位为1。" msgstr "The synthesized spatial derivative of displacement has a unit of 1." #: ../../source/Tutorial/dynamic/strain_stress.rst:112 -#: fedecbb468c547329b661f323a5b5fb9 msgid "合成应变、旋转、应力张量" msgstr "Synthesize strain, rotation, and stress tensors" #: ../../source/Tutorial/dynamic/strain_stress.rst:113 -#: b722111d167546159c76f872b5e6e5fd msgid "应变和应力均为二阶对称张量,故将输出6个独立分量;而旋转张量为二阶反对称张量,将输出3个独立分量。" msgstr "Strain and stress are both second-order symmetric tensors, so six independent components will be output; while the rotation tensor is a second-order skew symmetric tensor, three independent components will be output." #: ../../source/Tutorial/dynamic/strain_stress.rst:115 -#: 63c2510951364eaba61eed860261cb2f msgid "" "程序选择张量输出结果的坐标系的依据是——根据文件名/通道名判断是否存在 :math:`\\dfrac{\\partial " "u_x}{\\partial x}`,如果有则使用ZNE坐标系,否则使用ZRT坐标系。 " @@ -245,22 +211,18 @@ msgstr "" "by saving results in separate folders: :rst:dir:`syn_dc/` and :rst:dir:`syn_dc_zne/`." #: ../../source/Tutorial/dynamic/strain_stress.rst:117 -#: 19cc1ed9ad4446ebbbb7e98df6b01159 msgid "以下绘图使用Python绘制,绘图函数如下:" msgstr "The following plots are drawn using Python, and the plotting functions are as follows:" #: ../../source/Tutorial/dynamic/strain_stress.rst:126 -#: 18280103da3e471c96b1bb396d0966c2 msgid "应变张量" msgstr "strain tensor" #: ../../source/Tutorial/dynamic/strain_stress.rst:127 -#: 5c99582b1dc748bdb94b5de62688a607 msgid "根据几何方程(应变-位移关系) [#covariant]_" msgstr "According to the geometric equations (strain-displacement relationship) [#covariant]_" #: ../../source/Tutorial/dynamic/strain_stress.rst:129 -#: 4f1581249fa04422be745161410e7e1d msgid "" "e_{ij} = \\dfrac{1}{2} \\left( u_{i,j} + u_{j,i} \\right) = \\dfrac{1}{2}" " \\left( \\dfrac{\\partial u_i}{\\partial x_j} + \\dfrac{\\partial " @@ -268,7 +230,6 @@ msgid "" msgstr "" #: ../../source/Tutorial/dynamic/strain_stress.rst:143 -#: 3244ff49890447d688ed817eb7e2f916 msgid "" "在 :rst:dir:`syn_dc_zne/` 原路径下,生成 " ":file:`*.strain.??.sac`,文件名中包括分量名,如ZZ、ZN等。" @@ -277,22 +238,18 @@ msgstr "" #: ../../source/Tutorial/dynamic/strain_stress.rst:152 #: ../../source/Tutorial/dynamic/strain_stress.rst:218 -#: 9c84fba4ca084a1f8d1ab4c98cf3d610 d83f5bfa1f814dec96aeba77fab4f0ae msgid "返回的 |Stream| 通道名即为分量名,如ZZ、ZN等。" msgstr "The returned |Stream| channel names are the component names, such as ZZ, ZN, etc." #: ../../source/Tutorial/dynamic/strain_stress.rst:159 -#: 8615ff237d124d26a1c98a95b21a4057 msgid "旋转张量" msgstr "rotation tensor" #: ../../source/Tutorial/dynamic/strain_stress.rst:160 -#: 8dc622d76f814e72b2af325a0e6807a3 msgid "根据旋转-位移关系 [#covariant]_" msgstr "According to the rotation-displacement relationship [#covariant]_" #: ../../source/Tutorial/dynamic/strain_stress.rst:162 -#: c1dae8e9e9d0460db2db22e885500649 msgid "" "w_{ij} = \\dfrac{1}{2} \\left( u_{i,j} - u_{j,i} \\right) = \\dfrac{1}{2}" " \\left( \\dfrac{\\partial u_i}{\\partial x_j} - \\dfrac{\\partial " @@ -300,7 +257,6 @@ msgid "" msgstr "" #: ../../source/Tutorial/dynamic/strain_stress.rst:175 -#: 64d854b75d464bbfa84ed17be70ba060 msgid "" "在 :rst:dir:`syn_dc_zne/` 原路径下,生成 " ":file:`*.rotation.??.sac`,文件名中包括分量名,如ZN,ZE,NE。" @@ -308,29 +264,24 @@ msgstr "" "In the original path :rst:dir:`syn_dc_zne/`, files named :file:`*.rotation.??.sac` are generated, with component names such as ZN, ZE, NE included in the file names." #: ../../source/Tutorial/dynamic/strain_stress.rst:184 -#: d89ffc7da15b4ad5919bbed579a5a337 msgid "返回的 |Stream| 通道名即为分量名,如ZN,ZE,NE。" msgstr "The returned |Stream| channel names are the component names, such as ZN, ZE, NE." #: ../../source/Tutorial/dynamic/strain_stress.rst:191 -#: fd79f0c4047c4793be87c0761536ea77 msgid "应力张量" msgstr "stress tensor" #: ../../source/Tutorial/dynamic/strain_stress.rst:192 -#: ab09e2fdb76447cfa87fc3d124b2c9d9 msgid "根据各向同性介质的本构方程 [#covariant]_" msgstr "According to the constitutive equation of isotropic media [#covariant]_" #: ../../source/Tutorial/dynamic/strain_stress.rst:194 -#: 29a4812e93ad4d69849ccb0bbeaeb387 msgid "" "\\sigma_{ij} = \\lambda \\delta_{ij} e_{kk} + 2 \\mu e_{ij} = \\lambda " "\\delta_{ij} u_{kk} + \\mu \\left( u_{i,j} + u_{j,i} \\right)" msgstr "" #: ../../source/Tutorial/dynamic/strain_stress.rst:209 -#: cd57cfe68edc43e4b821f2ff76fab771 msgid "" "在 :rst:dir:`syn_dc_zne/` 原路径下,生成 " ":file:`*.stress.??.sac`,文件名中包括分量名,如ZZ、ZN等。" @@ -338,17 +289,14 @@ msgstr "" "In the original path :rst:dir:`syn_dc_zne/`, files named :file:`*.stress.??.sac` are generated, with component names such as ZZ, ZN included in the file names." #: ../../source/Tutorial/dynamic/strain_stress.rst:226 -#: c06c7bdead344a56bb96b5cdfa899f66 msgid "计算得到的应力的单位为 :math:`\\frac{\\text{dyne}}{\\text{cm}^2} = 0.1 \\text{Pa}`。" msgstr "The computed stress has a unit of :math:`\\frac{\\text{dyne}}{\\text{cm}^2} = 0.1 \\text{Pa}`." #: ../../source/Tutorial/dynamic/strain_stress.rst:229 -#: 47781896eafc48a39fdf6a3cbb33975c msgid "由于场点位于地表(自由表面),过Z平面的应力均为0(由于浮点数计算误差,呈极小非零数),结果和理论保持一致。" msgstr "Since the field point is located on the surface (free surface), the stress across the Z-plane is zero (appearing as a very small non-zero value due to floating-point calculation errors), consistent with the theoretical results." #: ../../source/Tutorial/dynamic/strain_stress.rst:233 -#: 1da62cff0bde425aa2c914d9708bebda msgid "这只适用于ZNE坐标系,对于ZRT坐标系需考虑协变导数。程序中已考虑,这里不再做公式介绍。" msgstr "This only applies to the ZNE coordinate system. For the ZRT coordinate system, covariant derivatives need to be considered. This has already been accounted for in the program, the formulas are not introduced here." diff --git a/docs/locales/en/LC_MESSAGES/Tutorial/dynamic/syn.po b/docs/locales/en/LC_MESSAGES/Tutorial/dynamic/syn.po index a64cc94a..c91c13c2 100644 --- a/docs/locales/en/LC_MESSAGES/Tutorial/dynamic/syn.po +++ b/docs/locales/en/LC_MESSAGES/Tutorial/dynamic/syn.po @@ -19,49 +19,49 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 2.16.0\n" -#: ../../source/Tutorial/dynamic/syn.rst:4 d9b74a0ce00245938766b7984fd2a27b +#: ../../source/Tutorial/dynamic/syn.rst:4 msgid "合成动态位移" msgstr "Synthesize Dynamic Displacements" -#: ../../source/Tutorial/dynamic/syn.rst c4e9310dfa404802979a02b21e557da5 +#: ../../source/Tutorial/dynamic/syn.rst msgid "Author" msgstr "" -#: ../../source/Tutorial/dynamic/syn.rst:6 ed7c8acec9fd4417a406541437b5d5f3 +#: ../../source/Tutorial/dynamic/syn.rst:6 msgid "Zhu Dengda" msgstr "" -#: ../../source/Tutorial/dynamic/syn.rst 0ab7f6c7ffac46dd8fa5e2c0e79493c8 +#: ../../source/Tutorial/dynamic/syn.rst msgid "Email" msgstr "" -#: ../../source/Tutorial/dynamic/syn.rst:7 ebc7b0f719984ae8a5f09e202ba9bd55 +#: ../../source/Tutorial/dynamic/syn.rst:7 msgid "zhudengda@mail.iggcas.ac.cn" msgstr "" -#: ../../source/Tutorial/dynamic/syn.rst:13 e78bd5eee1264f33901d4bc110adfeaf +#: ../../source/Tutorial/dynamic/syn.rst:13 msgid "**震源机制参数中(如单力源、矩张量源)Z轴取向下为正。**" msgstr "**In the focal mechanism parameters (e.g., single force source, moment tensor source), the Z-axis is positive downward.**" -#: ../../source/Tutorial/dynamic/syn.rst:16 05a5447921ff4e05920899c10fffd70a +#: ../../source/Tutorial/dynamic/syn.rst:16 msgid "" "Python中合成动态位移的主函数为 :func:`gen_syn_from_gf_*() " "` (\\*表示对不同震源) ,C程序为 :command:`grt.syn`。" msgstr "" "The main function in Python for synthesizing dynamic displacements is :func:`gen_syn_from_gf_*() ` (\\* represents different sources), and the corresponding C program is :command:`grt.syn`." -#: ../../source/Tutorial/dynamic/syn.rst:18 2973aec2c57544cd9ddcb6802e73d606 +#: ../../source/Tutorial/dynamic/syn.rst:18 msgid "使用上节计算的格林函数,合成动态位移(理论地震图)。方便起见,这里统一使用milrow模型,震源深度2km,场点位于地表,震中距10km的格林函数,方位角30°。" msgstr "Using the Green's functions calculated in the previous section, synthesize dynamic displacements (theoretical seismograms). For convenience, Green's function based on milrow model + focal depth 2km + surface receiver + epicenter distance 10km is used." -#: ../../source/Tutorial/dynamic/syn.rst:20 8362ccef7128450d9338e090b4ea3a23 +#: ../../source/Tutorial/dynamic/syn.rst:20 msgid "" "在已知三分量格林函数 :math:`W_m(t), Q_m(t), V_m(t)` 后,合成三分量位移 :math:`u_z(t), " "u_r(t), u_\\theta (t)` 的公式为" msgstr "" "After obtaining the three-component Green's functions :math:`W_m(t), Q_m(t), V_m(t)`, the formula for synthesizing the three-component displacements :math:`u_z(t), u_r(t), u_\\theta (t)` is" -#: ../../source/Tutorial/dynamic/syn.rst:22 fd1aec44299e421f94bdf32f8e8b65a2 +#: ../../source/Tutorial/dynamic/syn.rst:22 msgid "" "\\left\\{\n" "\\begin{aligned}\n" @@ -73,38 +73,38 @@ msgid "" "\\right." msgstr "" -#: ../../source/Tutorial/dynamic/syn.rst:32 73b4478c7790490eb3dbfab70cd6129f +#: ../../source/Tutorial/dynamic/syn.rst:32 msgid "" "其中 :math:`D(t)` 为震源时间函数,:math:`*` 表示卷积,:math:`A_m` 为与方位角和震源机制相关的方向因子,其中 " ":math:`u_z, u_r` 的方向因子相同,而 :math:`u_\\theta` 的方向因子满足" msgstr "" "where :math:`D(t)` is the source time function, :math:`*` denotes convolution, and :math:`A_m` represents the directional factors related to azimuth and source mechanism. The directional factors for :math:`u_z` and :math:`u_r` are the same, while the directional factor for :math:`u_\\theta` satisfies" -#: ../../source/Tutorial/dynamic/syn.rst:34 7f3473b566ff4a9cb670e3acf0f14dae +#: ../../source/Tutorial/dynamic/syn.rst:34 msgid "A_{m+3} = \\frac{d A_m}{d (m\\theta)}, m=1,2" msgstr "" -#: ../../source/Tutorial/dynamic/syn.rst:38 d689038f3bb345889abef2908e69caf2 +#: ../../source/Tutorial/dynamic/syn.rst:38 msgid "其中 :math:`m` 为阶数,:math:`\\theta` 为方位角。" msgstr "where :math:`m` is the order, :math:`\\theta` is azimuth." -#: ../../source/Tutorial/dynamic/syn.rst:43 9f2e5b6cf4334535b7f601b60d9d20c6 +#: ../../source/Tutorial/dynamic/syn.rst:43 msgid "合成位移的结果单位为 :math:`\\text{cm}`。" msgstr "The unit of the synthesized displacement results is :math:`\\text{cm}`." -#: ../../source/Tutorial/dynamic/syn.rst:47 706e2d2476274e79920f6a080a49e3ad +#: ../../source/Tutorial/dynamic/syn.rst:47 msgid "不同震源" msgstr "Types of sources" -#: ../../source/Tutorial/dynamic/syn.rst:49 a403a763f80a4304909d9b779ac7d479 +#: ../../source/Tutorial/dynamic/syn.rst:49 msgid "以下绘图使用Python绘制,绘图函数如下:" msgstr "The following plots are drawn using Python, and the plotting function is as follows:" -#: ../../source/Tutorial/dynamic/syn.rst:58 ab2ad394ecce4e39a777c535afff7e7f +#: ../../source/Tutorial/dynamic/syn.rst:58 msgid "爆炸源" msgstr "explosion" -#: ../../source/Tutorial/dynamic/syn.rst:59 c039d1408bf34da68c11354bae96414d +#: ../../source/Tutorial/dynamic/syn.rst:59 msgid "标量矩 1e24 dyne·cm。" msgstr "Scalar moment of 1e24 dyne·cm." @@ -114,10 +114,7 @@ msgstr "Scalar moment of 1e24 dyne·cm." #: ../../source/Tutorial/dynamic/syn.rst:139 #: ../../source/Tutorial/dynamic/syn.rst:165 #: ../../source/Tutorial/dynamic/syn.rst:191 -#: ../../source/Tutorial/dynamic/syn.rst:220 184d2754582143fba2fe45278bf7987b -#: 388f8a329e7547428220a460db3dff74 408d7027cf464856ba3dd115afa192fa -#: 41d9437e85be4da599f648a6e80c4c1d bb85542e955e44a98f607eb99aa9f65f -#: be533f2957e1478e8931ce9598504230 f82c160e3ad54dcda73efacc8bf28f0a +#: ../../source/Tutorial/dynamic/syn.rst:220 msgid "C" msgstr "" @@ -127,34 +124,31 @@ msgstr "" #: ../../source/Tutorial/dynamic/syn.rst:146 #: ../../source/Tutorial/dynamic/syn.rst:172 #: ../../source/Tutorial/dynamic/syn.rst:200 -#: ../../source/Tutorial/dynamic/syn.rst:228 6673845059b74869acfecbf5b8e1573b -#: 6ab88d78127f415a803f3fb47c5ff317 6c9b2b1f893a496d8862100a211b9553 -#: 7a3e690f430c44e2ac400fdb7eb14fbc 8e0a4e3f36a24644925a040ee0ca7c7b -#: bd580994ffba4737a3639dda1c14c197 dc4e845b2d404ac6af2a8f18fc9fbfb0 +#: ../../source/Tutorial/dynamic/syn.rst:228 msgid "Python" msgstr "" -#: ../../source/Tutorial/dynamic/syn.rst:84 261addb8d54244518252b358b608aea8 +#: ../../source/Tutorial/dynamic/syn.rst:84 msgid "单力源" msgstr "single force" -#: ../../source/Tutorial/dynamic/syn.rst:85 388955907e704574bb3f26253adc7b28 +#: ../../source/Tutorial/dynamic/syn.rst:85 msgid "北向力 :math:`f_N=1`,东向力 :math:`f_E=-0.5`,垂直向下的力 :math:`f_Z=2`,单位 1e16 dyne。" msgstr "Northward force :math:`f_N=1`, Eastward force :math:`f_E=-0.5`, and Downward vertical force :math:`f_Z=2`, unit of 1e16 dyne." -#: ../../source/Tutorial/dynamic/syn.rst:109 b9052296562c4a9e9e838141fb307127 +#: ../../source/Tutorial/dynamic/syn.rst:109 msgid "剪切源" msgstr "shear" -#: ../../source/Tutorial/dynamic/syn.rst:110 56949e6e4eea4741956727e71248a5bd +#: ../../source/Tutorial/dynamic/syn.rst:110 msgid "断层走向33°,倾角50°,滑动角120°,标量矩 1e24 dyne·cm。" msgstr "Strike of 33°, Dip of 50°, Slip of 120°, Scalar moment of 1e24 dyne·cm." -#: ../../source/Tutorial/dynamic/syn.rst:134 21a264badc6943b8bd9a1e7f8ac888eb +#: ../../source/Tutorial/dynamic/syn.rst:134 msgid "矩张量源" msgstr "moment tensor" -#: ../../source/Tutorial/dynamic/syn.rst:135 ded301cd49904672860fb6dad42f274b +#: ../../source/Tutorial/dynamic/syn.rst:135 msgid "" ":math:`M_{xx}=0.1, M_{xy}=-0.2, M_{xz}=1.0, M_{yy}=0.3, M_{yz}=-0.5, " "M_{zz}=-2.0`,单位 1e24 dyne·cm, **其中X为北向,Y为东向,Z为垂直向下**。" @@ -162,38 +156,38 @@ msgstr "" ":math:`M_{xx}=0.1, M_{xy}=-0.2, M_{xz}=1.0, M_{yy}=0.3, M_{yz}=-0.5, " "M_{zz}=-2.0`, unit 1e24 dyne·cm, **where X is Northward,Y is Eastward,Z is Downward.**" -#: ../../source/Tutorial/dynamic/syn.rst:160 265780a2cdda4cc899840d04f79cf716 +#: ../../source/Tutorial/dynamic/syn.rst:160 msgid "分量旋转" msgstr "Components rotation" -#: ../../source/Tutorial/dynamic/syn.rst:161 f9ba6af70d3741e2bca6b63f242f5f4b +#: ../../source/Tutorial/dynamic/syn.rst:161 msgid "**PyGRT** 计算默认输出为ZRT分量(柱坐标系),可以设置参数以输出ZNE分量,这里以剪切源为例," msgstr "**PyGRT** calculations by default output ZRT components (cylindrical coordinate system), but parameters can be set to output ZNE components. Here, a shear source is used as an example." -#: ../../source/Tutorial/dynamic/syn.rst:186 abf75aadb7fc4cd7a1800e698c726418 +#: ../../source/Tutorial/dynamic/syn.rst:186 msgid "卷积时间函数" msgstr "Convolve a time function" -#: ../../source/Tutorial/dynamic/syn.rst:187 3ef299e27a534d8398e77cd09f0c8a5d +#: ../../source/Tutorial/dynamic/syn.rst:187 msgid "**PyGRT** 内置了一些震源时间函数,例如抛物波、梯形波、雷克子波或自定义,这里以单力源为例。" msgstr "**PyGRT** has built-in source time functions such as parabolic wave, trapezoidal wave, Ricker wavelet, or custom ones. Here, a single force source is used as an example." -#: ../../source/Tutorial/dynamic/syn.rst:198 fb3debabac4545e78b9b06de2b195506 +#: ../../source/Tutorial/dynamic/syn.rst:198 msgid "" "生成的时间函数会以SAC格式保存在对应路径中,文件名为 :file:`sig.sac`。 其它时间函数以及具体参数用法可使用 " ":command:`grt.syn -h` 查看说明。" msgstr "" "The generated time function will be saved in SAC format at the corresponding path, with the filename :file:`sig.sac`. For other time functions and specific parameter usage, refer to the instructions using :command:`grt.syn -h`." -#: ../../source/Tutorial/dynamic/syn.rst:207 809c27c13bfd499c8dffdc7547e0d2eb +#: ../../source/Tutorial/dynamic/syn.rst:207 msgid "其它时间函数以及具体参数用法可在 :py:mod:`pygrt.signals` 模块中查看函数参数。" msgstr "Other time functions and specific parameter usage can be found in the :py:mod:`pygrt.signals` module by checking the function parameters." -#: ../../source/Tutorial/dynamic/syn.rst:215 d6a8c936c9834b93b7ecd888e5ad422c +#: ../../source/Tutorial/dynamic/syn.rst:215 msgid "位移对时间积分、微分" msgstr "Displacement integration and differentiation over time" -#: ../../source/Tutorial/dynamic/syn.rst:216 67e4d1496d574112ad00213b4f38fe70 +#: ../../source/Tutorial/dynamic/syn.rst:216 msgid "这里以矩张量源为例。" msgstr "Here, a moment tensor source is used as an example." diff --git a/docs/locales/en/LC_MESSAGES/Tutorial/index.po b/docs/locales/en/LC_MESSAGES/Tutorial/index.po index 6bc2f64f..393b56f3 100644 --- a/docs/locales/en/LC_MESSAGES/Tutorial/index.po +++ b/docs/locales/en/LC_MESSAGES/Tutorial/index.po @@ -19,27 +19,27 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 2.16.0\n" -#: ../../source/Tutorial/index.rst:2 053f43536cdd431d8549574dadb9cb61 +#: ../../source/Tutorial/index.rst:2 msgid "简易教程" msgstr "Simple Tutorial" -#: ../../source/Tutorial/index.rst 2c24e5dc56c74701989143be5b5718b4 +#: ../../source/Tutorial/index.rst msgid "Author" msgstr "" -#: ../../source/Tutorial/index.rst:4 9a32193861da4d05ba0749505f56274b +#: ../../source/Tutorial/index.rst:4 msgid "Zhu Dengda" msgstr "" -#: ../../source/Tutorial/index.rst cd21c797b3804ab59f6453aeb5f4d844 +#: ../../source/Tutorial/index.rst msgid "Email" msgstr "" -#: ../../source/Tutorial/index.rst:5 c0a442bba273453c9719e9f4eb881cdd +#: ../../source/Tutorial/index.rst:5 msgid "zhudengda@mail.iggcas.ac.cn" msgstr "" -#: ../../source/Tutorial/index.rst:9 cdcec9ee34c845b494e517d65b35c4ca +#: ../../source/Tutorial/index.rst:9 msgid "" "**PyGRT** 程序包由C和Python两个编程语言的代码组成,目的是兼并高效性和便捷性。底层复杂运算由C语言编写,编译链接成动态库 " "``libgrt.so`` 供Python调用。Python通过 ``ctypes`` " @@ -49,7 +49,7 @@ msgstr "" "``libgrt.so`` for Python to call. Python uses the ``ctypes`` " "library to import the dynamic library and utilize external functions, thus combining the efficiency of C with the convenience of Python." -#: ../../source/Tutorial/index.rst:11 1b91bbca71bc45e1902aaefd89ba106f +#: ../../source/Tutorial/index.rst:11 msgid "" "除了Python脚本式运行, **PyGRT** 保留传统命令行式运行C程序,即在建立动态库过程中也编译了一些可执行文件。 " "**C程序的运行独立于Python,不需要Python环境,以满足更多计算场景。** 每个C程序可使用 ``-h`` 查看帮助。" @@ -57,23 +57,23 @@ msgstr "" "In addition to running Python scripts, **PyGRT** retains the traditional command-line style for running C programs, where some executable files are also compiled during the creation of the dynamic library. " "**The execution of C programs is independent of Python and does not require a Python environment, catering to more computational scenarios.** Each C program can use ``-h`` to view help." -#: ../../source/Tutorial/index.rst:13 a33ae3c27380436d92e4023910066fd3 +#: ../../source/Tutorial/index.rst:13 msgid "计算 **动态解** 的主要计算流程如下:" msgstr "The main computational process for calculating **dynamic solutions** is as follows:" -#: ../../source/Tutorial/index.rst:15 d2bc453653514906830f19024a76985a +#: ../../source/Tutorial/index.rst:15 msgid "Python" msgstr "" -#: ../../source/Tutorial/index.rst:45 512f406640ed4bd28dfb3098c570ad7c +#: ../../source/Tutorial/index.rst:45 msgid "C" msgstr "" -#: ../../source/Tutorial/index.rst:75 dbf4a539e7a148d7a5ff4542e5fffe4b +#: ../../source/Tutorial/index.rst:75 msgid "计算 **静态解** 的过程相同,只是函数名称和程序名称有变化。" msgstr "The process for calculating **static solutions** is the same, only the function names and program names differ." -#: ../../source/Tutorial/index.rst:78 aae783d5f56e4d4894e556cacd04142f +#: ../../source/Tutorial/index.rst:78 msgid "" "以下是一些简易教程,可快速上手。Github主页的 :rst:dir:`example/` 文件夹中有更多示例,可在 `Github " "Releases `_ 中下载。" diff --git a/docs/locales/en/LC_MESSAGES/Tutorial/prepare.po b/docs/locales/en/LC_MESSAGES/Tutorial/prepare.po index cd3f0c71..1731b6ff 100644 --- a/docs/locales/en/LC_MESSAGES/Tutorial/prepare.po +++ b/docs/locales/en/LC_MESSAGES/Tutorial/prepare.po @@ -19,63 +19,63 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 2.16.0\n" -#: ../../source/Tutorial/prepare.rst:2 bcf4767a33194ef49ee42011cb904851 +#: ../../source/Tutorial/prepare.rst:2 msgid "准备工作" msgstr "Preparation" -#: ../../source/Tutorial/prepare.rst b667b98b7b8c49959f27ecc51e998acf +#: ../../source/Tutorial/prepare.rst msgid "Author" msgstr "" -#: ../../source/Tutorial/prepare.rst:4 8c24197880974f80959e9dc28b021f3e +#: ../../source/Tutorial/prepare.rst:4 msgid "Zhu Dengda" msgstr "" -#: ../../source/Tutorial/prepare.rst 037347520ab0454f9d34156cb5c638b7 +#: ../../source/Tutorial/prepare.rst msgid "Email" msgstr "" -#: ../../source/Tutorial/prepare.rst:5 acd877ca730d47fd956aa8fd1283fa62 +#: ../../source/Tutorial/prepare.rst:5 msgid "zhudengda@mail.iggcas.ac.cn" msgstr "" -#: ../../source/Tutorial/prepare.rst:11 145dbd59212442de90ae6979668a1740 +#: ../../source/Tutorial/prepare.rst:11 msgid "安装 **PyGRT**" msgstr "Install **PyGRT**" -#: ../../source/Tutorial/prepare.rst:13 8a833b5387284edba0c9bfbdb4f0fba5 +#: ../../source/Tutorial/prepare.rst:13 msgid "详见 :ref:`install_section` 。" msgstr "See :ref:`install_section` ." -#: ../../source/Tutorial/prepare.rst:17 5a46268d090c4b41944f69f8895457b0 +#: ../../source/Tutorial/prepare.rst:17 msgid "建立模型文件" msgstr "Create model file" -#: ../../source/Tutorial/prepare.rst:22 b4f6002f1a88408fb378b69c8876c341 +#: ../../source/Tutorial/prepare.rst:22 msgid "这里的选项卡 **C** 不代表内部是C语言代码,而是 **使用C语言编译出的可执行程序** (与之相关)。后续的选项卡沿用此设定,不再解释。" msgstr "The tab **C** here does not represent C language code inside, but rather **an executable program compiled using the C language** (related to it). Subsequent tabs follow this convention and will not be explained further." -#: ../../source/Tutorial/prepare.rst:26 b7d95291455a4175b34848bff36224c0 +#: ../../source/Tutorial/prepare.rst:26 msgid "C" msgstr "" -#: ../../source/Tutorial/prepare.rst:28 34639b39bbe64b578262a7739a79e69c +#: ../../source/Tutorial/prepare.rst:28 msgid "**PyGRT** 以如下自由格式定义模型中每层的物性参数,每列之间以空格隔开" msgstr "**PyGRT** defines the physical parameters of each layer in the model using the following free format, with columns separated by spaces." -#: ../../source/Tutorial/prepare.rst:35 51452a1644cf4055bb10f22e351c21c6 +#: ../../source/Tutorial/prepare.rst:35 msgid "例如 :file:`milrow` 模型(假设文本文件名为 `milrow` )" msgstr "For example, the :file:`milrow` model (assuming the text file is named `milrow`)." -#: ../../source/Tutorial/prepare.rst:41 f2c47f15bfe44229a2dbe6c0bfce5f5d +#: ../../source/Tutorial/prepare.rst:41 msgid "Python" msgstr "" -#: ../../source/Tutorial/prepare.rst:43 42d9deb60b8d44ef8387ed1ab6bebeb2 +#: ../../source/Tutorial/prepare.rst:43 msgid "模型格式与C一致,在Python中可以使用 :code:`np.loadtxt()` 导入文本文件,或者手动定义数组" msgstr "The model format is consistent with C, and in Python, you can use :code:`np.loadtxt()` to import the text file or manually define the array." -#: ../../source/Tutorial/prepare.rst:53 aeab016da4da48f1be3a89da56933fe5 +#: ../../source/Tutorial/prepare.rst:53 msgid "最后一行表示半空间,对应厚度值不会被使用。" msgstr "The last line represents the half-space, and the corresponding thickness value will not be used." diff --git a/docs/locales/en/LC_MESSAGES/Tutorial/static/static_gfunc.po b/docs/locales/en/LC_MESSAGES/Tutorial/static/static_gfunc.po index 0e888b0d..2da4c72c 100644 --- a/docs/locales/en/LC_MESSAGES/Tutorial/static/static_gfunc.po +++ b/docs/locales/en/LC_MESSAGES/Tutorial/static/static_gfunc.po @@ -20,32 +20,26 @@ msgstr "" "Generated-By: Babel 2.16.0\n" #: ../../source/Tutorial/static/static_gfunc.rst:2 -#: 23f2a5d175754514a37be833ac64528b msgid "计算静态格林函数" msgstr "Compute Static Green's Functions" #: ../../source/Tutorial/static/static_gfunc.rst -#: 795b02b0229c41f4a8e72809873875b3 msgid "Author" msgstr "" #: ../../source/Tutorial/static/static_gfunc.rst:4 -#: 439db6c1445440938fece394b30e060d msgid "Zhu Dengda" msgstr "" #: ../../source/Tutorial/static/static_gfunc.rst -#: 3fd3d2c18db0457497cb241a99c959af msgid "Email" msgstr "" #: ../../source/Tutorial/static/static_gfunc.rst:5 -#: 302fffe760ce4de3b82394e73e635bf9 msgid "zhudengda@mail.iggcas.ac.cn" msgstr "" #: ../../source/Tutorial/static/static_gfunc.rst:9 -#: f5a8ed5811c943eeb93f1e9decb47101 msgid "" "Python中计算静态格林函数的主函数为 :func:`compute_static_grn() " "` ,C程序为 :command:`stgrt`。" @@ -53,41 +47,34 @@ msgstr "" "The main function for computing static Green's functions in Python is :func:`compute_static_grn() `, and the corresponding C program is :command:`stgrt`." #: ../../source/Tutorial/static/static_gfunc.rst:11 -#: 04526115ca9d4f53a35f5615e87ea52a msgid "" "建议先阅读完动态格林函数的计算过程( :ref:`gfunc_rst` )。静态情况与动态情况采取的计算方法一致,只是推导细节会有不同,详见 " ":ref:`初稿 ` 。" msgstr "It is recommended to first read through the process of computing dynamic Green's functions (:ref:`gfunc_rst`). The computation methods for static and dynamic cases are the same, but the derivation details differ. See :ref:`初稿 ` for more details." #: ../../source/Tutorial/static/static_gfunc.rst:15 -#: 147bd7f0829446ecb0f279ec8720328c msgid "示例程序" msgstr "Simple run" #: ../../source/Tutorial/static/static_gfunc.rst:17 -#: f99be5faebb548fe9f39e0f2b023e5de msgid "" "假设在 :file:`milrow` " "模型中,震源深度2km,接收点位于地表。北向(X/km)在[-3,3]范围内等距采样41个点,东向(Y/km)在[-2.5,2.5]范围内等距采样33个点,计算这些点上的静态格林函数。" msgstr "Assume in the :file:`milrow` model, the source depth is 2 km, and the receiver is located on the surface. The north direction (X/km) is sampled evenly at 41 points within the range [-3, 3], and the east direction (Y/km) is sampled evenly at 33 points within the range [-2.5, 2.5]. Compute the static Green's functions at these points." #: ../../source/Tutorial/static/static_gfunc.rst:21 -#: 12ef70c2e1f04eafb81b1bdede5a1867 msgid "C" msgstr "" #: ../../source/Tutorial/static/static_gfunc.rst:28 -#: 5115ab2ea6ac4ec2b570548c77cd2159 msgid "输出的 :file:`grn` 文件内部如下,开头的 ``#`` 用于保存源点和场点所在介质层的物性参数。" msgstr "The content of the output :file:`grn` file is as follows, with the leading ``#`` used to store the physical properties of the medium layers where the source and receiver points are located." #: ../../source/Tutorial/static/static_gfunc.rst:34 -#: baaa1c9edae24b2594f8a86e8133531b msgid "Python" msgstr "" #: ../../source/Tutorial/static/static_gfunc.rst:41 -#: 11c496d1da55438bbf9762b1251d347e msgid "函数返回字典类型,包括一些基本参数以及格林函数(2D矩阵)。" msgstr "The function returns a dictionary type, including some basic parameters and Green's functions (2D matrix)." diff --git a/docs/locales/en/LC_MESSAGES/Tutorial/static/static_strain_stress.po b/docs/locales/en/LC_MESSAGES/Tutorial/static/static_strain_stress.po index 1b00dbd4..ee01cd5f 100644 --- a/docs/locales/en/LC_MESSAGES/Tutorial/static/static_strain_stress.po +++ b/docs/locales/en/LC_MESSAGES/Tutorial/static/static_strain_stress.po @@ -20,32 +20,26 @@ msgstr "" "Generated-By: Babel 2.16.0\n" #: ../../source/Tutorial/static/static_strain_stress.rst:2 -#: 2b101978700f428991b756a6b0d5ee6d msgid "计算静态应变、旋转、应力张量" msgstr "Compute Static Strain, Rotation, and Stress Tensors" #: ../../source/Tutorial/static/static_strain_stress.rst -#: f4563cd182e84f5e8c0477f0c9392f01 msgid "Author" msgstr "" #: ../../source/Tutorial/static/static_strain_stress.rst:4 -#: bb8d9e5695e34c0b8e5963561fa74d39 msgid "Zhu Dengda" msgstr "" #: ../../source/Tutorial/static/static_strain_stress.rst -#: 58bf9addafbe48a58105715ad0cc2ae8 msgid "Email" msgstr "" #: ../../source/Tutorial/static/static_strain_stress.rst:5 -#: a6d8ad8c7f624315b722fd7f26516527 msgid "zhudengda@mail.iggcas.ac.cn" msgstr "" #: ../../source/Tutorial/static/static_strain_stress.rst:9 -#: 576a0708ed834d5489e0cfa9b6bbe2f7 msgid "" "除了使用不同的函数名/程序名,输出文件不同之外,流程基本和 :ref:`strain_stress_rst` " "类似。这里直接给出脚本。运行后注意观察和 :ref:`static_syn_rst` 的输出有了什么变化。" @@ -53,17 +47,14 @@ msgstr "" "Apart from using different function names/program names and different output files, the process is basically similar to :ref:`strain_stress_rst`. Here, the script is provided directly. After running, pay attention to what changes have occurred compared to the output of :ref:`static_syn_rst`." #: ../../source/Tutorial/static/static_strain_stress.rst:13 -#: 2f8c968b542b4e2f8408df910416126c msgid "C" msgstr "" #: ../../source/Tutorial/static/static_strain_stress.rst:19 -#: 7e514705d7214776a72aa19ffc25a246 msgid "Python" msgstr "" #: ../../source/Tutorial/static/static_strain_stress.rst:40 -#: 298684e4d4154b95af016d688b859d3f msgid "由于场点位于地表(自由表面),过Z平面的应力均为0(由于浮点数计算误差,呈极小非零数),结果和理论保持一致。" msgstr "Since the field point is located on the surface (free surface), the stress across the Z-plane is zero (appearing as a very small non-zero value due to floating-point calculation errors), consistent with the theoretical results." diff --git a/docs/locales/en/LC_MESSAGES/Tutorial/static/static_syn.po b/docs/locales/en/LC_MESSAGES/Tutorial/static/static_syn.po index b2b92e48..405807ac 100644 --- a/docs/locales/en/LC_MESSAGES/Tutorial/static/static_syn.po +++ b/docs/locales/en/LC_MESSAGES/Tutorial/static/static_syn.po @@ -20,30 +20,26 @@ msgstr "" "Generated-By: Babel 2.16.0\n" #: ../../source/Tutorial/static/static_syn.rst:4 -#: 8b11bbc387d44d8b8a3588ad9e4a12a2 msgid "合成静态位移" msgstr "Synthesize Static Displacements" -#: ../../source/Tutorial/static/static_syn.rst f2d1b8ad71f24b48b5f95998726b5b5e +#: ../../source/Tutorial/static/static_syn.rst msgid "Author" msgstr "" #: ../../source/Tutorial/static/static_syn.rst:6 -#: c249600a818042a9828854de81b25a5c msgid "Zhu Dengda" msgstr "" -#: ../../source/Tutorial/static/static_syn.rst 559a6d6ee4094453998a6c6134428826 +#: ../../source/Tutorial/static/static_syn.rst msgid "Email" msgstr "" #: ../../source/Tutorial/static/static_syn.rst:7 -#: 21d923b92e8544ad821309665d007ab7 msgid "zhudengda@mail.iggcas.ac.cn" msgstr "" #: ../../source/Tutorial/static/static_syn.rst:11 -#: 631cf21c045d4d9ab9e66d2ecb0344b0 msgid "" "Python中合成静态位移的主函数为 :func:`gen_syn_from_gf_*() " "` (\\*表示对不同震源)(与合成动态位移的函数共用) ,C程序为 " @@ -52,17 +48,14 @@ msgstr "" "The main function in Python for synthesizing static displacements is :func:`gen_syn_from_gf_*() ` (\\* represents different sources) (same as the dynamic case), and the corresponding C program is :command:`stgrt.syn`." #: ../../source/Tutorial/static/static_syn.rst:13 -#: cb20d746e062466d8173c95498da6082 msgid "使用上节计算的格林函数,合成静态位移。为方便画图,以下结果都使用ZNE分量。" msgstr "Using the Green's functions calculated in the previous section, synthesize static displacements. For convenience in plotting, the following results all use the ZNE components." #: ../../source/Tutorial/static/static_syn.rst:16 -#: 22df650c2fe144f0ad8fb5407be6ce29 msgid "不同震源" msgstr "Types of sources" #: ../../source/Tutorial/static/static_syn.rst:17 -#: 22c0f531802e4ed2908b8c42f96c3007 msgid "" "以下绘图使用Python绘制,绘图函数如下。这里也提供 `GMT `_ 绘图脚本(需根据实际数据调整参数,仅作参考)。" @@ -75,25 +68,18 @@ msgstr "The following plots are drawn using Python, with the plotting functions #: ../../source/Tutorial/static/static_syn.rst:124 #: ../../source/Tutorial/static/static_syn.rst:153 #: ../../source/Tutorial/static/static_syn.rst:177 -#: 0673dd2ec05a4de781e7944b775dc07d 1c6811060b11430d8635319c19d5400f -#: 25f39ff0900343dbbd00a6cdc235f8cf 56fd297755e54f19a7d41eaccc824c5a -#: 7fb01bfa676849fb84f4e335d58c14f0 e4b63c7c897e4cd5b2de5c4267d126e7 -#: ff00b3953d7445238437824cc1918f55 msgid "Python" msgstr "" #: ../../source/Tutorial/static/static_syn.rst:28 -#: 254bc751da5d4c96b3f78415799042b0 msgid "GMT" msgstr "" #: ../../source/Tutorial/static/static_syn.rst:37 -#: 36034c65597f4f99b1125635f5418cbf msgid "爆炸源" msgstr "explosion" #: ../../source/Tutorial/static/static_syn.rst:38 -#: 2de7e9f92c8644d995c41afc1bbbc847 msgid "标量矩 1e24 dyne·cm。" msgstr "Scalar moment of 1e24 dyne·cm." @@ -103,44 +89,34 @@ msgstr "Scalar moment of 1e24 dyne·cm." #: ../../source/Tutorial/static/static_syn.rst:117 #: ../../source/Tutorial/static/static_syn.rst:146 #: ../../source/Tutorial/static/static_syn.rst:170 -#: 1d54828b358f408db5c88152905c96c4 37414ca4186e496da0ede9930199a902 -#: 6ffc0fa8d98f4790bfbc4f3e6ccbd2ff 96a8c7311f0e40de9d49e4997733f2da -#: dcdea25fec5f4331b7584c32a87960da f053a2b4a3ac4e66a64952a4367a916a msgid "C" msgstr "" #: ../../source/Tutorial/static/static_syn.rst:63 -#: 8c89c119867148be9a8e147c89500f28 msgid "单力源" msgstr "single force" #: ../../source/Tutorial/static/static_syn.rst:64 -#: fc475727c7e34341bd8dde694b851931 msgid "北向力 :math:`f_N=1`,东向力 :math:`f_E=-0.5`,垂直向下的力 :math:`f_Z=2`,单位 1e16 dyne。" msgstr "Northward force :math:`f_N=1`, Eastward force :math:`f_E=-0.5`, and Downward vertical force :math:`f_Z=2`, unit of 1e16 dyne." #: ../../source/Tutorial/static/static_syn.rst:89 -#: c3f62a510fba46989984f4d7dad1edf4 msgid "剪切源" msgstr "shear" #: ../../source/Tutorial/static/static_syn.rst:90 -#: 448be3cbb9bc44b0982f03629ce9a3b7 msgid "断层走向33°,倾角50°,滑动角120°,标量矩 1e24 dyne·cm。" msgstr "Strike of 33°, Dip of 50°, Slip of 120°, Scalar moment of 1e24 dyne·cm." #: ../../source/Tutorial/static/static_syn.rst:113 -#: 1e17ff709a4b4434b86d5d2e0f923dc0 msgid "这里如果改变倾角为90°,滑动角0°,就可以看到清晰的蝴蝶状辐射花样。" msgstr "If the dip angle is changed to 90° and the slip angle to 0°, a clear butterfly-shaped radiation pattern can be observed." #: ../../source/Tutorial/static/static_syn.rst:140 -#: 21702d5a9d804db1b3b48aa610ed898f msgid "矩张量源" msgstr "moment tensor" #: ../../source/Tutorial/static/static_syn.rst:141 -#: e53c12482c4744459ff6d707507faefc msgid "" ":math:`M_{xx}=0.1, M_{xy}=-0.2, M_{xz}=1.0, M_{yy}=0.3, M_{yz}=-0.5, " "M_{zz}=-2.0`,单位 1e24 dyne·cm, **其中X为北向,Y为东向,Z为垂直向下**。" @@ -149,7 +125,6 @@ msgstr "" "M_{zz}=-2.0`, unit 1e24 dyne·cm, **where X is Northward,Y is Eastward,Z is Downward.**" #: ../../source/Tutorial/static/static_syn.rst:166 -#: 5c1dbb81363949579df7932ba9115829 msgid "若指定 :math:`M_{xy}=-0.2`,其它均为零,则为纯剪切。" msgstr "If :math:`M_{xy}=-0.2` is specified and all others are zero, it represents pure shear." diff --git a/docs/locales/en/LC_MESSAGES/copyright.po b/docs/locales/en/LC_MESSAGES/copyright.po index 73a24c13..1407717e 100644 --- a/docs/locales/en/LC_MESSAGES/copyright.po +++ b/docs/locales/en/LC_MESSAGES/copyright.po @@ -19,23 +19,23 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 2.16.0\n" -#: ../../source/copyright.rst:2 818bf63e92874469bca547e5e3a8a3f0 +#: ../../source/copyright.rst:2 msgid "版权声明" msgstr "Copyright statement" -#: ../../source/copyright.rst:6 21a40ef21223452eac3ae474df76da89 +#: ../../source/copyright.rst:6 msgid "开源许可" msgstr "Open Source License" -#: ../../source/copyright.rst:8 08b58d3ba4514141abf752172bd6ef8f +#: ../../source/copyright.rst:8 msgid "本项目采用 GPL-3.0 开源许可证发布,您可自由访问、使用及修改代码,但须遵守以下约束:" msgstr "This project is released under GPL-3.0 license. You may freely access, use and modify the code, subject to the following restrictions:" -#: ../../source/copyright.rst:10 ebe1303e1179482eb0c228d1105b085a +#: ../../source/copyright.rst:10 msgid "**禁止商用** :未经书面许可,不得将本项目代码、衍生物或服务用于任何商业用途。" msgstr "**Commercial Use Prohibited**: Without explicit written permission, you may not use the code, derivatives or services for any commercial purposes." -#: ../../source/copyright.rst:11 9e062b9c76a94955b4c0675da217ffcf +#: ../../source/copyright.rst:11 msgid "" "**禁止二次分发** :您无权以任何形式(包括但不限于代码托管平台、打包发布等)公开分发本项目源代码。唯一官方下载渠道为: `PyGRT " "`_" @@ -45,15 +45,15 @@ msgstr "" "platforms or packaged releases). The only official distribution channel is: " "`PyGRT `_" -#: ../../source/copyright.rst:15 96b3e189624f4c9586c3ab8a80857518 +#: ../../source/copyright.rst:15 msgid "修改与贡献" msgstr "Modifications and Contributions" -#: ../../source/copyright.rst:17 a8a3f51abe4f4f3e9824879b3289bf0a +#: ../../source/copyright.rst:17 msgid "**开源义务** :任何基于本项目的修改或衍生作品,必须以相同许可证完全开源。" msgstr "**Open Source Requirement**: Any modifications or derivative works must be fully open-sourced under the same license." -#: ../../source/copyright.rst:18 7c88558f02a14c2f82c26d60214991d4 +#: ../../source/copyright.rst:18 msgid "**贡献建议** :欢迎通过 GitHub Pull Request 提交改进,所有贡献需遵循本项目代码规范与许可条款。" msgstr "**Contribution Guidelines**: Improvements via GitHub Pull Requests are welcome. All contributions must comply with the project's coding standards and license terms." diff --git a/docs/locales/en/LC_MESSAGES/index.po b/docs/locales/en/LC_MESSAGES/index.po index 805b45cf..d1ba6e5e 100644 --- a/docs/locales/en/LC_MESSAGES/index.po +++ b/docs/locales/en/LC_MESSAGES/index.po @@ -27,27 +27,27 @@ msgstr "Document Homepage" msgid "目录" msgstr "Table of Contents" -#: ../../source/index.rst:2 f4848c2a93124956808de83f80c8680f +#: ../../source/index.rst:2 msgid "**PyGRT** 文档" msgstr "**PyGRT** Document" -#: ../../source/index.rst b559b6af5d734114b6748b42d62a9a63 +#: ../../source/index.rst msgid "Author" msgstr "" -#: ../../source/index.rst:4 199cf64e44454e21bfb6b47ac5f9cec4 +#: ../../source/index.rst:4 msgid "Zhu Dengda" msgstr "" -#: ../../source/index.rst bd0f43ca0562407bba862145fa56d6c9 +#: ../../source/index.rst msgid "Email" msgstr "" -#: ../../source/index.rst:5 fb94d911a2fc4888a13c3ea35f12edb7 +#: ../../source/index.rst:5 msgid "zhudengda@mail.iggcas.ac.cn" msgstr "" -#: ../../source/index.rst:20 646d08afdfed40109fc6137002001765 +#: ../../source/index.rst:20 msgid "" "**PyGRT** : 一个用于计算在半无限水平分层均匀介质模型中的理论地震图的 " "**Python**\\程序包,使用广义反射透射系数矩阵法(**G**\\eneralized " @@ -58,30 +58,30 @@ msgstr "" "**G**\\eneralized **R**\\eflection-**T**\\ransmission coefficient matrix " "and Discrete Wavenumber Method. " -#: ../../source/index.rst:23 1871f0c2ad36435fb99c9cec41c1a023 +#: ../../source/index.rst:23 msgid "**PyGRT** 能计算什么?" msgstr "What can **PyGRT** calculate?" -#: ../../source/index.rst:24 777f80f55833448db260a3eb561ddd6d +#: ../../source/index.rst:24 msgid "目前,**PyGRT** 可计算区域尺度内半无限水平分层均匀介质中的 **动态与静态的位移,以及应力、应变、旋转张量。**" msgstr "" "At present, **PyGRT** can calculate **the dynamic and static " "displacements, as well as stress, strain and rotational tensors in semi-" "infinite horizontally layered media within the regional scale.**" -#: ../../source/index.rst:28 03e9f5f79fe444bda47c67d7bbeb7f6f +#: ../../source/index.rst:28 msgid "运行平台" msgstr "Operation Platform" -#: ../../source/index.rst:29 07f0d1fdf053418b9e9b616abe4ce5f9 +#: ../../source/index.rst:29 msgid "**Windows, Linux, MacOS**" msgstr "" -#: ../../source/index.rst:33 89274bc9424b409b979b570bd81d8182 +#: ../../source/index.rst:33 msgid "程序特点" msgstr "Features" -#: ../../source/index.rst:35 e9af1482a5cb41d8b53970dd9fc50ca2 +#: ../../source/index.rst:35 msgid "" "**格林函数频谱由C程序并行计算**。由于不同频率间的计算相互独立,在计算过程中基于 `OpenMP " "`_ 进行了 **并行优化**,极大提升了计算效率;" @@ -95,13 +95,10 @@ msgstr "" #: ../../source/index.rst:36 ../../source/index.rst:39 #: ../../source/index.rst:42 ../../source/index.rst:45 #: ../../source/index.rst:48 ../../source/index.rst:51 -#: 1e7271e61c9a4ccc803825b668707ac2 44d09527b2bf45ad9a668c6fa84ec1b1 -#: 64bbae586f8e4115a61dfcd0209feae3 8c991d94a6ff43a78ad968ff7709349a -#: cc83ac674ef8474da8a180d32e152fb9 e08b5efaa87045f5a8aa9efdcfc59767 msgid "\\" msgstr "" -#: ../../source/index.rst:38 cea453322d5d4fdbbf2e78cda8a7547c +#: ../../source/index.rst:38 msgid "" "**将Python语言的便携、可扩展性与C语言的计算高效特点结合**。C代码被编译链接成动态库 ``libgrt.so`` , **PyGRT**" " 再基于Python的 `ctypes `_ " @@ -122,20 +119,20 @@ msgstr "" "mature third-party libraries, it can flexibly realize various subsequent " "data processing." -#: ../../source/index.rst:41 e3a75b1e89b2431cb05b0717f853acc8 +#: ../../source/index.rst:41 msgid "" "**明确的中文注释**。我在代码中对计算过程给出了明确的中文注释以及相关的公式索引, **所有公式索引(除非特别指明)均来自** " ":ref:`该初稿 " "`,在代码中基本按照公式推导的计算逻辑,在不过多损失计算效率的前提下进行适当优化,保证了代码的可读性,希望能给学习过程中的你提供一些参考,解答一些疑惑。仅是我浅薄的理解,仅作参考,欢迎指正。" msgstr "Rich comments in the code." -#: ../../source/index.rst:44 331ada4b060f4aa29a943afa89783224 +#: ../../source/index.rst:44 msgid "**特殊情况下的计算优化**。目前包括两个部分:" msgstr "" "**Computational Optimization under Special Circumstances.** At present, " "it includes two parts:" -#: ../../source/index.rst:47 0e13f9acb3f54c1cb8eed35e77f99e78 +#: ../../source/index.rst:47 msgid "" "**当震中距** :math:`r` **很大时**。由于结果中Bessel函数的形式为 " ":math:`J_m(kr)`,当震中距变大时,积分要求波数 :math:`k` 的积分间隔就越小,导致计算变慢。目前 **PyGRT** 实现了" @@ -156,7 +153,7 @@ msgstr "" "interval, which can increase the integration interval of the wavenumber " "and improve the calculation speed." -#: ../../source/index.rst:50 7c4cb739158c42bcb7dad5e80259796d +#: ../../source/index.rst:50 msgid "" "**当震源深度和台站深度很接近时(如第一类Lamb问题,台站和震源均位于地表)**。此时核函数随着波数 :math:`k` " "的增加收敛非常慢,会在收敛值上下波动,导致很难到达到指定的收敛条件,需要耗费更多时间以达到更高的积分上限。目前 **PyGRT** 实现了 " @@ -177,7 +174,7 @@ msgstr "" "the reduced sequence :math:`M_i \\leftarrow 0.5\\times(M_i + M_{i+1})` is" " recursively taken to obtain the convergence value." -#: ../../source/index.rst:53 76b33cf3ba1a496986508b44b3afcfc2 +#: ../../source/index.rst:53 msgid "" "**积分过程可输出记录文件**。通过函数参数设置,在计算格林函数频谱时可输出不同频率的积分过程文件,记录了核函数随波数 :math:`k` " "的变化,且 **PyGRT** 包含了读取该文件的Python函数,可以简易地观察到相关量的变化,方便各种测试以及学习过程中的理解。" @@ -190,7 +187,7 @@ msgstr "" " of relevant quantities can be easily observed, which is convenient for " "various tests and understanding in the learning process." -#: ../../source/index.rst:59 5d8a95028c854e11a97453d42bbabb91 +#: ../../source/index.rst:59 msgid "" "以下包括 **Python** 和 **C** 两部分的API介绍。如果只关心程序的使用,可以只查看 **Python** " "部分;若对具体实现过程感兴趣,尤其是在学习 **广义反射透射系数矩阵、离散波数法、线性Filon积分法、峰谷平均法** " @@ -198,7 +195,7 @@ msgid "" ",希望能帮助你在学习相关内容时解答一些疑惑。" msgstr "\\" -#: ../../source/index.rst:61 537a78327af04a6e9fa0e6052fb07f65 +#: ../../source/index.rst:61 msgid "" "本文档页面源码位于 Github主页的 `docs/ " "`_,可查看示例代码和画图脚本。" @@ -207,11 +204,11 @@ msgstr "" "`docs/ `_, where" " you can view the example code and drawing scripts." -#: ../../source/index.rst:81 b96ad6d96b64480aa83f969c95b9edf2 +#: ../../source/index.rst:81 msgid "主要参考" msgstr "Main References" -#: ../../source/index.rst:85 a8a5388b51224cea8be6bfe54c18e3b1 +#: ../../source/index.rst:85 msgid "" "Michel Bouchon. 1981. A simple method to calculate Green's functions for " "elastic layered media. Bulletin of the Seismological Society of America. " @@ -219,13 +216,13 @@ msgid "" "`_" msgstr "" -#: ../../source/index.rst:89 9f8258a6519c4929ad22bc324000dc30 +#: ../../source/index.rst:89 msgid "纪晨, 姚振兴, 1995. 区域地震范围的宽频带理论地震图算法研究[J]. 地球物理学报, 38(4): 460-468." msgstr "" "Ji C, Yao Z, 1995. THE STUDY OF THE METHOD FOR BROADBAND REGIONAL " "SYNTHETIC SEISMOGRAM[J]. Chinese Journal of Geophysics. 38(4): 460-468." -#: ../../source/index.rst:93 25aff531ab87469fb1a06c482c566665 +#: ../../source/index.rst:93 msgid "" "谢小碧, 姚振兴, 1989. 计算分层介质中位错点源静态位移场的广义反射、透射系数矩阵和离散波数方法[J]. 地球物理学报, 32(3): " "270-280." @@ -235,11 +232,11 @@ msgstr "" "Half-Space by DisLocation Source[J]. Acta Geophysics Sinica, 32(3): " "270-280." -#: ../../source/index.rst:97 ab3a21a1852e436198dc1d62c32a50bf +#: ../../source/index.rst:97 msgid "姚振兴, 谢小碧. 2022/03. 理论地震图及其应用(初稿)." msgstr "" -#: ../../source/index.rst:101 87d0319e0f794cdbaa9b4beb48675329 +#: ../../source/index.rst:101 msgid "" "Yao Z. X. and D. G. Harkrider. 1983. A generalized refelection-" "transmission coefficient matrix and discrete wavenumber method for " @@ -247,11 +244,11 @@ msgid "" "`10.1785/BSSA07306A1685 `_" msgstr "" -#: ../../source/index.rst:105 c63257cf5e5e49ffae34d15649de49de +#: ../../source/index.rst:105 msgid "张海明. 2021. 地震学中的Lamb问题(上). 科学出版社." msgstr "" -#: ../../source/index.rst:109 5d418f2f8e48443cb74b7ea3b19ea2d5 +#: ../../source/index.rst:109 msgid "" "Zhang, H. M., Chen, X. F., and Chang, S. 2003. An efficient numerical " "method for computing synthetic seismograms for a layered half-space with " diff --git a/docs/locales/en/LC_MESSAGES/install.po b/docs/locales/en/LC_MESSAGES/install.po index 089fcc66..6b942d79 100644 --- a/docs/locales/en/LC_MESSAGES/install.po +++ b/docs/locales/en/LC_MESSAGES/install.po @@ -19,11 +19,11 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 2.16.0\n" -#: ../../source/install.rst:5 4ba143b274a84ddabf96a1e4551d03ec +#: ../../source/install.rst:5 msgid "安装" msgstr "Installation" -#: ../../source/install.rst ebf41afdaae944bf8a8287ca457b8149 +#: ../../source/install.rst msgid "Author" msgstr "" diff --git a/docs/source/conf.py b/docs/source/conf.py index c0a42456..948d5d02 100755 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -82,7 +82,7 @@ def setup(app): language = 'zh_CN' locale_dirs = ['../locales/'] # 存放翻译文件的目录 -gettext_uuid = True +gettext_uuid = False gettext_compact = False # -- Options for HTML output ------------------------------------------------- From 0204dcbdee74e8f1ccb13cf2d9259ac0e70db1d2 Mon Sep 17 00:00:00 2001 From: Dengda98 Date: Sun, 27 Apr 2025 14:03:51 +0800 Subject: [PATCH 08/25] DOC: use `EX` instead `EXP` to represent Explosion --- docs/source/Tutorial/dynamic/run/run.py | 2 +- docs/source/Tutorial/dynamic/run/run.sh | 4 ++-- docs/source/Tutorial/dynamic/syn.rst | 2 +- docs/source/Tutorial/static/run/run.py | 2 +- docs/source/Tutorial/static/run/run.sh | 6 +++--- docs/source/Tutorial/static/static_syn.rst | 2 +- example/compare_c_py/run_grt.sh | 16 ++++++++-------- example/compare_c_py/run_pygrt.py | 16 ++++++++-------- example/convolve_signals/run_grt.sh | 2 +- example/convolve_signals/run_pygrt.py | 2 +- pygrt/C_extension/src/static/stgrt_syn.c | 2 +- 11 files changed, 28 insertions(+), 28 deletions(-) diff --git a/docs/source/Tutorial/dynamic/run/run.py b/docs/source/Tutorial/dynamic/run/run.py index 6fc6d865..feb8e57b 100644 --- a/docs/source/Tutorial/dynamic/run/run.py +++ b/docs/source/Tutorial/dynamic/run/run.py @@ -135,7 +135,7 @@ def plot_int_dif(stsyn:Stream, stsyn_int:Stream, stsyn_dif:Stream, comp:str, out # .SYN..EXZ | 1970-01-01T00:00:00.000000Z - 1970-01-01T00:00:09.980000Z | 50.0 Hz, 500 samples # .SYN..EXR | 1970-01-01T00:00:00.000000Z - 1970-01-01T00:00:09.980000Z | 50.0 Hz, 500 samples # .SYN..EXT | 1970-01-01T00:00:00.000000Z - 1970-01-01T00:00:09.980000Z | 50.0 Hz, 500 samples -plot_syn(stsyn, "syn_exp.png") +plot_syn(stsyn, "syn_ex.png") # END SYN EX # ----------------------------------------------------------------------------------- diff --git a/docs/source/Tutorial/dynamic/run/run.sh b/docs/source/Tutorial/dynamic/run/run.sh index 9d2a34f2..bc64695b 100755 --- a/docs/source/Tutorial/dynamic/run/run.sh +++ b/docs/source/Tutorial/dynamic/run/run.sh @@ -29,8 +29,8 @@ echo "..." >> HFZ_head # ----------------------------------------------------------------------------------- # BEGIN SYN EXP -# 合成结果在 syn_exp/ 目录下,以SAC格式保存。 -grt.syn -GGRN/milrow_2_0_10 -S1e24 -A30 -Osyn_exp +# 合成结果在 syn_ex/ 目录下,以SAC格式保存。 +grt.syn -GGRN/milrow_2_0_10 -S1e24 -A30 -Osyn_ex # END SYN EXP # ----------------------------------------------------------------------------------- diff --git a/docs/source/Tutorial/dynamic/syn.rst b/docs/source/Tutorial/dynamic/syn.rst index e13b54cd..662b5122 100644 --- a/docs/source/Tutorial/dynamic/syn.rst +++ b/docs/source/Tutorial/dynamic/syn.rst @@ -75,7 +75,7 @@ Python中合成动态位移的主函数为 :func:`gen_syn_from_gf_*() > grn_head # --------------------------------------------------------------------------------- # BEGIN SYN EXP # 从标准输入中读取格林函数 -stgrt.syn -S1e24 -N < grn > syn_exp +stgrt.syn -S1e24 -N < grn > syn_ex # END SYN EXP # --------------------------------------------------------------------------------- -# gmt begin syn_exp png E300 -# gmtplot_static syn_exp -Si0.03c +# gmt begin syn_ex png E300 +# gmtplot_static syn_ex -Si0.03c # gmt colorbar -Bx+l"Z (cm)" # gmt end diff --git a/docs/source/Tutorial/static/static_syn.rst b/docs/source/Tutorial/static/static_syn.rst index 1d18286a..d0bd8c08 100644 --- a/docs/source/Tutorial/static/static_syn.rst +++ b/docs/source/Tutorial/static/static_syn.rst @@ -54,7 +54,7 @@ Python中合成静态位移的主函数为 :func:`gen_syn_from_gf_*() grn for N in "" "-N" ; do -stgrt.syn -S$S -e $N < grn > stsyn_exp$N -stgrt.strain < stsyn_exp$N > strain_exp$N -stgrt.rotation < stsyn_exp$N > rotation_exp$N -stgrt.stress < stsyn_exp$N > stress_exp$N +stgrt.syn -S$S -e $N < grn > stsyn_ex$N +stgrt.strain < stsyn_ex$N > strain_ex$N +stgrt.rotation < stsyn_ex$N > rotation_ex$N +stgrt.stress < stsyn_ex$N > stress_ex$N stgrt.syn -S$S -F$fn/$fe/$fz -e $N < grn > stsyn_sf$N stgrt.strain < stsyn_sf$N > strain_sf$N diff --git a/example/compare_c_py/run_pygrt.py b/example/compare_c_py/run_pygrt.py index 85d7e8e8..7603bafc 100644 --- a/example/compare_c_py/run_pygrt.py +++ b/example/compare_c_py/run_pygrt.py @@ -108,13 +108,13 @@ def _get_c_resDct(c_prefix:str): st = pygrt.utils.gen_syn_from_gf_EX(st_grn, S, az, ZNE=ZNE, calc_upar=True) sigs = pygrt.sigs.gen_triangle_wave(0.4, dt) pygrt.utils.stream_convolve(st, sigs) - AVGRERR.append(compare3(st, "syn_exp/cout", ZNE=ZNE)) + AVGRERR.append(compare3(st, "syn_ex/cout", ZNE=ZNE)) ststrain = pygrt.utils.compute_strain(st) strotation = pygrt.utils.compute_rotation(st) ststress = pygrt.utils.compute_stress(st) - AVGRERR.append(compare3(ststrain, "syn_exp/cout.strain.", ZNE=ZNE, dim2=True)) - AVGRERR.append(compare3(strotation, "syn_exp/cout.rotation.", ZNE=ZNE, dim2=True)) - AVGRERR.append(compare3(ststress, "syn_exp/cout.stress.", ZNE=ZNE, dim2=True)) + AVGRERR.append(compare3(ststrain, "syn_ex/cout.strain.", ZNE=ZNE, dim2=True)) + AVGRERR.append(compare3(strotation, "syn_ex/cout.rotation.", ZNE=ZNE, dim2=True)) + AVGRERR.append(compare3(ststress, "syn_ex/cout.stress.", ZNE=ZNE, dim2=True)) st = pygrt.utils.gen_syn_from_gf_SF(st_grn, S, fn, fe, fz, az, ZNE=ZNE, calc_upar=True) @@ -159,13 +159,13 @@ def _get_c_resDct(c_prefix:str): for ZNE in [False, True]: suffix = "-N" if ZNE else "" static_syn = pygrt.utils.gen_syn_from_gf_EX(static_grn, S, ZNE=ZNE, calc_upar=True) - AVGRERR.append(static_compare3(static_syn, f"static/stsyn_exp{suffix}")) + AVGRERR.append(static_compare3(static_syn, f"static/stsyn_ex{suffix}")) ststrain = pygrt.utils.compute_strain(static_syn) strotation = pygrt.utils.compute_rotation(static_syn) ststress = pygrt.utils.compute_stress(static_syn) - AVGRERR.append(static_compare3(ststrain, f"static/strain_exp{suffix}")) - AVGRERR.append(static_compare3(strotation, f"static/rotation_exp{suffix}")) - AVGRERR.append(static_compare3(ststress, f"static/stress_exp{suffix}")) + AVGRERR.append(static_compare3(ststrain, f"static/strain_ex{suffix}")) + AVGRERR.append(static_compare3(strotation, f"static/rotation_ex{suffix}")) + AVGRERR.append(static_compare3(ststress, f"static/stress_ex{suffix}")) print(static_syn, ststrain, strotation, ststress) static_syn = pygrt.utils.gen_syn_from_gf_SF(static_grn, S, fn, fe, fz, ZNE=ZNE, calc_upar=True) diff --git a/example/convolve_signals/run_grt.sh b/example/convolve_signals/run_grt.sh index 8f463171..b08715f4 100755 --- a/example/convolve_signals/run_grt.sh +++ b/example/convolve_signals/run_grt.sh @@ -18,7 +18,7 @@ G=$out/${modname}_${depsrc}_${deprcv}_${dist} P=cout S=1e24 az=39.2 -grt.syn -G$G -Osyn_exp -P$P -A$az -S$S -Dt/0.2/0.2/0.4 +grt.syn -G$G -Osyn_ex -P$P -A$az -S$S -Dt/0.2/0.2/0.4 fn=2 fe=-1 diff --git a/example/convolve_signals/run_pygrt.py b/example/convolve_signals/run_pygrt.py index 91ba55b7..0b0d947a 100644 --- a/example/convolve_signals/run_pygrt.py +++ b/example/convolve_signals/run_pygrt.py @@ -23,7 +23,7 @@ st = pygrt.utils.gen_syn_from_gf_EX(st_grn, S, az) sigs = pygrt.sigs.gen_triangle_wave(0.4, dt) pygrt.utils.stream_convolve(st, sigs) -pygrt.utils.stream_write_sac(st, "syn_exp/pout") +pygrt.utils.stream_write_sac(st, "syn_ex/pout") st = pygrt.utils.gen_syn_from_gf_SF(st_grn, S, 2, -1, 4, az) sigs = pygrt.sigs.gen_trap_wave(0.1, 0.3, 0.6, dt) diff --git a/pygrt/C_extension/src/static/stgrt_syn.c b/pygrt/C_extension/src/static/stgrt_syn.c index d16d6669..b2ba778b 100644 --- a/pygrt/C_extension/src/static/stgrt_syn.c +++ b/pygrt/C_extension/src/static/stgrt_syn.c @@ -119,7 +119,7 @@ printf("\n" " stgrt -Mmilrow -D2/0 -X-5/5/10 -Y-5/5/10 > grn\n" "\n" " Then you can get static displacement of Explosion\n" -" stgrt.syn -Su1e16 < grn > syn_exp\n" +" stgrt.syn -Su1e16 < grn > syn_ex\n" "\n" " or Shear\n" " stgrt.syn -Su1e16 -M100/20/80 < grn > syn_dc\n" From 4e263150d3e552aa69567029f507bda1284701b4 Mon Sep 17 00:00:00 2001 From: Dengda98 Date: Sun, 27 Apr 2025 14:14:36 +0800 Subject: [PATCH 09/25] DOC: fix typos --- pygrt/C_extension/src/common/fim.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pygrt/C_extension/src/common/fim.c b/pygrt/C_extension/src/common/fim.c index 4d0bb1e6..9351ac65 100755 --- a/pygrt/C_extension/src/common/fim.c +++ b/pygrt/C_extension/src/common/fim.c @@ -1,5 +1,5 @@ /** - * @file filon.c + * @file fim.c * @author Zhu Dengda (zhudengda@mail.iggcas.ac.cn) * @date 2024-07-24 * From 3ab2fd8e9f273a69a858b3ea02d8765e547464c4 Mon Sep 17 00:00:00 2001 From: Dengda98 Date: Wed, 30 Apr 2025 10:24:27 +0800 Subject: [PATCH 10/25] REFAC: include `` instead `` --- pygrt/C_extension/include/common/const.h | 6 ++++-- pygrt/C_extension/src/common/coord.c | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/pygrt/C_extension/include/common/const.h b/pygrt/C_extension/include/common/const.h index 4069a13d..4f71710d 100755 --- a/pygrt/C_extension/include/common/const.h +++ b/pygrt/C_extension/include/common/const.h @@ -9,8 +9,8 @@ #pragma once #include -#include -// #include +#include +// #include // CMPLX macro not exist on MacOS #ifndef CMPLX @@ -144,6 +144,8 @@ typedef int MYINT; ///< 整数 #define PTAM_WINDOW_SIZE 3 ///< 3, 使用连续点数判断是否为波峰或波谷 #define PTAM_MAX_WAITS 9 ///< 9, 判断波峰或波谷的最大等待次数,不能太小 +#define INVERSE_SUCCESS 0 ///< 求逆或除法没有遇到除0错误 +#define INVERSE_FAILURE -1 ///< 求逆或除法遇到除0错误 /** 分别对应爆炸源(0阶),垂直力源(0阶),水平力源(1阶),剪切源(0,1,2阶) */ extern const MYINT SRC_M_ORDERS[SRC_M_NUM]; diff --git a/pygrt/C_extension/src/common/coord.c b/pygrt/C_extension/src/common/coord.c index 37e4e700..66392e33 100644 --- a/pygrt/C_extension/src/common/coord.c +++ b/pygrt/C_extension/src/common/coord.c @@ -8,7 +8,7 @@ */ #include -#include +#include From 5338bb593cf1820b94d68a1658046523776889ed Mon Sep 17 00:00:00 2001 From: Dengda98 Date: Wed, 30 Apr 2025 10:32:53 +0800 Subject: [PATCH 11/25] FEAT: add `stats` argument and `INVERSE_FAILURE/SUCCESS` macro to avoid divide zero error; revert `omega` argument --- pygrt/C_extension/include/common/dwm.h | 3 +- pygrt/C_extension/include/common/fim.h | 3 +- pygrt/C_extension/include/common/kernel.h | 4 +- pygrt/C_extension/include/common/matrix.h | 12 ++-- pygrt/C_extension/include/common/ptam.h | 7 ++- pygrt/C_extension/include/common/recursion.h | 17 ++++-- pygrt/C_extension/include/dynamic/layer.h | 19 ++++--- pygrt/C_extension/include/dynamic/propagate.h | 5 +- .../include/static/static_propagate.h | 4 +- pygrt/C_extension/src/common/dwm.c | 6 +- pygrt/C_extension/src/common/fim.c | 10 ++-- pygrt/C_extension/src/common/ptam.c | 7 ++- pygrt/C_extension/src/common/recursion.c | 22 ++++---- pygrt/C_extension/src/dynamic/layer.c | 47 ++++++++++++---- pygrt/C_extension/src/dynamic/propagate.c | 56 ++++++++++++++----- .../C_extension/src/static/static_propagate.c | 24 ++++---- pygrt/C_extension/src/static/stgrt.c | 10 ++-- 17 files changed, 164 insertions(+), 92 deletions(-) diff --git a/pygrt/C_extension/include/common/dwm.h b/pygrt/C_extension/include/common/dwm.h index cbcaf92f..d43c117c 100644 --- a/pygrt/C_extension/include/common/dwm.h +++ b/pygrt/C_extension/include/common/dwm.h @@ -39,6 +39,7 @@ * * @param[out] fstats 文件指针,保存不同k值的格林函数积分核函数 * @param[in] kerfunc 计算核函数的函数指针 + * @param[out] stats 状态代码,是否有除零错误,非0为异常值 * * @return k 积分截至时的波数 */ @@ -49,4 +50,4 @@ MYREAL discrete_integ( bool calc_upar, MYCOMPLEX sum_uiz_J[nr][SRC_M_NUM][INTEG_NUM], MYCOMPLEX sum_uir_J[nr][SRC_M_NUM][INTEG_NUM], - FILE *fstats, KernelFunc kerfunc); + FILE *fstats, KernelFunc kerfunc, MYINT *stats); diff --git a/pygrt/C_extension/include/common/fim.h b/pygrt/C_extension/include/common/fim.h index a60a0a93..83b5a523 100755 --- a/pygrt/C_extension/include/common/fim.h +++ b/pygrt/C_extension/include/common/fim.h @@ -46,6 +46,7 @@ * * @param[out] fstats 文件指针,保存不同k值的格林函数积分核函数 * @param[in] kerfunc 计算核函数的函数指针 + * @param[out] stats 状态代码,是否有除零错误,非0为异常值 * * @return k 积分截至时的波数 */ @@ -56,6 +57,6 @@ MYREAL linear_filon_integ( bool calc_upar, MYCOMPLEX sum_uiz_J[nr][SRC_M_NUM][INTEG_NUM], MYCOMPLEX sum_uir_J[nr][SRC_M_NUM][INTEG_NUM], - FILE *fstats, KernelFunc kerfunc); + FILE *fstats, KernelFunc kerfunc, MYINT *stats); diff --git a/pygrt/C_extension/include/common/kernel.h b/pygrt/C_extension/include/common/kernel.h index 760cdbdf..0ebac2fe 100644 --- a/pygrt/C_extension/include/common/kernel.h +++ b/pygrt/C_extension/include/common/kernel.h @@ -17,5 +17,5 @@ * 计算核函数的函数指针,动态与静态的接口一致 */ typedef void (*KernelFunc) ( - const MODEL1D *mod1d, MYREAL k, MYCOMPLEX QWV[SRC_M_NUM][QWV_NUM], - bool calc_uiz, MYCOMPLEX QWV_uiz[SRC_M_NUM][QWV_NUM]); \ No newline at end of file + const MODEL1D *mod1d, MYCOMPLEX omega, MYREAL k, MYCOMPLEX QWV[SRC_M_NUM][QWV_NUM], + bool calc_uiz, MYCOMPLEX QWV_uiz[SRC_M_NUM][QWV_NUM], MYINT *stats); \ No newline at end of file diff --git a/pygrt/C_extension/include/common/matrix.h b/pygrt/C_extension/include/common/matrix.h index 2f0c3884..1742d9e3 100755 --- a/pygrt/C_extension/include/common/matrix.h +++ b/pygrt/C_extension/include/common/matrix.h @@ -15,8 +15,9 @@ * * @param[in] M 原矩阵 * @param[out] invM 逆矩阵 + * @param[out] stats 状态代码,是否有除零错误,非0为异常值 */ -inline GCC_ALWAYS_INLINE void cmat2x2_inv(const MYCOMPLEX M[2][2], MYCOMPLEX invM[2][2]) { +inline GCC_ALWAYS_INLINE void cmat2x2_inv(const MYCOMPLEX M[2][2], MYCOMPLEX invM[2][2], MYINT *stats) { MYCOMPLEX M00 = M[0][0]; MYCOMPLEX M11 = M[1][1]; MYCOMPLEX det = M00*M11 - M[0][1]*M[1][0]; @@ -24,7 +25,9 @@ inline GCC_ALWAYS_INLINE void cmat2x2_inv(const MYCOMPLEX M[2][2], MYCOMPLEX inv // fprintf(stderr, "%.5e+%.5ej %.5e+%.5ej \n", CREAL(M[0][0]), CIMAG(M[0][0]), CREAL(M[0][1]), CIMAG(M[0][1])); // fprintf(stderr, "%.5e+%.5ej %.5e+%.5ej \n", CREAL(M[1][0]), CIMAG(M[1][0]), CREAL(M[1][1]), CIMAG(M[1][1])); // fprintf(stderr, "matrix2x2 det=0.0, set matrix inv = 0.0.\n"); - det = RZERO; + // det = RZERO; + *stats = INVERSE_FAILURE; + return; } else { det = RONE/det; } @@ -33,6 +36,7 @@ inline GCC_ALWAYS_INLINE void cmat2x2_inv(const MYCOMPLEX M[2][2], MYCOMPLEX inv invM[0][1] = M[0][1] * (-det); invM[1][0] = M[1][0] * (-det); invM[1][1] = M00 * det; + *stats = INVERSE_SUCCESS; } /** @@ -198,8 +202,8 @@ inline GCC_ALWAYS_INLINE void cmatmxn_block(MYINT m1, MYINT n1, const MYCOMPLEX inline GCC_ALWAYS_INLINE void cmatmxn_print(MYINT m1, MYINT n1, const MYCOMPLEX M1[m1][n1]){ for(MYINT i=0; i RZERO)? filonK : kmax, keps, 0.0, nr, rs, sum_J, calc_upar, sum_uiz_J, sum_uir_J, - fstats, static_kernel); + fstats, static_kernel, &inv_stats); // 基于线性插值的Filon积分 if(filondk > RZERO){ k = linear_filon_integ( mod1d, k, dk, filondk, kmax, keps, 0.0, nr, rs, sum_J, calc_upar, sum_uiz_J, sum_uir_J, - fstats, static_kernel); + fstats, static_kernel, &inv_stats); } // k之后的部分使用峰谷平均法进行显式收敛,建议在浅源地震的时候使用 @@ -177,7 +179,7 @@ void integ_static_grn( PTA_method( mod1d, k, dk, 0.0, nr, rs, sum_J, calc_upar, sum_uiz_J, sum_uir_J, - ptam_fstatsnr, static_kernel); + ptam_fstatsnr, static_kernel, &inv_stats); } From d2f644a8fb1ef90c743b91318538ffd0219c3dd0 Mon Sep 17 00:00:00 2001 From: Dengda98 Date: Wed, 30 Apr 2025 11:25:54 +0800 Subject: [PATCH 12/25] FIX: change division form, use `a/b` instead `a*(1.0/b)`, sacrifice performance to gain precision --- pygrt/C_extension/include/common/matrix.h | 10 ++-- pygrt/C_extension/src/dynamic/layer.c | 63 ++++++++++------------- pygrt/C_extension/src/dynamic/propagate.c | 6 ++- pygrt/C_extension/src/dynamic/source.c | 36 +++++++------ 4 files changed, 55 insertions(+), 60 deletions(-) diff --git a/pygrt/C_extension/include/common/matrix.h b/pygrt/C_extension/include/common/matrix.h index 1742d9e3..a8484642 100755 --- a/pygrt/C_extension/include/common/matrix.h +++ b/pygrt/C_extension/include/common/matrix.h @@ -28,14 +28,12 @@ inline GCC_ALWAYS_INLINE void cmat2x2_inv(const MYCOMPLEX M[2][2], MYCOMPLEX inv // det = RZERO; *stats = INVERSE_FAILURE; return; - } else { - det = RONE/det; } - invM[0][0] = M11 * det; - invM[0][1] = M[0][1] * (-det); - invM[1][0] = M[1][0] * (-det); - invM[1][1] = M00 * det; + invM[0][0] = M11 / det; + invM[0][1] = - M[0][1] / det; + invM[1][0] = - M[1][0] / det; + invM[1][1] = M00 / det; *stats = INVERSE_SUCCESS; } diff --git a/pygrt/C_extension/src/dynamic/layer.c b/pygrt/C_extension/src/dynamic/layer.c index c776e766..f9c8b3fb 100755 --- a/pygrt/C_extension/src/dynamic/layer.c +++ b/pygrt/C_extension/src/dynamic/layer.c @@ -26,21 +26,20 @@ void calc_R_tilt( { // // 公式(5.3.10-14) - MYREAL k_inv = RONE/k; - MYCOMPLEX Delta_inv = RZERO; - MYREAL k2inv = k_inv*k_inv; - MYCOMPLEX kbkb_k2inv = kbkb0*k2inv; + MYCOMPLEX Delta = RZERO; + MYREAL kk = k*k; + MYCOMPLEX kbkb_k2inv = kbkb0/kk; MYCOMPLEX kbkb_k4inv = RQUART*kbkb_k2inv*kbkb_k2inv; // 对公式(5.3.10-14)进行重新整理,对浮点数友好一些 - Delta_inv = RONE / (-RONE + xa0*xb0 + kbkb_k2inv - kbkb_k4inv); - if(Delta_inv == CZERO){ + Delta = -RONE + xa0*xb0 + kbkb_k2inv - kbkb_k4inv; + if(Delta == CZERO){ *stats = INVERSE_FAILURE; return; } - R_tilt[0][0] = (RONE + xa0*xb0 - kbkb_k2inv + kbkb_k4inv) * Delta_inv; - R_tilt[0][1] = RTWO * xb0 * (RONE - RHALF*kbkb_k2inv) * Delta_inv; - R_tilt[1][0] = RTWO * xa0 * (RONE - RHALF*kbkb_k2inv) * Delta_inv; + R_tilt[0][0] = (RONE + xa0*xb0 - kbkb_k2inv + kbkb_k4inv) / Delta; + R_tilt[0][1] = RTWO * xb0 * (RONE - RHALF*kbkb_k2inv) / Delta; + R_tilt[1][0] = RTWO * xa0 * (RONE - RHALF*kbkb_k2inv) / Delta; R_tilt[1][1] = R_tilt[0][0]; } @@ -126,13 +125,12 @@ void calc_RT_2x2( // 定义一些中间变量来简化运算和书写 - MYREAL k_inv = RONE/k; - MYREAL k2_inv = k_inv*k_inv; + MYREAL kk = k*k; MYCOMPLEX dmu = mu1 - mu2; MYCOMPLEX dmu2 = dmu*dmu; - MYCOMPLEX kb1_k2 = kbkb1*k2_inv; - MYCOMPLEX kb2_k2 = kbkb2*k2_inv; + MYCOMPLEX kb1_k2 = kbkb1/kk; + MYCOMPLEX kb2_k2 = kbkb2/kk; MYCOMPLEX mu1kb1_k2 = mu1*kb1_k2; MYCOMPLEX mu2kb2_k2 = mu2*kb2_k2; @@ -145,47 +143,42 @@ void calc_RT_2x2( // 故会发生严重精度损失的情况。目前只在实部上观察到这个现象,虚部基本都在相近量级(或许是相对不明显) // // 以下对公式重新整理,提出k的高阶项,以避免上述问题 - MYCOMPLEX Delta_inv; - Delta_inv = dmu2*(RONE-xa1*xb1)*(RONE-xa2*xb2) + mu1kb1_k2*dmu*(rho21*(RONE-xa1*xb1) - (RONE-xa2*xb2)) - + RQUART*mu1kb1_k2*mu2kb2_k2*(rho12*(RONE-xa2*xb2) + rho21*(RONE-xa1*xb1) - RTWO - (xa1*xb2+xa2*xb1)); + MYCOMPLEX Delta; + Delta = dmu2*(RONE-xa1*xb1)*(RONE-xa2*xb2) + mu1kb1_k2*dmu*(rho21*(RONE-xa1*xb1) - (RONE-xa2*xb2)) + + RQUART*mu1kb1_k2*mu2kb2_k2*(rho12*(RONE-xa2*xb2) + rho21*(RONE-xa1*xb1) - RTWO - (xa1*xb2+xa2*xb1)); - if( Delta_inv == CZERO ){ + if( Delta == CZERO ){ // printf("# zero Delta_inv=%e+%eJ\n", CREAL(Delta_inv), CIMAG(Delta_inv)); *stats = INVERSE_FAILURE; return; - } else { - Delta_inv = RONE/(Delta_inv); - } - - MYCOMPLEX Delta_inv_exa = Delta_inv * exa; - MYCOMPLEX Delta_inv_exb = Delta_inv * exb; + } // REFELCTION - //------------------ RD ----------------------------------- - // rpp+ if(computeRayl){ + //------------------ RD ----------------------------------- + // rpp+ RD[0][0] = ( - dmu2*(RONE+xa1*xb1)*(RONE-xa2*xb2) - mu1kb1_k2*dmu*(rho21*(RONE+xa1*xb1) - (RONE-xa2*xb2)) - - RQUART*mu1kb1_k2*mu2kb2_k2*(rho12*(RONE-xa2*xb2) + rho21*(RONE+xa1*xb1) - RTWO + (xa1*xb2-xa2*xb1))) * Delta_inv * ex2a; + - RQUART*mu1kb1_k2*mu2kb2_k2*(rho12*(RONE-xa2*xb2) + rho21*(RONE+xa1*xb1) - RTWO + (xa1*xb2-xa2*xb1))) / Delta * ex2a; // rsp+ RD[0][1] = ( - dmu2*(RONE-xa2*xb2) + RHALF*mu1kb1_k2*dmu*((RONE-xa2*xb2) - RTWO*rho21) - + RQUART*mu1kb1_k2*mu2kb2_k2*(RONE-rho21)) * Delta_inv * (-RTWO*xb1) * exab; + + RQUART*mu1kb1_k2*mu2kb2_k2*(RONE-rho21)) / Delta * (-RTWO*xb1) * exab; // rps+ RD[1][0] = RD[0][1]*(xa1/xb1); // rss+ RD[1][1] = ( - dmu2*(RONE+xa1*xb1)*(RONE-xa2*xb2) - mu1kb1_k2*dmu*(rho21*(RONE+xa1*xb1) - (RONE-xa2*xb2)) - - RQUART*mu1kb1_k2*mu2kb2_k2*(rho12*(RONE-xa2*xb2) + rho21*(RONE+xa1*xb1) - RTWO - (xa1*xb2-xa2*xb1))) * Delta_inv * ex2b; + - RQUART*mu1kb1_k2*mu2kb2_k2*(rho12*(RONE-xa2*xb2) + rho21*(RONE+xa1*xb1) - RTWO - (xa1*xb2-xa2*xb1))) / Delta * ex2b; //------------------ RU ----------------------------------- // rpp- RU[0][0] = ( - dmu2*(RONE-xa1*xb1)*(RONE+xa2*xb2) - mu1kb1_k2*dmu*(rho21*(RONE-xa1*xb1) - (RONE+xa2*xb2)) - - RQUART*mu1kb1_k2*mu2kb2_k2*(rho12*(RONE+xa2*xb2) + rho21*(RONE-xa1*xb1) - RTWO - (xa1*xb2-xa2*xb1))) * Delta_inv; + - RQUART*mu1kb1_k2*mu2kb2_k2*(rho12*(RONE+xa2*xb2) + rho21*(RONE-xa1*xb1) - RTWO - (xa1*xb2-xa2*xb1))) / Delta; // rsp- RU[0][1] = ( - dmu2*(RONE-xa1*xb1) - RHALF*mu1kb1_k2*dmu*(rho21*(RONE-xa1*xb1) - RTWO) - + RQUART*mu1kb1_k2*mu2kb2_k2*(RONE-rho12)) * Delta_inv * (RTWO*xb2); + + RQUART*mu1kb1_k2*mu2kb2_k2*(RONE-rho12)) / Delta * (RTWO*xb2); // rps- RU[1][0] = RU[0][1]*(xa2/xb2); // rss- RU[1][1] = ( - dmu2*(RONE-xa1*xb1)*(RONE+xa2*xb2) - mu1kb1_k2*dmu*(rho21*(RONE-xa1*xb1) - (RONE+xa2*xb2)) - - RQUART*mu1kb1_k2*mu2kb2_k2*(rho12*(RONE+xa2*xb2) + rho21*(RONE-xa1*xb1) - RTWO + (xa1*xb2-xa2*xb1))) * Delta_inv; + - RQUART*mu1kb1_k2*mu2kb2_k2*(rho12*(RONE+xa2*xb2) + rho21*(RONE-xa1*xb1) - RTWO + (xa1*xb2-xa2*xb1))) / Delta; } if(computeLove){ *RUL = (mu2*xb2 - mu1*xb1) / (mu2*xb2 + mu1*xb1) ; @@ -196,13 +189,13 @@ void calc_RT_2x2( // REFRACTION if(computeRayl){ - tmp = mu1kb1_k2*xa1*(dmu*(xb2-xb1) - RHALF*mu1kb1_k2*(rho21*xb1+xb2))*Delta_inv_exa; + tmp = mu1kb1_k2*xa1*(dmu*(xb2-xb1) - RHALF*mu1kb1_k2*(rho21*xb1+xb2)) / Delta * exa; TD[0][0] = tmp; TU[0][0] = (rho21*xa2/xa1) * tmp; - tmp = mu1kb1_k2*xb1*(dmu*(RONE-xa1*xb2) - RHALF*mu1kb1_k2*(RONE-rho21))*Delta_inv_exb; + tmp = mu1kb1_k2*xb1*(dmu*(RONE-xa1*xb2) - RHALF*mu1kb1_k2*(RONE-rho21)) / Delta * exb; TD[0][1] = tmp; TU[1][0] = (rho21*xa2/xb1) * tmp; - tmp = mu1kb1_k2*xa1*(dmu*(RONE-xa2*xb1) - RHALF*mu1kb1_k2*(RONE-rho21))*Delta_inv_exa; + tmp = mu1kb1_k2*xa1*(dmu*(RONE-xa2*xb1) - RHALF*mu1kb1_k2*(RONE-rho21)) / Delta * exa; TD[1][0] = tmp; TU[0][1] = (rho21*xb2/xa1) * tmp; - tmp = mu1kb1_k2*xb1*(dmu*(xa2-xa1) - RHALF*mu1kb1_k2*(rho21*xa1+xa2))*Delta_inv_exb; + tmp = mu1kb1_k2*xb1*(dmu*(xa2-xa1) - RHALF*mu1kb1_k2*(rho21*xa1+xa2)) / Delta * exb; TD[1][1] = tmp; TU[1][1] = (rho21*xb2/xb1) * tmp; } if(computeLove){ diff --git a/pygrt/C_extension/src/dynamic/propagate.c b/pygrt/C_extension/src/dynamic/propagate.c index 46e63074..ed47925e 100755 --- a/pygrt/C_extension/src/dynamic/propagate.c +++ b/pygrt/C_extension/src/dynamic/propagate.c @@ -157,8 +157,10 @@ void kernel( mod1d_mu1 = lay->mu; mod1d_kaka1 = lay->kaka; mod1d_kbkb1 = lay->kbkb; - mod1d_xa1 = CSQRT(RONE - mod1d_kaka1/(k*k)); - mod1d_xb1 = CSQRT(RONE - mod1d_kbkb1/(k*k)); + // mod1d_xa1 = CSQRT(RONE - mod1d_kaka1/(k*k)); + // mod1d_xb1 = CSQRT(RONE - mod1d_kbkb1/(k*k)); + mod1d_xa1 = CSQRT(k*k - mod1d_kaka1)/k; + mod1d_xb1 = CSQRT(k*k - mod1d_kbkb1)/k; if(0==iy){ top_xa = mod1d_xa1; diff --git a/pygrt/C_extension/src/dynamic/source.c b/pygrt/C_extension/src/dynamic/source.c index b4ed555a..a7731b08 100755 --- a/pygrt/C_extension/src/dynamic/source.c +++ b/pygrt/C_extension/src/dynamic/source.c @@ -35,40 +35,42 @@ void source_coef( } - MYCOMPLEX src_a_inv = RONE / (k*src_xa); - MYCOMPLEX src_b_inv = RONE / (k*src_xb); + // MYCOMPLEX src_a_inv = RONE / (k*src_xa); + // MYCOMPLEX src_b_inv = RONE / (k*src_xb); + MYCOMPLEX a = k*src_xa; + MYCOMPLEX b = k*src_xb; MYREAL kk = k*k; - MYREAL k_inv = RONE / k; + // MYREAL k_inv = RONE / k; MYCOMPLEX tmp; // 爆炸源, 通过(4.9.8)的矩张量源公式,提取各向同性的量(M11+M22+M33),-a+k^2/a -> ka^2/a - coef[0][0][0] = tmp = src_kaka * src_a_inv; coef[0][0][1] = tmp; + coef[0][0][0] = tmp = src_kaka / a; coef[0][0][1] = tmp; // 垂直力源 (4.6.15) - coef[1][0][0] = tmp = -RONE; coef[1][0][1] = - tmp; - coef[1][1][0] = tmp = -k * src_b_inv; coef[1][1][1] = tmp; + coef[1][0][0] = tmp = -RONE; coef[1][0][1] = - tmp; + coef[1][1][0] = tmp = -k / b; coef[1][1][1] = tmp; // 水平力源 (4.6.21,26), 这里可以把x1,x2方向的力转到r,theta方向 // 推导可发现,r方向的力形成P,SV波, theta方向的力形成SH波 // 方向性因子包含水平力方向与震源台站连线方向的夹角 - coef[2][0][0] = tmp = -k * src_a_inv; coef[2][0][1] = tmp; - coef[2][1][0] = tmp = -RONE; coef[2][1][1] = - tmp; - coef[2][2][0] = tmp = src_kbkb * k_inv * src_b_inv; coef[2][2][1] = tmp; + coef[2][0][0] = tmp = -k / a; coef[2][0][1] = tmp; + coef[2][1][0] = tmp = -RONE; coef[2][1][1] = - tmp; + coef[2][2][0] = tmp = src_kbkb / k / b; coef[2][2][1] = tmp; // 剪切位错 (4.8.34) // m=0 - coef[3][0][0] = tmp = (RTWO*src_kaka - RTHREE*kk) * src_a_inv; coef[3][0][1] = tmp; - coef[3][1][0] = tmp = -RTHREE*k; coef[3][1][1] = - tmp; + coef[3][0][0] = tmp = (RTWO*src_kaka - RTHREE*kk) / a; coef[3][0][1] = tmp; + coef[3][1][0] = tmp = -RTHREE*k; coef[3][1][1] = - tmp; // m=1 - coef[4][0][0] = tmp = RTWO*k; coef[4][0][1] = - tmp; - coef[4][1][0] = tmp = (RTWO*kk - src_kbkb) * src_b_inv; coef[4][1][1] = tmp; - coef[4][2][0] = tmp = - src_kbkb * k_inv; coef[4][2][1] = - tmp; + coef[4][0][0] = tmp = RTWO*k; coef[4][0][1] = - tmp; + coef[4][1][0] = tmp = (RTWO*kk - src_kbkb) / b; coef[4][1][1] = tmp; + coef[4][2][0] = tmp = - src_kbkb / k; coef[4][2][1] = - tmp; // m=2 - coef[5][0][0] = tmp = - kk * src_a_inv; coef[5][0][1] = tmp; - coef[5][1][0] = tmp = - k; coef[5][1][1] = - tmp; - coef[5][2][0] = tmp = src_kbkb * src_b_inv; coef[5][2][1] = tmp; + coef[5][0][0] = tmp = - kk / a; coef[5][0][1] = tmp; + coef[5][1][0] = tmp = - k; coef[5][1][1] = - tmp; + coef[5][2][0] = tmp = src_kbkb / b; coef[5][2][1] = tmp; } From 4b6d8466abe1f9c70404a31fbf74050969643d9f Mon Sep 17 00:00:00 2001 From: Dengda98 Date: Thu, 1 May 2025 10:32:22 +0800 Subject: [PATCH 13/25] FIX: use `j` instead `J` in complex output format --- pygrt/C_extension/include/common/const.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pygrt/C_extension/include/common/const.h b/pygrt/C_extension/include/common/const.h index 4f71710d..2b1bccd6 100755 --- a/pygrt/C_extension/include/common/const.h +++ b/pygrt/C_extension/include/common/const.h @@ -127,7 +127,7 @@ typedef int MYINT; ///< 整数 #define GRT_STRING_FMT "%18s" ///< 字符串输出格式 #define GRT_REAL_FMT "%18.8e" ///< 浮点数输出格式 -#define GRT_CMPLX_FMT "%18.8e%-+14.8eJ" ///< 复数输出格式 +#define GRT_CMPLX_FMT "%18.8e%-+14.8ej" ///< 复数输出格式 #define GRT_STR_CMPLX_FMT "%34s" ///< 与复数格式同长度的字符串输出格式 From a5791eee8d5e3de67ffdc9bf43d231b5a0f45c55 Mon Sep 17 00:00:00 2001 From: Dengda98 Date: Sun, 4 May 2025 18:48:56 +0800 Subject: [PATCH 14/25] REFAC: use macro from `` --- pygrt/C_extension/include/common/const.h | 102 +++++--------------- pygrt/C_extension/src/common/attenuation.c | 6 +- pygrt/C_extension/src/common/bessel.c | 6 +- pygrt/C_extension/src/common/dwm.c | 6 +- pygrt/C_extension/src/common/fim.c | 12 +-- pygrt/C_extension/src/common/iostats.c | 4 +- pygrt/C_extension/src/common/model.c | 10 +- pygrt/C_extension/src/common/ptam.c | 10 +- pygrt/C_extension/src/common/recursion.c | 4 +- pygrt/C_extension/src/dynamic/grt_main.c | 6 +- pygrt/C_extension/src/dynamic/layer.c | 18 ++-- pygrt/C_extension/src/static/static_layer.c | 4 +- pygrt/C_extension/src/static/stgrt.c | 8 +- pygrt/C_extension/src/static/stgrt_main.c | 2 +- 14 files changed, 70 insertions(+), 128 deletions(-) diff --git a/pygrt/C_extension/include/common/const.h b/pygrt/C_extension/include/common/const.h index 2b1bccd6..3072508f 100755 --- a/pygrt/C_extension/include/common/const.h +++ b/pygrt/C_extension/include/common/const.h @@ -10,26 +10,22 @@ #include #include -// #include // CMPLX macro not exist on MacOS #ifndef CMPLX -#define CMPLX(real, imag) ((double)(real) + (double)(imag) * I) ///< 复数扩展宏,添加此指令以适配MacOS - + #define CMPLX(real, imag) ((double)(real) + (double)(imag) * I) ///< 复数扩展宏,添加此指令以适配MacOS #endif #if defined(_WIN32) || defined(__WIN32__) -#define _TEST_WHETHER_WIN32_ 1 + #define _TEST_WHETHER_WIN32_ 1 #else -#define _TEST_WHETHER_WIN32_ 0 ///< 测试是否是windows系统 - + #define _TEST_WHETHER_WIN32_ 0 ///< 测试是否是windows系统 #endif #if _TEST_WHETHER_WIN32_ -#include /* _mkdir */ -#define mkdir(x, y) _mkdir(x) ///< 为windows系统修改mkdir函数 - + #include /* _mkdir */ + #define mkdir(x, y) _mkdir(x) ///< 为windows系统修改mkdir函数 #endif @@ -42,81 +38,29 @@ typedef int MYINT; ///< 整数 #ifdef GRT_USE_FLOAT typedef float _Complex MYCOMPLEX; ///< 复数 typedef float MYREAL; ///< 浮点数 - // 数学函数 - #define EXP(x) (expf(x)) ///< \f$ \exp(x) \f$ - #define CEXP(x) (cexpf(x)) ///< 复数域 \f$ \exp(x) \f$ - #define CLOG(x) (clogf(x)) ///< 复数域 \f$ \ln(x) \f$ - #define CSQRT(x) (csqrtf(x)) ///< 复数域 \f$ x^{1/2} \f$ - #define SQRT(x) (sqrtf(x)) ///< \f$ \sqrt{x} \f$ - #define SIN(x) (sinf(x)) ///< \f$ \sin(x) \f$ - #define COS(x) (cosf(x)) ///< \f$ \cos(x) \f$ - #define FABS(x) (fabsf(x)) ///< \f$ |x| \f$ - #define CABS(x) (cabsf(x)) ///< 复数域 \f$ |x| \f$ - #define J0(x) (j0f(x)) ///< \f$ J_0(x) \f$ - #define J1(x) (j1f(x)) ///< \f$ J_1(x) \f$ - #define JN(n,x) (jnf((n),(x))) ///< \f$ J_n(x) \f$ - - #define CREAL(x) (crealf(x)) ///< 复数实部 \f$ \Re[x] \f$ - #define CIMAG(x) (cimagf(x)) ///< 复数虚部 \f$ \Im[x] \f$ - - // 常数 - #define RZERO 0.0f ///< 0.0 - #define RQUART 0.25f ///< 0.25 - #define RHALF 0.5f ///< 0.5 - #define RONE 1.0f ///< 1.0 - #define RTWO 2.0f ///< 2.0 - #define RTHREE 3.0f ///< 3.0 - #define RFOUR 4.0f ///< 4.0 - #define PI 3.1415926f ///< \f$ \pi \f$ - #define PI2 6.2831853f ///< \f$ 2\pi \f$ - #define HALFPI 1.5707963f ///< \f$ \frac{\pi}{2} \f$ - #define QUARTERPI 0.78539816f ///< \f$ \frac{\pi}{4} \f$ - #define THREEQUARTERPI 2.35619450f ///< \f$ \frac{3\pi}{4} \f$ - #define FIVEQUARTERPI 3.92699082f ///< \f$ \frac{5\pi}{4} \f$ - #define SEVENQUARTERPI 5.49778714f ///< \f$ \frac{7\pi}{4} \f$ - #define INV_SQRT_TWO 0.70710678f ///< \f$ \frac{1}{\sqrt{2}} \f$ - #define DEG1 0.017453293f ///< \f$ \frac{\pi}{180} \f$ - #else typedef double _Complex MYCOMPLEX; typedef double MYREAL; - // 数学函数 - #define EXP(x) (exp(x)) ///< \f$ \exp(x) \f$ - #define CEXP(x) (cexp(x)) ///< 复数域 \f$ \exp(x) \f$ - #define CLOG(x) (clog(x)) ///< 复数域 \f$ \ln(x) \f$ - #define CSQRT(x) (csqrt(x)) ///< 复数域 \f$ x^{1/2} \f$ - #define SQRT(x) (sqrt(x)) ///< \f$ \sqrt{x} \f$ - #define SIN(x) (sin(x)) ///< \f$ \sin(x) \f$ - #define COS(x) (cos(x)) ///< \f$ \cos(x) \f$ - #define FABS(x) (fabs(x)) ///< \f$ |x| \f$ - #define CABS(x) (cabs(x)) ///< 复数域 \f$ |x| \f$ - #define J0(x) (j0(x)) ///< \f$ J_0(x) \f$ - #define J1(x) (j1(x)) ///< \f$ J_1(x) \f$ - #define JN(n,x) (jn((n),(x))) ///< \f$ J_n(x) \f$ - - #define CREAL(x) (creal(x)) ///< 复数实部 \f$ \Re[x] \f$ - #define CIMAG(x) (cimag(x)) ///< 复数虚部 \f$ \Im[x] \f$ - - // 常数 - #define RZERO 0.0 ///< 0.0 - #define RQUART 0.25 ///< 0.25 - #define RHALF 0.5 ///< 0.5 - #define RONE 1.0 ///< 1.0 - #define RTWO 2.0 ///< 2.0 - #define RTHREE 3.0 ///< 3.0 - #define RFOUR 4.0 ///< 4.0 - #define PI 3.141592653589793 ///< \f$ \pi \f$ - #define PI2 6.283185307179586 ///< \f$ 2\pi \f$ - #define HALFPI 1.5707963267948966 ///< \f$ \frac{\pi}{2} \f$ - #define QUARTERPI 0.7853981633974483 ///< \f$ \frac{\pi}{4} \f$ - #define THREEQUARTERPI 2.356194490192345 ///< \f$ \frac{3\pi}{4} \f$ - #define FIVEQUARTERPI 3.9269908169872414 ///< \f$ \frac{5\pi}{4} \f$ - #define SEVENQUARTERPI 5.497787143782138 ///< \f$ \frac{7\pi}{4} \f$ - #define INV_SQRT_TWO 0.7071067811865475 ///< \f$ \frac{1}{\sqrt{2}} \f$ - #define DEG1 0.017453292519943295 ///< \f$ \frac{\pi}{180} \f$ - #endif +// 常数 +#define RZERO 0.0 ///< 0.0 +#define RQUART 0.25 ///< 0.25 +#define RHALF 0.5 ///< 0.5 +#define RONE 1.0 ///< 1.0 +#define RTWO 2.0 ///< 2.0 +#define RTHREE 3.0 ///< 3.0 +#define RFOUR 4.0 ///< 4.0 +#define PI 3.141592653589793 ///< \f$ \pi \f$ +#define PI2 6.283185307179586 ///< \f$ 2\pi \f$ +#define HALFPI 1.5707963267948966 ///< \f$ \frac{\pi}{2} \f$ +#define QUARTERPI 0.7853981633974483 ///< \f$ \frac{\pi}{4} \f$ +#define THREEQUARTERPI 2.356194490192345 ///< \f$ \frac{3\pi}{4} \f$ +#define FIVEQUARTERPI 3.9269908169872414 ///< \f$ \frac{5\pi}{4} \f$ +#define SEVENQUARTERPI 5.497787143782138 ///< \f$ \frac{7\pi}{4} \f$ +#define INV_SQRT_TWO 0.7071067811865475 ///< \f$ \frac{1}{\sqrt{2}} \f$ +#define DEG1 0.017453292519943295 ///< \f$ \frac{\pi}{180} \f$ + #define CZERO CMPLX(RZERO, RZERO) ///< 0.0 + j0.0 #define CONE CMPLX(RONE, RZERO) ///< 1.0 + j0.0 #define INIT_C_ZERO_2x2_MATRIX {{CZERO, CZERO}, {CZERO, CZERO}} ///< 初始化复数0矩阵 diff --git a/pygrt/C_extension/src/common/attenuation.c b/pygrt/C_extension/src/common/attenuation.c index 20ff9edc..83507ac0 100755 --- a/pygrt/C_extension/src/common/attenuation.c +++ b/pygrt/C_extension/src/common/attenuation.c @@ -13,7 +13,7 @@ MYCOMPLEX attenuation_law(MYREAL Qinv, MYCOMPLEX omega){ - return RONE + Qinv/PI * CLOG(omega/PI2) + RHALF*Qinv*I; + return RONE + Qinv/PI * log(omega/PI2) + RHALF*Qinv*I; // return RONE; } @@ -21,6 +21,6 @@ void py_attenuation_law(MYREAL Qinv, MYREAL omg[2], MYREAL atte[2]){ // 用于在python中调用attenuation_law MYCOMPLEX omega = omg[0] + I*omg[1]; MYCOMPLEX atte0 = attenuation_law(Qinv, omega); - atte[0] = CREAL(atte0); - atte[1] = CIMAG(atte0); + atte[0] = creal(atte0); + atte[1] = cimag(atte0); } \ No newline at end of file diff --git a/pygrt/C_extension/src/common/bessel.c b/pygrt/C_extension/src/common/bessel.c index 37195ab9..30284084 100755 --- a/pygrt/C_extension/src/common/bessel.c +++ b/pygrt/C_extension/src/common/bessel.c @@ -11,9 +11,9 @@ #include "common/const.h" void bessel012(MYREAL x, MYREAL *bj0, MYREAL *bj1, MYREAL *bj2){ - *bj0 = J0(x); - *bj1 = J1(x); - *bj2 = JN(2, x); + *bj0 = j0(x); + *bj1 = j1(x); + *bj2 = jn(2, x); } void besselp012(MYREAL x, MYREAL *bj0, MYREAL *bj1, MYREAL *bj2){ diff --git a/pygrt/C_extension/src/common/dwm.c b/pygrt/C_extension/src/common/dwm.c index af5f84f2..be9c236c 100644 --- a/pygrt/C_extension/src/common/dwm.c +++ b/pygrt/C_extension/src/common/dwm.c @@ -56,7 +56,7 @@ MYREAL discrete_integ( if(k > kmax && ik > 2) break; k += dk; - // printf("w=%15.5e, ik=%d\n", CREAL(omega), ik); + // printf("w=%15.5e, ik=%d\n", creal(omega), ik); // 计算核函数 F(k, w) kerfunc(mod1d, omega, k, QWV, calc_upar, QWV_uiz, stats); if(*stats==INVERSE_FAILURE) goto BEFORE_RETURN; @@ -88,7 +88,7 @@ MYREAL discrete_integ( // 是否提前判断达到收敛 if(keps < RZERO || (modr==0 && v!=0 && v!=2)) continue; - iendk0 = iendk0 && (CABS(SUM[i][v])/ CABS(sum_J[ir][i][v]) <= keps); + iendk0 = iendk0 && (fabs(SUM[i][v])/ fabs(sum_J[ir][i][v]) <= keps); } } @@ -134,7 +134,7 @@ MYREAL discrete_integ( } // END k loop - // printf("w=%15.5e, ik=%d\n", CREAL(omega), ik); + // printf("w=%15.5e, ik=%d\n", creal(omega), ik); BEFORE_RETURN: free(iendkrs); diff --git a/pygrt/C_extension/src/common/fim.c b/pygrt/C_extension/src/common/fim.c index 27ef8540..d18f285a 100755 --- a/pygrt/C_extension/src/common/fim.c +++ b/pygrt/C_extension/src/common/fim.c @@ -89,7 +89,7 @@ MYREAL linear_filon_integ( // 是否提前判断达到收敛 if(keps < RZERO || (modr==0 && v!=0 && v!=2)) continue; - iendk0 = iendk0 && (CABS(SUM[i][v])/ CABS(sum_J[ir][i][v]) <= keps); + iendk0 = iendk0 && (fabs(SUM[i][v])/ fabs(sum_J[ir][i][v]) <= keps); } } @@ -140,7 +140,7 @@ MYREAL linear_filon_integ( // ------------------------------------------------------------------------------ // 为累计项乘系数 for(MYINT ir=0; irlays+i; printf(" Va=%6.2f, Vb=%6.2f, thk=%6.2f, Rho=%6.2f, 1/Qa=%6.2e, 1/Qb=%6.2e\n", lay->Va, lay->Vb, lay->thk, lay->Rho, lay->Qainv, lay->Qbinv); - printf(" mu=(%e %+e I)\n", CREAL(lay->mu), CIMAG(lay->mu)); - printf(" lambda=(%e %+e I)\n", CREAL(lay->lambda), CIMAG(lay->lambda)); - printf(" delta=(%e %+e I)\n", CREAL(lay->delta), CIMAG(lay->delta)); - printf(" ka^2=%e%+eJ\n", CREAL(lay->kaka), CIMAG(lay->kaka)); - printf(" kb^2=%e%+eJ\n", CREAL(lay->kbkb), CIMAG(lay->kbkb)); + printf(" mu=(%e %+e I)\n", creal(lay->mu), cimag(lay->mu)); + printf(" lambda=(%e %+e I)\n", creal(lay->lambda), cimag(lay->lambda)); + printf(" delta=(%e %+e I)\n", creal(lay->delta), cimag(lay->delta)); + printf(" ka^2=%e%+eJ\n", creal(lay->kaka), cimag(lay->kaka)); + printf(" kb^2=%e%+eJ\n", creal(lay->kbkb), cimag(lay->kbkb)); for(MYINT u=0; u<50; ++u){printf("---"); } printf("\n"); } } diff --git a/pygrt/C_extension/src/common/ptam.c b/pygrt/C_extension/src/common/ptam.c index bcc75d94..6b3f81c6 100755 --- a/pygrt/C_extension/src/common/ptam.c +++ b/pygrt/C_extension/src/common/ptam.c @@ -233,7 +233,7 @@ void PTA_method( }// end k loop } - // printf("w=%f, ik=%d\n", CREAL(omega), ik); + // printf("w=%f, ik=%d\n", creal(omega), ik); // 做缩减序列,赋值最终解 @@ -280,9 +280,9 @@ MYINT cplx_peak_or_trough(MYINT idx1, MYINT idx2, const MYCOMPLEX arr[PTAM_WINDO f2 = arr[1][idx1][idx2]; f3 = arr[2][idx1][idx2]; - rf1 = CREAL(f1); - rf2 = CREAL(f2); - rf3 = CREAL(f3); + rf1 = creal(f1); + rf2 = creal(f2); + rf3 = creal(f3); if ( (rf1 <= rf2) && (rf2 >= rf3) ) stat = 1; else if( (rf1 >= rf2) && (rf2 <= rf3) ) stat = -1; else stat = 0; @@ -311,7 +311,7 @@ MYINT cplx_peak_or_trough(MYINT idx1, MYINT idx2, const MYCOMPLEX arr[PTAM_WINDO // 这里暂且使用范围来框定,如果在范围外,就直接使用x2的值 if(k0 < x3 && k0 > x1){ // printf("a=%f%+fI, b=%f%+fI, c=%f%+fI, xarr=(%f,%f,%f), yarr=(%f%+fI, %f%+fI, %f%+fI)\n", - // CREAL(a),CIMAG(a),CREAL(b),CIMAG(b),CREAL(c),CIMAG(c),x1,x2,x3,CREAL(f1),CIMAG(f1),CREAL(f2),CIMAG(f2),CREAL(f3),CIMAG(f3)); + // creal(a),cimag(a),creal(b),cimag(b),creal(c),cimag(c),x1,x2,x3,creal(f1),cimag(f1),creal(f2),cimag(f2),creal(f3),cimag(f3)); *pk = k0; *value = a*k0*k0 + b*k0; } diff --git a/pygrt/C_extension/src/common/recursion.c b/pygrt/C_extension/src/common/recursion.c index 6375a494..bfdb4d42 100644 --- a/pygrt/C_extension/src/common/recursion.c +++ b/pygrt/C_extension/src/common/recursion.c @@ -213,8 +213,8 @@ void recursion_RT_2x2_imaginary( MYCOMPLEX TD[2][2], MYCOMPLEX *TDL, MYCOMPLEX TU[2][2], MYCOMPLEX *TUL) { MYCOMPLEX exa, exb, exab, ex2a, ex2b; - exa = CEXP(-k*thk*xa1); - exb = CEXP(-k*thk*xb1); + exa = exp(-k*thk*xa1); + exb = exp(-k*thk*xb1); exab = exa * exb; ex2a = exa * exa; diff --git a/pygrt/C_extension/src/dynamic/grt_main.c b/pygrt/C_extension/src/dynamic/grt_main.c index cf9cd4b4..0b20f75c 100644 --- a/pygrt/C_extension/src/dynamic/grt_main.c +++ b/pygrt/C_extension/src/dynamic/grt_main.c @@ -702,7 +702,7 @@ static void ifft_one_trace( { // 赋值复数,包括时移 MYCOMPLEX cfac, ccoef; - cfac = CEXP(I*dw*delay); + cfac = exp(I*dw*delay); ccoef = mult; for(int i=0; in); get_mod1d(pymod1d, mod1d); - const MYREAL hs = (FABS(pymod1d->depsrc - pymod1d->deprcv) < MIN_DEPTH_GAP_SRC_RCV)? - MIN_DEPTH_GAP_SRC_RCV : FABS(pymod1d->depsrc - pymod1d->deprcv); // hs=max(震源和台站深度差,1.0) + const MYREAL hs = (fabs(pymod1d->depsrc - pymod1d->deprcv) < MIN_DEPTH_GAP_SRC_RCV)? + MIN_DEPTH_GAP_SRC_RCV : fabs(pymod1d->depsrc - pymod1d->deprcv); // hs=max(震源和台站深度差,1.0) // 乘相应系数 k0 *= PI/hs; if(vmin_ref < RZERO) keps = -RONE; // 若使用峰谷平均法,则不使用keps进行收敛判断 MYREAL k=0.0; - const MYREAL dk=FABS(PI2/(Length*rmax)); // 波数积分间隔 + const MYREAL dk=fabs(PI2/(Length*rmax)); // 波数积分间隔 const MYREAL filondk = (filonLength > RZERO) ? PI2/(filonLength*rmax) : RZERO; // Filon积分间隔 const MYREAL filonK = filonCut/rmax; // 波数积分和Filon积分的分割点 diff --git a/pygrt/C_extension/src/static/stgrt_main.c b/pygrt/C_extension/src/static/stgrt_main.c index 7bc98687..133aa035 100644 --- a/pygrt/C_extension/src/static/stgrt_main.c +++ b/pygrt/C_extension/src/static/stgrt_main.c @@ -402,7 +402,7 @@ static void getopt_from_command(int argc, char **argv){ rs = (MYREAL*)calloc(nr, sizeof(MYREAL)); for(int iy=0; iy Date: Sun, 4 May 2025 18:49:55 +0800 Subject: [PATCH 15/25] REFAC: remove unused lines --- pygrt/C_extension/src/dynamic/source.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/pygrt/C_extension/src/dynamic/source.c b/pygrt/C_extension/src/dynamic/source.c index a7731b08..8e9b9986 100755 --- a/pygrt/C_extension/src/dynamic/source.c +++ b/pygrt/C_extension/src/dynamic/source.c @@ -35,12 +35,9 @@ void source_coef( } - // MYCOMPLEX src_a_inv = RONE / (k*src_xa); - // MYCOMPLEX src_b_inv = RONE / (k*src_xb); MYCOMPLEX a = k*src_xa; MYCOMPLEX b = k*src_xb; MYREAL kk = k*k; - // MYREAL k_inv = RONE / k; MYCOMPLEX tmp; From 741e29ad652de3ed2e7f5214ecff04a9b64ee11f Mon Sep 17 00:00:00 2001 From: Dengda98 Date: Mon, 5 May 2025 13:13:16 +0800 Subject: [PATCH 16/25] FIX: assign `DS` components to zero when source and receiver are on surface, to avoid roundoff --- pygrt/C_extension/src/dynamic/propagate.c | 36 ++++++++++++++++------- 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/pygrt/C_extension/src/dynamic/propagate.c b/pygrt/C_extension/src/dynamic/propagate.c index ed47925e..05d2a2d8 100755 --- a/pygrt/C_extension/src/dynamic/propagate.c +++ b/pygrt/C_extension/src/dynamic/propagate.c @@ -187,7 +187,7 @@ void kernel( k, RD, pRDL, RU, pRUL, TD, pTDL, TU, pTUL, stats); - if(*stats==INVERSE_FAILURE) return; + if(*stats==INVERSE_FAILURE) goto BEFORE_RETURN; } #if Print_GRTCOEF == 1 @@ -238,7 +238,7 @@ void kernel( TD, TDL, TU, TUL, RD_FA, pRDL_FA, RU_FA, pRUL_FA, TD_FA, pTDL_FA, TU_FA, pTUL_FA, stats); - if(*stats==INVERSE_FAILURE) return; + if(*stats==INVERSE_FAILURE) goto BEFORE_RETURN; } } else if(iy==imin){ // 虚拟层位,可对递推公式简化 @@ -277,7 +277,7 @@ void kernel( TD, TDL, TU, TUL, RD_RS, pRDL_RS, RU_RS, pRUL_RS, TD_RS, pTDL_RS, TU_RS, pTUL_RS, stats); // 写入原地址 - if(*stats==INVERSE_FAILURE) return; + if(*stats==INVERSE_FAILURE) goto BEFORE_RETURN; } } else if(iy==imax){ // 虚拟层位,可对递推公式简化 @@ -329,7 +329,7 @@ void kernel( RD_BL, pRDL_BL, NULL, NULL, NULL, NULL, NULL, NULL, stats); // 写入原地址 } - if(*stats==INVERSE_FAILURE) return; + if(*stats==INVERSE_FAILURE) goto BEFORE_RETURN; } } // END if @@ -350,7 +350,7 @@ void kernel( // 递推RU_FA calc_R_tilt(top_xa, top_xb, top_kbkb, k, R_tilt, stats); - if(*stats==INVERSE_FAILURE) return; + if(*stats==INVERSE_FAILURE) goto BEFORE_RETURN; recursion_RU( R_tilt, RONE, RD_FA, RDL_FA, @@ -358,7 +358,7 @@ void kernel( TD_FA, TDL_FA, TU_FA, TUL_FA, RU_FA, pRUL_FA, NULL, NULL, stats); - if(*stats==INVERSE_FAILURE) return; + if(*stats==INVERSE_FAILURE) goto BEFORE_RETURN; // 根据震源和台站相对位置,计算最终的系数 if(ircvup){ // A接收 B震源 @@ -374,13 +374,14 @@ void kernel( TD_RS, TDL_RS, TU_RS, TUL_RS, RU_FB, pRUL_FB, inv_2x2T, &invT, stats); - if(*stats==INVERSE_FAILURE) return; - + if(*stats==INVERSE_FAILURE) goto BEFORE_RETURN; + + // 公式(5.7.12-14) cmat2x2_mul(RD_BL, RU_FB, tmpR2); cmat2x2_one_sub(tmpR2); cmat2x2_inv(tmpR2, tmpR2, stats);// (I - xx)^-1 - if(*stats==INVERSE_FAILURE) return; + if(*stats==INVERSE_FAILURE) goto BEFORE_RETURN; cmat2x2_mul(inv_2x2T, tmpR2, tmp2x2); if(calc_uiz) cmat2x2_assign(tmp2x2, tmp2x2_uiz); // 为后续计算空间导数备份 @@ -416,13 +417,13 @@ void kernel( TU_RS, TUL_RS, RD_BL, RDL_BL, RD_AL, pRDL_AL, inv_2x2T, &invT, stats); - if(*stats==INVERSE_FAILURE) return; + if(*stats==INVERSE_FAILURE) goto BEFORE_RETURN; // 公式(5.7.26-27) cmat2x2_mul(RU_FA, RD_AL, tmpR2); cmat2x2_one_sub(tmpR2); cmat2x2_inv(tmpR2, tmpR2, stats);// (I - xx)^-1 - if(*stats==INVERSE_FAILURE) return; + if(*stats==INVERSE_FAILURE) goto BEFORE_RETURN; cmat2x2_mul(inv_2x2T, tmpR2, tmp2x2); if(calc_uiz) cmat2x2_assign(tmp2x2, tmp2x2_uiz); // 为后续计算空间导数备份 @@ -448,5 +449,18 @@ void kernel( } // END if + + BEFORE_RETURN: + + // 对一些特殊情况的修正 + // 当震源和场点均位于地表时,可理论验证DS分量恒为0,这里直接赋0以避免后续的精度干扰 + if(mod1d->lays[isrc].dep == RZERO && mod1d->lays[ircv].dep == RZERO) + { + for(MYINT c=0; c Date: Mon, 5 May 2025 14:20:49 +0800 Subject: [PATCH 17/25] REFAC: Refactoring PyModel1D initialization in Python, using temporary files to store modarr and reading it through C functions --- pygrt/c_interfaces.py | 9 +++ pygrt/pymod.py | 138 ++++++++++++++---------------------------- 2 files changed, 54 insertions(+), 93 deletions(-) diff --git a/pygrt/c_interfaces.py b/pygrt/c_interfaces.py index e95176de..e596e76b 100755 --- a/pygrt/c_interfaces.py +++ b/pygrt/c_interfaces.py @@ -87,6 +87,15 @@ def set_num_threads(n): ] +C_read_pymod_from_file = libgrt.read_pymod_from_file +"""读取模型文件并进行预处理""" +C_read_pymod_from_file.restype = POINTER(c_PyModel1D) +C_read_pymod_from_file.argtypes = [c_char_p, c_char_p, c_double, c_double] + +C_free_pymod = libgrt.free_pymod +"""释放C程序中申请的PYMODEL1D结构体内存""" +C_free_pymod.restype = None +C_free_pymod.argtypes = [POINTER(c_PyModel1D)] # ------------------------------------------------------------------- # C函数定义的时间函数 diff --git a/pygrt/pymod.py b/pygrt/pymod.py index 7c32a766..3e7b079b 100755 --- a/pygrt/pymod.py +++ b/pygrt/pymod.py @@ -16,6 +16,7 @@ from scipy.fft import irfft, ifft from obspy.core import AttribDict from typing import List, Dict, Union +import tempfile from time import time from copy import deepcopy @@ -41,84 +42,30 @@ def __init__(self, modarr0:np.ndarray, depsrc:float, deprcv:float): :param deprcv: 台站深度(km) ''' - self.modarr:np.ndarray - self.depsrc = depsrc - self.deprcv = deprcv + self.modarr:np.ndarray = modarr0.copy() + self.depsrc:float = depsrc + self.deprcv:float = deprcv self.c_pymod1d:c_PyModel1D - if depsrc < 0: - raise ValueError(f"depsrc ({depsrc}) < 0") - if deprcv < 0: - raise ValueError(f"deprcv ({deprcv}) < 0") - - - modarr = modarr0.copy() - - # 最后一层,本质只为保证震源和台站能插入模型中 - modarr[-1, 0] = np.max([modarr[-1, 0], 9e10, deprcv, depsrc]) + 1.0 - - # 将震源和台站的虚拟层位插入模型 - dep = 0.0 - ircv = 0 - for i in range(modarr.shape[0]): - dep += modarr[i,0] - if dep > deprcv: - ircv = i+1 - lay = np.copy(modarr[i,:]) - lay[0] = dep - deprcv - modarr[i,0] -= lay[0] - modarr = np.insert(modarr, ircv, lay, axis=0) - break - - dep = 0.0 - isrc = 0 - for i in range(modarr.shape[0]): - dep += modarr[i,0] - if dep > depsrc: - isrc = i+1 - lay = np.copy(modarr[i,:]) - lay[0] = dep - depsrc - modarr[i,0] -= lay[0] - modarr = np.insert(modarr, isrc, lay, axis=0) - break - - # 如果台站位于震源深度以下,需要调整层索引; 因为先插入的台站,再插入的震源 - if depsrc < deprcv: - ircv += 1 - - # 调整层厚,拒绝0厚度层 - # for i in range(modarr.shape[0]): - # if modarr[i, 0] == 0.0: - # modarr[i, 0] = 1e-5 - - - c_pymod1d = c_PyModel1D( - modarr.shape[0], - depsrc, - deprcv, - isrc, - ircv, - (ircv=3): + continue + + modr = SRC_M_ORDERS[im] + sgn = 1 + for c in range(CHANNEL_NUM): + if(modr==0 and ZRTchs[c]=='T'): + continue + + sgn = -1 if ZRTchs[c]=='Z'=='Z' else 1 + stream.append(pygrnLst[ir][im][c].freq2time(delayT, travtP, travtS, sgn )) + if(calc_upar): + stream.append(pygrnLst_uiz[ir][im][c].freq2time(delayT, travtP, travtS, sgn*(-1) )) + stream.append(pygrnLst_uir[ir][im][c].freq2time(delayT, travtP, travtS, sgn )) # 在sac头段变量部分 @@ -467,7 +420,6 @@ def compute_grn( dataLst.append(stream) - return dataLst From b0687f186ded49d4715d5ba72a945d27b3d14ce8 Mon Sep 17 00:00:00 2001 From: Dengda98 Date: Mon, 5 May 2025 14:22:38 +0800 Subject: [PATCH 18/25] FEAT: add `dep` in `LAYER` struct --- pygrt/C_extension/include/common/model.h | 1 + pygrt/C_extension/src/common/model.c | 9 +++++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/pygrt/C_extension/include/common/model.h b/pygrt/C_extension/include/common/model.h index ffd0c6dc..daa2b2c5 100755 --- a/pygrt/C_extension/include/common/model.h +++ b/pygrt/C_extension/include/common/model.h @@ -15,6 +15,7 @@ /** 单个水平层的结构体 */ typedef struct _LAYER { MYREAL thk; ///< 层厚,最后一层厚度不使用(当作正无穷), km + MYREAL dep; ///< 该层上界面的深度,km MYREAL Va; ///< P波速度 km/s MYREAL Vb; ///< S波速度 km/s MYREAL Rho; ///< 密度 g/cm^3 diff --git a/pygrt/C_extension/src/common/model.c b/pygrt/C_extension/src/common/model.c index ab94b05d..a4076f20 100755 --- a/pygrt/C_extension/src/common/model.c +++ b/pygrt/C_extension/src/common/model.c @@ -22,8 +22,8 @@ void print_mod1d(const MODEL1D *mod1d){ for(MYINT u=0; u<50; ++u){printf("---"); } printf("\n"); for(MYINT i=0; in; ++i){ lay = mod1d->lays+i; - printf(" Va=%6.2f, Vb=%6.2f, thk=%6.2f, Rho=%6.2f, 1/Qa=%6.2e, 1/Qb=%6.2e\n", - lay->Va, lay->Vb, lay->thk, lay->Rho, lay->Qainv, lay->Qbinv); + printf(" Dep=%6.2f, Va=%6.2f, Vb=%6.2f, thk=%6.2f, Rho=%6.2f, 1/Qa=%6.2e, 1/Qb=%6.2e\n", + lay->dep, lay->Va, lay->Vb, lay->thk, lay->Rho, lay->Qainv, lay->Qbinv); printf(" mu=(%e %+e I)\n", creal(lay->mu), cimag(lay->mu)); printf(" lambda=(%e %+e I)\n", creal(lay->lambda), cimag(lay->lambda)); printf(" delta=(%e %+e I)\n", creal(lay->delta), cimag(lay->delta)); @@ -138,9 +138,11 @@ void get_mod1d(const PYMODEL1D *pymod1d, MODEL1D *mod1d){ // MYREAL Rho0; // MYREAL Vb0; LAYER *lay; + MYREAL dep=0.0; for(MYINT i=0; ilays + i; lay->thk = pymod1d->Thk[i]; + lay->dep = dep; lay->Va = pymod1d->Va[i]; lay->Vb = pymod1d->Vb[i]; lay->Rho = pymod1d->Rho[i]; @@ -150,6 +152,8 @@ void get_mod1d(const PYMODEL1D *pymod1d, MODEL1D *mod1d){ lay->mu = (lay->Vb)*(lay->Vb)*(lay->Rho); lay->lambda = (lay->Va)*(lay->Va)*(lay->Rho) - RTWO*lay->mu; lay->delta = (lay->lambda + lay->mu) / (lay->lambda + RTHREE*lay->mu); + + dep += pymod1d->Thk[i]; } } @@ -171,6 +175,7 @@ void copy_mod1d(const MODEL1D *mod1d1, MODEL1D *mod1d2){ lay2 = mod1d2->lays + i; lay2->thk = lay1->thk; + lay2->dep = lay1->dep; lay2->Va = lay1->Va; lay2->Vb = lay1->Vb; lay2->Rho = lay1->Rho; From 2dbb884340bd60a7890b893ff75dd81c26459c48 Mon Sep 17 00:00:00 2001 From: Dengda98 Date: Mon, 5 May 2025 14:24:52 +0800 Subject: [PATCH 19/25] FIX: freqband index --- pygrt/C_extension/src/dynamic/grt_main.c | 5 +++-- pygrt/pymod.py | 6 ++++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/pygrt/C_extension/src/dynamic/grt_main.c b/pygrt/C_extension/src/dynamic/grt_main.c index 0b20f75c..831f4926 100644 --- a/pygrt/C_extension/src/dynamic/grt_main.c +++ b/pygrt/C_extension/src/dynamic/grt_main.c @@ -1027,13 +1027,14 @@ int main(int argc, char **argv) { nf1 = 0; nf2 = nf-1; if(freq1 > 0.0){ - nf1 = (int)(freq1/df) + 1; + nf1 = ceil(freq1/df); if(nf1 >= nf-1) nf1 = nf-1; } if(freq2 > 0.0){ - nf2 = (int)(freq2/df) + 1; + nf2 = floor(freq2/df); if(nf2 >= nf-1) nf2 = nf-1; } + if(nf2 < nf1) nf2 = nf1; // 波数积分中间文件输出目录 if(nstatsidxs > 0){ diff --git a/pygrt/pymod.py b/pygrt/pymod.py index 3e7b079b..0d90f827 100755 --- a/pygrt/pymod.py +++ b/pygrt/pymod.py @@ -231,8 +231,10 @@ def compute_grn( f1 = max(0, f1) f2 = min(f2, fnyq + df) - nf1 = max(0, int(np.floor(f1/df))) - nf2 = min(int(np.ceil(f2/df)), nf-1) + nf1 = min(int(np.ceil(f1/df)), nf-1) + nf2 = min(int(np.floor(f2/df)), nf-1) + if nf2 < nf1: + nf2 = nf1 # 所有频点 freqs = (np.arange(0, nf)*df).astype(NPCT_REAL_TYPE) From dbe1748c82fc71e8b08e1d5809dae8c9d6bfcda6 Mon Sep 17 00:00:00 2001 From: Dengda98 Date: Mon, 5 May 2025 17:05:24 +0800 Subject: [PATCH 20/25] FEAT: add `2/3` constant macro --- pygrt/C_extension/include/common/const.h | 1 + 1 file changed, 1 insertion(+) diff --git a/pygrt/C_extension/include/common/const.h b/pygrt/C_extension/include/common/const.h index 3072508f..60dbcb3d 100755 --- a/pygrt/C_extension/include/common/const.h +++ b/pygrt/C_extension/include/common/const.h @@ -51,6 +51,7 @@ typedef int MYINT; ///< 整数 #define RTWO 2.0 ///< 2.0 #define RTHREE 3.0 ///< 3.0 #define RFOUR 4.0 ///< 4.0 +#define RTWOTHIRD 0.6666666666666667 ///< 2/3 #define PI 3.141592653589793 ///< \f$ \pi \f$ #define PI2 6.283185307179586 ///< \f$ 2\pi \f$ #define HALFPI 1.5707963267948966 ///< \f$ \frac{\pi}{2} \f$ From df98d0666850ba3b35ab7b44fd3c187fed66e0ad Mon Sep 17 00:00:00 2001 From: Dengda98 Date: Mon, 5 May 2025 17:07:00 +0800 Subject: [PATCH 21/25] REFAC: use `fabs` in `` --- pygrt/C_extension/src/common/search.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pygrt/C_extension/src/common/search.c b/pygrt/C_extension/src/common/search.c index eda3b11e..72bb7f8d 100644 --- a/pygrt/C_extension/src/common/search.c +++ b/pygrt/C_extension/src/common/search.c @@ -42,7 +42,7 @@ MYINT findClosest_MYREAL(const MYREAL array[], MYINT size, MYREAL target) { MYINT ires=0; MYREAL mindist=-1.0, dist=0.0; for (MYINT i = 0; i < size; ++i) { - dist = FABS(target-array[i]); + dist = fabs(target-array[i]); if(mindist < 0.0 || dist < mindist){ ires = i; mindist = dist; From be51e4ffd010e5c561bba1dd29fb559a7c2054ee Mon Sep 17 00:00:00 2001 From: Dengda98 Date: Mon, 5 May 2025 17:15:17 +0800 Subject: [PATCH 22/25] FEAT: first commit for Self-Adaptive Filon's Integration Method --- pygrt/C_extension/include/common/const.h | 15 + pygrt/C_extension/include/common/integral.h | 23 +- pygrt/C_extension/include/common/matrix.h | 14 +- pygrt/C_extension/include/common/safim.h | 63 +++ pygrt/C_extension/include/dynamic/grt.h | 3 +- pygrt/C_extension/include/static/stgrt.h | 3 +- pygrt/C_extension/src/common/const.c | 3 + pygrt/C_extension/src/common/integral.c | 115 ++++- pygrt/C_extension/src/common/safim.c | 445 ++++++++++++++++++++ pygrt/C_extension/src/dynamic/grt.c | 75 +++- pygrt/C_extension/src/dynamic/grt_main.c | 46 +- pygrt/C_extension/src/dynamic/propagate.c | 110 ++++- pygrt/C_extension/src/static/stgrt.c | 26 +- pygrt/C_extension/src/static/stgrt_main.c | 40 +- pygrt/c_interfaces.py | 4 +- pygrt/pymod.py | 52 ++- pygrt/utils.py | 8 + 17 files changed, 931 insertions(+), 114 deletions(-) create mode 100755 pygrt/C_extension/include/common/safim.h create mode 100644 pygrt/C_extension/src/common/safim.c diff --git a/pygrt/C_extension/include/common/const.h b/pygrt/C_extension/include/common/const.h index 60dbcb3d..e08233e9 100755 --- a/pygrt/C_extension/include/common/const.h +++ b/pygrt/C_extension/include/common/const.h @@ -92,9 +92,24 @@ typedef int MYINT; ///< 整数 #define INVERSE_SUCCESS 0 ///< 求逆或除法没有遇到除0错误 #define INVERSE_FAILURE -1 ///< 求逆或除法遇到除0错误 +#define GTYPES_MAX 2 ///< 2, 所有震源根据是否使用格林函数导数分为两类 + +/** 不同震源类型在全局数组中的索引 */ +enum { + SRC_M_EX_INDEX = 0, + SRC_M_VF_INDEX = 1, + SRC_M_HF_INDEX = 2, + SRC_M_DD_INDEX = 3, + SRC_M_DS_INDEX = 4, + SRC_M_SS_INDEX = 5, +}; + /** 分别对应爆炸源(0阶),垂直力源(0阶),水平力源(1阶),剪切源(0,1,2阶) */ extern const MYINT SRC_M_ORDERS[SRC_M_NUM]; +/** 不同震源类型使用的格林函数类型,0为Gij,1为格林函数导数Gij,k */ +extern const MYINT SRC_M_GTYPES[SRC_M_NUM]; + /** 不同震源,不同阶数的名称简写,用于命名 */ extern const char *SRC_M_NAME_ABBR[SRC_M_NUM]; diff --git a/pygrt/C_extension/include/common/integral.h b/pygrt/C_extension/include/common/integral.h index 300dab61..a15f9719 100644 --- a/pygrt/C_extension/include/common/integral.h +++ b/pygrt/C_extension/include/common/integral.h @@ -19,7 +19,7 @@ * * @param[in] k 波数 * @param[in] r 震中距 - * @param[out] QWV 不同震源,不同阶数的核函数 \f$ q_m, w_m, v_m \f$ + * @param[in] QWV 不同震源,不同阶数的核函数 \f$ q_m, w_m, v_m \f$ * @param[in] calc_uir 是否计算ui_r(位移u对坐标r的偏导) * @param[out] SUM 该dk区间内的积分值 * @@ -53,7 +53,7 @@ void merge_Pk( * @param[in] k 波数 * @param[in] r 震中距 * @param[in] iscos 是否使用cos函数,否则使用sin函数 - * @param[out] QWV 不同震源,不同阶数的核函数 \f$ q_m, w_m, v_m \f$ + * @param[in] QWV 不同震源,不同阶数的核函数 \f$ q_m, w_m, v_m \f$ * @param[in] calc_uir 是否计算ui_r(位移u对坐标r的偏导) * @param[out] SUM 该dk区间内的积分值 * @@ -63,3 +63,22 @@ void int_Pk_filon( const MYCOMPLEX QWV[SRC_M_NUM][QWV_NUM], bool calc_uir, MYCOMPLEX SUM[SRC_M_NUM][INTEG_NUM]); + + +/** + * 对sqrt(k)*F(k,w)进行二次曲线拟合,再计算 (a*k^2 + b*k + c) * cos(kr - (2m+1)/4) 的积分,其中涉及两种数组形状: + * + QWV. 存储的是核函数,第一个维度不同震源,不同阶数,第二个维度3代表三类系数qm,wm,vm + * + SUM. 存储的是该三点区间内的积分值,第一个维度不同震源,不同阶数,维度4代表4种类型的F(k,w)Jm(kr)k的类型 + * + * @param[in] k3 三点等距波数 + * @param[in] r 震中距 + * @param[in] QWV3 k3对应的不同震源,不同阶数的核函数 \f$ q_m, w_m, v_m \f$ + * @param[in] calc_uir 是否计算ui_r(位移u对坐标r的偏导) + * @param[out] SUM 该三点区间内的积分值 + * + */ +void int_Pk_sa_filon( + const MYREAL k3[3], MYREAL r, + const MYCOMPLEX QWV3[3][SRC_M_NUM][QWV_NUM], + bool calc_uir, + MYCOMPLEX SUM[SRC_M_NUM][INTEG_NUM]); \ No newline at end of file diff --git a/pygrt/C_extension/include/common/matrix.h b/pygrt/C_extension/include/common/matrix.h index a8484642..963b9b8b 100755 --- a/pygrt/C_extension/include/common/matrix.h +++ b/pygrt/C_extension/include/common/matrix.h @@ -19,11 +19,13 @@ */ inline GCC_ALWAYS_INLINE void cmat2x2_inv(const MYCOMPLEX M[2][2], MYCOMPLEX invM[2][2], MYINT *stats) { MYCOMPLEX M00 = M[0][0]; + MYCOMPLEX M01 = M[0][1]; + MYCOMPLEX M10 = M[1][0]; MYCOMPLEX M11 = M[1][1]; - MYCOMPLEX det = M00*M11 - M[0][1]*M[1][0]; + MYCOMPLEX det = M00*M11 - M01*M10; if ( det == RZERO ){ - // fprintf(stderr, "%.5e+%.5ej %.5e+%.5ej \n", CREAL(M[0][0]), CIMAG(M[0][0]), CREAL(M[0][1]), CIMAG(M[0][1])); - // fprintf(stderr, "%.5e+%.5ej %.5e+%.5ej \n", CREAL(M[1][0]), CIMAG(M[1][0]), CREAL(M[1][1]), CIMAG(M[1][1])); + // fprintf(stderr, "%.5e+%.5ej %.5e+%.5ej \n", creal(M[0][0]), cimag(M[0][0]), creal(M[0][1]), cimag(M[0][1])); + // fprintf(stderr, "%.5e+%.5ej %.5e+%.5ej \n", creal(M[1][0]), cimag(M[1][0]), creal(M[1][1]), cimag(M[1][1])); // fprintf(stderr, "matrix2x2 det=0.0, set matrix inv = 0.0.\n"); // det = RZERO; *stats = INVERSE_FAILURE; @@ -31,8 +33,8 @@ inline GCC_ALWAYS_INLINE void cmat2x2_inv(const MYCOMPLEX M[2][2], MYCOMPLEX inv } invM[0][0] = M11 / det; - invM[0][1] = - M[0][1] / det; - invM[1][0] = - M[1][0] / det; + invM[0][1] = - M01 / det; + invM[1][0] = - M10 / det; invM[1][1] = M00 / det; *stats = INVERSE_SUCCESS; } @@ -200,7 +202,7 @@ inline GCC_ALWAYS_INLINE void cmatmxn_block(MYINT m1, MYINT n1, const MYCOMPLEX inline GCC_ALWAYS_INLINE void cmatmxn_print(MYINT m1, MYINT n1, const MYCOMPLEX M1[m1][n1]){ for(MYINT i=0; i + +#include "common/const.h" +#include "common/model.h" +#include "common/kernel.h" + + + +/** + * 自适应Filon积分, 在大震中距下对Bessel函数取零阶近似,得 + * \f[ + * J_m(x) \approx \sqrt{\frac{2}{\pi x}} \cos(x - \frac{m \pi}{2} - \frac{\pi}{4}) + * \f] + * 其中\f$x=kr\f$. + * + * + * @param[in] mod1d `MODEL1D` 结构体指针 + * @param[in] vmin 最小速度,用于将k区间整体分为两段,在自适应过程中第二段使用更宽松的拟合规则 + * @param[in] k0 前一部分的波数积分结束点k值 + * @param[in] dk0 前一部分的波数积分间隔 + * @param[in] tol 自适应Filon积分的采样精度 + * @param[in] kmax 波数积分的上限 + * @param[in] omega 复数频率 + * @param[in] nr 震中距数量 + * @param[in] rs 震中距数组 + * + * @param[out] sum_J0 积分值 + * + * @param[in] calc_upar 是否计算位移u的空间导数 + * @param[out] sum_uiz_J0 uiz的积分值 + * @param[out] sum_uir_J0 uir的积分值 + * + * @param[out] fstats 文件指针,保存不同k值的格林函数积分核函数 + * @param[in] kerfunc 计算核函数的函数指针 + * @param[out] stats 状态代码,是否有除零错误,非0为异常值 + * + * @return k 积分截至时的波数 + */ +MYREAL sa_filon_integ( + const MODEL1D *mod1d, MYREAL vmin, MYREAL k0, MYREAL dk0, MYREAL tol, MYREAL kmax, MYCOMPLEX omega, + MYINT nr, MYREAL *rs, + MYCOMPLEX sum_J0[nr][SRC_M_NUM][INTEG_NUM], + bool calc_upar, + MYCOMPLEX sum_uiz_J0[nr][SRC_M_NUM][INTEG_NUM], + MYCOMPLEX sum_uir_J0[nr][SRC_M_NUM][INTEG_NUM], + FILE *fstats, KernelFunc kerfunc, MYINT *stats); + + diff --git a/pygrt/C_extension/include/dynamic/grt.h b/pygrt/C_extension/include/dynamic/grt.h index 6dbec719..97b923b8 100755 --- a/pygrt/C_extension/include/dynamic/grt.h +++ b/pygrt/C_extension/include/dynamic/grt.h @@ -41,6 +41,7 @@ void set_num_threads(int num_threads); * @param[in] k0 波数积分的上限 \f$ \tilde{k_{max}}=\sqrt{(k_{0}*\pi/hs)^2 + (ampk*w/vmin_{ref})^2} \f$ ,k循环必须退出, hs=max(震源和台站深度差,1.0) * @param[in] Length 波数k积分间隔 \f$ dk=2\pi/(fabs(L)*r_{max}) \f$ * @param[in] filonLength Filon积分间隔 + * @param[in] safilonTol 自适应Filon积分采样精度 * @param[in] filonCut 波数积分和Filon积分的分割点 * @param[in] print_progressbar 是否打印进度条 * @@ -58,7 +59,7 @@ void set_num_threads(int num_threads); void integ_grn_spec( PYMODEL1D *pymod1d, MYINT nf1, MYINT nf2, MYREAL *freqs, MYINT nr, MYREAL *rs, MYREAL wI, - MYREAL vmin_ref, MYREAL keps, MYREAL ampk, MYREAL k0, MYREAL Length, MYREAL filonLength, MYREAL filonCut, + MYREAL vmin_ref, MYREAL keps, MYREAL ampk, MYREAL k0, MYREAL Length, MYREAL filonLength, MYREAL safilonTol, MYREAL filonCut, bool print_progressbar, // 返回值,代表Z、R、T分量 diff --git a/pygrt/C_extension/include/static/stgrt.h b/pygrt/C_extension/include/static/stgrt.h index 0bea19c0..6fe766af 100644 --- a/pygrt/C_extension/include/static/stgrt.h +++ b/pygrt/C_extension/include/static/stgrt.h @@ -29,6 +29,7 @@ * @param[in] k0 波数积分的上限 * @param[in] Length 波数k积分间隔 \f$ dk=2\pi/(fabs(L)*r_{max}) \f$ * @param[in] filonLength Filon积分间隔 + * @param[in] safilonTol 自适应Filon积分的采样精度 * @param[in] filonCut 波数积分和Filon积分的分割点 * * @param[out] grn 浮点数数组,不同震源不同阶数的静态格林函数的Z、R、T分量 @@ -42,7 +43,7 @@ */ void integ_static_grn( PYMODEL1D *pymod1d, MYINT nr, MYREAL *rs, MYREAL vmin_ref, MYREAL keps, MYREAL k0, MYREAL Length, - MYREAL filonLength, MYREAL filonCut, + MYREAL filonLength, MYREAL safilonTol, MYREAL filonCut, // 返回值,代表Z、R、T分量 MYREAL grn[nr][SRC_M_NUM][CHANNEL_NUM], diff --git a/pygrt/C_extension/src/common/const.c b/pygrt/C_extension/src/common/const.c index 4ad293bb..3d6aeb87 100644 --- a/pygrt/C_extension/src/common/const.c +++ b/pygrt/C_extension/src/common/const.c @@ -12,6 +12,9 @@ /** 分别对应爆炸源(0阶),垂直力源(0阶),水平力源(1阶),剪切源(0,1,2阶) */ const MYINT SRC_M_ORDERS[SRC_M_NUM] = {0, 0, 1, 0, 1, 2}; +/** 不同震源类型使用的格林函数类型,0为Gij,1为格林函数导数Gij,k */ +const MYINT SRC_M_GTYPES[SRC_M_NUM] = {1, 0, 0, 1, 1, 1}; + /** 不同震源,不同阶数的名称简写,用于命名 */ const char *SRC_M_NAME_ABBR[SRC_M_NUM] = {"EX", "VF", "HF", "DD", "DS", "SS"}; diff --git a/pygrt/C_extension/src/common/integral.c b/pygrt/C_extension/src/common/integral.c index d4296499..87ab6880 100644 --- a/pygrt/C_extension/src/common/integral.c +++ b/pygrt/C_extension/src/common/integral.c @@ -10,10 +10,12 @@ #include #include +#include #include "common/integral.h" #include "common/const.h" #include "common/bessel.h" +#include "common/quadratic.h" @@ -70,9 +72,7 @@ void int_Pk( void int_Pk_filon( MYREAL k, MYREAL r, bool iscos, - // F(ki,w), 第一个维度表示不同震源,不同阶数,第二个维度3代表三类系数qm,wm,vm const MYCOMPLEX QWV[SRC_M_NUM][QWV_NUM], - // F(ki,w)Jm(ki*r)ki,第一个维度表示不同震源,不同阶数,第二个维度代表4种类型的F(k,w)Jm(kr)k的类型 bool calc_uir, MYCOMPLEX SUM[SRC_M_NUM][INTEG_NUM]) { @@ -80,29 +80,25 @@ void int_Pk_filon( if(! iscos) phi0 = - HALFPI; // 在cos函数中添加的相位差,用于计算sin函数 MYREAL kr = k*r; - MYREAL kr_inv = RONE/kr; - MYREAL kcoef = SQRT(k); + MYREAL kcoef = sqrt(k); MYREAL bjmk[MORDER_MAX+1] = {0}; - MYREAL Jmcoef[MORDER_MAX+1] = {0}; - if(calc_uir){ kcoef *= k; // 使用bessel递推公式 Jm'(x) = m/x * Jm(x) - J_{m+1}(x) // 考虑大震中距,忽略第一项,再使用bessel渐近公式 - bjmk[0] = - COS(kr - THREEQUARTERPI - phi0); - bjmk[1] = - COS(kr - FIVEQUARTERPI - phi0); - bjmk[2] = - COS(kr - SEVENQUARTERPI - phi0); + bjmk[0] = - cos(kr - THREEQUARTERPI - phi0); + bjmk[1] = - cos(kr - FIVEQUARTERPI - phi0); + bjmk[2] = - cos(kr - SEVENQUARTERPI - phi0); } else { - bjmk[0] = COS(kr - QUARTERPI - phi0); - bjmk[1] = COS(kr - THREEQUARTERPI - phi0); - bjmk[2] = COS(kr - FIVEQUARTERPI - phi0); + bjmk[0] = cos(kr - QUARTERPI - phi0); + bjmk[1] = cos(kr - THREEQUARTERPI - phi0); + bjmk[2] = cos(kr - FIVEQUARTERPI - phi0); } - for(MYINT i=1; i<=MORDER_MAX; ++i) Jmcoef[i] = bjmk[i]*kr_inv*kcoef; for(MYINT i=0; i<=MORDER_MAX; ++i) bjmk[i] *= kcoef; - // 公式(5.6.22), 将公式分解为F(k,w)Jm(kr)k的形式 + // 公式(5.6.22), 将公式分解为F(k,w)Jm(kr)k的形式,忽略近场项 for(MYINT i=0; i +#include +#include +#include + +#include "common/safim.h" +#include "common/integral.h" +#include "common/iostats.h" +#include "common/const.h" +#include "common/model.h" + + +/** + * 用于判断拟合情况,当|F(k)| < s * max{|F(k)|},调整该区间的F(k)积分和, + * 防止其在小幅值处采样过多。 + */ +#define REF_AMP_SCALE 1e-6 + +/** + * 自适应划分区间的最小dk + */ +#define SA_MIN_DK 1e-7 + + +/** 辛普森积分的区间范围 */ +typedef enum { + SIMPSON_As2H_A = -1, + SIMPSON_A_Ap2H = 1, + SIMPSON_Ap2H_Ap4H = 2, + SIMPSON_A_ApH = 3, + SIMPSON_ApH_Ap2H = 4 +} SIMPSON_INTV; + + + + +// 区间结构体 +typedef struct { + MYREAL k3[3]; + MYCOMPLEX F3[3][SRC_M_NUM][QWV_NUM]; + MYCOMPLEX F3_uiz[3][SRC_M_NUM][QWV_NUM]; +} KInterval; + +// 区间栈结构体 +typedef struct { + KInterval *data; + int size; + int capacity; +} KIntervalStack; + +/** 初始化区间栈 */ +static void stack_init(KIntervalStack *stack, int init_capacity) { + stack->data = (KInterval*)malloc(init_capacity * sizeof(KInterval)); + stack->size = 0; + stack->capacity = init_capacity; +} + +/** 从栈顶部压入元素 */ +static void stack_push(KIntervalStack *stack, KInterval item) { + // 扩容 + if(stack->size >= stack->capacity){ + stack->capacity *= 2; + stack->data = (KInterval*)realloc(stack->data, stack->capacity * sizeof(KInterval)); + } + stack->data[stack->size++] = item; +} + +/** 从栈顶部拿走元素 */ +static KInterval stack_pop(KIntervalStack *stack) { + if(stack->size == 0) { + fprintf(stderr, "Pop from empty stack\n"); + exit(EXIT_FAILURE); + } + return stack->data[--stack->size]; +} + + + + +/** + * 三点辛普森积分计算,基于区间内三个点的函数值,定义二次曲线,再根据stats定义积分区间, + * 假设区间内三点为[a, a+h, a+2h],stats的取值对应的积分区间为 + * + stats = -1, [a-2h, a] + * + stats = 1, [a, a+2h] + * + stats = 2, [a+2h, a+4h] + * + stats = 3, [a, a+h] + * + stats = 4, [a+h, a+2h] + * + */ +static MYCOMPLEX simpson(const KInterval *item_pt, MYINT im, MYINT iqwv, bool isuiz, SIMPSON_INTV stats) { + MYCOMPLEX Fint = 0.0; + MYREAL klen = item_pt->k3[2] - item_pt->k3[0]; + const MYCOMPLEX (*F3)[SRC_M_NUM][QWV_NUM] = (isuiz)? item_pt->F3_uiz : item_pt->F3; + + // 使用F(k)*sqrt(k)来衡量积分值,这可以平衡后续计算F(k)*Jm(kr)k积分时的系数 + MYREAL sk[3]; + for(MYINT i=0; i<3; ++i){ + sk[i] = sqrt(item_pt->k3[i]); + } + + if(stats == SIMPSON_A_Ap2H){ + Fint = klen * (F3[0][im][iqwv]*sk[0] + 4.0*F3[1][im][iqwv]*sk[1] + F3[2][im][iqwv]*sk[2]) / 6.0; + } + else if(stats == SIMPSON_As2H_A){ + Fint = klen * (19.0*F3[0][im][iqwv]*sk[0] - 20.0*F3[1][im][iqwv]*sk[1] + 7.0*F3[2][im][iqwv]*sk[2]) / 6.0; + } + else if(stats == SIMPSON_Ap2H_Ap4H){ + Fint = klen * (7.0*F3[0][im][iqwv]*sk[0] - 20.0*F3[1][im][iqwv]*sk[1] + 19.0*F3[2][im][iqwv]*sk[2]) / 6.0; + } + else if(stats == SIMPSON_A_ApH){ + Fint = klen * (5.0*F3[0][im][iqwv]*sk[0] + 8.0*F3[1][im][iqwv]*sk[1] - F3[2][im][iqwv]*sk[2]) / 24.0; + } + else if(stats == SIMPSON_ApH_Ap2H){ + Fint = klen * ( - F3[0][im][iqwv]*sk[0] + 8.0*F3[1][im][iqwv]*sk[1] + 5.0*F3[2][im][iqwv]*sk[2]) / 24.0; + } + else{ + fprintf(stderr, "wrong simpson stats (%d).\n", stats); + exit(EXIT_FAILURE); + } + + return Fint; +} + +/** 比较QWV的最大绝对值 */ +static void get_maxabsQWV(const MYCOMPLEX F[SRC_M_NUM][QWV_NUM], MYREAL maxabsF[GTYPES_MAX]){ + MYREAL tmp; + for(MYINT i=0; i maxabsF[SRC_M_GTYPES[i]]){ + maxabsF[SRC_M_GTYPES[i]] = tmp; + } + } + } +} + + +/** 检查区间是否符合要求,返回True表示通过 */ +static bool check_fit( + const KInterval *ptKitv, const KInterval *ptKitvL, const KInterval *ptKitvR, MYREAL kref, + bool isuiz, MYREAL maxabsQWV[GTYPES_MAX], MYREAL tol) +{ + // 计算积分差异 + MYCOMPLEX S11, S12, S21, S22; + + // 核函数 + const MYCOMPLEX (*F3L)[SRC_M_NUM][QWV_NUM] = (isuiz)? ptKitvL->F3_uiz : ptKitvL->F3; + const MYCOMPLEX (*F3R)[SRC_M_NUM][QWV_NUM] = (isuiz)? ptKitvR->F3_uiz : ptKitvR->F3; + + // 取近似积分 \int_k1^k2 k^0.5 dk + MYREAL kcoef13 = RTWOTHIRD*( ptKitv->k3[2]*sqrt(ptKitv->k3[2]) - ptKitv->k3[0]*sqrt(ptKitv->k3[0]) ); + MYREAL kcoef12 = RTWOTHIRD*( ptKitvL->k3[2]*sqrt(ptKitvL->k3[2]) - ptKitvL->k3[0]*sqrt(ptKitvL->k3[0]) ); + MYREAL kcoef23 = RTWOTHIRD*( ptKitvR->k3[2]*sqrt(ptKitvR->k3[2]) - ptKitvR->k3[0]*sqrt(ptKitvR->k3[0]) ); + + MYREAL S_dif, S_ref; + bool badtol = false; + for(MYINT im=0; imk3[0] > kref && qwvchs[c]!='v') continue; + + S11 = simpson(ptKitv, im, c, isuiz, SIMPSON_A_ApH); + S12 = simpson(ptKitv, im, c, isuiz, SIMPSON_ApH_Ap2H); + S21 = simpson(ptKitvL, im, c, isuiz, SIMPSON_A_Ap2H); + S22 = simpson(ptKitvR, im, c, isuiz, SIMPSON_A_Ap2H); + + bool islowamp = true; + MYREAL ref_amp = REF_AMP_SCALE*maxabsQWV[igtyp]; + // 比较当前区间内5个核函数幅值,是否都低于参考值 + for(MYINT d=0; d<3; ++d){ + islowamp = islowamp && (fabs(F3L[d][im][c]) < ref_amp); + if(d>0){ + islowamp = islowamp && (fabs(F3R[d][im][c]) < ref_amp); + } + } + // 如果核函数幅值确实较低,则限制S_ref,此时正负号不重要 + // 三个拟合规则(a,b,c) + // (a) + if(islowamp){ + S_ref = ref_amp * kcoef13; + } else { + S_ref = fabs(S11 + S12 + S21 + S22); + } + S_dif = fabs(S11 + S12 - S21 - S22); + badtol = badtol || (S_dif/S_ref > tol); // 有一个不合格就继续采样 + if(badtol) goto BEFORE_RETURN; + // (b) + if(islowamp){ + S_ref = ref_amp * kcoef12; + } else { + S_ref = fabs(S11 + S21); + } + S_dif = fabs(S11 - S21); + badtol = badtol || (S_dif/S_ref > tol); // 有一个不合格就继续采样 + if(badtol) goto BEFORE_RETURN; + // (c) + if(islowamp){ + S_ref = ref_amp * kcoef23; + } else { + S_ref = fabs(S12 + S22); + } + S_dif = fabs(S12 - S22); + badtol = badtol || (S_dif/S_ref > tol); // 有一个不合格就继续采样 + if(badtol) goto BEFORE_RETURN; + + } + } + + BEFORE_RETURN: + return (! badtol); +} + +/** + * 根据该区间内采样的三个点,拟合二次函数,计算 F(k,w)Jm(kr)k 在区间内的积分 + * 将Bessel函数近似为 sqrt(2/(\pi kr)) cos(kr - (2m+1)/4 \pi), + * 以下实际拟合的二次函数是 sqrt(k)*F(k,w), 这样积分时可以避免计算超越函数 + * + */ +static void interv_integ( + const KInterval *ptKitv, + MYINT nr, MYREAL *rs, + MYCOMPLEX sum_J[nr][SRC_M_NUM][INTEG_NUM], + bool calc_upar, + MYCOMPLEX sum_uiz_J[nr][SRC_M_NUM][INTEG_NUM], + MYCOMPLEX sum_uir_J[nr][SRC_M_NUM][INTEG_NUM]) +{ + MYCOMPLEX SUM[SRC_M_NUM][INTEG_NUM]={0}; + + // 震中距rs循环 + for(MYINT ir=0; irk3, rs[ir], ptKitv->F3, false, SUM); + for(MYINT i=0; ik3, rs[ir], ptKitv->F3_uiz, false, SUM); + for(MYINT i=0; ik3, rs[ir], ptKitv->F3, true, SUM); + for(MYINT i=0; i 0) { + Kitv = stack_pop(&stack); + + // 左右两个区间 + KInterval Kitv_left = { + .k3 = { + Kitv.k3[0], + (Kitv.k3[0]+Kitv.k3[1])*0.5, + Kitv.k3[1] + }, + .F3 = {{{0}}}, + .F3_uiz = {{{0}}} + }; + KInterval Kitv_right = { + .k3 = { + Kitv.k3[1], + (Kitv.k3[1]+Kitv.k3[2])*0.5, + Kitv.k3[2] + }, + .F3 = {{{0}}}, + .F3_uiz = {{{0}}} + }; + memcpy(Kitv_left.F3[0], Kitv.F3[0], sizeof(MYCOMPLEX)*SRC_M_NUM*QWV_NUM); + memcpy(Kitv_left.F3[2], Kitv.F3[1], sizeof(MYCOMPLEX)*SRC_M_NUM*QWV_NUM); + memcpy(Kitv_right.F3[0], Kitv.F3[1], sizeof(MYCOMPLEX)*SRC_M_NUM*QWV_NUM); + memcpy(Kitv_right.F3[2], Kitv.F3[2], sizeof(MYCOMPLEX)*SRC_M_NUM*QWV_NUM); + if(calc_upar){ + memcpy(Kitv_left.F3_uiz[0], Kitv.F3_uiz[0], sizeof(MYCOMPLEX)*SRC_M_NUM*QWV_NUM); + memcpy(Kitv_left.F3_uiz[2], Kitv.F3_uiz[1], sizeof(MYCOMPLEX)*SRC_M_NUM*QWV_NUM); + memcpy(Kitv_right.F3_uiz[0], Kitv.F3_uiz[1], sizeof(MYCOMPLEX)*SRC_M_NUM*QWV_NUM); + memcpy(Kitv_right.F3_uiz[2], Kitv.F3_uiz[2], sizeof(MYCOMPLEX)*SRC_M_NUM*QWV_NUM); + } + kerfunc(mod1d, omega, Kitv_left.k3[1], Kitv_left.F3[1], calc_upar, Kitv_left.F3_uiz[1], stats); + if(*stats==INVERSE_FAILURE) goto BEFORE_RETURN; + + kerfunc(mod1d, omega, Kitv_right.k3[1], Kitv_right.F3[1], calc_upar, Kitv_right.F3_uiz[1], stats); + if(*stats==INVERSE_FAILURE) goto BEFORE_RETURN; + + + // 增加新值,并比较QWV最大绝对值 + for(MYINT i=0; i<3; ++i){ + get_maxabsQWV(Kitv_left.F3[i], maxabsQWV); + if(calc_upar) get_maxabsQWV(Kitv_left.F3_uiz[i], maxabsQWV_uiz); + if(i>0){ + get_maxabsQWV(Kitv_right.F3[i], maxabsQWV); + if(calc_upar) get_maxabsQWV(Kitv_right.F3_uiz[i], maxabsQWV_uiz); + } + } + + // 检查区间是否符合要求 + MYREAL goodtol = check_fit(&Kitv, &Kitv_left, &Kitv_right, kref, false, maxabsQWV, tol); + if(calc_upar){ + goodtol = goodtol && check_fit(&Kitv, &Kitv_left, &Kitv_right, kref, true, maxabsQWV_uiz, tol); + } + + // 区间不符合要求,且采样间隔还足够继续细分 + if(! goodtol && Kitv_left.k3[2] - Kitv_left.k3[0] > SA_MIN_DK) { + // 推入右子区间(后进先出) + stack_push(&stack, Kitv_right); + // 推入左子区间(先处理) + stack_push(&stack, Kitv_left); + } else { + // 由于栈的特性,最终记录的k值采样是按顺序的 + // 记录后四个采样值 + if(fstats!=NULL){ + for(MYINT i=1; i<3; ++i){ + write_stats(fstats, Kitv_left.k3[i], Kitv_left.F3[i]); + } + for(MYINT i=1; i<3; ++i){ + write_stats(fstats, Kitv_right.k3[i], Kitv_right.F3[i]); + } + } + // 计算积分 + interv_integ(&Kitv, nr, rs, sum_J, calc_upar, sum_uiz_J, sum_uir_J); + } + } // END sampling + + // 乘上总系数 sqrt(RTWO/(PI*r)) / dk0, 除dks0是在该函数外还会再乘dk0, 并将结果加到原数组中 + for(MYINT ir=0; irlays + main_mod1d->isrc; const MYREAL Rho = src_lay->Rho; // 震源区密度 const MYREAL fac = RONE/(RFOUR*PI*Rho); - const MYREAL hs = (FABS(pymod1d->depsrc - pymod1d->deprcv) < MIN_DEPTH_GAP_SRC_RCV)? - MIN_DEPTH_GAP_SRC_RCV : FABS(pymod1d->depsrc - pymod1d->deprcv); // hs=max(震源和台站深度差,1.0) + const MYREAL hs = (fabs(pymod1d->depsrc - pymod1d->deprcv) < MIN_DEPTH_GAP_SRC_RCV)? + MIN_DEPTH_GAP_SRC_RCV : fabs(pymod1d->depsrc - pymod1d->deprcv); // hs=max(震源和台站深度差,1.0) // 乘相应系数 k0 *= PI/hs; @@ -120,6 +121,7 @@ void integ_grn_spec( if(vmin_ref < RZERO) keps = -RONE; // 若使用峰谷平均法,则不使用keps进行收敛判断 + bool useFIM = (filonLength > RZERO) || (safilonTol > RZERO) ; // 是否使用Filon积分(包括自适应Filon) const MYREAL dk=PI2/(Length*rmax); // 波数积分间隔 const MYREAL filondk = (filonLength > RZERO) ? PI2/(filonLength*rmax) : RZERO; // Filon积分间隔 const MYREAL filonK = filonCut/rmax; // 波数积分和Filon积分的分割点 @@ -148,6 +150,9 @@ void integ_grn_spec( // 进度条变量 MYINT progress=0; + // 每个频率的计算中是否有除0错误 + MYINT freq_invstats[nf2+1]; + // 频率omega循环 // schedule语句可以动态调度任务,最大程度地使用计算资源 #pragma omp parallel for schedule(guided) default(shared) @@ -217,42 +222,58 @@ void integ_grn_spec( MYREAL kmax; // vmin_ref的正负性在这里不影响 - kmax = SQRT(k02 + ampk2*(w/vmin_ref)*(w/vmin_ref)); + kmax = sqrt(k02 + ampk2*(w/vmin_ref)*(w/vmin_ref)); + // 计算核函数过程中是否有遇到除零错误 + freq_invstats[iw]=INVERSE_SUCCESS; // 常规的波数积分 k = discrete_integ( - local_mod1d, dk, (filondk > RZERO)? filonK : kmax, keps, omega, nr, rs, + local_mod1d, dk, (useFIM)? filonK : kmax, keps, omega, nr, rs, sum_J, calc_upar, sum_uiz_J, sum_uir_J, - fstats, kernel); - - // 基于线性插值的Filon积分 - if(filondk > RZERO){ - k = linear_filon_integ( - local_mod1d, k, dk, filondk, kmax, keps, omega, nr, rs, - sum_J, calc_upar, sum_uiz_J, sum_uir_J, - fstats, kernel); + fstats, kernel, &freq_invstats[iw]); + + // 使用Filon积分 + if(useFIM && freq_invstats[iw]==INVERSE_SUCCESS){ + if(filondk > RZERO){ + // 基于线性插值的Filon积分,固定采样间隔 + k = linear_filon_integ( + local_mod1d, k, dk, filondk, kmax, keps, omega, nr, rs, + sum_J, calc_upar, sum_uiz_J, sum_uir_J, + fstats, kernel, &freq_invstats[iw]); + } + else if(safilonTol > RZERO){ + // 基于自适应采样的Filon积分 + k = sa_filon_integ( + local_mod1d, fabs(vmin_ref)/ampk, k, dk, safilonTol, kmax, omega, nr, rs, + sum_J, calc_upar, sum_uiz_J, sum_uir_J, + fstats, kernel, &freq_invstats[iw]); + } } // k之后的部分使用峰谷平均法进行显式收敛,建议在浅源地震的时候使用 - if(vmin_ref < RZERO){ + if(vmin_ref < RZERO && freq_invstats[iw]==INVERSE_SUCCESS){ PTA_method( local_mod1d, k, dk, omega, nr, rs, sum_J, calc_upar, sum_uiz_J, sum_uir_J, - ptam_fstatsnr, kernel); + ptam_fstatsnr, kernel, &freq_invstats[iw]); } - // printf("iw=%d, w=%.5e, k=%.5e, dk=%.5e, nk=%d\n", iw, w, k, dk, (int)(k/dk)); - - + // fprintf(stderr, "iw=%d, w=%.5e, k=%.5e, dk=%.5e, nk=%d\n", iw, w, k, dk, (int)(k/dk)); + // fflush(stderr); // 记录到格林函数结构体内 - recordin_GRN(iw, nr, coef, sum_J, grn); - if(calc_upar){ - recordin_GRN(iw, nr, coef, sum_uiz_J, grn_uiz); - recordin_GRN(iw, nr, coef, sum_uir_J, grn_uir); + // 如果计算核函数过程中存在除零错误,则放弃该频率【通常在大震中距的低频段】 + if(freq_invstats[iw]==INVERSE_SUCCESS){ + recordin_GRN(iw, nr, coef, sum_J, grn); + if(calc_upar){ + recordin_GRN(iw, nr, coef, sum_uiz_J, grn_uiz); + recordin_GRN(iw, nr, coef, sum_uir_J, grn_uir); + } } - + // else{ + // fprintf(stderr, "iw=%d, f=%f, failed, filled with 0.\n", iw, w/PI2); + // } if(fstats!=NULL) fclose(fstats); for(MYINT ir=0; ir: lower frequency (Hz), %.1f means low pass.\n", freq1); printf( " : upper frequency (Hz), %.1f means high pass.\n", freq2); printf( "\n" -" -L[//]\n" +" -L[a][//]\n" " Define the wavenumber integration interval\n" " dk=(2*PI)/(*rmax). rmax is the maximum \n" " epicentral distance. \n" -" There are 3 cases:\n" +" There are 4 cases:\n" " + (default) not set or set %.1f.\n", Length); printf( " will be determined automatically\n" " in program with the criterion (Bouchon, 1980).\n" @@ -215,6 +216,9 @@ printf("\n" " into two parts, [0, k*] and [k*, kmax], \n" " in which k*=/rmax, and use DWM with\n" " and FIM with , respectively.\n" +" + manually set three POSITIVE values, with -La,\n" +" in this case, will be for Self-\n" +" Adaptive FIM.\n" "\n" " -V \n" " Minimum velocity (km/s) for reference. This\n" @@ -403,11 +407,19 @@ static void getopt_from_command(int argc, char **argv){ } break; - // 波数积分间隔 -L[//] + // 波数积分间隔 -L[a][//] case 'L': L_flag = 1; { - int n = sscanf(optarg, "%lf/%lf/%lf", &Length, &filonLength, &filonCut); + // 检查首字母是否为a,表明使用自适应Filon积分 + int pos=0; + bool useSAFIM = false; + if(optarg[0] == 'a'){ + pos++; + useSAFIM = true; + } + double filona = 0.0; + int n = sscanf(optarg+pos, "%lf/%lf/%lf", &Length, &filona, &filonCut); if(n != 1 && n != 3){ fprintf(stderr, "[%s] " BOLD_RED "Error in -L.\n" DEFAULT_RESTORE, command); exit(EXIT_FAILURE); @@ -416,10 +428,17 @@ static void getopt_from_command(int argc, char **argv){ fprintf(stderr, "[%s] " BOLD_RED "Error! In -L, length should be positive.\n" DEFAULT_RESTORE, command); exit(EXIT_FAILURE); } - if(n == 3 && (filonLength <= 0 || filonCut < 0)){ - fprintf(stderr, "[%s] " BOLD_RED "Error! In -L, Flength should be positive, Fcut should be nonnegative.\n" DEFAULT_RESTORE, command); + if(n == 3 && (filona <= 0 || filonCut < 0)){ + fprintf(stderr, "[%s] " BOLD_RED "Error! In -L, Flength/Ftol should be positive, Fcut should be nonnegative.\n" DEFAULT_RESTORE, command); exit(EXIT_FAILURE); } + if(n == 3){ + if(useSAFIM){ + safilonTol = filona; + } else { + filonLength = filona; + } + } } break; @@ -739,7 +758,7 @@ static void ifft_one_trace( static void print_parameters(){ // 模拟打两列表格,第一列参数名,第二列参数值 print_pymod(pymod); - const int nlen1=20, nlen2=30; // 两列字符宽度 + const int nlen1=20, nlen2=45; // 两列字符宽度 // 制作每行分割线 char splitline[nlen1+nlen2+2]; splitline[0] = '+'; @@ -766,7 +785,10 @@ static void print_parameters(){ if(filonLength > 0.0){ snprintf(tmp, sizeof(tmp), "%f,%f,%f", Length, filonLength, filonCut); strncat(tmp, ", using FIM.", sizeof(tmp)-strlen(tmp)-1); - } + } else if(safilonTol > 0.0){ + snprintf(tmp, sizeof(tmp), "%f,%f,%f", Length, safilonTol, filonCut); + strncat(tmp, ", using SAFIM.", sizeof(tmp)-strlen(tmp)-1); + } printf("| %-*s | %-*s |\n", nlen1-3, "length", nlen2-3, tmp); // printf("| %-*s | %-*d |\n", nlen1-3, "nt", nlen2-3, nt); @@ -1083,7 +1105,7 @@ int main(int argc, char **argv) { // 计算格林函数 integ_grn_spec( pymod, nf1, nf2, freqs, nr, rs, wI, - vmin_ref, keps, ampk, k0, Length, filonLength, filonCut, !silenceInput, + vmin_ref, keps, ampk, k0, Length, filonLength, safilonTol, filonCut, !silenceInput, grn, calc_upar, grn_uiz, grn_uir, s_statsdir, nstatsidxs, statsidxs ); diff --git a/pygrt/C_extension/src/dynamic/propagate.c b/pygrt/C_extension/src/dynamic/propagate.c index 05d2a2d8..115fdfda 100755 --- a/pygrt/C_extension/src/dynamic/propagate.c +++ b/pygrt/C_extension/src/dynamic/propagate.c @@ -47,6 +47,10 @@ void kernel( MYINT imin, imax; // 相对浅层深层层位 imin = mod1d->imin; imax = mod1d->imax; + // bool ircvup = true; + // MYINT isrc = 2; + // MYINT ircv = 1; + // MYINT imin=1, imax=2; // 初始化广义反射透射系数矩阵 @@ -107,8 +111,14 @@ void kernel( // 定义物理层内的反射透射系数矩阵,相对于界面上的系数矩阵增加了时间延迟因子 - MYCOMPLEX RD[2][2], RDL, TD[2][2], TDL; - MYCOMPLEX RU[2][2], RUL, TU[2][2], TUL; + MYCOMPLEX RD[2][2] = INIT_C_ZERO_2x2_MATRIX; + MYCOMPLEX RDL = CZERO; + MYCOMPLEX RU[2][2] = INIT_C_ZERO_2x2_MATRIX; + MYCOMPLEX RUL = CZERO; + MYCOMPLEX TD[2][2] = INIT_C_IDENTITY_2x2_MATRIX; + MYCOMPLEX TDL = CONE; + MYCOMPLEX TU[2][2] = INIT_C_IDENTITY_2x2_MATRIX; + MYCOMPLEX TUL = CONE; MYCOMPLEX *const pRDL = &RDL; MYCOMPLEX *const pTDL = &TDL; MYCOMPLEX *const pRUL = &RUL; @@ -157,10 +167,10 @@ void kernel( mod1d_mu1 = lay->mu; mod1d_kaka1 = lay->kaka; mod1d_kbkb1 = lay->kbkb; - // mod1d_xa1 = CSQRT(RONE - mod1d_kaka1/(k*k)); - // mod1d_xb1 = CSQRT(RONE - mod1d_kbkb1/(k*k)); - mod1d_xa1 = CSQRT(k*k - mod1d_kaka1)/k; - mod1d_xb1 = CSQRT(k*k - mod1d_kbkb1)/k; + mod1d_xa1 = sqrt(RONE - mod1d_kaka1/(k*k)); + mod1d_xb1 = sqrt(RONE - mod1d_kbkb1/(k*k)); + // mod1d_xa1 = sqrt(k*k - mod1d_kaka1)/k; + // mod1d_xb1 = sqrt(k*k - mod1d_kbkb1)/k; if(0==iy){ top_xa = mod1d_xa1; @@ -192,19 +202,27 @@ void kernel( #if Print_GRTCOEF == 1 // TEST------------------------------------------------------------- - fprintf(stderr, "k=%f. iy=%d\n", k, iy); - fprintf(stderr, "RD\n"); - cmatmxn_print(2, 2, RD); - fprintf(stderr, "RDL="GRT_CMPLX_FMT"\n", CREAL(RDL), CIMAG(RDL)); - fprintf(stderr, "RU\n"); - cmatmxn_print(2, 2, RU); - fprintf(stderr, "RUL="GRT_CMPLX_FMT"\n", CREAL(RUL), CIMAG(RUL)); - fprintf(stderr, "TD\n"); - cmatmxn_print(2, 2, TD); - fprintf(stderr, "TDL="GRT_CMPLX_FMT"\n", CREAL(TDL), CIMAG(TDL)); - fprintf(stderr, "TU\n"); - cmatmxn_print(2, 2, TU); - fprintf(stderr, "TUL="GRT_CMPLX_FMT"\n", CREAL(TUL), CIMAG(TUL)); + // fprintf(stderr, "k=%f. iy=%d\n", k, iy); + // fprintf(stderr, "RD\n"); + // cmatmxn_print(2, 2, RD); + // fprintf(stderr, "RDL="GRT_CMPLX_FMT"\n", creal(RDL), cimag(RDL)); + // fprintf(stderr, "RU\n"); + // cmatmxn_print(2, 2, RU); + // fprintf(stderr, "RUL="GRT_CMPLX_FMT"\n", creal(RUL), cimag(RUL)); + // fprintf(stderr, "TD\n"); + // cmatmxn_print(2, 2, TD); + // fprintf(stderr, "TDL="GRT_CMPLX_FMT"\n", creal(TDL), cimag(TDL)); + // fprintf(stderr, "TU\n"); + // cmatmxn_print(2, 2, TU); + // fprintf(stderr, "TUL="GRT_CMPLX_FMT"\n", creal(TUL), cimag(TUL)); + // if(creal(omega)==PI2*15e-4 && iy==5){ + // fprintf(stderr, GRT_REAL_FMT, k); + // for(int i=0; i<2; ++i) for(int j=0; j<2; ++j) fprintf(stderr, GRT_CMPLX_FMT, creal(RD[i][j]), cimag(RD[i][j])); + // for(int i=0; i<2; ++i) for(int j=0; j<2; ++j) fprintf(stderr, GRT_CMPLX_FMT, creal(RU[i][j]), cimag(RU[i][j])); + // for(int i=0; i<2; ++i) for(int j=0; j<2; ++j) fprintf(stderr, GRT_CMPLX_FMT, creal(TD[i][j]), cimag(TD[i][j])); + // for(int i=0; i<2; ++i) for(int j=0; j<2; ++j) fprintf(stderr, GRT_CMPLX_FMT, creal(TU[i][j]), cimag(TU[i][j])); + // fprintf(stderr, "\n"); + // } // TEST------------------------------------------------------------- #endif // FA @@ -375,7 +393,40 @@ void kernel( TU_RS, TUL_RS, RU_FB, pRUL_FB, inv_2x2T, &invT, stats); if(*stats==INVERSE_FAILURE) goto BEFORE_RETURN; - + +#if Print_GRTCOEF == 1 + // TEST------------------------------------------------------------- + if(creal(omega)==PI2*0.1){ + fprintf(stderr, GRT_REAL_FMT, k); + for(int i=0; i<2; ++i) for(int j=0; j<2; ++j) fprintf(stderr, GRT_CMPLX_FMT, creal(RD_BL[i][j]), cimag(RD_BL[i][j])); + for(int i=0; i<2; ++i) for(int j=0; j<2; ++j) fprintf(stderr, GRT_CMPLX_FMT, creal(RU_BL[i][j]), cimag(RU_BL[i][j])); + for(int i=0; i<2; ++i) for(int j=0; j<2; ++j) fprintf(stderr, GRT_CMPLX_FMT, creal(TD_BL[i][j]), cimag(TD_BL[i][j])); + for(int i=0; i<2; ++i) for(int j=0; j<2; ++j) fprintf(stderr, GRT_CMPLX_FMT, creal(TU_BL[i][j]), cimag(TU_BL[i][j])); + for(int i=0; i<2; ++i) for(int j=0; j<2; ++j) fprintf(stderr, GRT_CMPLX_FMT, creal(RD_RS[i][j]), cimag(RD_RS[i][j])); + for(int i=0; i<2; ++i) for(int j=0; j<2; ++j) fprintf(stderr, GRT_CMPLX_FMT, creal(RU_RS[i][j]), cimag(RU_RS[i][j])); + for(int i=0; i<2; ++i) for(int j=0; j<2; ++j) fprintf(stderr, GRT_CMPLX_FMT, creal(TD_RS[i][j]), cimag(TD_RS[i][j])); + for(int i=0; i<2; ++i) for(int j=0; j<2; ++j) fprintf(stderr, GRT_CMPLX_FMT, creal(TU_RS[i][j]), cimag(TU_RS[i][j])); + for(int i=0; i<2; ++i) for(int j=0; j<2; ++j) fprintf(stderr, GRT_CMPLX_FMT, creal(RD_FA[i][j]), cimag(RD_FA[i][j])); + for(int i=0; i<2; ++i) for(int j=0; j<2; ++j) fprintf(stderr, GRT_CMPLX_FMT, creal(RU_FA[i][j]), cimag(RU_FA[i][j])); + for(int i=0; i<2; ++i) for(int j=0; j<2; ++j) fprintf(stderr, GRT_CMPLX_FMT, creal(TD_FA[i][j]), cimag(TD_FA[i][j])); + for(int i=0; i<2; ++i) for(int j=0; j<2; ++j) fprintf(stderr, GRT_CMPLX_FMT, creal(TU_FA[i][j]), cimag(TU_FA[i][j])); + for(int i=0; i<2; ++i) for(int j=0; j<2; ++j) fprintf(stderr, GRT_CMPLX_FMT, creal(RU_FB[i][j]), cimag(RU_FB[i][j])); + for(int i=0; i<2; ++i) for(int j=0; j<2; ++j) fprintf(stderr, GRT_CMPLX_FMT, creal(R_tilt[i][j]), cimag(R_tilt[i][j])); + for(int i=0; i<2; ++i) for(int j=0; j<2; ++j) fprintf(stderr, GRT_CMPLX_FMT, creal(R_EV[i][j]), cimag(R_EV[i][j])); + for(int i=0; i<2; ++i) for(int j=0; j<2; ++j) fprintf(stderr, GRT_CMPLX_FMT, creal(inv_2x2T[i][j]), cimag(inv_2x2T[i][j])); + cmat2x2_mul(RD_BL, RU_FB, tmpR2); + for(int i=0; i<2; ++i) for(int j=0; j<2; ++j) fprintf(stderr, GRT_CMPLX_FMT, creal(tmpR2[i][j]), cimag(tmpR2[i][j])); + cmat2x2_one_sub(tmpR2); + cmat2x2_inv(tmpR2, tmpR2, stats);// (I - xx)^-1 + for(int i=0; i<2; ++i) for(int j=0; j<2; ++j) fprintf(stderr, GRT_CMPLX_FMT, creal(tmpR2[i][j]), cimag(tmpR2[i][j])); + cmat2x2_mul(inv_2x2T, tmpR2, tmp2x2); + for(int i=0; i<2; ++i) for(int j=0; j<2; ++j) fprintf(stderr, GRT_CMPLX_FMT, creal(tmp2x2[i][j]), cimag(tmp2x2[i][j])); + cmat2x2_mul(R_EV, tmp2x2, tmp2x2); + for(int i=0; i<2; ++i) for(int j=0; j<2; ++j) fprintf(stderr, GRT_CMPLX_FMT, creal(tmp2x2[i][j]), cimag(tmp2x2[i][j])); + fprintf(stderr, "\n"); + } + // TEST------------------------------------------------------------- +#endif // 公式(5.7.12-14) cmat2x2_mul(RD_BL, RU_FB, tmpR2); @@ -392,6 +443,25 @@ void kernel( for(MYINT i=0; i RZERO) || (safilonTol > RZERO) ; // 是否使用Filon积分(包括自适应Filon) const MYREAL dk=fabs(PI2/(Length*rmax)); // 波数积分间隔 const MYREAL filondk = (filonLength > RZERO) ? PI2/(filonLength*rmax) : RZERO; // Filon积分间隔 const MYREAL filonK = filonCut/rmax; // 波数积分和Filon积分的分割点 @@ -162,16 +164,26 @@ void integ_static_grn( // 常规的波数积分 k = discrete_integ( - mod1d, dk, (filondk > RZERO)? filonK : kmax, keps, 0.0, nr, rs, + mod1d, dk, (useFIM)? filonK : kmax, keps, 0.0, nr, rs, sum_J, calc_upar, sum_uiz_J, sum_uir_J, fstats, static_kernel, &inv_stats); // 基于线性插值的Filon积分 - if(filondk > RZERO){ - k = linear_filon_integ( - mod1d, k, dk, filondk, kmax, keps, 0.0, nr, rs, - sum_J, calc_upar, sum_uiz_J, sum_uir_J, - fstats, static_kernel, &inv_stats); + if(useFIM){ + if(filondk > RZERO){ + // 基于线性插值的Filon积分,固定采样间隔 + k = linear_filon_integ( + mod1d, k, dk, filondk, kmax, keps, 0.0, nr, rs, + sum_J, calc_upar, sum_uiz_J, sum_uir_J, + fstats, static_kernel, &inv_stats); + } + else if(safilonTol > RZERO){ + // 基于自适应采样的Filon积分 + k = sa_filon_integ( + mod1d, kmax, k, dk, safilonTol, kmax, 0.0, nr, rs, + sum_J, calc_upar, sum_uiz_J, sum_uir_J, + fstats, static_kernel, &inv_stats); + } } // k之后的部分使用峰谷平均法进行显式收敛,建议在浅源地震的时候使用 diff --git a/pygrt/C_extension/src/static/stgrt_main.c b/pygrt/C_extension/src/static/stgrt_main.c index 133aa035..bcb95f25 100644 --- a/pygrt/C_extension/src/static/stgrt_main.c +++ b/pygrt/C_extension/src/static/stgrt_main.c @@ -23,9 +23,9 @@ #include "common/iostats.h" #include "common/search.h" -static char *command; -static PYMODEL1D *pymod; -static double depsrc, deprcv; +extern char *optarg; +extern int optind; +extern int optopt; //****************** 在该文件以内的全局变量 ***********************// // 命令名称 @@ -38,8 +38,8 @@ static double vmax, vmin; // 震源和场点深度 static double depsrc, deprcv; static char *s_depsrc = NULL, *s_deprcv = NULL; -// 波数积分间隔, Filon积分间隔,Filon积分起始点 -static double Length=0.0, filonLength=0.0, filonCut=0.0; +// 波数积分间隔, Filon积分间隔,自适应Filon积分采样精度,Filon积分起始点 +static double Length=0.0, filonLength=0.0, safilonTol=0.0, filonCut=0.0; static double Length0=15.0; // 默认Length // 波数积分相关变量 static double keps=-1.0, k0=5.0; @@ -113,7 +113,7 @@ printf("\n" " : end coordinate (km).\n" " : number of points.\n" "\n" -" -L[//]\n" +" -L[a][//]\n" " Define the wavenumber integration interval\n" " dk=(2*PI)/(*rmax). rmax is the maximum \n" " epicentral distance. \n" @@ -126,6 +126,9 @@ printf("\n" " into two parts, [0, k*] and [k*, kmax], \n" " in which k*=/rmax, and use DWM with\n" " and FIM with , respectively.\n" +" + manually set three POSITIVE values, with -La,\n" +" in this case, will be for Self-\n" +" Adaptive FIM.\n" "\n" " -V \n" " (Inherited from the dynamic case, and the numerical\n" @@ -247,11 +250,19 @@ static void getopt_from_command(int argc, char **argv){ } break; - // 波数积分间隔 -L[//] + // 波数积分间隔 -L[a][//] case 'L': L_flag = 1; { - int n = sscanf(optarg, "%lf/%lf/%lf", &Length, &filonLength, &filonCut); + // 检查首字母是否为a,表明使用自适应Filon积分 + int pos=0; + bool useSAFIM = false; + if(optarg[0] == 'a'){ + pos++; + useSAFIM = true; + } + double filona = 0.0; + int n = sscanf(optarg+pos, "%lf/%lf/%lf", &Length, &filona, &filonCut); if(n != 1 && n != 3){ fprintf(stderr, "[%s] " BOLD_RED "Error in -L.\n" DEFAULT_RESTORE, command); exit(EXIT_FAILURE); @@ -260,10 +271,17 @@ static void getopt_from_command(int argc, char **argv){ fprintf(stderr, "[%s] " BOLD_RED "Error! In -L, length should be positive.\n" DEFAULT_RESTORE, command); exit(EXIT_FAILURE); } - if(n == 3 && (filonLength <= 0 || filonCut < 0)){ - fprintf(stderr, "[%s] " BOLD_RED "Error! In -L, Flength should be positive, Fcut should be nonnegative.\n" DEFAULT_RESTORE, command); + if(n == 3 && (filona <= 0 || filonCut < 0)){ + fprintf(stderr, "[%s] " BOLD_RED "Error! In -L, Flength/Ftol should be positive, Fcut should be nonnegative.\n" DEFAULT_RESTORE, command); exit(EXIT_FAILURE); } + if(n == 3){ + if(useSAFIM){ + safilonTol = filona; + } else { + filonLength = filona; + } + } } break; @@ -514,7 +532,7 @@ int main(int argc, char **argv){ //============================================================================== // 计算静态格林函数 integ_static_grn( - pymod, nr, rs, vmin_ref, keps, k0, Length, filonLength, filonCut, + pymod, nr, rs, vmin_ref, keps, k0, Length, filonLength, safilonTol, filonCut, grn, calc_upar, grn_uiz, grn_uir, s_statsdir ); diff --git a/pygrt/c_interfaces.py b/pygrt/c_interfaces.py index e596e76b..22e9d4cf 100755 --- a/pygrt/c_interfaces.py +++ b/pygrt/c_interfaces.py @@ -32,7 +32,7 @@ C_integ_grn_spec.argtypes = [ POINTER(c_PyModel1D), c_int, c_int, PREAL, c_int, PREAL, REAL, - REAL, REAL, REAL, REAL, REAL, REAL, REAL, + REAL, REAL, REAL, REAL, REAL, REAL, REAL, REAL, c_bool, POINTER((PCPLX*CHANNEL_NUM)*SRC_M_NUM), @@ -54,7 +54,7 @@ C_integ_static_grn.restype = None C_integ_static_grn.argtypes = [ POINTER(c_PyModel1D), c_int, PREAL, REAL, REAL, REAL, REAL, - REAL, REAL, + REAL, REAL, REAL, POINTER((REAL*CHANNEL_NUM)*SRC_M_NUM), c_bool, POINTER((REAL*CHANNEL_NUM)*SRC_M_NUM), diff --git a/pygrt/pymod.py b/pygrt/pymod.py index 0d90f827..89901de0 100755 --- a/pygrt/pymod.py +++ b/pygrt/pymod.py @@ -143,7 +143,9 @@ def compute_grn( ampk:float=1.15, k0:float=5.0, Length:float=0.0, - filonLC:Union[np.ndarray,List[float]]=[0.0,0.0], + filonLength:float=0.0, + safilonTol:float=0.0, + filonCut:float=0.0, delayT0:float=0.0, delayV0:float=0.0, calc_upar:bool=False, @@ -172,7 +174,9 @@ def compute_grn( :param k0: 波数k积分的上限 :math:`\tilde{k_{max}}=\sqrt{(k_{0}*\pi/hs)^2 + (ampk*w/vmin_{ref})^2}` , 波数k积分循环必须退出, hs=max(震源和台站深度差,1.0) :param Length: 定义波数k积分的间隔 `dk=2\pi / (L*rmax)`, 选取要求见 :ref:`(Bouchon, 1981) ` :ref:`(张海明, 2021) `,默认自动选择 - :param filonLC: Filon积分的间隔 filonLength, 和波数积分和Filon积分的分割点filonCut, k*=/rmax + :param filonLength: Filon积分的间隔 + :param safilonTol: 自适应Filon积分采样精度 + :param filonCut: 波数积分和Filon积分的分割点filonCut, k*=/rmax :param calc_upar: 是否计算位移u的空间导数 :param gf_source: 待计算的震源类型 :param statsfile: 波数k积分(包括Filon积分和峰谷平均法)的过程记录文件,常用于debug或者观察积分过程中 :math:`F(k,\omega)` 和 :math:`F(k,\omega)J_m(kr)k` 的变化 @@ -211,11 +215,17 @@ def compute_grn( if Length < 0.0: raise ValueError(f"Length ({Length}) < 0") - if np.any(filonLC) < 0.0: - raise ValueError(f"filonLC ({filonLC}) < 0") + if filonLength < 0.0: + raise ValueError(f"filonLength ({filonLength}) < 0") + if filonCut < 0.0: + raise ValueError(f"filonCut ({filonCut}) < 0") + if safilonTol < 0.0: + raise ValueError(f"filonCut ({safilonTol}) < 0") + + # 只能设置一种filon积分方法 + if safilonTol > 0.0 and filonLength > 0.0: + raise ValueError(f"You should only set one of filonLength and safilonTol.") - filonLC = np.array(filonLC).astype(NPCT_REAL_TYPE) - nf = nt//2+1 df = 1/(nt*dt) fnyq = 1/(2*dt) @@ -322,8 +332,10 @@ def compute_grn( else: print("") print(f"Length={abs(Length)}", end="") - if filonLC[0] > 0.0: - print(f",{filonLC}, using FIM.") + if filonLength > 0.0: + print(f",{filonLength},{filonCut}, using FIM.") + elif safilonTol > 0.0: + print(f",{safilonTol},{filonCut}, using SAFIM.") else: print("") print(f"nt={nt}") @@ -354,7 +366,7 @@ def compute_grn( #================================================================================= C_integ_grn_spec( self.c_pymod1d, nf1, nf2, c_freqs, nrs, c_rs, wI, - vmin_ref, keps, ampk, k0, Length, filonLC[0], filonLC[1], print_runtime, + vmin_ref, keps, ampk, k0, Length, filonLength, safilonTol, filonCut, print_runtime, c_grnArr, calc_upar, c_grnArr_uiz, c_grnArr_uir, c_statsfile, nstatsidxs, c_statsidxs ) @@ -434,7 +446,9 @@ def compute_static_grn( keps:float=-1.0, k0:float=5.0, Length:float=15.0, - filonLC:Union[np.ndarray,List[float]]=[0.0,0.0], + filonLength:float=0.0, + safilonTol:float=0.0, + filonCut:float=0.0, calc_upar:bool=False, statsfile:Union[str,None]=None): @@ -449,7 +463,9 @@ def compute_static_grn( 为负数代表不提前判断收敛,按照波数积分上限进行积分 :param k0: 波数k积分的上限 :math:`\tilde{k_{max}}=(k_{0}*\pi/hs)^2` , 波数k积分循环必须退出, hs=max(震源和台站深度差,1.0) :param Length: 定义波数k积分的间隔 `dk=2\pi / (L*rmax)`, 默认15;负数表示使用Filon积分 - :param filonLC: Filon积分的间隔 filonLength, 和波数积分和Filon积分的分割点filonCut, k*=/rmax + :param filonLength: Filon积分的间隔 + :param safilonTol: 自适应Filon积分采样精度 + :param filonCut: 波数积分和Filon积分的分割点filonCut, k*=/rmax :param calc_upar: 是否计算位移u的空间导数 :param statsfile: 波数k积分(包括Filon积分和峰谷平均法)的过程记录文件,常用于debug或者观察积分过程中 :math:`F(k,\omega)` 和 :math:`F(k,\omega)J_m(kr)k` 的变化 @@ -459,8 +475,16 @@ def compute_static_grn( if Length < 0.0: raise ValueError(f"Length ({Length}) < 0") - if np.any(filonLC) < 0.0: - raise ValueError(f"filonLC ({filonLC}) < 0") + if filonLength < 0.0: + raise ValueError(f"filonLength ({filonLength}) < 0") + if filonCut < 0.0: + raise ValueError(f"filonCut ({filonCut}) < 0") + if safilonTol < 0.0: + raise ValueError(f"filonCut ({safilonTol}) < 0") + + # 只能设置一种filon积分方法 + if safilonTol > 0.0 and filonLength > 0.0: + raise ValueError(f"You should only set one of filonLength and safilonTol.") depsrc = self.depsrc @@ -516,7 +540,7 @@ def compute_static_grn( # 剪切源 DD[ZR],DS[ZRT],SS[ZRT] 1e-20 cm/(dyne*cm) #================================================================================= C_integ_static_grn( - self.c_pymod1d, nr, c_rs, vmin_ref, keps, k0, Length, filonLC[0], filonLC[1], + self.c_pymod1d, nr, c_rs, vmin_ref, keps, k0, Length, filonLength, safilonTol, filonCut, c_pygrn, calc_upar, c_pygrn_uiz, c_pygrn_uir, c_statsfile ) diff --git a/pygrt/utils.py b/pygrt/utils.py index cf9f9e9a..b10dcab9 100755 --- a/pygrt/utils.py +++ b/pygrt/utils.py @@ -1438,6 +1438,10 @@ def plot_statsdata(statsdata:np.ndarray, dist:float, srctype:str, ptype:str, Ror karr = statsdata['k'] dk = (karr[1] - karr[0]) # 假设均匀dk + is_evendk = np.allclose(np.diff(karr), dk, atol=1e-10) # 是否为均匀dk + if not is_evendk: + raise ValueError("Sorry, this function only supports even-distributed k.") + if 0.5*np.pi/dk < dist: # 对于bessel函数这种震荡函数,假设一个周期内至少取4个点 print(f"WARNING! dist ({dist}) > PI/(2*dk) ({0.5*np.pi/dk:.5e}.)") @@ -1530,6 +1534,10 @@ def plot_statsdata_ptam(statsdata1:np.ndarray, statsdata2:np.ndarray, statsdata_ dk2 = karr2[1] - karr2[0] Fname, Farr2, FJname, FJarr2 = _get_stats_Fname(statsdata2, karr2, dist, srctype, ptype) + is_evendk = np.allclose(np.diff(karr1), dk1, atol=1e-10) and np.allclose(np.diff(karr2), dk2, atol=1e-10) # 是否为均匀dk + if not is_evendk: + raise ValueError("Sorry, this function only supports even-distributed k.") + # 将两个过程的结果拼起来 Farr = np.hstack((Farr1, Farr2)) karr = np.hstack((karr1, karr2)) From 978864c0e61136cd6962a2f1a6b49d4441260767 Mon Sep 17 00:00:00 2001 From: Dengda98 Date: Mon, 5 May 2025 17:33:15 +0800 Subject: [PATCH 23/25] FIX: extract c_pymod in python --- pygrt/pymod.py | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/pygrt/pymod.py b/pygrt/pymod.py index 89901de0..e25e337e 100755 --- a/pygrt/pymod.py +++ b/pygrt/pymod.py @@ -42,7 +42,6 @@ def __init__(self, modarr0:np.ndarray, depsrc:float, deprcv:float): :param deprcv: 台站深度(km) ''' - self.modarr:np.ndarray = modarr0.copy() self.depsrc:float = depsrc self.deprcv:float = deprcv self.c_pymod1d:c_PyModel1D @@ -63,8 +62,10 @@ def __init__(self, modarr0:np.ndarray, depsrc:float, deprcv:float): self.isrc = self.c_pymod1d.isrc self.ircv = self.c_pymod1d.ircv - self.vmax = np.max(self.modarr[:, 1:3]) - self.vmin = np.min(self.modarr[:, 1:3]) + va = npct.as_array(self.c_pymod1d.Va, (self.c_pymod1d.n,)) + vb = npct.as_array(self.c_pymod1d.Vb, (self.c_pymod1d.n,)) + self.vmin = min(np.min(va), np.min(vb)) + self.vmax = max(np.max(va), np.max(vb)) def compute_travt1d(self, dist:float): @@ -374,14 +375,14 @@ def compute_grn( #///////////////////////////////////////////////////////////////////////////////// # 震源和场点层的物性,写入sac头段变量 - rcv_va = self.modarr[self.ircv, 1] - rcv_vb = self.modarr[self.ircv, 2] - rcv_rho = self.modarr[self.ircv, 3] - rcv_qainv = 1.0/self.modarr[self.ircv, 4] - rcv_qbinv = 1.0/self.modarr[self.ircv, 5] - src_va = self.modarr[self.isrc, 1] - src_vb = self.modarr[self.isrc, 2] - src_rho = self.modarr[self.isrc, 3] + rcv_va = self.c_pymod1d.Va[self.ircv] + rcv_vb = self.c_pymod1d.Vb[self.ircv] + rcv_rho = self.c_pymod1d.Rho[self.ircv] + rcv_qainv = 1.0/self.c_pymod1d.Qa[self.ircv] + rcv_qbinv = 1.0/self.c_pymod1d.Qb[self.ircv] + src_va = self.c_pymod1d.Va[self.isrc] + src_vb = self.c_pymod1d.Vb[self.isrc] + src_rho = self.c_pymod1d.Rho[self.isrc] # 对应实际采集的地震信号,取向上为正(和理论推导使用的方向相反) dataLst = [] @@ -548,12 +549,12 @@ def compute_static_grn( #///////////////////////////////////////////////////////////////////////////////// # 震源和场点层的物性 - rcv_va = self.modarr[self.ircv, 1] - rcv_vb = self.modarr[self.ircv, 2] - rcv_rho = self.modarr[self.ircv, 3] - src_va = self.modarr[self.isrc, 1] - src_vb = self.modarr[self.isrc, 2] - src_rho = self.modarr[self.isrc, 3] + rcv_va = self.c_pymod1d.Va[self.ircv] + rcv_vb = self.c_pymod1d.Vb[self.ircv] + rcv_rho = self.c_pymod1d.Rho[self.ircv] + src_va = self.c_pymod1d.Va[self.isrc] + src_vb = self.c_pymod1d.Vb[self.isrc] + src_rho = self.c_pymod1d.Rho[self.isrc] # 结果字典 dataDct = {} From ec3bfd089ff25cb5a6d5e2d3c3825fe9465156fa Mon Sep 17 00:00:00 2001 From: Dengda98 Date: Mon, 5 May 2025 17:33:54 +0800 Subject: [PATCH 24/25] TEST: add far_field example using SAFIM --- example/far_field/milrow | 9 +++++++++ example/far_field/run.py | 19 +++++++++++++++++++ example/far_field/run.sh | 3 +++ 3 files changed, 31 insertions(+) create mode 100644 example/far_field/milrow create mode 100644 example/far_field/run.py create mode 100755 example/far_field/run.sh diff --git a/example/far_field/milrow b/example/far_field/milrow new file mode 100644 index 00000000..390e1985 --- /dev/null +++ b/example/far_field/milrow @@ -0,0 +1,9 @@ +0.2 3.4 1.7 2.3 9e10 9e10 +0.6 3.7 1.9 2.4 9e10 9e10 +0.5 4.2 2.1 2.4 9e10 9e10 +0.5 4.6 2.3 2.5 9e10 9e10 +0.7 4.9 2.8 2.6 9e10 9e10 +0.5 5.1 2.9 2.7 9e10 9e10 +6.0 5.9 3.3 2.7 9e10 9e10 +28. 6.9 4.0 2.8 9e10 9e10 +0.0 8.2 4.7 3.2 9e10 9e10 diff --git a/example/far_field/run.py b/example/far_field/run.py new file mode 100644 index 00000000..f504a0ea --- /dev/null +++ b/example/far_field/run.py @@ -0,0 +1,19 @@ +import numpy as np +import matplotlib.pyplot as plt +import pygrt + + +modarr = np.loadtxt("milrow") + +pymod = pygrt.PyModel1D(modarr, 10, 0) + +st_grn = pymod.compute_grn( + distarr=[1800], + nt=1400, + dt=1, + Length=20, + safilonTol=1e-2, + delayT0=100, +)[0] + +st_grn.plot(equal_scale=False, outfile='test.pdf') \ No newline at end of file diff --git a/example/far_field/run.sh b/example/far_field/run.sh new file mode 100755 index 00000000..d781d363 --- /dev/null +++ b/example/far_field/run.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +grt -Mmilrow -OGRN -N1400/1 -D10/0 -R1800 -La20/1e-2/0 -E100 -S-1 # -G0/1/1/0 From 3a857e20a47601a64eea8092e1996fc7ee636735 Mon Sep 17 00:00:00 2001 From: Dengda98 Date: Mon, 5 May 2025 17:38:46 +0800 Subject: [PATCH 25/25] CI: add far field test --- .github/workflows/build.yml | 7 +++++++ .github/workflows/testbuild.yml | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index abf3143f..1d53af92 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -318,6 +318,13 @@ jobs: ./run1.sh python run2.py + - name: Test far field using SAFIM + working-directory: ${{ env.EXAMPLE_COPY_PATH }}/far_field + run: | + chmod +x *.sh + ./run.sh + python run.py + - name: Test strain stress (dynamic) working-directory: ${{ env.EXAMPLE_COPY_PATH }}/compute_strain_stress/dynamic run: | diff --git a/.github/workflows/testbuild.yml b/.github/workflows/testbuild.yml index 4689f6c5..61fc3da6 100644 --- a/.github/workflows/testbuild.yml +++ b/.github/workflows/testbuild.yml @@ -250,6 +250,13 @@ jobs: ./run_grt.sh python run_pygrt.py + - name: Test far field using SAFIM + working-directory: ${{ env.EXAMPLE_COPY_PATH }}/far_field + run: | + chmod +x *.sh + ./run.sh + python run.py + # - name: Test 2 site_effect # working-directory: ${{ env.EXAMPLE_COPY_PATH }}/site_effect # run: |