public void Perform() { var alfaDt = alfa * dt; var dtAlfa = dt * (1 - alfa); var primal = new double[dimension]; var timeSteps = Temperature.Length; That = new double[dimension]; Tdot = new double[timeSteps][]; for (var i = 0; i < timeSteps; i++) { Tdot[i] = new double[dimension]; } // calculate initial temperature gradients var rhs = MatrixAlgebra.Mult(k, Temperature[0], profile); for (var i = 0; i < dimension; i++) { Tdot[0][i] = (ForcingFunction[0][i] - rhs[i]) / c[i]; } // evaluate constant coefficient matrix var cm = new double[dimension][]; for (var row = 0; row < dimension; row++) { cm[row] = new double[row + 1 - profile[row]]; for (var col = 0; col <= (row - profile[row]); col++) { cm[row][col] = alfaDt * k[row][col]; } cm[row][row - profile[row]] += c[row]; } var profileSolverStatus = new ProfileSolverStatus(cm, rhs, primal, status, profile); profileSolverStatus.Decompose(); for (var counter = 1; counter < timeSteps; counter++) { // calculate temperature gradients at restrained nodes for (var i = 0; i < dimension; i++) { if (status[i]) { Tdot[counter][i] = (Temperature[counter][i] - Temperature[counter - 1][i]) / dt; } } // calculate T(hat) for next step for (var i = 0; i < dimension; i++) { if (status[i]) { That[i] = Temperature[counter][i]; } else { That[i] = Temperature[counter - 1][i] + dtAlfa * Tdot[counter - 1][i]; } } // modification of RHS rhs = MatrixAlgebra.Mult(k, That, status, profile); var rhSfr = MatrixAlgebra.MultUl(cm, Tdot[counter], status, profile); for (var i = 0; i < dimension; i++) { rhs[i] = ForcingFunction[counter][i] - rhSfr[i] - rhs[i]; } // backsubstitution profileSolverStatus.SetRhs(rhs); profileSolverStatus.SolvePrimal(); // temperatures and gradients at next time step for unrestrained nodes for (var i = 0; i < dimension; i++) { if (status[i]) { continue; } Tdot[counter][i] = primal[i]; Temperature[counter][i] = That[i] + alfaDt * primal[i]; } } }