double HistoBase<x_value_type,y_value_type,Derived>::derivative(const_iterator x) const { // If the bin is the first or the last bin, use the simple formula using only one neighbour if (x == min_x_value()) { const_iterator x_plus(x); ++x_plus; return static_cast<double>(x_plus->second - x->second)/static_cast<double>(x_plus->first - x->first); } else if (x == max_x_value()) { const_iterator x_minus(x); --x_minus; return static_cast<double>(x->second - x_minus->second)/static_cast<double>(x->first - x_minus->first); } // If we have a bin in the middle, use both neighbouring points else { const_iterator x_plus(x); ++x_plus; const_iterator x_minus(x); --x_minus; return static_cast<double>(x_plus->second - x_minus->second)/static_cast<double>(x_plus->first - x_minus->first); } }
/* * todo : Need to fix the problem */ void Reconstruct:: SecondOrderMUSCL(Data::DataStorage& Wcll, Data::DataStorage& Wcl, Data::DataStorage& Wcr, Data::DataStorage& Wcrr, vector<double>& xcll, vector<double>& xcl, vector<double>& xcr, vector<double>& xcrr, vector<double>& xf, bool use_limiter, int limiter, Data::DataStorage& Wp, Data::DataStorage& Wm) { double dx, dx_plus, dx_minus, dx_f, dx_fp; Math::VECTOR x(xcl, xcr); Math::VECTOR x_plus(xcr, xcrr); Math::VECTOR x_minus(xcll, xcl); Math::VECTOR x_f(xcl, xf); dx = x.length(); dx_plus = x_plus.length(); dx_minus = x_minus.length(); dx_f = x_f.length(); dx_fp = dx - dx_f; double dW; double dW_plus; double dW_minus; double r, alpha; double phi; double W_min; double W_max; bool error = false; for (int index = 0; index <= Wcll.numData-1; index++) { dW = (Wcr(index) - Wcl(index)); if (dW != 0.0 && dx > 1.0e-10) { dW = dW / dx; dW_minus = Wcl(index) - Wcll(index); dW_plus = Wcrr(index) - Wcr(index); if (dx_minus > 1.0e-10 && dW_minus != 0.0) { dW_minus /= dx_minus; r = dW / dW_minus; alpha = dx / dx_f; phi = Limiter(r, alpha, limiter); } else { phi = 0.0; } Wp(index) = Wcl(index) + phi*dW*dx_f; if (dx_plus > 1.0e-10 && dW_plus != 0.0) { dW_plus /= dx_plus; r = dW_plus / dW; alpha = dx / dx_fp; phi = Limiter(r, alpha, limiter); } else { phi = 0.0; } Wm(index) = Wcr(index) - phi*dW*dx_fp; //if (Wp(index) != Wp(index)) throw Common::ExceptionNaNValue (FromHere(), "NaN value in ReconstructMUSCL"); //if (Wp(index) == numeric_limits<double>::infinity()) throw Common::ExceptionInfiniteValue (FromHere(), "Infinite value in ReconstructMUSCL"); //if (Wm(index) != Wm(index)) throw Common::ExceptionNaNValue (FromHere(), "NaN value in ReconstructMUSCL"); //if (Wm(index) == numeric_limits<double>::infinity()) throw Common::ExceptionInfiniteValue (FromHere(), "Infinite value in ReconstructMUSCL"); W_min = Math::fmin<double>(Wcl(index), Wcr(index)); W_max = Math::fmax<double>(Wcl(index), Wcr(index)); if (Wp(index) < W_min || Wm(index) < W_min || Wp(index) > W_max ||Wm(index) > W_max) { error = true; break; } /* if (Wp(index) < W_min) Wp(index) = W_min; if (Wm(index) < W_min) Wm(index) = W_min; if (Wp(index) > W_max) Wp(index) = W_max; if (Wm(index) > W_max) Wm(index) = W_max; */ } else { Wp(index) = Wcl(index); Wm(index) = Wcr(index); } } if (error == true) { Wp = Wcl; Wm = Wcr; } }
void Reconstruct::SecondOrderMUSCL_ver2(Data::DataStorage& Wcll, Data::DataStorage& Wcl, Data::DataStorage& Wcr, Data::DataStorage& Wcrr, vector<double>& xcll, vector<double>& xcl, vector<double>& xcr, vector<double>& xcrr, vector<double>& xf, bool use_limiter, int limiter, Data::DataStorage& Wp, Data::DataStorage& Wm) { double dx, dx_plus, dx_minus, dx_f, dx_fp; Math::VECTOR x(xcl, xcr); Math::VECTOR x_plus(xcr, xcrr); Math::VECTOR x_minus(xcll, xcl); Math::VECTOR x_f(xcl, xf); dx = x.length(); dx_plus = x_plus.length(); dx_minus = x_minus.length(); dx_f = x_f.length(); dx_fp = dx - dx_f; double dxf_dx = dx_f / dx; double dxfp_dx = dx_fp / dx; double dxp_dx = dx_plus / dx; double dxm_dx = dx_minus / dx; double dW; double dW_plus; double dW_minus; double r, alpha; double phi; double W_min; double W_max; bool error = false; for (int index = 0; index <= Wcll.numData-1; index++) { dW = (Wcr(index) - Wcl(index)); if (dW != 0.0 && dx > 1.0e-10) { dW_minus = Wcl(index) - Wcll(index); dW_plus = Wcrr(index) - Wcr(index); if (dW_plus != 0.0) r = dW / dW_plus * dxp_dx; else r = 0.0; phi = Limiter2(r, limiter); Wp(index) = Wcl(index) + phi*dW*dxf_dx; if (dW_minus != 0.0) r = dW / dW_minus * dxm_dx; else r = 0.0; phi = Limiter2(r, limiter); Wm(index) = Wcr(index) - phi*dW*dxfp_dx; W_min = Math::fmin<double>(Wcl(index), Wcr(index)); W_max = Math::fmax<double>(Wcl(index), Wcr(index)); if (Wp(index) < W_min || Wm(index) < W_min || Wp(index) > W_max ||Wm(index) > W_max) { error = true; break; } } else { Wp(index) = Wcl(index); Wm(index) = Wcr(index); } } if (error == true) { Wp = Wcl; Wm = Wcr; } }