gctl_potential/lib/potential/gkernel_rectangle2d.cpp
2024-09-10 19:56:41 +08:00

314 lines
10 KiB
C++

/********************************************************
* ██████╗ ██████╗████████╗██╗
* ██╔════╝ ██╔════╝╚══██╔══╝██║
* ██║ ███╗██║ ██║ ██║
* ██║ ██║██║ ██║ ██║
* ╚██████╔╝╚██████╗ ██║ ███████╗
* ╚═════╝ ╚═════╝ ╚═╝ ╚══════╝
* 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 <http://www.gnu.org/licenses/>.
*
* 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<double> &out_kernel, const gctl::array<gctl::rectangle2d> &ele,
const gctl::array<gctl::point2dc> &obsp, gctl::verbose_type_e verbose);
void gkernel_rectangle_vz(gctl::matrix<double> &out_kernel, const gctl::array<gctl::rectangle2d> &ele,
const gctl::array<gctl::point2dc> &obsp, gctl::verbose_type_e verbose);
void gkernel_rectangle_vzx(gctl::matrix<double> &out_kernel, const gctl::array<gctl::rectangle2d> &ele,
const gctl::array<gctl::point2dc> &obsp, gctl::verbose_type_e verbose);
void gkernel_rectangle_vzz(gctl::matrix<double> &out_kernel, const gctl::array<gctl::rectangle2d> &ele,
const gctl::array<gctl::point2dc> &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<double> &out_kernel, const array<rectangle2d> &ele,
const array<point2dc> &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<double> &out_obs, const gctl::array<gctl::rectangle2d> &ele_ptr,
const gctl::array<gctl::point2dc> &op_ptr, const gctl::array<double> &rho_ptr, gctl::verbose_type_e verbose);
void gobser_rectangle_vz(gctl::array<double> &out_obs, const gctl::array<gctl::rectangle2d> &ele_ptr,
const gctl::array<gctl::point2dc> &op_ptr, const gctl::array<double> &rho_ptr, gctl::verbose_type_e verbose);
void gobser_rectangle_vzx(gctl::array<double> &out_obs, const gctl::array<gctl::rectangle2d> &ele_ptr,
const gctl::array<gctl::point2dc> &op_ptr, const gctl::array<double> &rho_ptr, gctl::verbose_type_e verbose);
void gobser_rectangle_vzz(gctl::array<double> &out_obs, const gctl::array<gctl::rectangle2d> &ele_ptr,
const gctl::array<gctl::point2dc> &op_ptr, const gctl::array<double> &rho_ptr, gctl::verbose_type_e verbose);
void gctl::gobser(array<double> &out_obs, const array<rectangle2d> &ele, const array<point2dc> &obsp,
const array<double> &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<double> &out_kernel, const gctl::array<gctl::rectangle2d> &ele,
const gctl::array<gctl::point2dc> &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<double> &out_kernel, const gctl::array<gctl::rectangle2d> &ele,
const gctl::array<gctl::point2dc> &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<double> &out_kernel, const gctl::array<gctl::rectangle2d> &ele,
const gctl::array<gctl::point2dc> &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<double> &out_obs, const gctl::array<gctl::rectangle2d> &ele_ptr,
const gctl::array<gctl::point2dc> &op_ptr, const gctl::array<double> &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<double> &out_obs, const gctl::array<gctl::rectangle2d> &ele_ptr,
const gctl::array<gctl::point2dc> &op_ptr, const gctl::array<double> &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<double> &out_obs, const gctl::array<gctl::rectangle2d> &ele_ptr,
const gctl::array<gctl::point2dc> &op_ptr, const gctl::array<double> &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));
}