/******************************************************** * ██████╗ ██████╗████████╗██╗ * ██╔════╝ ██╔════╝╚══██╔══╝██║ * ██║ ███╗██║ ██║ ██║ * ██║ ██║██║ ██║ ██║ * ╚██████╔╝╚██████╗ ██║ ███████╗ * ╚═════╝ ╚═════╝ ╚═╝ ╚══════╝ * Geophysical Computational Tools & Library (GCTL) * * Copyright (c) 2022 Yi Zhang (yizhang-geo@zju.edu.cn) * * GCTL is distributed under a dual licensing scheme. You can redistribute * it and/or modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation, either version 2 * of the License, or (at your option) any later version. You should have * received a copy of the GNU Lesser General Public License along with this * program. If not, see . * * If the terms and conditions of the LGPL v.2. would prevent you from using * the GCTL, please consider the option to obtain a commercial license for a * fee. These licenses are offered by the GCTL's original author. As a rule, * licenses are provided "as-is", unlimited in time for a one time fee. Please * send corresponding requests to: yizhang-geo@zju.edu.cn. Please do not forget * to include some description of your company and the realm of its activities. * Also add information on how to contact you by electronic and paper mail. ******************************************************/ #include "gkernel_tesseroid.h" #ifdef GCTL_POTENTIAL_TESS extern "C" { #include "tess/glq.h" #include "tess/constants.h" #include "tess/geometry.h" #include "tess/grav_tess.h" } typedef void (*gkernel_tess_ptr)(gctl::matrix &out_kernel, const gctl::array &ele, const gctl::array &ops, gctl::verbose_type_e verbose); void gkernel_tesseroid_pot(gctl::matrix &out_kernel, const gctl::array &ele, const gctl::array &ops, gctl::verbose_type_e verbose); void gkernel_tesseroid_vr(gctl::matrix &out_kernel, const gctl::array &ele, const gctl::array &ops, gctl::verbose_type_e verbose); void gkernel_tesseroid_vrp(gctl::matrix &out_kernel, const gctl::array &ele, const gctl::array &ops, gctl::verbose_type_e verbose); void gkernel_tesseroid_vrt(gctl::matrix &out_kernel, const gctl::array &ele, const gctl::array &ops, gctl::verbose_type_e verbose); void gkernel_tesseroid_vrr(gctl::matrix &out_kernel, const gctl::array &ele, const gctl::array &ops, gctl::verbose_type_e verbose); void gctl::gkernel(matrix &out_kernel, const array &ele, const array &ops, gravitational_field_type_e comp_id, verbose_type_e verbose) { gkernel_tess_ptr tesseroid_kernel; switch (comp_id) { case GravPot: tesseroid_kernel = gkernel_tesseroid_pot; break; case Vz: tesseroid_kernel = gkernel_tesseroid_vr; break; case Tzx: tesseroid_kernel = gkernel_tesseroid_vrp; break; case Tzy: tesseroid_kernel = gkernel_tesseroid_vrt; break; case Tzz: tesseroid_kernel = gkernel_tesseroid_vrr; break; default: tesseroid_kernel = gkernel_tesseroid_vr; break; } return tesseroid_kernel(out_kernel, ele, ops, verbose); } typedef void (*gobser_tess_ptr)(gctl::array &out_obs, const gctl::array &ele, const gctl::array &ops, const gctl::array &rho, gctl::verbose_type_e verbose); void gobser_tesseroid_pot(gctl::array &out_obs, const gctl::array &ele, const gctl::array &ops, const gctl::array &rho, gctl::verbose_type_e verbose); void gobser_tesseroid_vr(gctl::array &out_obs, const gctl::array &ele, const gctl::array &ops, const gctl::array &rho, gctl::verbose_type_e verbose); void gobser_tesseroid_vrp(gctl::array &out_obs, const gctl::array &ele, const gctl::array &ops, const gctl::array &rho, gctl::verbose_type_e verbose); void gobser_tesseroid_vrt(gctl::array &out_obs, const gctl::array &ele, const gctl::array &ops, const gctl::array &rho, gctl::verbose_type_e verbose); void gobser_tesseroid_vrr(gctl::array &out_obs, const gctl::array &ele, const gctl::array &ops, const gctl::array &rho, gctl::verbose_type_e verbose); void gctl::gobser(array &out_obs, const array &ele, const array &ops, const array &rho, gravitational_field_type_e comp_id, verbose_type_e verbose) { gobser_tess_ptr tesseroid_obser; switch (comp_id) { case GravPot: tesseroid_obser = gobser_tesseroid_pot; break; case Vz: tesseroid_obser = gobser_tesseroid_vr; break; case Tzx: tesseroid_obser = gobser_tesseroid_vrp; break; case Tzy: tesseroid_obser = gobser_tesseroid_vrt; break; case Tzz: tesseroid_obser = gobser_tesseroid_vrr; break; default: tesseroid_obser = gobser_tesseroid_vr; break; } return tesseroid_obser(out_obs, ele, ops, rho, verbose); } // 以下是具体的实现 void gkernel_tesseroid_pot(gctl::matrix &out_kernel, const gctl::array &ele, const gctl::array &ops, gctl::verbose_type_e verbose) { int i, j; int o_size = ops.size(); int e_size = ele.size(); out_kernel.resize(o_size, e_size); TESSEROID tess; GLQ *glqlon, *glqlat, *glqr; glqlon = glq_new(2, -1, 1); // 暂时固定使用2阶高斯积分 glqlat = glq_new(2, -1, 1); glqr = glq_new(2, -1, 1); gctl::progress_bar bar(e_size, "gkernel_pot"); for (j = 0; j < e_size; j++) { if (verbose == gctl::FullMsg) bar.progressed(j); else if (verbose == gctl::ShortMsg) bar.progressed_simple(j); tess.density = 1000.0; // unit density tess.w = ele[j].dl->lon; tess.e = ele[j].ur->lon; tess.s = ele[j].dl->lat; tess.n = ele[j].ur->lat; tess.r1 = ele[j].dl->rad; tess.r2 = ele[j].ur->rad; //#pragma omp parallel for private(i) schedule(guided) for (i = 0; i < o_size; i++) { out_kernel[i][j] = calc_tess_model_adapt(&tess, 1, ops[i].lon, ops[i].lat, ops[i].rad, glqlon, glqlat, glqr, tess_pot, TESSEROID_GZ_SIZE_RATIO); } } glq_free(glqlon); glq_free(glqlat); glq_free(glqr); return; } void gkernel_tesseroid_vr(gctl::matrix &out_kernel, const gctl::array &ele, const gctl::array &ops, gctl::verbose_type_e verbose) { int i, j; int o_size = ops.size(); int e_size = ele.size(); out_kernel.resize(o_size, e_size); TESSEROID tess; GLQ *glqlon, *glqlat, *glqr; glqlon = glq_new(2, -1, 1); // 暂时固定使用2阶高斯积分 glqlat = glq_new(2, -1, 1); glqr = glq_new(2, -1, 1); gctl::progress_bar bar(e_size, "gkernel_vr"); for (j = 0; j < e_size; j++) { if (verbose == gctl::FullMsg) bar.progressed(j); else if (verbose == gctl::ShortMsg) bar.progressed_simple(j); tess.density = 1000.0; // unit density tess.w = ele[j].dl->lon; tess.e = ele[j].ur->lon; tess.s = ele[j].dl->lat; tess.n = ele[j].ur->lat; tess.r1 = ele[j].dl->rad; tess.r2 = ele[j].ur->rad; //#pragma omp parallel for private(i) schedule(guided) for (i = 0; i < o_size; i++) { out_kernel[i][j] = calc_tess_model_adapt(&tess, 1, ops[i].lon, ops[i].lat, ops[i].rad, glqlon, glqlat, glqr, tess_gz, TESSEROID_GZ_SIZE_RATIO); } } glq_free(glqlon); glq_free(glqlat); glq_free(glqr); return; } void gkernel_tesseroid_vrp(gctl::matrix &out_kernel, const gctl::array &ele, const gctl::array &ops, gctl::verbose_type_e verbose) { int i, j; int o_size = ops.size(); int e_size = ele.size(); out_kernel.resize(o_size, e_size); TESSEROID tess; GLQ *glqlon, *glqlat, *glqr; glqlon = glq_new(2, -1, 1); // 暂时固定使用2阶高斯积分 glqlat = glq_new(2, -1, 1); glqr = glq_new(2, -1, 1); gctl::progress_bar bar(e_size, "gkernel_vrp"); for (j = 0; j < e_size; j++) { if (verbose == gctl::FullMsg) bar.progressed(j); else if (verbose == gctl::ShortMsg) bar.progressed_simple(j); tess.density = 1000.0; // unit density tess.w = ele[j].dl->lon; tess.e = ele[j].ur->lon; tess.s = ele[j].dl->lat; tess.n = ele[j].ur->lat; tess.r1 = ele[j].dl->rad; tess.r2 = ele[j].ur->rad; //#pragma omp parallel for private(i) schedule(guided) for (i = 0; i < o_size; i++) { out_kernel[i][j] = calc_tess_model_adapt(&tess, 1, ops[i].lon, ops[i].lat, ops[i].rad, glqlon, glqlat, glqr, tess_gyz, TESSEROID_GYZ_SIZE_RATIO); } } glq_free(glqlon); glq_free(glqlat); glq_free(glqr); return; } void gkernel_tesseroid_vrt(gctl::matrix &out_kernel, const gctl::array &ele, const gctl::array &ops, gctl::verbose_type_e verbose) { int i, j; int o_size = ops.size(); int e_size = ele.size(); out_kernel.resize(o_size, e_size); TESSEROID tess; GLQ *glqlon, *glqlat, *glqr; glqlon = glq_new(2, -1, 1); // 暂时固定使用2阶高斯积分 glqlat = glq_new(2, -1, 1); glqr = glq_new(2, -1, 1); gctl::progress_bar bar(e_size, "gkernel_vrt"); for (j = 0; j < e_size; j++) { if (verbose == gctl::FullMsg) bar.progressed(j); else if (verbose == gctl::ShortMsg) bar.progressed_simple(j); tess.density = 1000.0; // unit density tess.w = ele[j].dl->lon; tess.e = ele[j].ur->lon; tess.s = ele[j].dl->lat; tess.n = ele[j].ur->lat; tess.r1 = ele[j].dl->rad; tess.r2 = ele[j].ur->rad; //#pragma omp parallel for private(i) schedule(guided) for (i = 0; i < o_size; i++) { out_kernel[i][j] = calc_tess_model_adapt(&tess, 1, ops[i].lon, ops[i].lat, ops[i].rad, glqlon, glqlat, glqr, tess_gxz, TESSEROID_GXZ_SIZE_RATIO); } } glq_free(glqlon); glq_free(glqlat); glq_free(glqr); return; } void gkernel_tesseroid_vrr(gctl::matrix &out_kernel, const gctl::array &ele, const gctl::array &ops, gctl::verbose_type_e verbose) { int i, j; int o_size = ops.size(); int e_size = ele.size(); out_kernel.resize(o_size, e_size); TESSEROID tess; GLQ *glqlon, *glqlat, *glqr; glqlon = glq_new(2, -1, 1); // 暂时固定使用2阶高斯积分 glqlat = glq_new(2, -1, 1); glqr = glq_new(2, -1, 1); gctl::progress_bar bar(e_size, "gkernel_vrr"); for (j = 0; j < e_size; j++) { if (verbose == gctl::FullMsg) bar.progressed(j); else if (verbose == gctl::ShortMsg) bar.progressed_simple(j); tess.density = 1000.0; // unit density tess.w = ele[j].dl->lon; tess.e = ele[j].ur->lon; tess.s = ele[j].dl->lat; tess.n = ele[j].ur->lat; tess.r1 = ele[j].dl->rad; tess.r2 = ele[j].ur->rad; //#pragma omp parallel for private(i) schedule(guided) for (i = 0; i < o_size; i++) { out_kernel[i][j] = calc_tess_model_adapt(&tess, 1, ops[i].lon, ops[i].lat, ops[i].rad, glqlon, glqlat, glqr, tess_gzz, TESSEROID_GZZ_SIZE_RATIO); } } glq_free(glqlon); glq_free(glqlat); glq_free(glqr); return; } void gobser_tesseroid_pot(gctl::array &out_obs, const gctl::array &ele, const gctl::array &ops, const gctl::array &rho, gctl::verbose_type_e verbose) { int i, j; int o_size = ops.size(); int e_size = ele.size(); out_obs.resize(o_size, 0.0); TESSEROID tess; GLQ *glqlon, *glqlat, *glqr; glqlon = glq_new(2, -1, 1); // 暂时固定使用2阶高斯积分 glqlat = glq_new(2, -1, 1); glqr = glq_new(2, -1, 1); gctl::progress_bar bar(o_size, "gobser_pot"); for (j = 0; j < e_size; j++) { if (verbose == gctl::FullMsg) bar.progressed(j); else if (verbose == gctl::ShortMsg) bar.progressed_simple(j); tess.density = 1000.0*rho[j]; tess.w = ele[j].dl->lon; tess.e = ele[j].ur->lon; tess.s = ele[j].dl->lat; tess.n = ele[j].ur->lat; tess.r1 = ele[j].dl->rad; tess.r2 = ele[j].ur->rad; //#pragma omp parallel for private(i) schedule(guided) for (i = 0; i < o_size; i++) { out_obs[i] += calc_tess_model_adapt(&tess, 1, ops[i].lon, ops[i].lat, ops[i].rad, glqlon, glqlat, glqr, tess_gz, TESSEROID_GZ_SIZE_RATIO); } } glq_free(glqlon); glq_free(glqlat); glq_free(glqr); return; } void gobser_tesseroid_vr(gctl::array &out_obs, const gctl::array &ele, const gctl::array &ops, const gctl::array &rho, gctl::verbose_type_e verbose) { int i, j; int o_size = ops.size(); int e_size = ele.size(); out_obs.resize(o_size, 0.0); TESSEROID tess; GLQ *glqlon, *glqlat, *glqr; glqlon = glq_new(2, -1, 1); // 暂时固定使用2阶高斯积分 glqlat = glq_new(2, -1, 1); glqr = glq_new(2, -1, 1); gctl::progress_bar bar(o_size, "gobser_vr"); for (j = 0; j < e_size; j++) { if (verbose == gctl::FullMsg) bar.progressed(j); else if (verbose == gctl::ShortMsg) bar.progressed_simple(j); tess.density = 1000.0*rho[j]; tess.w = ele[j].dl->lon; tess.e = ele[j].ur->lon; tess.s = ele[j].dl->lat; tess.n = ele[j].ur->lat; tess.r1 = ele[j].dl->rad; tess.r2 = ele[j].ur->rad; //#pragma omp parallel for private(i) schedule(guided) for (i = 0; i < o_size; i++) { out_obs[i] += calc_tess_model_adapt(&tess, 1, ops[i].lon, ops[i].lat, ops[i].rad, glqlon, glqlat, glqr, tess_gz, TESSEROID_GZ_SIZE_RATIO); } } glq_free(glqlon); glq_free(glqlat); glq_free(glqr); return; } void gobser_tesseroid_vrp(gctl::array &out_obs, const gctl::array &ele, const gctl::array &ops, const gctl::array &rho, gctl::verbose_type_e verbose) { int i, j; int o_size = ops.size(); int e_size = ele.size(); out_obs.resize(o_size, 0.0); TESSEROID tess; GLQ *glqlon, *glqlat, *glqr; glqlon = glq_new(2, -1, 1); // 暂时固定使用2阶高斯积分 glqlat = glq_new(2, -1, 1); glqr = glq_new(2, -1, 1); gctl::progress_bar bar(o_size, "gobser_vrp"); for (j = 0; j < e_size; j++) { if (verbose == gctl::FullMsg) bar.progressed(j); else if (verbose == gctl::ShortMsg) bar.progressed_simple(j); tess.density = 1000.0*rho[j]; tess.w = ele[j].dl->lon; tess.e = ele[j].ur->lon; tess.s = ele[j].dl->lat; tess.n = ele[j].ur->lat; tess.r1 = ele[j].dl->rad; tess.r2 = ele[j].ur->rad; //#pragma omp parallel for private(i) schedule(guided) for (i = 0; i < o_size; i++) { out_obs[i] += calc_tess_model_adapt(&tess, 1, ops[i].lon, ops[i].lat, ops[i].rad, glqlon, glqlat, glqr, tess_gyz, TESSEROID_GYZ_SIZE_RATIO); } } glq_free(glqlon); glq_free(glqlat); glq_free(glqr); return; } void gobser_tesseroid_vrt(gctl::array &out_obs, const gctl::array &ele, const gctl::array &ops, const gctl::array &rho, gctl::verbose_type_e verbose) { int i, j; int o_size = ops.size(); int e_size = ele.size(); out_obs.resize(o_size, 0.0); TESSEROID tess; GLQ *glqlon, *glqlat, *glqr; glqlon = glq_new(2, -1, 1); // 暂时固定使用2阶高斯积分 glqlat = glq_new(2, -1, 1); glqr = glq_new(2, -1, 1); gctl::progress_bar bar(o_size, "gobser_vrt"); for (j = 0; j < e_size; j++) { if (verbose == gctl::FullMsg) bar.progressed(j); else if (verbose == gctl::ShortMsg) bar.progressed_simple(j); tess.density = 1000.0*rho[j]; tess.w = ele[j].dl->lon; tess.e = ele[j].ur->lon; tess.s = ele[j].dl->lat; tess.n = ele[j].ur->lat; tess.r1 = ele[j].dl->rad; tess.r2 = ele[j].ur->rad; //#pragma omp parallel for private(i) schedule(guided) for (i = 0; i < o_size; i++) { out_obs[i] += calc_tess_model_adapt(&tess, 1, ops[i].lon, ops[i].lat, ops[i].rad, glqlon, glqlat, glqr, tess_gxz, TESSEROID_GXZ_SIZE_RATIO); } } glq_free(glqlon); glq_free(glqlat); glq_free(glqr); return; } void gobser_tesseroid_vrr(gctl::array &out_obs, const gctl::array &ele, const gctl::array &ops, const gctl::array &rho, gctl::verbose_type_e verbose) { int i, j; int o_size = ops.size(); int e_size = ele.size(); out_obs.resize(o_size, 0.0); TESSEROID tess; GLQ *glqlon, *glqlat, *glqr; glqlon = glq_new(2, -1, 1); // 暂时固定使用2阶高斯积分 glqlat = glq_new(2, -1, 1); glqr = glq_new(2, -1, 1); gctl::progress_bar bar(o_size, "gobser_vrr"); for (j = 0; j < e_size; j++) { if (verbose == gctl::FullMsg) bar.progressed(j); else if (verbose == gctl::ShortMsg) bar.progressed_simple(j); tess.density = 1000.0*rho[j]; tess.w = ele[j].dl->lon; tess.e = ele[j].ur->lon; tess.s = ele[j].dl->lat; tess.n = ele[j].ur->lat; tess.r1 = ele[j].dl->rad; tess.r2 = ele[j].ur->rad; //#pragma omp parallel for private(i) schedule(guided) for (i = 0; i < o_size; i++) { out_obs[i] += calc_tess_model_adapt(&tess, 1, ops[i].lon, ops[i].lat, ops[i].rad, glqlon, glqlat, glqr, tess_gzz, TESSEROID_GZZ_SIZE_RATIO); } } glq_free(glqlon); glq_free(glqlat); glq_free(glqr); return; } #endif // GCTL_POTENTIAL_TESS