#define MAX_TETRA_ORDER 3
#define MAX_TETRA_POINTS 5
static int Tetra__nPoints[MAX_TETRA_ORDER] = {
1, 4, 5
};
#define TETRA_A2 0.13819660
static double Tetra__L0123_Ip
[MAX_TETRA_ORDER][MAX_TETRA_POINTS][4] = {
{ { 1.0/4, 1.0/4, 1.0/4, 1.0/4 } },
{ { 1.0 - 2 * TETRA_A2, TETRA_A2, TETRA_A2, TETRA_A2 },
{ TETRA_A2, 1.0 - 2 * TETRA_A2, TETRA_A2, TETRA_A2 },
{ TETRA_A2, TETRA_A2, 1.0 - 2 * TETRA_A2, TETRA_A2 },
{ TETRA_A2, TETRA_A2, TETRA_A2, 1.0 - 2 * TETRA_A2 } },
{ { 1.0/4, 1.0/4, 1.0/4, 1.0/4 },
{ 1.0/2, 1.0/6, 1.0/6, 1.0/6 },
{ 1.0/6, 1.0/2, 1.0/6, 1.0/6 },
{ 1.0/6, 1.0/6, 1.0/2, 1.0/6 },
{ 1.0/6, 1.0/6, 1.0/6, 1.0/2 } }
};
static double Tetra__w_Ip
[MAX_TETRA_ORDER][MAX_TETRA_POINTS] = {
{ 1.0 },
{ 1.0/4, 1.0/4, 1.0/4, 1.0/4 },
{ -16.0/20,
9.0/20, 9.0/20, 9.0/20, 9.0/20 }
};
/* 領域での積分点数 */
void WH_Fem__NumInt__Gauss3D__Tetra__nPoints
(int order,
int *OUT__nPoints)
/*
入力引数:
order は整数で、ガウス積分の次数
出力引数:
OUT__nPoints は整数で、積分点数
*/
{
assert(0 < order);
assert(order <= MAX_TETRA_ORDER);
*OUT__nPoints = Tetra__nPoints[order - 1];
}
/* 領域での積分点の自然座標 */
void WH_Fem__NumInt__Gauss3D__Tetra__whV_xi_Ip
(int order,
int Ip,
double OUT__whV_xi_Ip[3])
/*
入力引数:
order は整数で、ガウス積分の次数
Ip は整数で、積分点ID
出力引数:
OUT__whV_xi_Ip はベクトルで、自然座標
*/
{
double L0, L1, L2, L3;
assert(0 < order);
assert(order <= MAX_TETRA_ORDER);
assert(0 <= Ip);
assert(Ip < Tetra__nPoints[order - 1]);
L0 = Tetra__L0123_Ip[order - 1][Ip][0];
L1 = Tetra__L0123_Ip[order - 1][Ip][1];
L2 = Tetra__L0123_Ip[order - 1][Ip][2];
L3 = Tetra__L0123_Ip[order - 1][Ip][3];
OUT__whV_xi_Ip[0] = L1;
OUT__whV_xi_Ip[1] = L2;
OUT__whV_xi_Ip[2] = L3;
}
/* 領域での積分点の重み係数 */
void WH_Fem__NumInt__Gauss3D__Tetra__w_Ip
(int order,
int Ip,
double *OUT__w_Ip)
/*
入力引数:
order は整数で、ガウス積分の次数
Ip は整数で、積分点ID
出力引数:
OUT__w_Ip はスカラーで、重み係数
*/
{
assert(0 < order);
assert(order <= MAX_TETRA_ORDER);
assert(0 <= Ip);
assert(Ip < Tetra__nPoints[order - 1]);
*OUT__w_Ip = Tetra__w_Ip[order - 1][Ip];
}
/* 境界表面上での積分点数 */
void WH_Fem__NumInt__Gauss3D__Tetra__nPoints_Iface
(int order,
int Iface,
int *OUT__nPoints)
/*
入力引数:
order は整数で、ガウス積分の次数
Iface は整数で、要素面ID
出力引数:
OUT__nPoints は整数で、積分点数
*/
{
WH_Fem__NumInt__Gauss2D__Tri__nPoints
(order,
OUT__nPoints);
}
/* 境界表面上での積分点の自然座標 */
void WH_Fem__NumInt__Gauss3D__Tetra__whV_xi_IfaceIp
(int order,
int Iface,
int Ip,
double OUT__whV_xi_Ip[3])
/*
入力引数:
order は整数で、ガウス積分の次数
Iface は整数で、要素面ID
Ip は整数で、積分点ID
出力引数:
OUT__whV_xi_Ip はベクトルで、自然座標
*/
{
double whV_xi_tri[2];
double L0_tri, L1_tri, L2_tri;
double L0, L1, L2, L3;
WH_Fem__NumInt__Gauss2D__Tri__whV_xi_Ip
(order, Ip,
whV_xi_tri);
L0_tri = 1.0 - whV_xi_tri[0] - whV_xi_tri[1];
L1_tri = whV_xi_tri[0];
L2_tri = whV_xi_tri[1];
switch (Iface) {
case 0: /* L0 */
L0 = 0.0;
L1 = L0_tri;
L2 = L1_tri;
L3 = L2_tri;
break;
case 1: /* L1 */
L0 = L2_tri;
L1 = 0.0;
L2 = L0_tri;
L3 = L1_tri;
break;
case 2: /* L2 */
L0 = L1_tri;
L1 = L2_tri;
L2 = 0.0;
L3 = L0_tri;
break;
case 3: /* L3 */
L0 = L0_tri;
L1 = L1_tri;
L2 = L2_tri;
L3 = 0.0;
break;
default:
assert(0);
break;
}
OUT__whV_xi_Ip[0] = L1;
OUT__whV_xi_Ip[1] = L2;
OUT__whV_xi_Ip[2] = L3;
}
/* 境界表面上での積分点の重み係数 */
void WH_Fem__NumInt__Gauss3D__Tetra__w_IfaceIp
(int order,
int Iface,
int Ip,
double *OUT__w_Ip)
/*
入力引数:
order は整数で、ガウス積分の次数
Iface は整数で、要素面ID
Ip は整数で、積分点ID
出力引数:
OUT__w_Ip はスカラーで、重み係数
*/
{
WH_Fem__NumInt__Gauss2D__Tri__w_Ip
(order, Ip,
OUT__w_Ip);
}