位置(全体座標)は、配列変数として実装される。
/* 位置変数 whV_x はベクトルで、 例えば以下のように定義される。 double whV_x[3]; whV_x[0] は x, whV_x[1] は y, whV_x[2] は zを表す。 */
体積座標から位置(全体座標)を求める 関数は以下のようになる。
/* 体積座標に対応する位置 */ void WH_Fem__Simplex3D__whV_x (double whV_x0[3], double whV_x1[3], double whV_x2[3], double whV_x3[3], double L0, double L1, double L2, double L3, double OUT__whV_x[3]) /* 入力引数: whV_x0, whV_x1, whV_x2, whV_x3 はベクトルで、各頂点の位置 L0, L1, L2, L3 はスカラーで、体積座標 出力引数: OUT__whV_x はベクトルで、位置 */ { OUT__whV_x[0] = L0 * whV_x0[0] + L1 * whV_x1[0] + L2 * whV_x2[0]; OUT__whV_x[1] = L0 * whV_x0[1] + L1 * whV_x1[1] + L2 * whV_x2[1]; OUT__whV_x[2] = L0 * whV_x0[2] + L1 * whV_x1[2] + L2 * whV_x2[2]; }
位置(全体座標)から体積座標を求める 関数は以下のようになる。
/* 係数 a */ void WH_Fem__Simplex3D__a (double whV_x0[3], double whV_x1[3], double whV_x2[3], double whV_x3[3], double V, double *OUT__a0, double *OUT__a1, double *OUT__a2, double *OUT__a3) /* 入力引数: whV_x0, whV_x1, whV_x2, whV_x3 はベクトルで、各頂点の位置 V はスカラーで、四面体の体積 出力引数: OUT__a0, OUT__a1, OUT__a2, OUT__a3 はスカラーで、係数 */ { double x0 = whV_x0[0]; double x1 = whV_x1[0]; double x2 = whV_x2[0]; double x3 = whV_x3[0]; double y0 = whV_x0[1]; double y1 = whV_x1[1]; double y2 = whV_x2[1]; double y3 = whV_x3[1]; double z0 = whV_x0[2]; double z1 = whV_x1[2]; double z2 = whV_x2[2]; double z3 = whV_x3[2]; double factor = 1.0 / (6.0 * V); *OUT__a0 = factor * (+ x1 * y2 * z3 + x3 * y1 * z2 + x2 * y3 * z1 - x1 * y3 * z2 - x2 * y1 * z3 - x3 * y2 * z1); *OUT__a1 = factor * (+ x0 * y2 * z3 + x3 * y0 * z2 + x2 * y3 * z0 - x0 * y3 * z2 - x2 * y0 * z3 - x3 * y2 * z0); *OUT__a2 = factor * (+ x0 * y1 * z3 + x3 * y0 * z1 + x1 * y3 * z0 - x0 * y3 * z1 - x1 * y0 * z3 - x3 * y1 * z0); *OUT__a3 = factor * (+ x0 * y1 * z2 + x2 * y0 * z1 + x1 * y2 * z0 - x0 * y2 * z1 - x1 * y0 * z2 - x3 * y1 * z0); } /* 係数 b, c, d */ void WH_Fem__Simplex3D__bcd (double whV_x0[3], double whV_x1[3], double whV_x2[3], double whV_x3[3], double V, double *OUT__b0, double *OUT__b1, double *OUT__b2, double *OUT__b3, double *OUT__c0, double *OUT__c1, double *OUT__c2, double *OUT__c3, double *OUT__d0, double *OUT__d1, double *OUT__d2, double *OUT__d3) /* 入力引数: whV_x0, whV_x1, whV_x2, whV_x3 はベクトルで、各頂点の位置 V はスカラーで、四面体の体積 出力引数: OUT__b0, OUT__b1, OUT__b2, OUT__b3 はスカラーで、係数 b OUT__c0, OUT__c1, OUT__c2, OUT__c3 はスカラーで、係数 c OUT__d0, OUT__d1, OUT__d2, OUT__d3 はスカラーで、係数 d */ { double x0 = whV_x0[0]; double x1 = whV_x1[0]; double x2 = whV_x2[0]; double x3 = whV_x3[0]; double y0 = whV_x0[1]; double y1 = whV_x1[1]; double y2 = whV_x2[1]; double y3 = whV_x3[1]; double z0 = whV_x0[2]; double z1 = whV_x1[2]; double z2 = whV_x2[2]; double z3 = whV_x3[2]; double factor = 1.0 / (6.0 * V); *OUT__b0 = factor * (- y1 * z2 + y1 * z3 + y2 * z1 - y2 * z3 - y3 * z1 + y3 * z2); *OUT__b1 = factor * (+ y0 * z2 - y0 * z3 - y2 * z0 + y2 * z3 + y3 * z0 - y3 * z2); *OUT__b2 = factor * (- y0 * z1 + y0 * z3 + y1 * z0 - y1 * z3 - y3 * z0 + y3 * z1); *OUT__b3 = factor * (+ y0 * z1 - y0 * z2 - y1 * z0 + y1 * z2 + y2 * z0 - y2 * z1); *OUT__c0 = factor * (+ z2 * x1 - z3 * x1 - z1 * x2 + z3 * x2 + z1 * x3 - z2 * x3); *OUT__c1 = factor * (- z2 * x0 + z3 * x0 + z0 * x2 - z3 * x2 - z0 * x3 + z2 * x3); *OUT__c2 = factor * (+ z1 * x0 - z3 * x0 - z0 * x1 + z3 * x1 + z0 * x3 - z1 * x3); *OUT__c3 = factor * (- z1 * x0 + z2 * x0 + z0 * x1 - z2 * x1 - z0 * x2 + z1 * x2); *OUT__d0 = factor * (- x2 * y1 + x3 * y1 + x1 * y2 - x3 * y2 - x1 * y3 + x2 * y3); *OUT__d1 = factor * (+ x2 * y1 - x3 * y1 - x1 * y2 + x3 * y2 + x1 * y3 - x2 * y3); *OUT__d2 = factor * (- x2 * y1 + x3 * y1 + x1 * y2 - x3 * y2 - x1 * y3 + x2 * y3); *OUT__d3 = factor * (+ x2 * y1 - x3 * y1 - x1 * y2 + x3 * y2 + x1 * y3 - x2 * y3); } /* 位置(全体座標)に対応する体積座標 */ void WH_Fem__Simplex3D__L0123 (double whV_x0[3], double whV_x1[3], double whV_x2[3], double whV_x3[3], double whV_x[3], double *OUT__L0, double *OUT__L1, double *OUT__L2, double *OUT__L3) /* 入力引数: whV_x0, whV_x1, whV_x2, whV_x3 はベクトルで、各頂点の位置 whV_x はベクトルで、位置(全体座標) 出力引数: OUT__L0, OUT__L1, OUT__L2, OUT__L3 はスカラーで、体積座標 */ { double x = whV_x[0]; double y = whV_x[1]; double z = whV_x[2]; double V; double a0, a1, a2, a3; double b0, b1, b2, b3; double c0, c1, c2, c3; double d0, d1, d2, d3; WH_Fem__Simplex3D__V (whV_x0, whV_x1, whV_x2, whV_x3, &V); WH_Fem__Simplex3D__a (whV_x0, whV_x1, whV_x2, whV_x3, V, &a0, &a1, &a2, &a3); WH_Fem__Simplex3D__bcd (whV_x0, whV_x1, whV_x2, whV_x3, V, &b0, &b1, &b2, &b3, &c0, &c1, &c2, &c3, &d0, &d1, &d2, &d3); *OUT__L0 = a0 + b0 * x + c0 * y + d0 * z; *OUT__L1 = a1 + b1 * x + c1 * y + d1 * z; *OUT__L2 = a2 + b2 * x + c2 * y + d2 * z; *OUT__L3 = a3 + b3 * x + c3 * y + d3 * z; }
体積座標の勾配を求める 関数は以下のようになる。
/* 体積座標の勾配 */ void WH_Fem__Simplex3D__whP_L0123_whV_x (double whV_x0[3], double whV_x1[3], double whV_x2[3], double whV_x3[3], double OUT__whP_L0_whV_x[3], double OUT__whP_L1_whV_x[3], double OUT__whP_L2_whV_x[3], double OUT__whP_L3_whV_x[3]) /* 入力引数: whV_x0, whV_x1, whV_x2, whV_x3 はベクトルで、各頂点の位置 出力引数: OUT__whP_L0_whV_x, OUT__whP_L1_whV_x, OUT__whP_L2_whV_x, OUT__whP_L3_whV_x はベクトルで、体積座標の勾配 */ { double V; double b0, b1, b2, b3; double c0, c1, c2, c3; double d0, d1, d2, d3; WH_Fem__Simplex3D__V (whV_x0, whV_x1, whV_x2, whV_x3, &V); WH_Fem__Simplex3D__bcd (whV_x0, whV_x1, whV_x2, whV_x3, V, &b0, &b1, &b2, &b3, &c0, &c1, &c2, &c3, &d0, &d1, &d2, &d3); OUT__whP_L0_whV_x[0] = b0; OUT__whP_L1_whV_x[0] = b1; OUT__whP_L2_whV_x[0] = b2; OUT__whP_L3_whV_x[0] = b3; OUT__whP_L0_whV_x[1] = c0; OUT__whP_L1_whV_x[1] = c1; OUT__whP_L2_whV_x[1] = c2; OUT__whP_L3_whV_x[1] = c3; OUT__whP_L0_whV_x[2] = d0; OUT__whP_L1_whV_x[2] = d1; OUT__whP_L2_whV_x[2] = d2; OUT__whP_L3_whV_x[2] = d3; }