Example #1
0
    /*!
     * \brief Initialize the phase viscosity for oil saturated gas
     *
     * The gas viscosity is a function of \f$(p_g, X_g^O)\f$, but this method only
     * requires the viscosity of oil-saturated gas (which only depends on pressure) while
     * there is assumed to be no dependence on the gas mass fraction...
     */
    void setSaturatedGasViscosity(int regionIdx, const SamplingPoints &samplePoints  )
    {
        auto& oilVaporizationFactor = oilVaporizationFactorTable_[regionIdx];

        Scalar RvMin = 0.0;
        Scalar RvMax = oilVaporizationFactor.eval(oilVaporizationFactorTable_[regionIdx].xMax(), /*extrapolate=*/true);

        Scalar poMin = samplePoints.front().first;
        Scalar poMax = samplePoints.back().first;

        size_t nRv = 20;
        size_t nP = samplePoints.size()*2;

        Spline mugSpline;
        mugSpline.setContainerOfTuples(samplePoints, /*type=*/Spline::Monotonic);

        // calculate a table of estimated densities depending on pressure and gas mass
        // fraction
        for (size_t RvIdx = 0; RvIdx < nRv; ++RvIdx) {
            Scalar Rv = RvMin + (RvMax - RvMin)*RvIdx/nRv;

            gasMu_[regionIdx].appendXPos(Rv);

            for (size_t pIdx = 0; pIdx < nP; ++pIdx) {
                Scalar pg = poMin + (poMax - poMin)*pIdx/nP;
                Scalar mug = mugSpline.eval(pg, /*extrapolate=*/true);

                gasMu_[regionIdx].appendSamplePoint(RvIdx, pg, mug);
            }
        }
    }
Example #2
0
void testMonotonic(const Spline &sp,
                   const double *x,
                   const double *y)
{
    // test the common properties of splines
    testCommon(sp, x, y);

    size_t n = sp.numSamples();

    for (size_t i = 0; i < n - 1; ++ i) {
        // make sure that the spline is monotonic for each interval
        // between sampling points
        if (!sp.monotonic(x[i], x[i + 1]))
            OPM_THROW(std::runtime_error,
                      "Spline says it is not monotonic in interval "
                      << i << " where it should be");

        // test the intersection methods
        double d = (y[i] + y[i+1])/2;
        double interX = sp.template intersectInterval<double>(x[i], x[i+1],
                                                              /*a=*/0, /*b=*/0, /*c=*/0, d);
        double interY = sp.eval(interX);
        if (std::abs(interY - d) > 1e-5)
            OPM_THROW(std::runtime_error,
                      "Spline::intersectInterval() seems to be broken: "
                      << sp.eval(interX) << " - " << d << " = " << sp.eval(interX) - d << "!");
    }

    // make sure the spline says to be monotonic on the (extrapolated)
    // left and right sides
    if (!sp.monotonic(x[0] - 1.0, (x[0] + x[1])/2, /*extrapolate=*/true))
        OPM_THROW(std::runtime_error,
                  "Spline says it is not monotonic on left side where it should be");
    if (!sp.monotonic((x[n - 2]+ x[n - 1])/2, x[n-1] + 1.0, /*extrapolate=*/true))
        OPM_THROW(std::runtime_error,
                  "Spline says it is not monotonic on right side where it should be");

    for (size_t i = 0; i < n - 2; ++ i) {
        // make sure that the spline says that it is non-monotonic for
        // if extrema are within the queried interval
        if (sp.monotonic((x[i] + x[i + 1])/2, (x[i + 1] + x[i + 2])/2))
            OPM_THROW(std::runtime_error,
                      "Spline says it is monotonic in interval "
                      << i << " where it should not be");
    }
}
Example #3
0
    /*!
     * \brief Initialize the function for the gas formation volume factor
     *
     * The gas formation volume factor \f$B_g\f$ is a function of \f$(p_g, X_g^O)\f$ and
     * represents the partial density of the oil component in the gas phase at a given
     * pressure. This method only requires the volume factor of oil-saturated gas (which
     * only depends on pressure) while the dependence on the oil mass fraction is
     * guesstimated...
     */
    void setSaturatedGasFormationVolumeFactor(int regionIdx, const SamplingPoints &samplePoints)
    {
        auto& invGasB = inverseGasB_[regionIdx];

        auto &Rv = oilVaporizationFactorTable_[regionIdx];

        Scalar T = BlackOilFluidSystem::surfaceTemperature;

        Scalar RvMin = 0.0;
        Scalar RvMax = Rv.eval(oilVaporizationFactorTable_[regionIdx].xMax(), /*extrapolate=*/true);

        Scalar poMin = samplePoints.front().first;
        Scalar poMax = samplePoints.back().first;

        size_t nRv = 20;
        size_t nP = samplePoints.size()*2;

        Scalar rhogRef = BlackOilFluidSystem::referenceDensity(gasPhaseIdx, regionIdx);
        Scalar rhooRef = BlackOilFluidSystem::referenceDensity(oilPhaseIdx, regionIdx);

        Spline gasFormationVolumeFactorSpline;
        gasFormationVolumeFactorSpline.setContainerOfTuples(samplePoints, /*type=*/Spline::Monotonic);

        updateSaturationPressureSpline_(regionIdx);

        // calculate a table of estimated densities depending on pressure and gas mass
        // fraction
        for (size_t RvIdx = 0; RvIdx < nRv; ++RvIdx) {
            Scalar Rv = RvMin + (RvMax - RvMin)*RvIdx/nRv;
            Scalar XgO = Rv/(rhooRef/rhogRef + Rv);

            invGasB.appendXPos(Rv);

            for (size_t pIdx = 0; pIdx < nP; ++pIdx) {
                Scalar pg = poMin + (poMax - poMin)*pIdx/nP;

                Scalar poSat = gasSaturationPressure(regionIdx, T, XgO);
                Scalar BgSat = gasFormationVolumeFactorSpline.eval(poSat, /*extrapolate=*/true);
                Scalar drhoo_dp = (1.1200 - 1.1189)/((5000 - 4000)*6894.76);
                Scalar rhoo = BlackOilFluidSystem::referenceDensity(oilPhaseIdx, regionIdx)/BgSat*(1 + drhoo_dp*(pg - poSat));

                Scalar Bg = BlackOilFluidSystem::referenceDensity(oilPhaseIdx, regionIdx)/rhoo;

                invGasB.appendSamplePoint(RvIdx, pg, 1.0/Bg);
            }
        }
    }
Example #4
0
    static Scalar regularizedSqrt_(Scalar x)
    {
        static const Scalar xMin = 1e-2;
        static const Scalar sqrtXMin = std::sqrt(xMin);
        static const Scalar fPrimeXMin = 1.0/(2*std::sqrt(xMin));
        static const Scalar fPrime0 = 2*fPrimeXMin;
        typedef Opm::Spline<Scalar> Spline;
        static const Spline sqrtRegSpline(0, xMin, // x0, x1
                                          0, sqrtXMin, // y0, y1
                                          fPrime0, fPrimeXMin); // m0, m1

        if (x > xMin)
            return std::sqrt(x);
        else if (x <= 0)
            return fPrime0 * x;
        else
            return sqrtRegSpline.eval(x);
    }
Example #5
0
void testCommon(const Spline &sp,
                const double *x,
                const double *y)
{
    static double eps = 1e-10;
    static double epsFD = 1e-7;

    size_t n = sp.numSamples();
    for (size_t i = 0; i < n; ++i) {
        // sure that we hit all sampling points
        double y0 = (i>0)?sp.eval(x[i]-eps):y[0];
        double y1 = sp.eval(x[i]);
        double y2 = (i<n-1)?sp.eval(x[i]+eps):y[n-1];

        if (std::abs(y0 - y[i]) > 100*eps || std::abs(y2 - y[i]) > 100*eps)
            OPM_THROW(std::runtime_error,
                       "Spline seems to be discontinuous at sampling point " << i << "!");
        if (std::abs(y1 - y[i]) > eps)
            OPM_THROW(std::runtime_error,
                       "Spline does not capture sampling point " << i << "!");

        // make sure the derivative is continuous (assuming that the
        // second derivative is smaller than 1000)
        double d1 = sp.evalDerivative(x[i]);
        double d0 = (i>0)?sp.evalDerivative(x[i]-eps):d1;
        double d2 = (i<n-1)?sp.evalDerivative(x[i]+eps):d1;

        if (std::abs(d1 - d0) > 1000*eps || std::abs(d2 - d0) > 1000*eps)
            OPM_THROW(std::runtime_error,
                      "Spline seems to exhibit a discontinuous derivative at sampling point " << i << "!");
    }

    // make sure the derivatives are consistent with the curve
    size_t np = 3*n;
    for (size_t i = 0; i < np; ++i) {
        double xMin = sp.xAt(0);
        double xMax = sp.xAt(sp.numSamples() - 1);
        double xval = xMin + (xMax - xMin)*i/np;

        // first derivative
        double y1 = sp.eval(xval+epsFD);
        double y0 = sp.eval(xval);

        double mFD = (y1 - y0)/epsFD;
        double m = sp.evalDerivative(xval);

        if (std::abs( mFD - m ) > 1000*epsFD)
            OPM_THROW(std::runtime_error,
                      "Derivative of spline seems to be inconsistent with cuve"
                      " (" << mFD << " - " << m << " = " << mFD - m << ")!");

        // second derivative
        y1 = sp.evalDerivative(xval+epsFD);
        y0 = sp.evalDerivative(xval);

        mFD = (y1 - y0)/epsFD;
        m = sp.evalSecondDerivative(xval);

        if (std::abs( mFD - m ) > 1000*epsFD)
            OPM_THROW(std::runtime_error,
                      "Second derivative of spline seems to be inconsistent with cuve"
                      " (" << mFD << " - " << m << " = " << mFD - m << ")!");

        // Third derivative
        y1 = sp.evalSecondDerivative(xval+epsFD);
        y0 = sp.evalSecondDerivative(xval);

        mFD = (y1 - y0)/epsFD;
        m = sp.evalThirdDerivative(xval);

        if (std::abs( mFD - m ) > 1000*epsFD)
            OPM_THROW(std::runtime_error,
                      "Third derivative of spline seems to be inconsistent with cuve"
                      " (" << mFD << " - " << m << " = " << mFD - m << ")!");
    }
}
Example #6
0
int main(int argc, char **argv)
{
	using Calibration::HistogramF;
	using Calibration::VarProcessor;

	ROOT::Cintex::Cintex::Enable();

	if (argc != 3) {
		std::cerr << "Syntax: " << argv[0] << " <MVA File> "
		          << "<output ROOT file>" << std::endl;
		return 1;
	}

	Calibration::MVAComputer *calib =
		MVAComputer::readCalibration(argv[1]);
	if (!calib)
		return 1;

	std::map<std::string, HistogramF*> histos;

	std::vector<VarProcessor*> procs = calib->getProcessors();
	for(unsigned int z = 0; z < procs.size(); ++z) {
		VarProcessor *proc = procs[z];
		if (!proc)
			continue;

		std::ostringstream ss3;
		ss3 << (z + 1);

		Calibration::ProcLikelihood *lkh =
			dynamic_cast<Calibration::ProcLikelihood*>(proc);
		Calibration::ProcNormalize *norm =
			dynamic_cast<Calibration::ProcNormalize*>(proc);

		if (lkh) {
			for(unsigned int i = 0; i < lkh->pdfs.size(); i++) {
				std::ostringstream ss2;
				ss2 << (i + 1);
				histos["proc" + ss3.str() + "_sig" + ss2.str()] = &lkh->pdfs[i].signal;
				histos["proc" + ss3.str() + "_bkg" + ss2.str()] = &lkh->pdfs[i].background;
			}
		} else if (norm) {
			for(unsigned int i = 0; i < norm->distr.size(); i++) {
				std::ostringstream ss2;
				ss2 << (i + 1);
				histos["proc" + ss3.str() + "_norm" + ss2.str()] = &norm->distr[i];
			}
		}
	}

	TFile *f = TFile::Open(argv[2], "RECREATE");
	if (!f)
		return 2;

	for(std::map<std::string, HistogramF*>::const_iterator iter = histos.begin();
	    iter != histos.end(); ++iter) {
		std::string name = iter->first;
		HistogramF *histo = iter->second;

		unsigned int size = histo->values().size() - 2;
		std::vector<double> values(
				histo->values().begin() + 1,
				histo->values().end() - 1);
		Spline spline;
		spline.set(values.size(), &values.front());

		double min = histo->range().min;
		double max = histo->range().max;

		TH1F *h = new TH1F((name + "_histo").c_str(), (name + "_histo").c_str(),
		                   size, min - 0.5 * (max - min) / size,
		                   max + 0.5 * (max - min) / size);
		TH1F *s = new TH1F((name + "_spline").c_str(), (name + "_spline").c_str(),
		                   size * precision, min, max);

		for(unsigned int i = 0; i < size; i++) {
			h->SetBinContent(i + 1, histo->values()[i + 1]);
			for(int j = 0; j < precision; j++) {
				unsigned int k = i * precision + j;
				double x = (k + 0.5) / (size * precision);
				double v = spline.eval(x);
				s->SetBinContent(k, v);
			}
		}
	}

	f->Write();
	delete f;

	return 0;
}