public bool CalcularBDFSegundaOrdem(double[] tempo, ref double[] resultadoNumerico, FuncaoBDF funcao) { bool houveErro = ExecutarLoopMetodoNumerico(tempo, ref resultadoNumerico, NewtonRaphson, NewtonRaphson, NewtonRaphson, BDFSegundaOrdemNewtonRaphson, EulerImplicitoNewtonRaphson, EulerImplicitoNewtonRaphson, funcao); return houveErro; }
private bool ExecutarLoopMetodoNumerico(double[] tempo, ref double[] resultadoNumerico, METODOPARALOOP metodoParaLoop,METODOPARALOOP metodoParaEstimativaInicial, METODOPARALOOP metodoParaExtremidades,METODONEWTONRAPHSON metodoNewtonRaphson, METODONEWTONRAPHSON metodoNewtonRaphsonParaEstimativa, METODONEWTONRAPHSON metodoNewtonRaphsonParaExtremidades,FuncaoBDF funcao) { bool houveErro = false; int i; for (i = 1; i < tempo.Length; i++) { double resultado = resultadoNumerico[i - 1]; //Primeira estimativa double resultadoAnterior = resultadoNumerico[i - 1]; double resultadoAnteriorAnterior; if (i > 1) resultadoAnteriorAnterior = resultadoNumerico[i - 2]; else resultadoAnteriorAnterior = double.NaN; if (metodoParaEstimativaInicial != null) { houveErro = metodoParaEstimativaInicial(tempo[i], (tempo[i] - tempo[i - 1]), resultadoAnteriorAnterior, resultadoAnterior, ref resultado, metodoNewtonRaphsonParaEstimativa, funcao); if (houveErro) return houveErro; } if (i > 1) { houveErro = metodoParaLoop(tempo[i], (tempo[i] - tempo[i - 1]), resultadoAnteriorAnterior, resultadoAnterior, ref resultado, metodoNewtonRaphson, funcao); } else { houveErro = metodoParaExtremidades(tempo[i], (tempo[i] - tempo[i - 1]), resultadoAnteriorAnterior, resultadoAnterior, ref resultado, metodoNewtonRaphsonParaExtremidades, funcao); } if (houveErro) return houveErro; resultadoNumerico[i] = resultado; } return houveErro; }
private bool BDFSegundaOrdemNewtonRaphson(double yAnteriorAnterior, double yAnterior, double yAtual, double intervalo, double tempo, FuncaoBDF funcao, out double resultadoFuncao, out double resultadoDerivadaFuncao) { bool houveErro = false; double valorFuncao; double valorDerivada; houveErro = funcao(tempo, yAtual, out valorFuncao, out valorDerivada); if (houveErro) { resultadoFuncao = 0.0; resultadoDerivadaFuncao = 0.0; return houveErro; } resultadoFuncao = (3 * yAtual - 4 * yAnterior + yAnteriorAnterior) / (2 * intervalo) - valorFuncao; resultadoDerivadaFuncao = 3 / (2 * intervalo) - valorDerivada; return houveErro; }
private bool EulerImplicitoNewtonRaphson(double yAnteriorAnterior, double yAnterior, double yAtual, double intervalo, double tempo, FuncaoBDF funcao, out double resultadoFuncao, out double resultadoDerivadaFuncao) { bool houveErro = false; double valorFuncao; double valorDerivada; houveErro = funcao(tempo, yAtual, out valorFuncao, out valorDerivada); if (houveErro) { resultadoFuncao = 0.0; resultadoDerivadaFuncao = 0.0; return houveErro; } resultadoFuncao = yAnterior - yAtual + intervalo * valorFuncao; resultadoDerivadaFuncao = -1 + intervalo * valorDerivada; return houveErro; }
private bool NewtonRaphson(double tempo, double intervaloDeTempo, double yAnteriorAnterior, double yAnterior, ref double yAtual, METODONEWTONRAPHSON metodoNewtonRaphson, FuncaoBDF funcao) { bool houveErro = false; int numeroMaxIteracoes = 500; int contadorIteracoes = 0; double tolerancia = 1e-14; double estimativaInicial = yAtual; double valorCalculado = estimativaInicial; double delta = 10 * tolerancia; while (delta > tolerancia) { double fx; double dfx; houveErro = metodoNewtonRaphson(yAnteriorAnterior, yAnterior, valorCalculado, intervaloDeTempo, tempo, funcao, out fx, out dfx); if (houveErro) return houveErro; double fix = valorCalculado - fx / dfx; delta = Math.Abs(fix - valorCalculado); if (delta > tolerancia) valorCalculado = fix; contadorIteracoes++; if (contadorIteracoes > numeroMaxIteracoes) { houveErro = true; return houveErro; } } yAtual = valorCalculado; return houveErro; }