コード例 #1
0
ファイル: Matrix.cs プロジェクト: windripple/popolo
 /// <summary>行列とベクトルの積と和を計算する(y = α op(A) x + βy)</summary>
 /// <param name="vectorX">ベクトルX</param>
 /// <param name="vectorY">ベクトルY(解が上書きされる)</param>
 /// <param name="alpha">第一項の係数</param>
 /// <param name="beta">第二項の係数</param>
 internal void VectorProduct(Vector vectorX, ref Vector vectorY, double alpha, double beta)
 {
     for (uint i = 0; i < this.Columns; i++)
     {
         vectorY.SetValue(i, vectorY.GetValue(i) * beta);
         for (uint j = 0; j < this.Rows; j++)
         {
             vectorY.AddValue(i, alpha * this.GetValue(i, j) * vectorX.GetValue(j));
         }
     }
 }
コード例 #2
0
ファイル: Matrix.cs プロジェクト: windripple/popolo
 /// <summary>matrix1の逆行列を計算してmatrix2に設定する</summary>
 /// <param name="matrix"></param>
 internal void GetInverse(ref Matrix matrix)
 {
     LUDecomposition();
     Vector col = new Vector(Columns);
     for (uint j = 0; j < Columns; j++)
     {
         col.SetValue(0);
         col.SetValue(j, 1);
         LUSolve(ref col);
         for (uint i = 0; i < Columns; i++) matrix.SetValue(i, j, col.GetValue(i));
     }
 }
コード例 #3
0
ファイル: Matrix.cs プロジェクト: windripple/popolo
 /// <summary></summary>
 /// <param name="vector"></param>
 internal void LUSolve(ref Vector vector)
 {
     if (isMatrixView)
     {
         uint ii = 0;
         for (uint i = 0; i < Rows; i++)
         {
             uint ip = perm[i];
             double sum = vector.GetValue(ip);
             vector.SetValue(ip, vector.GetValue(i));
             if (ii != 0)
             {
                 for (uint j = ii - 1; j < i; j++) sum -= GetValue(i, j) * vector.GetValue(j);
             }
             else if (sum != 0) ii = i + 1;
             vector.SetValue(i, sum);
         }
         for (int i = (int)Rows - 1; i >= 0; i--)
         {
             uint iii = (uint)i;
             double sum = vector.GetValue(iii);
             for (uint j = iii + 1; j < Columns; j++) sum -= GetValue(iii, j) * vector.GetValue(j);
             vector.SetValue(iii, sum / GetValue(iii, iii));
         }
     }
     else
     {
         uint ii = 0;
         for (uint i = 0; i < Rows; i++)
         {
             uint ip = perm[i];
             double sum = vector.GetValue(ip);
             vector.SetValue(ip, vector.GetValue(i));
             if (ii != 0)
             {
                 for (uint j = ii - 1; j < i; j++) sum -= mat[i, j] * vector.GetValue(j);
             }
             else if (sum != 0) ii = i + 1;
             vector.SetValue(i, sum);
         }
         for (int i = (int)Rows - 1; i >= 0; i--)
         {
             uint iii = (uint)i;
             double sum = vector.GetValue(iii);
             for (uint j = iii + 1; j < Columns; j++) sum -= mat[iii, j] * vector.GetValue(j);
             vector.SetValue(iii, sum / mat[iii, iii]);
         }
     }
 }
コード例 #4
0
ファイル: BodyPart.cs プロジェクト: windripple/popolo
        /// <summary>行列要素を設定する(JOSモデル)</summary>
        /// <param name="zm">ZMベクトル(要素の単位は全てW)</param>
        /// <param name="bm">BM行列(要素の単位は全てW/K)</param>
        private void makeJOSMatrix(ref Vector zm, ref Matrix bm)
        {
            const double RCS = HumanBody.RHO_C / 3.6d;  //流量単位がL/hなので、ここで単位を調整
            double dt = Body.timeStep;
            bool hasAVA = (heatCapacity_SuperficialVein != 0);
            double sum;

            //JOS計算用にコア・脂肪・筋肉層を統合
            double hcapCore = heatCapacity_Core + heatCapacity_Fat + heatCapacity_Muscle;
            double bfCore = bloodFlow_Core + bloodFlow_Fat + bloodFlow_Muscle;
            double mrCore = metabolicRate_Core + metabolicRate_Fat + metabolicRate_Muscle;

            //皮膚・空気間の熱コンダクタンスを更新
            updateHeatConductance_Skin_Air();

            //蒸発熱損失を計算
            //不感蒸泄分
            double eMax = LatentHeatConductance_Skin_Air * (HumanBody.getSaturatedVaporPressure(SkinTemperature_NonContact)
                - HumanBody.getVaporPressure(DrybulbTemperature, RelativeHumidity, Body.AtmosphericPressure));
            EvaporativeHeatLoss = 0.06 * eMax + EvaporativeHeatLoss_Sweat * 0.94;

            //ZMベクトルを設定*************************************************************************
            zm.SetValue(0, hcapCore * 3600 * coreTemperature / dt + mrCore + WorkLoad + ShiveringLoad);
            zm.SetValue(1, heatCapacity_Skin * 3600 * SkinTemperature_Contact / dt + MaterialTemperature * HeatConductance_Skin_Material * SurfaceArea + metabolicRate_Skin);
            zm.SetValue(2, heatCapacity_Skin * 3600 * SkinTemperature_NonContact / dt + OperativeTemperature * HeatConductance_Skin_Air + metabolicRate_Skin - EvaporativeHeatLoss);
            zm.SetValue(3, heatCapacity_Artery * 3600 * arteryTemperature / dt);
            zm.SetValue(4, heatCapacity_DeepVein * 3600 * deepVeinTemperature / dt);
            if (hasAVA) zm.SetValue(5, heatCapacity_SuperficialVein * 3600 * superficialVeinTemperature / dt);

            //BM行列を設定*****************************************************************************
            //コア層
            bm.SetValue(0, 0, hcapCore * 3600d / dt + RCS * bfCore
                + 2 * heatConductance_Vein_Core + heatConductance_Core_Skin);
            bm.SetValue(0, 1, -ContactPortionRate * heatConductance_Core_Skin);
            bm.SetValue(0, 2, -NonContactPortionRate * heatConductance_Core_Skin);
            bm.SetValue(0, 3, -(RCS * bfCore + heatConductance_Vein_Core));
            bm.SetValue(0, 4, -heatConductance_Vein_Core);
            if (hasAVA) bm.SetValue(0, 5, 0);

            //皮膚層接触部
            bm.SetValue(1, 0, -heatConductance_Core_Skin);
            bm.SetValue(1, 1, heatCapacity_Skin * 3600d / dt + RCS * bloodFlow_Skin + heatConductance_Core_Skin
                + heatConductance_SuperficialVein_Skin + HeatConductance_Skin_Material * SurfaceArea);
            bm.SetValue(1, 2, 0);
            bm.SetValue(1, 3, -RCS * bloodFlow_Skin);
            bm.SetValue(1, 4, 0);
            if (hasAVA) bm.SetValue(1, 5, -heatConductance_SuperficialVein_Skin);

            //皮膚層非接触部
            bm.SetValue(2, 0, -heatConductance_Core_Skin);
            bm.SetValue(2, 1, 0);
            bm.SetValue(2, 2, heatCapacity_Skin * 3600d / dt + RCS * bloodFlow_Skin + heatConductance_Core_Skin
                + heatConductance_SuperficialVein_Skin + HeatConductance_Skin_Air);
            bm.SetValue(2, 3, -RCS * bloodFlow_Skin);
            bm.SetValue(2, 4, 0);
            if (hasAVA) bm.SetValue(2, 5, -heatConductance_SuperficialVein_Skin);

            //動脈
            bm.SetValue(3, 0, -heatConductance_Vein_Core);
            bm.SetValue(3, 1, 0);
            bm.SetValue(3, 2, 0);
            bm.SetValue(3, 3, heatCapacity_Artery * 3600d / dt + RCS * bloodFlow_Artery + heatConductance_Vein_Core + heatConductance_Artery_DeepVein);
            bm.SetValue(3, 4, -heatConductance_Artery_DeepVein);
            if (hasAVA) bm.SetValue(3, 5, 0);

            //深部静脈
            bm.SetValue(4, 0, -(RCS * bfCore + heatConductance_Vein_Core));
            bm.SetValue(4, 1, -ContactPortionRate * RCS * bloodFlow_Skin);
            bm.SetValue(4, 2, -NonContactPortionRate * RCS * bloodFlow_Skin);
            bm.SetValue(4, 3, -heatConductance_Artery_DeepVein);
            sum = heatCapacity_DeepVein * 3600d / dt + RCS * bfCore + RCS * bloodFlow_Skin
                + heatConductance_Vein_Core + heatConductance_Artery_DeepVein;
            foreach (BodyPart bp in bpConnectTo)
            {
                if (Position == HumanBody.Nodes.Pelvis) sum += RCS * (bp.GetBloodFlow(Segments.DeepVein) + bp.GetBloodFlow(Segments.SuperficialVein));
                else sum += RCS * bp.GetBloodFlow(Segments.DeepVein);
            }
            bm.SetValue(4, 4, sum);
            if (hasAVA) bm.SetValue(4, 5, 0);

            //表在静脈
            if (hasAVA)
            {
                bm.SetValue(5, 0, 0);
                bm.SetValue(5, 1, -ContactPortionRate * heatConductance_SuperficialVein_Skin);
                bm.SetValue(5, 2, -NonContactPortionRate * heatConductance_SuperficialVein_Skin);
                //四肢末端部の場合
                if ((Position & HumanBody.Nodes.TerminalPart) != HumanBody.Nodes.None) bm.SetValue(5, 3, -RCS * GetBloodFlow(Segments.SuperficialVein));
                //その他
                else bm.SetValue(5, 3, 0);
                bm.SetValue(5, 4, 0);
                sum = heatCapacity_SuperficialVein * 3600d / dt + heatConductance_SuperficialVein_Skin;
                if ((Position & HumanBody.Nodes.TerminalPart) != HumanBody.Nodes.None) sum += RCS * GetBloodFlow(Segments.SuperficialVein);
                if (Position != HumanBody.Nodes.Pelvis)
                {
                    foreach (BodyPart bp in bpConnectTo) sum += RCS * bp.GetBloodFlow(Segments.SuperficialVein);
                }
                bm.SetValue(5, 5, sum);
            }
        }