unsafe public override void __update() { //積分点のアップデート elemGrad.zeros(); elemLoad.zeros(); elemEnergy = 0; integralPoint _i = null; //体積の計算 double _v = 0; fixed(double *_ptr1 = &elemGrad.rawData[0], _ptr2 = &this.elemLoad.rawData[0]) { for (int i = 0; i < nIntPoints; i++) { _i = intPoints[i]; _i.Update(); _v += _i.w * Math.Sqrt(_i.metric.det); } this._volume = _v; for (int i = 0; i < nIntPoints; i++) { _i = intPoints[i]; _i.stress2 = constitutive(this, _i); _i.gravity = constitutiveG(this, _i); _i.stress.Products(_i.stress2, _i.metric); double *ptr1 = _ptr1; double J = Math.Sqrt(_i.metric.det); /*energy*/ elemEnergy += _i.energyDensity * _i.w * J; /*stress*/ for (int k = 0; k < this.dof; k++) { *ptr1 += 0.5 * _i.w * J * matrix.DoubleDot(_i.stress2, _i.difMetric[k]); ptr1++; } /*volume force*/ double *ptr2 = _ptr2; for (int j = 0; j < nNodes; j++) { for (int k = 0; k < __dim; k++) { *ptr2 += J * _i.w * _i.wp[j] * _i.gravity[k]; ptr2++; } } } } }
public isoparametricElement(params int[] _el) : base(_el) { if (this.nNodes == 2) { __N = 1; } else if (this.nNodes == 4) { __N = 2; } else if (this.nNodes == 8) { __N = 3; } else { throw new mikity.Exceptions.NumberOfNodesIncompatibleException("Isoparametric element only accept 2,4,8 nodes."); } nNodes = this.nNodes; nIntPoints = mikity.MathUtil.__pow_INT_INT(nIntMed, __N); nVisPoints = mikity.MathUtil.__pow_INT_INT(nVisMed, __N); intPoints = new integralPoint[nIntPoints]; this.nodes = new matrix(this.nNodes, this.__dim); for (int i = 0; i < intPoints.Length; i++) { intPoints[i] = new integralPoint(__N, this.nodes, this.__dim); } //形状関数生成用数列 psi = mikity.MathUtil.generate(__N, 2); phi = -2 * psi + 1; psi2 = mikity.MathUtil.generate(__N, nIntMed); psi3 = mikity.MathUtil.generate(__N, nVisMed); //積分点要素内座標生成 for (int i = 0; i < nIntPoints; i++) { double[] t = new double[__N]; for (int j = 0; j < __N; j++) { t[j] = __u[psi2[i, j]]; } intPoints[i].setLocalCoordinates(t); } //積分点積分用重み生成 for (int i = 0; i < nIntPoints; i++) { double w = 1.0d; for (int j = 0; j < __N; j++) { w *= __w[psi2[i, j]]; } intPoints[i].setIntegralWeights(w); } //重み算出用補助数列生成 for (int i = 0; i < nIntPoints; i++) { mikity.LinearAlgebra.matrix T = new mikity.LinearAlgebra.matrix(nNodes, __N); for (int j = 0; j < nNodes; j++) { for (int k = 0; k < __N; k++) { T[j, k] = intPoints[i].localCoordinates(k) * phi[j, k] + psi[j, k]; } } intPoints[i].setHelperNumber(T); } //積分点位置ベクトル算出用重み生成 for (int i = 0; i < nIntPoints; i++) { mikity.LinearAlgebra.vector tt = new mikity.LinearAlgebra.vector(nNodes); for (int j = 0; j < nNodes; j++) { tt[j] = 1.0d; for (int k = 0; k < __N; k++) { tt[j] *= (intPoints[i].Tij[j, k]); } } intPoints[i].setNodeWeights(tt); } //積分点基底ベクトル算出用重み生成 for (int i = 0; i < nIntPoints; i++) { mikity.LinearAlgebra.matrix ttt = new mikity.LinearAlgebra.matrix(nNodes, __N); for (int j = 0; j < nNodes; j++) { for (int k = 0; k < __N; k++) { ttt[j, k] = intPoints[i].wp[j] / (intPoints[i].Tij[j, k]) * phi[j, k]; } } intPoints[i].setBaseWeights(ttt); } this.makeBoundary(); }
//一辺に並ぶ積分点の数 public simplexElement(int[] _el) : base(_el) { __N = _el.Length - 1; if (__N < 1) { throw new mikity.Exceptions.NumberOfNodesIncompatibleException("Simplex element only accept 2,3,4 nodes."); } if (__N > 3) { throw new mikity.Exceptions.NumberOfNodesIncompatibleException("Simplex element only accept 2,3,4 nodes."); } nIntPoints = 1; nVisPoints = 1; intPoints = new integralPoint[nIntPoints]; this.nodes = new matrix(this.nNodes, this.__dim); for (int i = 0; i < intPoints.Length; i++) { intPoints[i] = new integralPoint(__N, this.nodes, this.__dim); } //積分点要素内座標生成 for (int i = 0; i < nIntPoints; i++) { double[] t = new double[__N]; double F = __N + 1; for (int j = 0; j < __N; j++) { t[j] = (double)j / F; } intPoints[i].setLocalCoordinates(t); } //積分点積分用重み生成 for (int i = 0; i < nIntPoints; i++) { double w = 1.0d; for (int j = 1; j <= __N; j++) { w /= (double)j; } intPoints[i].setIntegralWeights(w); } //積分点位置ベクトル算出用重み生成 for (int i = 0; i < nIntPoints; i++) { mikity.LinearAlgebra.vector tt = new mikity.LinearAlgebra.vector(nNodes); if (__N == 1) { tt[0] = intPoints[i].localCoordinates(0); tt[1] = -intPoints[i].localCoordinates(0) + 1; } if (__N == 2) { tt[0] = intPoints[i].localCoordinates(0); tt[1] = -intPoints[i].localCoordinates(0) + intPoints[i].localCoordinates(1); tt[2] = -intPoints[i].localCoordinates(1) + 1; } if (__N == 3) { tt[0] = intPoints[i].localCoordinates(0); tt[1] = -intPoints[i].localCoordinates(0) + intPoints[i].localCoordinates(1); tt[1] = -intPoints[i].localCoordinates(1) + intPoints[i].localCoordinates(2); tt[2] = -intPoints[i].localCoordinates(2) + 1; } intPoints[i].setNodeWeights(tt); } //積分点基底ベクトル算出用重み生成 for (int i = 0; i < nIntPoints; i++) { mikity.LinearAlgebra.matrix ttt = new mikity.LinearAlgebra.matrix(nNodes, __N); if (__N == 1) { ttt[0, 0] = 1; ttt[1, 0] = -1; } if (__N == 2) { ttt[0, 0] = 1; ttt[1, 0] = -1; ttt[1, 1] = 1; ttt[2, 1] = -1; } if (__N == 3) { ttt[0, 0] = 1; ttt[1, 0] = -1; ttt[1, 1] = 1; ttt[2, 1] = -1; ttt[2, 2] = 1; ttt[3, 2] = -1; } intPoints[i].setBaseWeights(ttt); } this.makeBoundary(); }