986 lines
36 KiB
C++
986 lines
36 KiB
C++
/********************************************************
|
|
* ██████╗ ██████╗████████╗██╗
|
|
* ██╔════╝ ██╔════╝╚══██╔══╝██║
|
|
* ██║ ███╗██║ ██║ ██║
|
|
* ██║ ██║██║ ██║ ██║
|
|
* ╚██████╔╝╚██████╗ ██║ ███████╗
|
|
* ╚═════╝ ╚═════╝ ╚═╝ ╚══════╝
|
|
* Geophysical Computational Tools & Library (GCTL)
|
|
*
|
|
* Copyright (c) 2023 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 "shapefunc.h"
|
|
|
|
double gctl::linear_sf::line(double x, double x1, double x2, size_t idx, gradient_type_e vt)
|
|
{
|
|
#ifdef GCTL_CHECK_BOUNDER
|
|
if (x1 >= x2)
|
|
{
|
|
throw length_error("Invalid definition range. From gctl::linear_sf::line(...)");
|
|
}
|
|
|
|
if (x < x1 || x > x2)
|
|
{
|
|
throw out_of_range("Invalid calculating point. From gctl::linear_sf::line(...)");
|
|
}
|
|
#endif
|
|
|
|
switch (10*idx + vt)
|
|
{
|
|
case 0:
|
|
return (x2 - x)/(x2 - x1);
|
|
case 1:
|
|
return -1.0/(x2 - x1);
|
|
case 10:
|
|
return (x - x1)/(x2 - x1);
|
|
case 11:
|
|
return 1.0/(x2 - x1);
|
|
default:
|
|
throw runtime_error("Invalid calculating type. From gctl::linear_sf::line(...)");
|
|
}
|
|
}
|
|
|
|
double gctl::linear_sf::quad(double x, double y, double x1, double x2, double y1, double y2,
|
|
size_t idx, gradient_type_e vt)
|
|
{
|
|
#ifdef GCTL_CHECK_BOUNDER
|
|
if (x1 >= x2 || y1 >= y2)
|
|
{
|
|
throw length_error("Invalid definition range. From gctl::linear_sf::quad(...)");
|
|
}
|
|
|
|
if (x < x1 || x > x2 || y < y1 || y > y2)
|
|
{
|
|
throw out_of_range("Invalid calculating point. From gctl::linear_sf::quad(...)");
|
|
}
|
|
#endif
|
|
|
|
double square;
|
|
switch (10*idx + vt)
|
|
{
|
|
case 0:
|
|
square = (x2 - x1)*(y2 - y1);
|
|
return (x - x2)*(y - y2)/square;
|
|
case 1:
|
|
square = (x2 - x1)*(y2 - y1);
|
|
return (y - y2)/square;
|
|
case 2:
|
|
square = (x2 - x1)*(y2 - y1);
|
|
return (x - x2)/square;
|
|
case 10:
|
|
square = (x2 - x1)*(y2 - y1);
|
|
return -1.0*(x - x1)*(y - y2)/square;
|
|
case 11:
|
|
square = (x2 - x1)*(y2 - y1);
|
|
return -1.0*(y - y2)/square;
|
|
case 12:
|
|
square = (x2 - x1)*(y2 - y1);
|
|
return -1.0*(x - x1)/square;
|
|
case 20:
|
|
square = (x2 - x1)*(y2 - y1);
|
|
return (x - x1)*(y - y1)/square;
|
|
case 21:
|
|
square = (x2 - x1)*(y2 - y1);
|
|
return (y - y1)/square;
|
|
case 22:
|
|
square = (x2 - x1)*(y2 - y1);
|
|
return (x - x1)/square;
|
|
case 30:
|
|
square = (x2 - x1)*(y2 - y1);
|
|
return -1.0*(x - x2)*(y - y1)/square;
|
|
case 31:
|
|
square = (x2 - x1)*(y2 - y1);
|
|
return -1.0*(y - y1)/square;
|
|
case 32:
|
|
square = (x2 - x1)*(y2 - y1);
|
|
return -1.0*(x - x2)/square;
|
|
default:
|
|
throw runtime_error("Invalid calculating type. From gctl::linear_sf::quad(...)");
|
|
}
|
|
}
|
|
|
|
double gctl::linear_sf::triangle(double x, double y, double x1, double x2, double x3,
|
|
double y1, double y2, double y3, size_t idx, gradient_type_e vt)
|
|
{
|
|
#ifdef GCTL_CHECK_BOUNDER
|
|
if ((x2-x1)*(y3-y1)-(y2-y1)*(x3-x1) <= FEM_SF_ZERO) // 这里没有设置为0是为了检测三个点是否共线
|
|
{
|
|
throw length_error("Invalid definition range. From gctl::linear_sf::triangle(...)");
|
|
}
|
|
|
|
if ((x1-x)*(y2-y)-(y1-y)*(x2-x) < 0.0 ||
|
|
(x2-x)*(y3-y)-(y2-y)*(x3-x) < 0.0 ||
|
|
(x3-x)*(y1-y)-(y3-y)*(x1-x) < 0.0)
|
|
{
|
|
throw out_of_range("Invalid calculating point. From gctl::linear_sf::triangle(...)");
|
|
}
|
|
#endif
|
|
|
|
double a, b, c, d;
|
|
switch (10*idx + vt)
|
|
{
|
|
case 0:
|
|
d = (x2 - x3)*(y1 - y2) - (x1 - x2)*(y2 - y3);
|
|
a = (y3 - y2)/d;
|
|
b = (x2 - x3)/d;
|
|
c = 1.0 - x1*a - y1*b;
|
|
return a*x+b*y+c;
|
|
case 1:
|
|
d = (x2 - x3)*(y1 - y2) - (x1 - x2)*(y2 - y3);
|
|
return (y3 - y2)/d;
|
|
case 2:
|
|
d = (x2 - x3)*(y1 - y2) - (x1 - x2)*(y2 - y3);
|
|
return (x2 - x3)/d;
|
|
case 10:
|
|
d = (x3 - x1)*(y2 - y3) - (x2 - x3)*(y3 - y1);
|
|
a = (y1 - y3)/d;
|
|
b = (x3 - x1)/d;
|
|
c = 1.0 - x2*a - y2*b;
|
|
return a*x+b*y+c;
|
|
case 11:
|
|
d = (x3 - x1)*(y2 - y3) - (x2 - x3)*(y3 - y1);
|
|
return (y1 - y3)/d;
|
|
case 12:
|
|
d = (x3 - x1)*(y2 - y3) - (x2 - x3)*(y3 - y1);
|
|
return (x3 - x1)/d;
|
|
case 20:
|
|
d = (x1 - x2)*(y3 - y1) - (x3 - x1)*(y1 - y2);
|
|
a = (y2 - y1)/d;
|
|
b = (x1 - x2)/d;
|
|
c = 1.0 - x3*a - y3*b;
|
|
return a*x+b*y+c;
|
|
case 21:
|
|
d = (x1 - x2)*(y3 - y1) - (x3 - x1)*(y1 - y2);
|
|
return (y2 - y1)/d;
|
|
case 22:
|
|
d = (x1 - x2)*(y3 - y1) - (x3 - x1)*(y1 - y2);
|
|
return (x1 - x2)/d;
|
|
default:
|
|
throw runtime_error("Invalid calculating type. From gctl::linear_sf::triangle(...)");
|
|
}
|
|
}
|
|
|
|
double gctl::linear_sf::triangle_interpolate(double x, double y, double x1, double x2, double x3,
|
|
double y1, double y2, double y3, double v1, double v2, double v3, gradient_type_e vt)
|
|
{
|
|
double sum = triangle(x, y, x1, x2, x3, y1, y2, y3, 0, vt) * v1;
|
|
sum += triangle(x, y, x1, x2, x3, y1, y2, y3, 1, vt) * v2;
|
|
sum += triangle(x, y, x1, x2, x3, y1, y2, y3, 2, vt) * v3;
|
|
return sum;
|
|
}
|
|
|
|
double gctl::linear_sf::cube(double x, double y, double z, double x1, double x2,
|
|
double y1, double y2, double z1, double z2, size_t idx, gradient_type_e vt)
|
|
{
|
|
#ifdef GCTL_CHECK_BOUNDER
|
|
if (x1 >= x2 || y1 >= y2 || z1 >= z2)
|
|
{
|
|
throw length_error("Invalid definition range. From gctl::linear_sf::cube(...)");
|
|
}
|
|
|
|
if (x < x1 || x > x2 || y < y1 || y > y2 || z < z1 || z > z2)
|
|
{
|
|
throw out_of_range("Invalid calculating point. From gctl::linear_sf::cube(...)");
|
|
}
|
|
#endif
|
|
|
|
double vol;
|
|
switch (10*idx + vt)
|
|
{
|
|
case 0:
|
|
vol = (x2 - x1)*(y2 - y1)*(z2 - z1);
|
|
return (x2 - x)*(y2 - y)*(z2 - z)/vol;
|
|
case 1:
|
|
vol = (x2 - x1)*(y2 - y1)*(z2 - z1);
|
|
return -1.0*(y2 - y)*(z2 - z)/vol;
|
|
case 2:
|
|
vol = (x2 - x1)*(y2 - y1)*(z2 - z1);
|
|
return -1.0*(x2 - x)*(z2 - z)/vol;
|
|
case 3:
|
|
vol = (x2 - x1)*(y2 - y1)*(z2 - z1);
|
|
return -1.0*(x2 - x)*(y2 - y)/vol;
|
|
case 10:
|
|
vol = (x2 - x1)*(y2 - y1)*(z2 - z1);
|
|
return (x - x1)*(y2 - y)*(z2 - z)/vol;
|
|
case 11:
|
|
vol = (x2 - x1)*(y2 - y1)*(z2 - z1);
|
|
return (y2 - y)*(z2 - z)/vol;
|
|
case 12:
|
|
vol = (x2 - x1)*(y2 - y1)*(z2 - z1);
|
|
return -1.0*(x - x1)*(z2 - z)/vol;
|
|
case 13:
|
|
vol = (x2 - x1)*(y2 - y1)*(z2 - z1);
|
|
return -1.0*(x - x1)*(y2 - y)/vol;
|
|
case 20:
|
|
vol = (x2 - x1)*(y2 - y1)*(z2 - z1);
|
|
return (x - x1)*(y - y1)*(z2 - z)/vol;
|
|
case 21:
|
|
vol = (x2 - x1)*(y2 - y1)*(z2 - z1);
|
|
return (y - y1)*(z2 - z)/vol;
|
|
case 22:
|
|
vol = (x2 - x1)*(y2 - y1)*(z2 - z1);
|
|
return (x - x1)*(z2 - z)/vol;
|
|
case 23:
|
|
vol = (x2 - x1)*(y2 - y1)*(z2 - z1);
|
|
return -1.0*(x - x1)*(y - y1)/vol;
|
|
case 30:
|
|
vol = (x2 - x1)*(y2 - y1)*(z2 - z1);
|
|
return (x2 - x)*(y - y1)*(z2 - z)/vol;
|
|
case 31:
|
|
vol = (x2 - x1)*(y2 - y1)*(z2 - z1);
|
|
return -1.0*(y - y1)*(z2 - z)/vol;
|
|
case 32:
|
|
vol = (x2 - x1)*(y2 - y1)*(z2 - z1);
|
|
return (y - y1)*(z2 - z)/vol;
|
|
case 33:
|
|
vol = (x2 - x1)*(y2 - y1)*(z2 - z1);
|
|
return -1.0*(x2 - x)*(y - y1)/vol;
|
|
case 40:
|
|
vol = (x2 - x1)*(y2 - y1)*(z2 - z1);
|
|
return (x2 - x)*(y2 - y)*(z - z1)/vol;
|
|
case 41:
|
|
vol = (x2 - x1)*(y2 - y1)*(z2 - z1);
|
|
return -1.0*(y2 - y)*(z - z1)/vol;
|
|
case 42:
|
|
vol = (x2 - x1)*(y2 - y1)*(z2 - z1);
|
|
return -1.0*(x2 - x)*(z - z1)/vol;
|
|
case 43:
|
|
vol = (x2 - x1)*(y2 - y1)*(z2 - z1);
|
|
return (x2 - x)*(y2 - y)/vol;
|
|
case 50:
|
|
vol = (x2 - x1)*(y2 - y1)*(z2 - z1);
|
|
return (x - x1)*(y2 - y)*(z - z1)/vol;
|
|
case 51:
|
|
vol = (x2 - x1)*(y2 - y1)*(z2 - z1);
|
|
return (y2 - y)*(z - z1)/vol;
|
|
case 52:
|
|
vol = (x2 - x1)*(y2 - y1)*(z2 - z1);
|
|
return -1.0*(x - x1)*(z - z1)/vol;
|
|
case 53:
|
|
vol = (x2 - x1)*(y2 - y1)*(z2 - z1);
|
|
return (x - x1)*(y2 - y)/vol;
|
|
case 60:
|
|
vol = (x2 - x1)*(y2 - y1)*(z2 - z1);
|
|
return (x - x1)*(y - y1)*(z - z1)/vol;
|
|
case 61:
|
|
vol = (x2 - x1)*(y2 - y1)*(z2 - z1);
|
|
return (y - y1)*(z - z1)/vol;
|
|
case 62:
|
|
vol = (x2 - x1)*(y2 - y1)*(z2 - z1);
|
|
return (x - x1)*(z - z1)/vol;
|
|
case 63:
|
|
vol = (x2 - x1)*(y2 - y1)*(z2 - z1);
|
|
return (x - x1)*(y - y1)/vol;
|
|
case 70:
|
|
vol = (x2 - x1)*(y2 - y1)*(z2 - z1);
|
|
return (x2 - x)*(y - y1)*(z - z1)/vol;
|
|
case 71:
|
|
vol = (x2 - x1)*(y2 - y1)*(z2 - z1);
|
|
return -1.0*(y - y1)*(z - z1)/vol;
|
|
case 72:
|
|
vol = (x2 - x1)*(y2 - y1)*(z2 - z1);
|
|
return (x2 - x)*(z - z1)/vol;
|
|
case 73:
|
|
vol = (x2 - x1)*(y2 - y1)*(z2 - z1);
|
|
return (x2 - x)*(y - y1)/vol;
|
|
default:
|
|
throw runtime_error("Invalid calculating type. From gctl::linear_sf::cube(...)");
|
|
}
|
|
}
|
|
|
|
double gctl::linear_sf::tetrahedron(double ksi, double eta, double zta, double x1, double x2, double x3, double x4,
|
|
double y1, double y2, double y3, double y4, double z1, double z2, double z3, double z4,
|
|
size_t idx, gradient_type_e vt)
|
|
{
|
|
double J[9], invJ[9];
|
|
J[0] = x2 - x1; J[1] = x3 - x1; J[2] = x4 - x1;
|
|
J[3] = y2 - y1; J[4] = y3 - y1; J[5] = y4 - y1;
|
|
J[6] = z2 - z1; J[7] = z3 - z1; J[8] = z4 - z1;
|
|
if (!inverse3x3(&J[0], &invJ[0])) throw runtime_error("gctl::linear_sf::tetrahedron(...) got an invalid Det(J) value.");
|
|
|
|
switch (10*idx + vt)
|
|
{
|
|
case 0:
|
|
return 1.0 - ksi - eta - zta;
|
|
case 1:
|
|
return -1.0*(invJ[0] + invJ[3] + invJ[6]);
|
|
case 2:
|
|
return -1.0*(invJ[1] + invJ[4] + invJ[7]);
|
|
case 3:
|
|
return -1.0*(invJ[2] + invJ[5] + invJ[8]);
|
|
case 10:
|
|
return ksi;
|
|
case 11:
|
|
return invJ[0];
|
|
case 12:
|
|
return invJ[1];
|
|
case 13:
|
|
return invJ[2];
|
|
case 20:
|
|
return eta;
|
|
case 21:
|
|
return invJ[3];
|
|
case 22:
|
|
return invJ[4];
|
|
case 23:
|
|
return invJ[5];
|
|
case 30:
|
|
return zta;
|
|
case 31:
|
|
return invJ[6];
|
|
case 32:
|
|
return invJ[7];
|
|
case 33:
|
|
return invJ[8];
|
|
default:
|
|
throw invalid_argument("gctl::linear_sf::tetrahedron(...) got an invalid calculating type.");
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
void gctl::linear_sf::local2global_tetrahedron(double &x, double &y, double &z, double ksi, double eta, double zta,
|
|
double x1, double x2, double x3, double x4, double y1, double y2, double y3, double y4,
|
|
double z1, double z2, double z3, double z4)
|
|
{
|
|
if (ksi < 0.0 || ksi > 1.0 || eta < 0.0 || eta > 1.0 || zta < 0.0 || zta > 1.0)
|
|
{
|
|
throw runtime_error("gctl::linear_sf::local2global_tetrahedron(...) got an invalid local coordinate.");
|
|
}
|
|
|
|
x = (x2-x1)*ksi + (x3-x1)*eta + (x4-x1)*zta + x1;
|
|
y = (y2-y1)*ksi + (y3-y1)*eta + (y4-y1)*zta + y1;
|
|
z = (z2-z1)*ksi + (z3-z1)*eta + (z4-z1)*zta + z1;
|
|
return;
|
|
}
|
|
|
|
void gctl::linear_sf::global2local_tetrahedron(double &ksi, double &eta, double &zta, double x, double y, double z,
|
|
double x1, double x2, double x3, double x4, double y1, double y2, double y3, double y4,
|
|
double z1, double z2, double z3, double z4)
|
|
{
|
|
double J[9], invJ[9];
|
|
J[0] = x2 - x1; J[1] = x3 - x1; J[2] = x4 - x1;
|
|
J[3] = y2 - y1; J[4] = y3 - y1; J[5] = y4 - y1;
|
|
J[6] = z2 - z1; J[7] = z3 - z1; J[8] = z4 - z1;
|
|
if (!inverse3x3(&J[0], &invJ[0])) throw runtime_error("gctl::linear_sf::global2local_tetrahedron(...) got an invalid Det(J) value.");
|
|
|
|
ksi = (x - x1)*invJ[0] + (y - y1)*invJ[1] + (z - z1)*invJ[2];
|
|
eta = (x - x1)*invJ[3] + (y - y1)*invJ[4] + (z - z1)*invJ[5];
|
|
zta = (x - x1)*invJ[6] + (y - y1)*invJ[7] + (z - z1)*invJ[8];
|
|
return;
|
|
}
|
|
|
|
double gctl::linear_sf::tetrahedron_interpolate(double x, double y, double z, double x1, double x2,
|
|
double x3, double x4, double y1, double y2, double y3, double y4, double z1, double z2,
|
|
double z3, double z4, double v1, double v2, double v3, double v4, gradient_type_e vt)
|
|
{
|
|
double ksi, eta, zta;
|
|
global2local_tetrahedron(ksi, eta, zta, x, y, z, x1, x2, x3, x4, y1, y2, y3, y4, z1, z2, z3, z4);
|
|
|
|
double sum = tetrahedron(ksi, eta, zta, x1, x2, x3, x4, y1, y2, y3, y4, z1, z2, z3, z4, 0, vt) * v1;
|
|
sum += tetrahedron(ksi, eta, zta, x1, x2, x3, x4, y1, y2, y3, y4, z1, z2, z3, z4, 1, vt) * v2;
|
|
sum += tetrahedron(ksi, eta, zta, x1, x2, x3, x4, y1, y2, y3, y4, z1, z2, z3, z4, 2, vt) * v3;
|
|
sum += tetrahedron(ksi, eta, zta, x1, x2, x3, x4, y1, y2, y3, y4, z1, z2, z3, z4, 3, vt) * v4;
|
|
return sum;
|
|
}
|
|
|
|
void gctl::linear_sf::local2global_triprism(double &x, double &y, double &z, double ksi, double eta, double zta,
|
|
double *xs, double *ys, double *zs)
|
|
{
|
|
if (ksi < 0.0 || ksi > 1.0 || eta < 0.0 || eta > 1.0 || zta < 0.0 || zta > 1.0)
|
|
{
|
|
throw runtime_error("gctl::linear_sf::local2global_triprism(...) got an invalid local coordinate.");
|
|
}
|
|
|
|
x = (1.0 - ksi - eta)*(1.0 - zta)*xs[0] + ksi*(1.0 - zta)*xs[1] + eta*(1.0 - zta)*xs[2]
|
|
+ (1.0 - ksi - eta)*zta*xs[3] + ksi*zta*xs[4] + eta*zta*xs[5];
|
|
y = (1.0 - ksi - eta)*(1.0 - zta)*ys[0] + ksi*(1.0 - zta)*ys[1] + eta*(1.0 - zta)*ys[2]
|
|
+ (1.0 - ksi - eta)*zta*ys[3] + ksi*zta*ys[4] + eta*zta*ys[5];
|
|
z = (1.0 - ksi - eta)*(1.0 - zta)*zs[0] + ksi*(1.0 - zta)*zs[1] + eta*(1.0 - zta)*zs[2]
|
|
+ (1.0 - ksi - eta)*zta*zs[3] + ksi*zta*zs[4] + eta*zta*zs[5];
|
|
return;
|
|
}
|
|
|
|
double gctl::linear_sf::triprism(double ksi, double eta, double zta, double *xs, double *ys, double *zs, size_t idx, gradient_type_e vt)
|
|
{
|
|
double J[9], invJ[9];
|
|
J[0] = zta*(xs[0] - xs[1] - xs[3] + xs[4]) + xs[1] - xs[0];
|
|
J[1] = zta*(xs[0] - xs[2] - xs[3] + xs[5]) + xs[2] - xs[0];
|
|
J[2] = ksi*(xs[0] - xs[1] - xs[3] + xs[4]) + eta*(xs[0] - xs[2] - xs[3] + xs[5]) + xs[3] - xs[0];
|
|
J[3] = zta*(ys[0] - ys[1] - ys[3] + ys[4]) + ys[1] - ys[0];
|
|
J[4] = zta*(ys[0] - ys[2] - ys[3] + ys[5]) + ys[2] - ys[0];
|
|
J[5] = ksi*(ys[0] - ys[1] - ys[3] + ys[4]) + eta*(ys[0] - ys[2] - ys[3] + ys[5]) + ys[3] - ys[0];
|
|
J[6] = zta*(zs[0] - zs[1] - zs[3] + zs[4]) + zs[1] - zs[0];
|
|
J[7] = zta*(zs[0] - zs[2] - zs[3] + zs[5]) + zs[2] - zs[0];
|
|
J[8] = ksi*(zs[0] - zs[1] - zs[3] + zs[4]) + eta*(zs[0] - zs[2] - zs[3] + zs[5]) + zs[3] - zs[0];
|
|
if (!inverse3x3(&J[0], &invJ[0])) throw runtime_error("gctl::linear_sf::triprism(...) got an invalid Det(J) value.");
|
|
|
|
switch (10*idx + vt)
|
|
{
|
|
case 0:
|
|
return (1.0 - ksi - eta)*(1.0 - zta);
|
|
case 1:
|
|
return (zta - 1.0)*invJ[0] + (zta - 1.0)*invJ[3] + (ksi + eta - 1.0)*invJ[6];
|
|
case 2:
|
|
return (zta - 1.0)*invJ[1] + (zta - 1.0)*invJ[4] + (ksi + eta - 1.0)*invJ[7];
|
|
case 3:
|
|
return (zta - 1.0)*invJ[2] + (zta - 1.0)*invJ[5] + (ksi + eta - 1.0)*invJ[8];
|
|
case 10:
|
|
return ksi*(1.0 - zta);
|
|
case 11:
|
|
return (1.0 - zta)*invJ[0] - ksi*invJ[6];
|
|
case 12:
|
|
return (1.0 - zta)*invJ[1] - ksi*invJ[7];
|
|
case 13:
|
|
return (1.0 - zta)*invJ[2] - ksi*invJ[8];
|
|
case 20:
|
|
return eta*(1.0 - zta);
|
|
case 21:
|
|
return (1.0 - zta)*invJ[3] - eta*invJ[6];
|
|
case 22:
|
|
return (1.0 - zta)*invJ[4] - eta*invJ[7];
|
|
case 23:
|
|
return (1.0 - zta)*invJ[5] - eta*invJ[8];
|
|
case 30:
|
|
return (1.0 - ksi - eta)*zta;
|
|
case 31:
|
|
return -1.0*zta*invJ[0] - zta*invJ[3] + (1.0 - ksi - eta)*invJ[6];
|
|
case 32:
|
|
return -1.0*zta*invJ[1] - zta*invJ[4] + (1.0 - ksi - eta)*invJ[7];
|
|
case 33:
|
|
return -1.0*zta*invJ[2] - zta*invJ[5] + (1.0 - ksi - eta)*invJ[8];
|
|
case 40:
|
|
return ksi*zta;
|
|
case 41:
|
|
return zta*invJ[0] + ksi*invJ[6];
|
|
case 42:
|
|
return zta*invJ[1] + ksi*invJ[7];
|
|
case 43:
|
|
return zta*invJ[2] + ksi*invJ[8];
|
|
case 50:
|
|
return eta*zta;
|
|
case 51:
|
|
return zta*invJ[3] + eta*invJ[6];
|
|
case 52:
|
|
return zta*invJ[4] + eta*invJ[7];
|
|
case 53:
|
|
return zta*invJ[5] + eta*invJ[8];
|
|
default:
|
|
throw std::invalid_argument("gctl::linear_sf::triprism(...) got an invalid calculating type.");
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
void gctl::linear_esf::triangle(double x, double y, double x1, double x2, double x3,
|
|
double y1, double y2, double y3, size_t idx, eshape_value_e vt, edge_orient_e ot, double &xval, double &yval)
|
|
{
|
|
// Assign output values to defaults
|
|
xval = yval = 0.0;
|
|
|
|
double len;
|
|
if (idx == 0) len = sqrt((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1));
|
|
else if (idx == 1) len = sqrt((x3-x2)*(x3-x2) + (y3-y2)*(y3-y2));
|
|
else if (idx == 2) len = sqrt((x3-x1)*(x3-x1) + (y3-y1)*(y3-y1));
|
|
else throw std::invalid_argument("gctl::linear_esf::triangle(...) got an invalid calculating index.");
|
|
|
|
gctl::linear_sf lsf;
|
|
if (vt == VecValue)
|
|
{
|
|
xval = len*(lsf.triangle(x,y,x1,x2,x3,y1,y2,y3,idx,gctl::Value)*lsf.triangle(x,y,x1,x2,x3,y1,y2,y3,(idx+1)%3,gctl::Dx)
|
|
- lsf.triangle(x,y,x1,x2,x3,y1,y2,y3,(idx+1)%3,gctl::Value)*lsf.triangle(x,y,x1,x2,x3,y1,y2,y3,idx,gctl::Dx));
|
|
|
|
yval = len*(lsf.triangle(x,y,x1,x2,x3,y1,y2,y3,idx,gctl::Value)*lsf.triangle(x,y,x1,x2,x3,y1,y2,y3,(idx+1)%3,gctl::Dy)
|
|
- lsf.triangle(x,y,x1,x2,x3,y1,y2,y3,(idx+1)%3,gctl::Value)*lsf.triangle(x,y,x1,x2,x3,y1,y2,y3,idx,gctl::Dy));
|
|
}
|
|
else
|
|
{
|
|
xval = len*(lsf.triangle(x,y,x1,x2,x3,y1,y2,y3,idx,gctl::Dy)*lsf.triangle(x,y,x1,x2,x3,y1,y2,y3,(idx+1)%3,gctl::Dx)
|
|
- lsf.triangle(x,y,x1,x2,x3,y1,y2,y3,(idx+1)%3,gctl::Dy)*lsf.triangle(x,y,x1,x2,x3,y1,y2,y3,idx,gctl::Dx)); // dVx/dy
|
|
|
|
yval = len*(lsf.triangle(x,y,x1,x2,x3,y1,y2,y3,idx,gctl::Dx)*lsf.triangle(x,y,x1,x2,x3,y1,y2,y3,(idx+1)%3,gctl::Dy)
|
|
- lsf.triangle(x,y,x1,x2,x3,y1,y2,y3,(idx+1)%3,gctl::Dx)*lsf.triangle(x,y,x1,x2,x3,y1,y2,y3,idx,gctl::Dy)); // dVy/dx
|
|
|
|
if (vt == VecCurl)
|
|
{
|
|
xval = yval = yval - xval;
|
|
}
|
|
}
|
|
|
|
if (ot) // Ordered in reversed direction
|
|
{
|
|
xval *= -1.0;
|
|
yval *= -1.0;
|
|
}
|
|
return;
|
|
}
|
|
|
|
void gctl::linear_esf::tetrahedron(double x, double y, double z, double x1, double x2, double x3, double x4,
|
|
double y1, double y2, double y3, double y4, double z1, double z2, double z3, double z4,
|
|
size_t idx, eshape_value_e vt, edge_orient_e ot, double &xval, double &yval, double &zval,
|
|
double &xval2, double &yval2, double &zval2)
|
|
{
|
|
// Assign output values to defaults
|
|
xval = yval = zval = 0.0;
|
|
xval2= yval2= zval2= 0.0;
|
|
|
|
double x12 = x2-x1, y12 = y2-y1, z12 = z2-z1;
|
|
double x13 = x3-x1, y13 = y3-y1, z13 = z3-z1;
|
|
double x14 = x4-x1, y14 = y4-y1, z14 = z4-z1;
|
|
double crx = y12*z13-z12*y13;
|
|
double cry = z12*x13-x12*z13;
|
|
double crz = x12*y13-y12*x13;
|
|
double scl = (x14*crx+y14*cry+z14*crz);
|
|
// No need to get the absolute value here
|
|
//if (scl < 0) scl = -1.0*scl;
|
|
|
|
size_t l_id, k_id;
|
|
double len;
|
|
if (idx == 0)
|
|
{
|
|
l_id = 0; k_id = 1;
|
|
len = sqrt((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1) + (z2-z1)*(z2-z1));
|
|
}
|
|
else if (idx == 1)
|
|
{
|
|
l_id = 0; k_id = 2;
|
|
len = sqrt((x3-x1)*(x3-x1) + (y3-y1)*(y3-y1) + (z3-z1)*(z3-z1));
|
|
}
|
|
else if (idx == 2)
|
|
{
|
|
l_id = 0; k_id = 3;
|
|
len = sqrt((x4-x1)*(x4-x1) + (y4-y1)*(y4-y1) + (z4-z1)*(z4-z1));
|
|
}
|
|
else if (idx == 3)
|
|
{
|
|
l_id = 1; k_id = 2;
|
|
len = sqrt((x3-x2)*(x3-x2) + (y3-y2)*(y3-y2) + (z3-z2)*(z3-z2));
|
|
}
|
|
else if (idx == 4)
|
|
{
|
|
l_id = 1; k_id = 3;
|
|
len = sqrt((x4-x2)*(x4-x2) + (y4-y2)*(y4-y2) + (z4-z2)*(z4-z2));
|
|
}
|
|
else if (idx == 5)
|
|
{
|
|
l_id = 2; k_id = 3;
|
|
len = sqrt((x4-x3)*(x4-x3) + (y4-y3)*(y4-y3) + (z4-z3)*(z4-z3));
|
|
}
|
|
else throw std::invalid_argument("gctl::linear_esf::tetrahedron(...) got an invalid calculating index.");
|
|
|
|
if (vt == VecValue)
|
|
{
|
|
gctl::linear_sf lsf;
|
|
xval = (lsf.tetrahedron(x,y,z,x1,x2,x3,x4,y1,y2,y3,y4,z1,z2,z3,z4,l_id,gctl::Value)*lsf.tetrahedron(x,y,z,x1,x2,x3,x4,y1,y2,y3,y4,z1,z2,z3,z4,k_id,gctl::Dx)
|
|
- lsf.tetrahedron(x,y,z,x1,x2,x3,x4,y1,y2,y3,y4,z1,z2,z3,z4,k_id,gctl::Value)*lsf.tetrahedron(x,y,z,x1,x2,x3,x4,y1,y2,y3,y4,z1,z2,z3,z4,l_id,gctl::Dx))*len;
|
|
|
|
yval = (lsf.tetrahedron(x,y,z,x1,x2,x3,x4,y1,y2,y3,y4,z1,z2,z3,z4,l_id,gctl::Value)*lsf.tetrahedron(x,y,z,x1,x2,x3,x4,y1,y2,y3,y4,z1,z2,z3,z4,k_id,gctl::Dy)
|
|
- lsf.tetrahedron(x,y,z,x1,x2,x3,x4,y1,y2,y3,y4,z1,z2,z3,z4,k_id,gctl::Value)*lsf.tetrahedron(x,y,z,x1,x2,x3,x4,y1,y2,y3,y4,z1,z2,z3,z4,l_id,gctl::Dy))*len;
|
|
|
|
zval = (lsf.tetrahedron(x,y,z,x1,x2,x3,x4,y1,y2,y3,y4,z1,z2,z3,z4,l_id,gctl::Value)*lsf.tetrahedron(x,y,z,x1,x2,x3,x4,y1,y2,y3,y4,z1,z2,z3,z4,k_id,gctl::Dz)
|
|
- lsf.tetrahedron(x,y,z,x1,x2,x3,x4,y1,y2,y3,y4,z1,z2,z3,z4,k_id,gctl::Value)*lsf.tetrahedron(x,y,z,x1,x2,x3,x4,y1,y2,y3,y4,z1,z2,z3,z4,l_id,gctl::Dz))*len;
|
|
|
|
if (ot) // Ordered in reversed direction
|
|
{
|
|
xval *= -1.0; // Vx
|
|
yval *= -1.0; // Vy
|
|
zval *= -1.0; // Vz
|
|
}
|
|
return;
|
|
}
|
|
|
|
// Gradient or Curl
|
|
double a1, a2, b1, b2, c1, c2;
|
|
if (idx == 0)
|
|
{
|
|
// edge 0->1
|
|
a1 = -1.0*jacoby3(1.0, y2, z2, 1.0, y3, z3, 1.0, y4, z4)/scl;
|
|
b1 = jacoby3(1.0, x2, z2, 1.0, x3, z3, 1.0, x4, z4)/scl;
|
|
c1 = -1.0*jacoby3(1.0, x2, y2, 1.0, x3, y3, 1.0, x4, y4)/scl;
|
|
|
|
a2 = jacoby3(1.0, y1, z1, 1.0, y3, z3, 1.0, y4, z4)/scl;
|
|
b2 = -1.0*jacoby3(1.0, x1, z1, 1.0, x3, z3, 1.0, x4, z4)/scl;
|
|
c2 = jacoby3(1.0, x1, y1, 1.0, x3, y3, 1.0, x4, y4)/scl;
|
|
}
|
|
else if (idx == 1)
|
|
{
|
|
// edge 0->2
|
|
a1 = -1.0*jacoby3(1.0, y2, z2, 1.0, y3, z3, 1.0, y4, z4)/scl;
|
|
b1 = jacoby3(1.0, x2, z2, 1.0, x3, z3, 1.0, x4, z4)/scl;
|
|
c1 = -1.0*jacoby3(1.0, x2, y2, 1.0, x3, y3, 1.0, x4, y4)/scl;
|
|
|
|
a2 = -1.0*jacoby3(1.0, y1, z1, 1.0, y2, z2, 1.0, y4, z4)/scl;
|
|
b2 = jacoby3(1.0, x1, z1, 1.0, x2, z2, 1.0, x4, z4)/scl;
|
|
c2 = -1.0*jacoby3(1.0, x1, y1, 1.0, x2, y2, 1.0, x4, y4)/scl;
|
|
}
|
|
else if (idx == 2)
|
|
{
|
|
// edge 0->3
|
|
a1 = -1.0*jacoby3(1.0, y2, z2, 1.0, y3, z3, 1.0, y4, z4)/scl;
|
|
b1 = jacoby3(1.0, x2, z2, 1.0, x3, z3, 1.0, x4, z4)/scl;
|
|
c1 = -1.0*jacoby3(1.0, x2, y2, 1.0, x3, y3, 1.0, x4, y4)/scl;
|
|
|
|
a2 = jacoby3(1.0, y1, z1, 1.0, y2, z2, 1.0, y3, z3)/scl;
|
|
b2 = -1.0*jacoby3(1.0, x1, z1, 1.0, x2, z2, 1.0, x3, z3)/scl;
|
|
c2 = jacoby3(1.0, x1, y1, 1.0, x2, y2, 1.0, x3, y3)/scl;
|
|
}
|
|
else if (idx == 3)
|
|
{
|
|
// edge 1->2
|
|
a1 = jacoby3(1.0, y1, z1, 1.0, y3, z3, 1.0, y4, z4)/scl;
|
|
b1 = -1.0*jacoby3(1.0, x1, z1, 1.0, x3, z3, 1.0, x4, z4)/scl;
|
|
c1 = jacoby3(1.0, x1, y1, 1.0, x3, y3, 1.0, x4, y4)/scl;
|
|
|
|
a2 = -1.0*jacoby3(1.0, y1, z1, 1.0, y2, z2, 1.0, y4, z4)/scl;
|
|
b2 = jacoby3(1.0, x1, z1, 1.0, x2, z2, 1.0, x4, z4)/scl;
|
|
c2 = -1.0*jacoby3(1.0, x1, y1, 1.0, x2, y2, 1.0, x4, y4)/scl;
|
|
}
|
|
else if (idx == 4)
|
|
{
|
|
// edge 1->3
|
|
a1 = jacoby3(1.0, y1, z1, 1.0, y3, z3, 1.0, y4, z4)/scl;
|
|
b1 = -1.0*jacoby3(1.0, x1, z1, 1.0, x3, z3, 1.0, x4, z4)/scl;
|
|
c1 = jacoby3(1.0, x1, y1, 1.0, x3, y3, 1.0, x4, y4)/scl;
|
|
|
|
a2 = jacoby3(1.0, y1, z1, 1.0, y2, z2, 1.0, y3, z3)/scl;
|
|
b2 = -1.0*jacoby3(1.0, x1, z1, 1.0, x2, z2, 1.0, x3, z3)/scl;
|
|
c2 = jacoby3(1.0, x1, y1, 1.0, x2, y2, 1.0, x3, y3)/scl;
|
|
}
|
|
else if (idx == 5)
|
|
{
|
|
// edge 2->3
|
|
a1 = -1.0*jacoby3(1.0, y1, z1, 1.0, y2, z2, 1.0, y4, z4)/scl;
|
|
b1 = jacoby3(1.0, x1, z1, 1.0, x2, z2, 1.0, x4, z4)/scl;
|
|
c1 = -1.0*jacoby3(1.0, x1, y1, 1.0, x2, y2, 1.0, x4, y4)/scl;
|
|
|
|
a2 = jacoby3(1.0, y1, z1, 1.0, y2, z2, 1.0, y3, z3)/scl;
|
|
b2 = -1.0*jacoby3(1.0, x1, z1, 1.0, x2, z2, 1.0, x3, z3)/scl;
|
|
c2 = jacoby3(1.0, x1, y1, 1.0, x2, y2, 1.0, x3, y3)/scl;
|
|
}
|
|
else throw std::invalid_argument("gctl::linear_esf::tetrahedron(...) got an invalid calculating index.");
|
|
|
|
if (vt == VecGradient)
|
|
{
|
|
xval = (b1*a2 - b2*a1)*len; // dVx/dy
|
|
xval2= (c1*a2 - c2*a1)*len; // dVx/dz
|
|
yval = (a1*b2 - a2*b1)*len; // dVy/dx
|
|
yval2= (c1*b2 - c2*b1)*len; // dVy/dz
|
|
zval = (a1*c2 - a2*c1)*len; // dVz/dx
|
|
zval2= (b1*c2 - b2*c1)*len; // dVz/dy
|
|
}
|
|
else
|
|
{
|
|
xval = 2.0*(b1*c2 - b2*c1)*len; // curl(V)_x
|
|
yval = 2.0*(c1*a2 - c2*a1)*len; // curl(V)_y
|
|
zval = 2.0*(a1*b2 - a2*b1)*len; // curl(V)_z
|
|
}
|
|
|
|
if (ot) // Ordered in reversed direction
|
|
{
|
|
xval *= -1.0;
|
|
yval *= -1.0;
|
|
zval *= -1.0;
|
|
xval2*= -1.0;
|
|
yval2*= -1.0;
|
|
zval2*= -1.0;
|
|
}
|
|
return;
|
|
}
|
|
|
|
void gctl::linear_esf::cube(double x, double y, double z, double x1, double x2,
|
|
double y1, double y2, double z1, double z2, size_t idx, eshape_value_e vt, edge_orient_e ot,
|
|
double &xval, double &yval, double &zval, double &xval2, double &yval2, double &zval2)
|
|
{
|
|
// Assign output values to defaults
|
|
xval = yval = zval = 0.0;
|
|
xval2= yval2= zval2= 0.0;
|
|
|
|
double lex = x2 - x1, ley = y2 - y1, lez = z2 - z1;
|
|
double cx = 0.5*(x1 + x2), cy = 0.5*(y1 + y2), cz = 0.5*(z1 + z2);
|
|
|
|
if (vt == VecValue)
|
|
{
|
|
if (idx >= 0 && idx <= 3)
|
|
{
|
|
if (idx == 0) xval = (cy + 0.5*ley - y)*(cz + 0.5*lez - z)/(ley*lez);
|
|
else if (idx == 1) xval = (y - cy + 0.5*ley)*(cz + 0.5*lez - z)/(ley*lez);
|
|
else if (idx == 2) xval = (cy + 0.5*ley - y)*(z - cz + 0.5*lez)/(ley*lez);
|
|
else if (idx == 3) xval = (y - cy + 0.5*ley)*(z - cz + 0.5*lez)/(ley*lez);
|
|
}
|
|
else if (idx >= 4 && idx <= 7)
|
|
{
|
|
if (idx == 4) yval = (cz + 0.5*lez - z)*(cx + 0.5*lex - x)/(lex*lez);
|
|
else if (idx == 5) yval = (z - cz + 0.5*lez)*(cx + 0.5*lex - x)/(lex*lez);
|
|
else if (idx == 6) yval = (cz + 0.5*lez - z)*(x - cx + 0.5*lex)/(lex*lez);
|
|
else if (idx == 7) yval = (z - cz + 0.5*lez)*(x - cx + 0.5*lex)/(lex*lez);
|
|
}
|
|
else if (idx >= 8 && idx <= 11)
|
|
{
|
|
if (idx == 8) zval = (cx + 0.5*lex - x)*(cy + 0.5*ley - y)/(lex*ley);
|
|
else if (idx == 9) zval = (x - cx + 0.5*lex)*(cy + 0.5*ley - y)/(lex*ley);
|
|
else if (idx == 10)zval = (cx + 0.5*lex - x)*(y - cy + 0.5*ley)/(lex*ley);
|
|
else if (idx == 11)zval = (x - cx + 0.5*lex)*(y - cy + 0.5*ley)/(lex*ley);
|
|
}
|
|
else throw std::invalid_argument("gctl::linear_esf::cube(...) got an invalid calculating index.");
|
|
|
|
if (ot) // Ordered in reversed direction
|
|
{
|
|
xval *= -1.0; // Vx
|
|
yval *= -1.0; // Vy
|
|
zval *= -1.0; // Vz
|
|
}
|
|
return;
|
|
}
|
|
|
|
if (vt == VecGradient)
|
|
{
|
|
if (idx >= 0 && idx <= 3)
|
|
{
|
|
if (idx == 0)
|
|
{
|
|
xval = -1.0*(cz + 0.5*lez - z)/(ley*lez); // dVx/Dy
|
|
xval2= -1.0*(cy + 0.5*ley - y)/(ley*lez); // dVx/Dz
|
|
}
|
|
else if (idx == 1)
|
|
{
|
|
xval = (cz + 0.5*lez - z)/(ley*lez);
|
|
xval2= -1.0*(y - cy + 0.5*ley)/(ley*lez);
|
|
}
|
|
else if (idx == 2)
|
|
{
|
|
xval = -1.0*(z - cz + 0.5*lez)/(ley*lez);
|
|
xval2= (cy + 0.5*ley - y)/(ley*lez);
|
|
}
|
|
else if (idx == 3)
|
|
{
|
|
xval = (z - cz + 0.5*lez)/(ley*lez);
|
|
xval2= (y - cy + 0.5*ley)/(ley*lez);
|
|
}
|
|
}
|
|
else if (idx >= 4 && idx <= 7)
|
|
{
|
|
if (idx == 4)
|
|
{
|
|
yval = -1.0*(cz + 0.5*lez - z)/(lex*lez); // dVy/dx
|
|
yval2= -1.0*(cx + 0.5*lex - x)/(lex*lez); // dVy/dz
|
|
}
|
|
else if (idx == 5)
|
|
{
|
|
yval = -1.0*(z - cz + 0.5*lez)/(lex*lez);
|
|
yval2= (cx + 0.5*lex - x)/(lex*lez);
|
|
}
|
|
else if (idx == 6)
|
|
{
|
|
yval = (cz + 0.5*lez - z)/(lex*lez);
|
|
yval2= -1.0*(x - cx + 0.5*lex)/(lex*lez);
|
|
}
|
|
else if (idx == 7)
|
|
{
|
|
yval = (z - cz + 0.5*lez)/(lex*lez);
|
|
yval2= (x - cx + 0.5*lex)/(lex*lez);
|
|
}
|
|
}
|
|
else if (idx >= 8 && idx <= 11)
|
|
{
|
|
if (idx == 8)
|
|
{
|
|
zval = -1.0*(cy + 0.5*ley - y)/(lex*ley); // dVz/dx
|
|
zval2= -1.0*(cx + 0.5*lex - x)/(lex*ley); // dVz/dy
|
|
}
|
|
else if (idx == 9)
|
|
{
|
|
zval = (cy + 0.5*ley - y)/(lex*ley);
|
|
zval2= -1.0*(x - cx + 0.5*lex)/(lex*ley);
|
|
}
|
|
else if (idx == 10)
|
|
{
|
|
zval = -1.0*(y - cy + 0.5*ley)/(lex*ley);
|
|
zval2= (cx + 0.5*lex - x)/(lex*ley);
|
|
}
|
|
else if (idx == 11)
|
|
{
|
|
zval = (y - cy + 0.5*ley)/(lex*ley);
|
|
zval2= (x - cx + 0.5*lex)/(lex*ley);
|
|
}
|
|
}
|
|
else throw std::invalid_argument("gctl::linear_esf::cube(...) got an invalid calculating index.");
|
|
|
|
if (ot) // Ordered in reversed direction
|
|
{
|
|
xval *= -1.0;
|
|
yval *= -1.0;
|
|
zval *= -1.0;
|
|
xval2*= -1.0;
|
|
yval2*= -1.0;
|
|
zval2*= -1.0;
|
|
}
|
|
}
|
|
|
|
// Curl
|
|
if (idx >= 0 && idx <= 3)
|
|
{
|
|
if (idx == 0)
|
|
{
|
|
yval = -1.0*(cy + 0.5*ley - y)/(ley*lez); // dVx/Dz
|
|
zval = (cz + 0.5*lez - z)/(ley*lez); // dVx/Dy
|
|
}
|
|
else if (idx == 1)
|
|
{
|
|
yval = -1.0*(y - cy + 0.5*ley)/(ley*lez);
|
|
zval = -1.0*(cz + 0.5*lez - z)/(ley*lez);
|
|
}
|
|
else if (idx == 2)
|
|
{
|
|
yval= (cy + 0.5*ley - y)/(ley*lez);
|
|
zval = (z - cz + 0.5*lez)/(ley*lez);
|
|
}
|
|
else if (idx == 3)
|
|
{
|
|
yval= (y - cy + 0.5*ley)/(ley*lez);
|
|
zval = -1.0*(z - cz + 0.5*lez)/(ley*lez);
|
|
}
|
|
}
|
|
else if (idx >= 4 && idx <= 7)
|
|
{
|
|
if (idx == 4)
|
|
{
|
|
xval= (cx + 0.5*lex - x)/(lex*lez); // dVy/dz
|
|
zval = -1.0*(cz + 0.5*lez - z)/(lex*lez); // dVy/dx
|
|
}
|
|
else if (idx == 5)
|
|
{
|
|
xval = -1.0*(cx + 0.5*lex - x)/(lex*lez);
|
|
zval = -1.0*(z - cz + 0.5*lez)/(lex*lez);
|
|
}
|
|
else if (idx == 6)
|
|
{
|
|
xval = (x - cx + 0.5*lex)/(lex*lez);
|
|
zval = (cz + 0.5*lez - z)/(lex*lez);
|
|
}
|
|
else if (idx == 7)
|
|
{
|
|
xval = -1.0*(x - cx + 0.5*lex)/(lex*lez);
|
|
zval = (z - cz + 0.5*lez)/(lex*lez);
|
|
}
|
|
}
|
|
else if (idx >= 8 && idx <= 11)
|
|
{
|
|
if (idx == 8)
|
|
{
|
|
xval = -1.0*(cx + 0.5*lex - x)/(lex*ley); // dVz/dy
|
|
yval = (cy + 0.5*ley - y)/(lex*ley); // dVz/dx
|
|
}
|
|
else if (idx == 9)
|
|
{
|
|
xval = -1.0*(x - cx + 0.5*lex)/(lex*ley);
|
|
yval = -1.0*(cy + 0.5*ley - y)/(lex*ley);
|
|
}
|
|
else if (idx == 10)
|
|
{
|
|
xval = (cx + 0.5*lex - x)/(lex*ley);
|
|
yval = (y - cy + 0.5*ley)/(lex*ley);
|
|
}
|
|
else if (idx == 11)
|
|
{
|
|
xval = (x - cx + 0.5*lex)/(lex*ley);
|
|
yval = -1.0*(y - cy + 0.5*ley)/(lex*ley);
|
|
}
|
|
}
|
|
else throw std::invalid_argument("gctl::linear_esf::cube(...) got an invalid calculating index.");
|
|
|
|
if (ot) // Ordered in reversed direction
|
|
{
|
|
xval *= -1.0;
|
|
yval *= -1.0;
|
|
zval *= -1.0;
|
|
xval2*= -1.0;
|
|
yval2*= -1.0;
|
|
zval2*= -1.0;
|
|
}
|
|
return;
|
|
}
|
|
|
|
/*
|
|
double gctl::linear_sf::tetrahedron(double x, double y, double z, double x1, double x2, double x3, double x4,
|
|
double y1, double y2, double y3, double y4, double z1, double z2, double z3, double z4,
|
|
size_t idx, gradient_type_e vt)
|
|
{
|
|
double x12 = x2-x1, y12 = y2-y1, z12 = z2-z1;
|
|
double x13 = x3-x1, y13 = y3-y1, z13 = z3-z1;
|
|
double x14 = x4-x1, y14 = y4-y1, z14 = z4-z1;
|
|
double crx = y12*z13-z12*y13;
|
|
double cry = z12*x13-x12*z13;
|
|
double crz = x12*y13-y12*x13;
|
|
double scl = (x14*crx+y14*cry+z14*crz);
|
|
//if (scl < 0) scl = -1.0*scl; // 不要判断正负 正好后面有用
|
|
|
|
double a, b, c, d;
|
|
switch (10*idx + vt)
|
|
{
|
|
case 0:
|
|
a = -1.0*jacoby3(1.0, y2, z2, 1.0, y3, z3, 1.0, y4, z4)/scl;
|
|
b = jacoby3(1.0, x2, z2, 1.0, x3, z3, 1.0, x4, z4)/scl;
|
|
c = -1.0*jacoby3(1.0, x2, y2, 1.0, x3, y3, 1.0, x4, y4)/scl;
|
|
d = jacoby3(x2, y2, z2, x3, y3, z3, x4, y4, z4)/scl;
|
|
return a*x+b*y+c*z+d;
|
|
case 1:
|
|
return -1.0*jacoby3(1.0, y2, z2, 1.0, y3, z3, 1.0, y4, z4)/scl;
|
|
case 2:
|
|
return jacoby3(1.0, x2, z2, 1.0, x3, z3, 1.0, x4, z4)/scl;
|
|
case 3:
|
|
return -1.0*jacoby3(1.0, x2, y2, 1.0, x3, y3, 1.0, x4, y4)/scl;
|
|
case 10:
|
|
a = jacoby3(1.0, y1, z1, 1.0, y3, z3, 1.0, y4, z4)/scl;
|
|
b = -1.0*jacoby3(1.0, x1, z1, 1.0, x3, z3, 1.0, x4, z4)/scl;
|
|
c = jacoby3(1.0, x1, y1, 1.0, x3, y3, 1.0, x4, y4)/scl;
|
|
d = -1.0*jacoby3(x1, y1, z1, x3, y3, z3, x4, y4, z4)/scl;
|
|
return a*x+b*y+c*z+d;
|
|
case 11:
|
|
return jacoby3(1.0, y1, z1, 1.0, y3, z3, 1.0, y4, z4)/scl;
|
|
case 12:
|
|
return -1.0*jacoby3(1.0, x1, z1, 1.0, x3, z3, 1.0, x4, z4)/scl;
|
|
case 13:
|
|
return jacoby3(1.0, x1, y1, 1.0, x3, y3, 1.0, x4, y4)/scl;
|
|
case 20:
|
|
a = -1.0*jacoby3(1.0, y1, z1, 1.0, y2, z2, 1.0, y4, z4)/scl;
|
|
b = jacoby3(1.0, x1, z1, 1.0, x2, z2, 1.0, x4, z4)/scl;
|
|
c = -1.0*jacoby3(1.0, x1, y1, 1.0, x2, y2, 1.0, x4, y4)/scl;
|
|
d = jacoby3(x1, y1, z1, x2, y2, z2, x4, y4, z4)/scl;
|
|
return a*x+b*y+c*z+d;
|
|
case 21:
|
|
return -1.0*jacoby3(1.0, y1, z1, 1.0, y2, z2, 1.0, y4, z4)/scl;
|
|
case 22:
|
|
return jacoby3(1.0, x1, z1, 1.0, x2, z2, 1.0, x4, z4)/scl;
|
|
case 23:
|
|
return -1.0*jacoby3(1.0, x1, y1, 1.0, x2, y2, 1.0, x4, y4)/scl;
|
|
case 30:
|
|
a = jacoby3(1.0, y1, z1, 1.0, y2, z2, 1.0, y3, z3)/scl;
|
|
b = -1.0*jacoby3(1.0, x1, z1, 1.0, x2, z2, 1.0, x3, z3)/scl;
|
|
c = jacoby3(1.0, x1, y1, 1.0, x2, y2, 1.0, x3, y3)/scl;
|
|
d = -1.0*jacoby3(x1, y1, z1, x2, y2, z2, x3, y3, z3)/scl;
|
|
return a*x+b*y+c*z+d;
|
|
case 31:
|
|
return jacoby3(1.0, y1, z1, 1.0, y2, z2, 1.0, y3, z3)/scl;
|
|
case 32:
|
|
return -1.0*jacoby3(1.0, x1, z1, 1.0, x2, z2, 1.0, x3, z3)/scl;
|
|
case 33:
|
|
return jacoby3(1.0, x1, y1, 1.0, x2, y2, 1.0, x3, y3)/scl;
|
|
default:
|
|
throw runtime_error("Invalid calculating type. From gctl::linear_sf::tetrahedron(...)");
|
|
}
|
|
}
|
|
*/ |