Example #1
0
            public TreeNode(FCurves window, Utl.ParameterTreeNode paramTreeNode)
            {
                this.window = window;
                ID          = "###" + Manager.GetUniqueID().ToString();

                Children = new List <TreeNode>();
                FCurves  = new List <FCurve>();

                ParamTreeNode = paramTreeNode;

                foreach (var tn in paramTreeNode.Children)
                {
                    Children.Add(new TreeNode(window, tn));
                }

                foreach (var v in paramTreeNode.Parameters)
                {
                    var v_ = FCurve.Create(v, window);
                    v_.ParentNode = this;

                    FCurves.Add(v_);
                }
            }
Example #2
0
        void SetParameters(Utl.ParameterTreeNode paramTreeNodes)
        {
            List<FCurve> befores = new List<FCurve>();
            List<FCurve> afters = new List<FCurve>();

            Action<TreeNode, List<FCurve>> getFcurves = null;
            getFcurves = (node, target) =>
                {
                    if (node == null) return;
                    foreach (var f in node.FCurves)
                    {
                        target.Add(f);
                    }

                    foreach (var c in node.Children)
                    {
                        getFcurves(c, target);
                    }
                };

            getFcurves(treeNodes, befores);

            // 初期設定
            if (treeNodes == null)
            {
                treeNodes = new TreeNode(this, paramTreeNodes);
            }

            // ノードの構造比較変更
            if (treeNodes.ParamTreeNode.Node != paramTreeNodes.Node)
            {
                treeNodes = new TreeNode(this, paramTreeNodes);
            }
            else
            {
                Action<Utl.ParameterTreeNode, TreeNode> refleshNodes = null;
                refleshNodes = (ptn, tn) =>
                    {
                        // 変更がないか確認
                        bool nochange = tn.Children.Count() == ptn.Children.Count();
                        for (int i = 0; i < ptn.Children.Count() && nochange; i++)
                        {
                            if (tn.Children[i].ParamTreeNode != ptn.Children[i])
                            {
                                nochange = false;
                                break;
                            }
                        }
                        if (nochange) return;

                        // 変更があった場合
                        var a = new TreeNode[ptn.Children.Count()];

                        for (int i = 0; i < ptn.Children.Count(); i++)
                        {
                            TreeNode tn_ = tn.Children.FirstOrDefault(_ => _.ParamTreeNode.Node == ptn.Children[i].Node);
                            if (tn_ != null)
                            {
                                // コピー
                                refleshNodes(ptn.Children[i], tn_);
                                a[i] = tn_;
                            }
                            else
                            {
                                // 新規
                                a[i] = new TreeNode(this, ptn.Children[i]);
                            }
                        }

                        tn.Children.Clear();
                        tn.Children.AddRange(a);
                    };

                refleshNodes(paramTreeNodes, treeNodes);
            }

            // パラメーターの構造比較変更
            {
                Action<Utl.ParameterTreeNode, TreeNode> refleshNodes = null;
                refleshNodes = (ptn, tn) =>
                {
                    // 変更がないか確認
                    bool nochange = true;
                    if (tn.FCurves.Count() == ptn.Parameters.Count())
                    {
                        for (int i = 0; i < tn.FCurves.Count(); i++)
                        {
                            if (tn.FCurves[i].GetValueAsObject() != ptn.Parameters[i].Item2)
                            {
                                nochange = false;
                                break;
                            }
                        }
                    }
                    else
                    {
                        nochange = false;
                    }

                    if (nochange)
                    {
                        for (int i = 0; i < tn.Children.Count(); i++)
                        {
                            refleshNodes(ptn.Children[i], tn.Children[i]);
                        }
                        return;
                    }

                    // 変更があった場合
                    var a = new FCurve[ptn.Parameters.Count()];

                    for (int i = 0; i < ptn.Parameters.Count(); i++)
                    {
                        FCurve f = tn.FCurves.FirstOrDefault(_ => _.GetValueAsObject() == ptn.Parameters[i].Item2);
                        if (f != null)
                        {
                            // コピー
                            a[i] = f;
                        }
                        else
                        {
                            // 新規
                            a[i] = FCurve.Create(ptn.Parameters[i], this);
                            a[i].ParentNode = tn;
                        }
                    }

                    tn.FCurves.Clear();
                    tn.FCurves.AddRange(a);

                    for (int i = 0; i < tn.Children.Count(); i++)
                    {
                        refleshNodes(ptn.Children[i], tn.Children[i]);
                    }
                };

                refleshNodes(paramTreeNodes, treeNodes);
            }

            getFcurves(treeNodes, afters);

            // 消滅イベント
            foreach (var f in befores)
            {
                if (!afters.Contains(f))
                {
                    f.OnRemoved(this.splitContainer.Panel2);
                }
            }

            // 追加イベント
            foreach (var f in afters)
            {
                if (!befores.Contains(f))
                {
                    f.OnAdded(this.splitContainer.Panel2);
                }
            }

            treeNodes.CalculatePosition();

            paramaterTreeNode = paramTreeNodes;
        }
Example #3
0
 public FCurveVector2D()
 {
     X = new FCurve<float>(0);
     Y = new FCurve<float>(0);
 }
Example #4
0
        void SetParameters(Utl.ParameterTreeNode paramTreeNodes)
        {
            List <FCurve> befores = new List <FCurve>();
            List <FCurve> afters  = new List <FCurve>();

            Action <TreeNode, List <FCurve> > getFcurves = null;

            getFcurves = (node, target) =>
            {
                if (node == null)
                {
                    return;
                }
                foreach (var f in node.FCurves)
                {
                    target.Add(f);
                }

                foreach (var c in node.Children)
                {
                    getFcurves(c, target);
                }
            };

            getFcurves(treeNodes, befores);

            // initialize
            if (treeNodes == null)
            {
                treeNodes = new TreeNode(this, paramTreeNodes);
            }

            // compare node structures
            if (treeNodes.ParamTreeNode.Node != paramTreeNodes.Node)
            {
                treeNodes = new TreeNode(this, paramTreeNodes);
            }
            else
            {
                Action <Utl.ParameterTreeNode, TreeNode> refleshNodes = null;
                refleshNodes = (ptn, tn) =>
                {
                    // check whether modification doesn't exist
                    bool nochange = tn.Children.Count() == ptn.Children.Count();
                    for (int i = 0; i < ptn.Children.Count() && nochange; i++)
                    {
                        if (tn.Children[i].ParamTreeNode.Node != ptn.Children[i].Node)
                        {
                            nochange = false;
                            break;
                        }
                    }
                    if (nochange)
                    {
                        return;
                    }

                    // if moditications exsist
                    var a = new TreeNode[ptn.Children.Count()];

                    for (int i = 0; i < ptn.Children.Count(); i++)
                    {
                        TreeNode tn_ = tn.Children.FirstOrDefault(_ => _.ParamTreeNode.Node == ptn.Children[i].Node);
                        if (tn_ != null)
                        {
                            // copy
                            refleshNodes(ptn.Children[i], tn_);
                            a[i] = tn_;
                        }
                        else
                        {
                            // new
                            a[i] = new TreeNode(this, ptn.Children[i]);
                        }
                    }

                    tn.Children.Clear();
                    tn.Children.AddRange(a);
                };

                refleshNodes(paramTreeNodes, treeNodes);
            }

            // compare node structures
            {
                Action <Utl.ParameterTreeNode, TreeNode> refleshNodes = null;
                refleshNodes = (ptn, tn) =>
                {
                    // check whether modification doesn't exist
                    bool nochange = true;
                    if (tn.FCurves.Count() == ptn.Parameters.Count())
                    {
                        for (int i = 0; i < tn.FCurves.Count(); i++)
                        {
                            if (tn.FCurves[i].GetValueAsObject() != ptn.Parameters[i].Item2)
                            {
                                nochange = false;
                                break;
                            }
                        }
                    }
                    else
                    {
                        nochange = false;
                    }

                    if (nochange)
                    {
                        for (int i = 0; i < tn.Children.Count(); i++)
                        {
                            refleshNodes(ptn.Children[i], tn.Children[i]);
                        }
                        return;
                    }

                    // if moditications exsist
                    var a = new FCurve[ptn.Parameters.Count()];

                    for (int i = 0; i < ptn.Parameters.Count(); i++)
                    {
                        FCurve f = tn.FCurves.FirstOrDefault(_ => _.GetValueAsObject() == ptn.Parameters[i].Item2);
                        if (f != null)
                        {
                            // copy
                            a[i] = f;
                        }
                        else
                        {
                            // new
                            a[i]            = FCurve.Create(ptn.Parameters[i], this);
                            a[i].ParentNode = tn;
                        }
                    }

                    tn.FCurves.Clear();
                    tn.FCurves.AddRange(a);

                    for (int i = 0; i < tn.Children.Count(); i++)
                    {
                        refleshNodes(ptn.Children[i], tn.Children[i]);
                    }
                };

                refleshNodes(paramTreeNodes, treeNodes);
            }

            getFcurves(treeNodes, afters);

            // event on removing
            foreach (var f in befores)
            {
                if (!afters.Contains(f))
                {
                    f.OnRemoved();
                }
            }

            // event on adding
            foreach (var f in afters)
            {
                if (!befores.Contains(f))
                {
                    f.OnAdded();
                }
            }

            paramaterTreeNode = paramTreeNodes;
        }
Example #5
0
        // For rectangular sections
        public TemperatureProfile(double lx, double ly, double time, FCurve fcurve)
        {
            NT = Convert.ToInt32((time / 7200) * 1800);
            double dt = time / NT;
            double dx = lx / 2 / (NX - 1);
            double dy = ly / 2 / (NY - 1);

            double[] fireResistances = new double[] { 30, 60, 90, 120, 180, 240 };

            Lx = lx / 2;
            Ly = ly / 2;

            var M = Matrix <double> .Build;
            var V = Vector <double> .Build;

            Temp = M.Dense(NX, NY, 20.0);

            Matrix <double> A;
            Matrix <double> B;

            X = V.Dense(NX, i => i * dx + dx / 2);
            Y = V.Dense(NY, i => i * dy + dy / 2);

            double Tfire = 0;

            for (int n = 0; n <= NT; n++)
            {
                double t = n * dt / 60;
                if (fcurve == FCurve.Standard)
                {
                    Tfire = 20 + 345 * Math.Log10(8 * t + 1);
                }
                else if (fcurve == FCurve.Hydrocarbon)
                {
                    Tfire = 1080 * (1 - 0.325 * Math.Exp(-0.167 * t) - 0.675 * Math.Exp(-2.5 * t)) + 20;
                }
                // conditions due to symmetry
                Temp.SetColumn(NX - 1, Temp.Column(NX - 2));
                Temp.SetRow(NY - 1, Temp.Row(NY - 2));

                A = M.Dense(NX, NY, (i, j) => (GetA(i, j)));
                B = M.Dense(NX, NY, (i, j) => (GetB(i, j)));

                Temp.SetRow(0, V.Dense(NY, j =>
                {
                    double l = 1.36 - 0.136 * Temp[0, j] / 100 + 0.0057 * (Temp[0, j] / 100) * (Temp[0, j] / 100);
                    return(Temp[0, j] + 25 * dx / l * (Tfire - Temp[0, j]) - dt * B[0, j] / l * 0.7 * 5.6703E-8 * Math.Pow(Temp[0, j] + 273, 4));
                }));

                Temp.SetColumn(0, V.Dense(NX, i =>
                {
                    double l = 1.36 - 0.136 * Temp[i, 0] / 100 + 0.0057 * (Temp[i, 0] / 100) * (Temp[i, 0] / 100);
                    return(Temp[i, 0] + 25 * dy / l * (Tfire - Temp[i, 0]) - dt * B[i, 0] / l * 0.7 * 5.6703E-8 * Math.Pow(Temp[i, 0] + 273, 4));
                }));

                var Temp2 = Temp.SubMatrix(1, NX - 2, 1, NY - 2)
                            + dt / (4 * dx * dx) * A.SubMatrix(1, NX - 2, 1, NY - 2).PointwiseMultiply(Temp.SubMatrix(2, NX - 2, 1, NY - 2).PointwisePower(2) - 2 * Temp.SubMatrix(2, NX - 2, 1, NY - 2).PointwiseMultiply(Temp.SubMatrix(0, NX - 2, 1, NY - 2)) + Temp.SubMatrix(0, NX - 2, 1, NY - 2).PointwisePower(2))
                            + dt / (4 * dy * dy) * A.SubMatrix(1, NX - 2, 1, NY - 2).PointwiseMultiply(Temp.SubMatrix(1, NX - 2, 2, NY - 2).PointwisePower(2) - 2 * Temp.SubMatrix(1, NX - 2, 2, NY - 2).PointwiseMultiply(Temp.SubMatrix(1, NX - 2, 0, NY - 2)) + Temp.SubMatrix(1, NX - 2, 0, NY - 2).PointwisePower(2))
                            + dt / (dx * dx) * B.SubMatrix(1, NX - 2, 1, NY - 2).PointwiseMultiply(Temp.SubMatrix(2, NX - 2, 1, NY - 2) - 2 * Temp.SubMatrix(1, NX - 2, 1, NY - 2) + Temp.SubMatrix(0, NX - 2, 1, NY - 2))
                            + dt / (dy * dy) * B.SubMatrix(1, NX - 2, 1, NY - 2).PointwiseMultiply(Temp.SubMatrix(1, NX - 2, 2, NY - 2) - 2 * Temp.SubMatrix(1, NX - 2, 1, NY - 2) + Temp.SubMatrix(1, NX - 2, 0, NY - 2));


                Temp.SetSubMatrix(1, 1, Temp2);

                if (fireResistances.Contains(t))
                {
                    TempMap.Add(t, Temp.Clone());
                }
            }
        }
Example #6
0
        // For Custom Shape sections
        public TemperatureProfile(double cLx, double cLy, double d1x, double d1y, double d2x, double d2y, double d3x, double d3y, double d4x, double d4y, double time, FCurve fcurve)
        {
            NT = Convert.ToInt32((time / 7200) * 1800);
            double dt = time / NT;

            while (NX < 3000)
            {
                double t1 = (NX - 1) * d1x / cLx;
                double t2 = (NX - 1) * d2x / cLx;
                double t3 = (NX - 1) * d3x / cLx;
                double t4 = (NX - 1) * d4x / cLx;
                if (t1 - Convert.ToInt32(t1) == 0 && t2 - Convert.ToInt32(t2) == 0 && t3 - Convert.ToInt32(t3) == 0 && t4 - Convert.ToInt32(t4) == 0)
                {
                    break;
                }
                else
                {
                    NX++;
                }
            }
            while (NY < 3000)
            {
                double t1 = (NY - 1) * d1y / cLy;
                double t2 = (NY - 1) * d2y / cLy;
                double t3 = (NY - 1) * d3y / cLy;
                double t4 = (NY - 1) * d4y / cLy;
                if (t1 - Convert.ToInt32(t1) == 0 && t2 - Convert.ToInt32(t2) == 0 && t3 - Convert.ToInt32(t3) == 0 && t4 - Convert.ToInt32(t4) == 0)
                {
                    break;
                }
                else
                {
                    NY++;
                }
            }
            double dx = cLx / (NX - 1);
            double dy = cLy / (NY - 1);

            int n1x = Convert.ToInt32(d1x / dx);
            int n1y = Convert.ToInt32(d1y / dy);
            int n2x = Convert.ToInt32(d2x / dx);
            int n2y = Convert.ToInt32(d2y / dy);
            int n3x = Convert.ToInt32(d3x / dx);
            int n3y = Convert.ToInt32(d3y / dy);
            int n4x = Convert.ToInt32(d4x / dx);
            int n4y = Convert.ToInt32(d4y / dy);

            double[] fireResistances = new double[] { 30, 60, 90, 120, 180, 240 };

            Lx = cLx;
            Ly = cLy;

            var M = Matrix <double> .Build;
            var V = Vector <double> .Build;

            Temp = M.Dense(NX, NY, 20.0);

            Matrix <double> A;
            Matrix <double> B;

            X = V.Dense(NX, i => i * dx + dx / 2);
            Y = V.Dense(NY, i => i * dy + dy / 2);

            double Tfire = 0;

            for (int n = 0; n <= NT; n++)
            {
                double t = n * dt / 60;
                if (fcurve == FCurve.Standard)
                {
                    Tfire = 20 + 345 * Math.Log10(8 * t + 1);
                }
                else if (fcurve == FCurve.Hydrocarbon)
                {
                    Tfire = 1080 * (1 - 0.325 * Math.Exp(-0.167 * t) - 0.675 * Math.Exp(-2.5 * t)) + 20;
                }

                A = M.Dense(NX, NY, (i, j) => (GetA(i, j)));
                B = M.Dense(NX, NY, (i, j) => (GetB(i, j)));

                // Boundary conditions

                Temp.SetRow(0, V.Dense(NY, j =>
                {
                    double l = 1.36 - 0.136 * Temp[0, j] / 100 + 0.0057 * (Temp[0, j] / 100) * (Temp[0, j] / 100);
                    return(Temp[0, j] + 25 * dx / l * (Tfire - Temp[0, j]) - dt * B[0, j] / l * 0.7 * 5.6703E-8 * Math.Pow(Temp[0, j] + 273, 4));
                }));

                Temp.SetRow(NX - 1, V.Dense(NY, j =>
                {
                    double l = 1.36 - 0.136 * Temp[NX - 1, j] / 100 + 0.0057 * (Temp[NX - 1, j] / 100) * (Temp[NX - 1, j] / 100);
                    return(Temp[NX - 1, j] + 25 * dx / l * (Tfire - Temp[NX - 1, j]) - dt * B[NX - 1, j] / l * 0.7 * 5.6703E-8 * Math.Pow(Temp[NX - 1, j] + 273, 4));
                }));

                Temp.SetColumn(0, V.Dense(NX, i =>
                {
                    double l = 1.36 - 0.136 * Temp[i, 0] / 100 + 0.0057 * (Temp[i, 0] / 100) * (Temp[i, 0] / 100);
                    return(Temp[i, 0] + 25 * dy / l * (Tfire - Temp[i, 0]) - dt * B[i, 0] / l * 0.7 * 5.6703E-8 * Math.Pow(Temp[i, 0] + 273, 4));
                }));

                Temp.SetColumn(NY - 1, V.Dense(NX, i =>
                {
                    double l = 1.36 - 0.136 * Temp[i, NY - 1] / 100 + 0.0057 * (Temp[i, NY - 1] / 100) * (Temp[i, NY - 1] / 100);
                    return(Temp[i, NY - 1] + 25 * dy / l * (Tfire - Temp[i, NY - 1]) - dt * B[i, NY - 1] / l * 0.7 * 5.6703E-8 * Math.Pow(Temp[i, NY - 1] + 273, 4));
                }));

                Temp.SetSubMatrix(0, 0, M.Dense(n1x + 1, n1y + 1, Tfire));
                Temp.SetSubMatrix(NX - n2x - 1, 0, M.Dense(n2x + 1, n2y + 1, Tfire));
                Temp.SetSubMatrix(NX - n3x - 1, NY - n3y - 1, M.Dense(n3x + 1, n3y + 1, Tfire));
                Temp.SetSubMatrix(0, NY - n4y - 1, M.Dense(n4x + 1, n4y + 1, Tfire));

                var Temp2 = Temp.SubMatrix(1, NX - 2, 1, NY - 2)
                            + dt / (4 * dx * dx) * A.SubMatrix(1, NX - 2, 1, NY - 2).PointwiseMultiply(Temp.SubMatrix(2, NX - 2, 1, NY - 2).PointwisePower(2) - 2 * Temp.SubMatrix(2, NX - 2, 1, NY - 2).PointwiseMultiply(Temp.SubMatrix(0, NX - 2, 1, NY - 2)) + Temp.SubMatrix(0, NX - 2, 1, NY - 2).PointwisePower(2))
                            + dt / (4 * dy * dy) * A.SubMatrix(1, NX - 2, 1, NY - 2).PointwiseMultiply(Temp.SubMatrix(1, NX - 2, 2, NY - 2).PointwisePower(2) - 2 * Temp.SubMatrix(1, NX - 2, 2, NY - 2).PointwiseMultiply(Temp.SubMatrix(1, NX - 2, 0, NY - 2)) + Temp.SubMatrix(1, NX - 2, 0, NY - 2).PointwisePower(2))
                            + dt / (dx * dx) * B.SubMatrix(1, NX - 2, 1, NY - 2).PointwiseMultiply(Temp.SubMatrix(2, NX - 2, 1, NY - 2) - 2 * Temp.SubMatrix(1, NX - 2, 1, NY - 2) + Temp.SubMatrix(0, NX - 2, 1, NY - 2))
                            + dt / (dy * dy) * B.SubMatrix(1, NX - 2, 1, NY - 2).PointwiseMultiply(Temp.SubMatrix(1, NX - 2, 2, NY - 2) - 2 * Temp.SubMatrix(1, NX - 2, 1, NY - 2) + Temp.SubMatrix(1, NX - 2, 0, NY - 2));

                Temp.SetSubMatrix(1, 1, Temp2);

                if (fireResistances.Contains(t))
                {
                    TempMap.Add(t, Temp.Clone());
                }
            }
        }
Example #7
0
        // For T Shaped sections
        public TemperatureProfile(double Hx, double Hy, double hx, double hy, double time, FCurve fcurve)
        {
            NT = Convert.ToInt32((time / 7200) * 1800);
            double dt = time / NT;

            while (NX < 3000)
            {
                double t  = (NX - 1) * (Hx - hx) / 2 / Hx;
                double t2 = (NX - 1) * hx / Hx;
                if (t - Convert.ToInt32(t) == 0 && t2 - Convert.ToInt32(t2) == 0)
                {
                    break;
                }
                else
                {
                    NX++;
                }
            }
            while (NY < 3000)
            {
                double t  = (NY - 1) * (Hy - hy) / 2 / Hy;
                double t2 = (NY - 1) * hy / Hy;
                if (t - Convert.ToInt32(t) == 0 && t2 - Convert.ToInt32(t2) == 0)
                {
                    break;
                }
                else
                {
                    NY++;
                }
            }
            double dx = Hx / (NX - 1);
            double dy = Hy / (NY - 1);

            int nx = Convert.ToInt32(hx / dx);
            int ny = Convert.ToInt32(hy / dy);

            double[] fireResistances = new double[] { 30, 60, 90, 120, 180, 240 };

            Lx = Hx;
            Ly = Hy;

            lx = hx;
            ly = hy;

            var M = Matrix <double> .Build;
            var V = Vector <double> .Build;

            Temp = M.Dense(NX, NY, 20.0);

            Matrix <double> A;
            Matrix <double> B;

            X = V.Dense(NX, i => i * dx + dx / 2);
            Y = V.Dense(NY, i => i * dy + dy / 2);

            double Tfire = 0;

            for (int n = 0; n <= NT; n++)
            {
                double t = n * dt / 60;
                if (fcurve == FCurve.Standard)
                {
                    Tfire = 20 + 345 * Math.Log10(8 * t + 1);
                }
                else if (fcurve == FCurve.Hydrocarbon)
                {
                    Tfire = 1080 * (1 - 0.325 * Math.Exp(-0.167 * t) - 0.675 * Math.Exp(-2.5 * t)) + 20;
                }

                A = M.Dense(NX, NY, (i, j) => (GetA(i, j)));
                B = M.Dense(NX, NY, (i, j) => (GetB(i, j)));

                // Boundary conditions

                Temp.SetRow(0, V.Dense(NY, j =>
                {
                    double l = 1.36 - 0.136 * Temp[0, j] / 100 + 0.0057 * (Temp[0, j] / 100) * (Temp[0, j] / 100);
                    return(Temp[0, j] + 25 * dx / l * (Tfire - Temp[0, j]) - dt * B[0, j] / l * 0.7 * 5.6703E-8 * Math.Pow(Temp[0, j] + 273, 4));
                }));

                Temp.SetRow(NX - 1, V.Dense(NY, j =>
                {
                    double l = 1.36 - 0.136 * Temp[NX - 1, j] / 100 + 0.0057 * (Temp[NX - 1, j] / 100) * (Temp[NX - 1, j] / 100);
                    return(Temp[NX - 1, j] + 25 * dx / l * (Tfire - Temp[NX - 1, j]) - dt * B[NX - 1, j] / l * 0.7 * 5.6703E-8 * Math.Pow(Temp[NX - 1, j] + 273, 4));
                }));

                Temp.SetColumn(0, V.Dense(NX, i =>
                {
                    double l = 1.36 - 0.136 * Temp[i, 0] / 100 + 0.0057 * (Temp[i, 0] / 100) * (Temp[i, 0] / 100);
                    return(Temp[i, 0] + 25 * dy / l * (Tfire - Temp[i, 0]) - dt * B[i, 0] / l * 0.7 * 5.6703E-8 * Math.Pow(Temp[i, 0] + 273, 4));
                }));

                Temp.SetColumn(NY - 1, V.Dense(NX, i =>
                {
                    double l = 1.36 - 0.136 * Temp[i, NY - 1] / 100 + 0.0057 * (Temp[i, NY - 1] / 100) * (Temp[i, NY - 1] / 100);
                    return(Temp[i, NY - 1] + 25 * dy / l * (Tfire - Temp[i, NY - 1]) - dt * B[i, NY - 1] / l * 0.7 * 5.6703E-8 * Math.Pow(Temp[i, NY - 1] + 273, 4));
                }));

                Temp.SetSubMatrix(0, 0, M.Dense((NX - nx) / 2 + 1, NY - ny, Tfire));
                Temp.SetSubMatrix((NX + nx) / 2, 0, M.Dense((NX - nx) / 2, NY - ny, Tfire));

                var Temp2 = Temp.SubMatrix(1, NX - 2, 1, NY - 2)
                            + dt / (4 * dx * dx) * A.SubMatrix(1, NX - 2, 1, NY - 2).PointwiseMultiply(Temp.SubMatrix(2, NX - 2, 1, NY - 2).PointwisePower(2) - 2 * Temp.SubMatrix(2, NX - 2, 1, NY - 2).PointwiseMultiply(Temp.SubMatrix(0, NX - 2, 1, NY - 2)) + Temp.SubMatrix(0, NX - 2, 1, NY - 2).PointwisePower(2))
                            + dt / (4 * dy * dy) * A.SubMatrix(1, NX - 2, 1, NY - 2).PointwiseMultiply(Temp.SubMatrix(1, NX - 2, 2, NY - 2).PointwisePower(2) - 2 * Temp.SubMatrix(1, NX - 2, 2, NY - 2).PointwiseMultiply(Temp.SubMatrix(1, NX - 2, 0, NY - 2)) + Temp.SubMatrix(1, NX - 2, 0, NY - 2).PointwisePower(2))
                            + dt / (dx * dx) * B.SubMatrix(1, NX - 2, 1, NY - 2).PointwiseMultiply(Temp.SubMatrix(2, NX - 2, 1, NY - 2) - 2 * Temp.SubMatrix(1, NX - 2, 1, NY - 2) + Temp.SubMatrix(0, NX - 2, 1, NY - 2))
                            + dt / (dy * dy) * B.SubMatrix(1, NX - 2, 1, NY - 2).PointwiseMultiply(Temp.SubMatrix(1, NX - 2, 2, NY - 2) - 2 * Temp.SubMatrix(1, NX - 2, 1, NY - 2) + Temp.SubMatrix(1, NX - 2, 0, NY - 2));

                Temp.SetSubMatrix(1, 1, Temp2);

                if (fireResistances.Contains(t))
                {
                    TempMap.Add(t, Temp.Clone());
                }
            }
        }