/******************************************************** * ██████╗ ██████╗████████╗██╗ * ██╔════╝ ██╔════╝╚══██╔══╝██║ * ██║ ███╗██║ ██║ ██║ * ██║ ██║██║ ██║ ██║ * ╚██████╔╝╚██████╗ ██║ ███████╗ * ╚═════╝ ╚═════╝ ╚═╝ ╚══════╝ * 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_rectangle2d.h" #include "cmath" /** * @brief callback interface of the gravitational kernel of a rectangle element * * @param[in] out_kernel Output gravitational kernel. * @param[in] ele Element array. * @param[in] obsp observation point array. * @param[in] show_progress Show progress or not. * */ typedef void (*gkernel_rectangle_ptr)(gctl::matrix &out_kernel, const gctl::array &ele, const gctl::array &obsp, gctl::verbose_type_e verbose); void gkernel_rectangle_vz(gctl::matrix &out_kernel, const gctl::array &ele, const gctl::array &obsp, gctl::verbose_type_e verbose); void gkernel_rectangle_vzx(gctl::matrix &out_kernel, const gctl::array &ele, const gctl::array &obsp, gctl::verbose_type_e verbose); void gkernel_rectangle_vzz(gctl::matrix &out_kernel, const gctl::array &ele, const gctl::array &obsp, gctl::verbose_type_e verbose); /** * @brief Integrated callback function of the gravitational kernel of given elements type. * * @param out_kernel Output gravitational kernel * @param[in] ele element array * @param[in] obsp observation point array * @param[in] comp_id The component identifier * @param[in] show_progress Show progress or not */ void gctl::gkernel(matrix &out_kernel, const array &ele, const array &obsp, gravitational_field_type_e comp_id, verbose_type_e verbose) { gkernel_rectangle_ptr rectangle_kernel; switch (comp_id) { case Vz: rectangle_kernel = gkernel_rectangle_vz; break; case Tzx: rectangle_kernel = gkernel_rectangle_vzx; break; case Tzz: rectangle_kernel = gkernel_rectangle_vzz; break; default: rectangle_kernel = gkernel_rectangle_vz; break; } return rectangle_kernel(out_kernel, ele, obsp, verbose); } typedef void (*gobser_rectangle_ptr)(gctl::array &out_obs, const gctl::array &ele_ptr, const gctl::array &op_ptr, const gctl::array &rho_ptr, gctl::verbose_type_e verbose); void gobser_rectangle_vz(gctl::array &out_obs, const gctl::array &ele_ptr, const gctl::array &op_ptr, const gctl::array &rho_ptr, gctl::verbose_type_e verbose); void gobser_rectangle_vzx(gctl::array &out_obs, const gctl::array &ele_ptr, const gctl::array &op_ptr, const gctl::array &rho_ptr, gctl::verbose_type_e verbose); void gobser_rectangle_vzz(gctl::array &out_obs, const gctl::array &ele_ptr, const gctl::array &op_ptr, const gctl::array &rho_ptr, gctl::verbose_type_e verbose); void gctl::gobser(array &out_obs, const array &ele, const array &obsp, const array &rho, gravitational_field_type_e comp_id, verbose_type_e verbose) { gobser_rectangle_ptr rectangle_obser; switch (comp_id) { case Vz: rectangle_obser = gobser_rectangle_vz; break; case Tzx: rectangle_obser = gobser_rectangle_vzx; break; case Tzz: rectangle_obser = gobser_rectangle_vzz; break; default: rectangle_obser = gobser_rectangle_vz; break; } rectangle_obser(out_obs, ele, obsp, rho, verbose); return; } double gkernel_rectangle_vz_sig(gctl::rectangle2d *ele_ptr, gctl::point2dc *op_ptr); double gkernel_rectangle_vzx_sig(gctl::rectangle2d *ele_ptr, gctl::point2dc *op_ptr); double gkernel_rectangle_vzz_sig(gctl::rectangle2d *ele_ptr, gctl::point2dc *op_ptr); void gkernel_rectangle_vz(gctl::matrix &out_kernel, const gctl::array &ele, const gctl::array &obsp, gctl::verbose_type_e verbose) { int i, j; out_kernel.resize(obsp.size(), ele.size()); int o_size = obsp.size(); int e_size = ele.size(); gctl::progress_bar bar(o_size, "gkernel_vz"); for (i = 0; i < o_size; i++) { if (verbose == gctl::FullMsg) bar.progressed(i); else if (verbose == gctl::ShortMsg) bar.progressed_simple(i); for (j = 0; j < e_size; j++) { out_kernel.at(i, j) = gkernel_rectangle_vz_sig(ele.get(j), obsp.get(i)); } } return; } void gkernel_rectangle_vzx(gctl::matrix &out_kernel, const gctl::array &ele, const gctl::array &obsp, gctl::verbose_type_e verbose) { int i, j; out_kernel.resize(obsp.size(), ele.size()); int o_size = obsp.size(); int e_size = ele.size(); gctl::progress_bar bar(o_size, "gkernel_vzx"); for (i = 0; i < o_size; i++) { if (verbose == gctl::FullMsg) bar.progressed(i); else if (verbose == gctl::ShortMsg) bar.progressed_simple(i); for (j = 0; j < e_size; j++) { out_kernel.at(i, j) = gkernel_rectangle_vzx_sig(ele.get(j), obsp.get(i)); } } return; } void gkernel_rectangle_vzz(gctl::matrix &out_kernel, const gctl::array &ele, const gctl::array &obsp, gctl::verbose_type_e verbose) { int i, j; out_kernel.resize(obsp.size(), ele.size()); int o_size = obsp.size(); int e_size = ele.size(); gctl::progress_bar bar(o_size, "gkernel_vzz"); for (i = 0; i < o_size; i++) { if (verbose == gctl::FullMsg) bar.progressed(i); else if (verbose == gctl::ShortMsg) bar.progressed_simple(i); for (j = 0; j < e_size; j++) { out_kernel.at(i, j) = gkernel_rectangle_vzz_sig(ele.get(j), obsp.get(i)); } } return; } void gobser_rectangle_vz(gctl::array &out_obs, const gctl::array &ele_ptr, const gctl::array &op_ptr, const gctl::array &rho_ptr, gctl::verbose_type_e verbose) { int i, j; out_obs.resize(op_ptr.size(), 0.0); int o_size = op_ptr.size(); int e_size = ele_ptr.size(); gctl::progress_bar bar(e_size, "gobser_vz"); for (j = 0; j < e_size; j++) { if (verbose == gctl::FullMsg) bar.progressed(j); else if (verbose == gctl::ShortMsg) bar.progressed_simple(j); for (i = 0; i < o_size; i++) { out_obs[i] += gkernel_rectangle_vz_sig(ele_ptr.get(j), op_ptr.get(i)) * rho_ptr[j]; } } return; } void gobser_rectangle_vzx(gctl::array &out_obs, const gctl::array &ele_ptr, const gctl::array &op_ptr, const gctl::array &rho_ptr, gctl::verbose_type_e verbose) { int i, j; out_obs.resize(op_ptr.size(), 0.0); int o_size = op_ptr.size(); int e_size = ele_ptr.size(); gctl::progress_bar bar(e_size, "gobser_vzx"); for (j = 0; j < e_size; j++) { if (verbose == gctl::FullMsg) bar.progressed(j); else if (verbose == gctl::ShortMsg) bar.progressed_simple(j); for (i = 0; i < o_size; i++) { out_obs[i] += gkernel_rectangle_vzx_sig(ele_ptr.get(j), op_ptr.get(i)) * rho_ptr[j]; } } return; } void gobser_rectangle_vzz(gctl::array &out_obs, const gctl::array &ele_ptr, const gctl::array &op_ptr, const gctl::array &rho_ptr, gctl::verbose_type_e verbose) { int i, j; out_obs.resize(op_ptr.size(), 0.0); int o_size = op_ptr.size(); int e_size = ele_ptr.size(); gctl::progress_bar bar(e_size, "gobser_vzz"); for (j = 0; j < e_size; j++) { if (verbose == gctl::FullMsg) bar.progressed(j); else if (verbose == gctl::ShortMsg) bar.progressed_simple(j); for (i = 0; i < o_size; i++) { out_obs[i] += gkernel_rectangle_vzz_sig(ele_ptr.get(j), op_ptr.get(i)) * rho_ptr[j]; } } return; } double gkernel_rectangle_vz_sig(gctl::rectangle2d *ele_ptr, gctl::point2dc *op_ptr) { double x1, x2, y1, y2; double G11, G12, G21, G22; x1 = ele_ptr->dl->x - op_ptr->x; x2 = ele_ptr->ur->x - op_ptr->x; y1 = ele_ptr->dl->y - op_ptr->y; y2 = ele_ptr->ur->y - op_ptr->y; G11 = 2.0*y1*atan(x1/y1) + x1*log(x1*x1 + y1*y1); G12 = 2.0*y2*atan(x1/y2) + x1*log(x1*x1 + y2*y2); G21 = 2.0*y1*atan(x2/y1) + x2*log(x2*x2 + y1*y1); G22 = 2.0*y2*atan(x2/y2) + x2*log(x2*x2 + y2*y2); return -1.0e+8*GCTL_G0*(G11+G22-G12-G21); } double gkernel_rectangle_vzx_sig(gctl::rectangle2d *ele_ptr, gctl::point2dc *op_ptr) { double x1, x2, y1, y2; double G11, G12, G21, G22; x1 = ele_ptr->dl->x - op_ptr->x; x2 = ele_ptr->ur->x - op_ptr->x; y1 = ele_ptr->dl->y - op_ptr->y; y2 = ele_ptr->ur->y - op_ptr->y; G11 = x1*x1 + y1*y1; G12 = x1*x1 + y2*y2; G21 = x2*x2 + y1*y1; G22 = x2*x2 + y2*y2; return 1.0e+8*GCTL_G0*(log(G22/G21) - log(G12/G11)); } double gkernel_rectangle_vzz_sig(gctl::rectangle2d *ele_ptr, gctl::point2dc *op_ptr) { double x1, x2, y1, y2; double G11, G12, G21, G22; x1 = ele_ptr->dl->x - op_ptr->x; x2 = ele_ptr->ur->x - op_ptr->x; y1 = ele_ptr->dl->y - op_ptr->y; y2 = ele_ptr->ur->y - op_ptr->y; G11 = x1/y1; G12 = x1/y2; G21 = x2/y1; G22 = x2/y2; return -1.0e+8*GCTL_G0*(atan(G11) + atan(G22) - atan(G12) - atan(G21)); }