Exemplo n.º 1
0
double  SimulatedAnnealingOptimizer::SimAnnealEvalFunction(const SC_DoubleArray& normParEstimates)
{
    if (!NormParOK(normParEstimates))
        return currFitVal;

    // should simulate this
    if (!CalcFitValue(normParEstimates, currFitVal))
    {
        if (runCount == 1)
            throw SimError("failure on first sa calculation");
        currFitVal = worstFitVal * 1.1;
    }
    else
        optProgressOutput.CalcAndUpdate();

    updateCB(*this);

    if ((currFitVal < bestFitVal) || (runCount == 1))
    {
        bestFitVal = currFitVal;
        bestNormParEst = normParEstimates;
        GetOptParEst(bestParEst);
    }

    if (currFitVal > worstFitVal)
        worstFitVal = currFitVal;

    return currFitVal;
}
Exemplo n.º 2
0
void SingleWell1DNonLinearGas::MatSolve(bool& setupRequired)  
{
    NonlinearMatSolve();

    if (nodePressure[0] < 0.0) 
        throw SimError("-ve pressure in gas well - reduce pumping rate", SimError::seSemiFatal);

    currSeqTZ.tzPressure = nodePressure[0] - atmosPressure;
    currSeqTZ.formFlow = NLCalcDTerm(0, nodePressure[0], nodePressure[1])
                            + NLCalcFormSTerm(nodePressure[0])  
                            - NLCalcFormSTerm(lastSeqTZ.tzPressure + atmosPressure);
}
void SingleWell1DNonLinearLiquid::MatSolve(bool& setupRequired)
{
  NonlinearMatSolve();

  if ((nodePressure[0] < 0.0) && (!allowNegativePressure))
    throw SimError("well sucked dry - reduce pumping rate", SimError::seSemiFatal);

  currSeqTZ.tzPressure = nodePressure[0];
  currSeqTZ.formFlow = NLCalcDTerm(0, nodePressure[0], nodePressure[1])
                       + NLCalcFormSTerm(nodePressure[0])
                       - NLCalcFormSTerm(lastSeqTZ.tzPressure);
}
Exemplo n.º 4
0
void  SingleWell1DLinear::MatSolve(bool& setupRequired)  // main driver
{
  if (!allAreConstant)
  {
    parameterTime = currSeqTime.testTime;
    BuildMatrices();
    setupRequired = true;
  }

  if (setupRequired)
  {
    LinearMatSetup();
    setupRequired = false;
  }

  LinearMatSolve();

  currSeqTZ.tzPressure = nodePressure[0];
  currSeqTZ.formFlow = wellDTerm * (currSeqTZ.tzPressure - nodePressure[1]) +
                       fracSVector[0] * (currSeqTZ.tzPressure - lastSeqTZ.tzPressure) / deltaT;

  if ((currSeqTZ.tzPressure < 0.0) && (!allowNegativePressure))
    throw SimError("1D linear well sucked dry - reduce pumping rate", SimError::seSemiFatal);
}
Exemplo n.º 5
0
void  SingleWell1DLinear::LinearMatSolve()
{
  int indxOff = SolveNodeOffset();
  for (int i = 0; i < nequations; i++)
    fracRhs[i] = fracSSolve[i] * nodePressure[i + indxOff];

  if (control.IsDual())
    AddSCRhsTerm(matrix);

  if (control.IsLeaky())
  {
    if (leakageType == ltUpperLower)
    {
      AddSCRhsTerm(upperLeak);
      AddSCRhsTerm(lowerLeak);
    }
    else
      AddSCRhsTerm(singleLeak);
  }

  fracRhs[nequations - 1] -= externalBoundaryTerm;

  if (currentSeqIsFixed)
    fracRhs[0] += currSeqTZ.tzPressure * wellDTerm;
  else
    fracRhs[0] += GetWellBCRhs();

#ifdef LAPACK

  //for LAPACK, just use the simple tri-diagonal solver.
  int N = nequations;
  int nrhs = 1;
  double *DL = new double[N-1];
  double *D = new double[N];
  double *DU = new double[N-1];
  double *B = new double[N];

  for(int i = 0; i < N-1; i++)
  {
    DL[i]=fracSolveUpper[i];
    DU[i]=fracSolveUpper[i];
    D[i]=fracSolveDiag[i];
    B[i]=fracRhs[i];
  }
  D[N-1]=fracSolveDiag[N-1];
  B[N-1]=fracRhs[N-1];
  int ldb = N;
  int info;

  dgtsv_(&N, &nrhs, DL, D, DU, B, &ldb, &info);

  if(info == 0)
  {
    for(int i = 0; i < N; i++)
    {
      nodePressure[i]=B[i];
    }
  }
  else //info != 0
  {
    throw SimError("SingleWell1DLinear::LinearMatSolve - failed tri-diagonal solve", SimError::seSemiFatal);
  }

  delete [] DL;
  delete [] DU;
  delete [] D;
  delete [] B;

#else // LAPACK
  ThomasSolve(fracSolveDiag, fracSolveUpper, fracWork, fracRhs, nodePressure, nequations);
#endif // LAPACK

  if (currentSeqIsFixed)
  {
    for (int i = nequations; i > 0; i--)
      nodePressure[i] = nodePressure[i - 1];
    nodePressure[0] = currSeqTZ.tzPressure;
  }

  if (control.IsDual())
    SCGaussSolve(matrix);
  if (control.IsLeaky())
  {
    if (leakageType == ltUpperLower)
    {
      SCGaussSolve(upperLeak);
      SCGaussSolve(lowerLeak);
    }
    else
      SCGaussSolve(singleLeak);
  }
}
Exemplo n.º 6
0
void WorkingSequence::StartSequence(      SeqTimeVals&  initTime,
                                    const SeqBoundVals& lastSeqEndBC,  // at end of prev seq - used for TS/TZ rel init pressure
                                          SeqBoundVals& initBC)
{
    // set up time
    initTime.seqTime  = 0.0;
    initTime.testTime = startTime;
    switch (timeStepType)
    {
        case TimeStep::tstStatic : {
            initTime.deltaT = linDeltaT;
            break;
        }
        case TimeStep::tstLog : {
            initTime.deltaT = logTStart;
            break;
        }
        case TimeStep::tstDynamicP : case TimeStep::tstDynamicQ :{
            initTime.deltaT = minTS;
            if (initTime.deltaT < 0.01)
                initTime.deltaT = 0.01;
            lastQOK = false;
            break;
        }
    }

    // set up BC
    tsSavePressure = lastSeqEndBC.tsPressure;  // maintained for duration of pulse
                                               // or for flow/hist with isolated

    initBC.tsPressure   = lastSeqEndBC.tsPressure;

    switch (seqType)
    {
        case Sequence::stFlow  : {
            initBC.tzPressure   = lastSeqEndBC.tzPressure;  // maintained for duration of pulse
            initBC.wellFlow     = tzFlowBC.GetCurveY(initTime) + fixedOffset;
            break;
        }
        case Sequence::stHistory  : {
            initBC.tzPressure = tzPressBC.GetCurveY(initTime) + fixedOffset;
            break;
        }
        case Sequence::stPulse  : case Sequence::stSlug  : {
            switch (initialPressureType)
            {
                case PulseSlugBase::ipAbsolute : {
                    initBC.tzPressure = initialPressure;
                    break;
                }
                case PulseSlugBase::ipTSRelative : {
                    initBC.tzPressure = lastSeqEndBC.tsPressure + initialPressure;
                    break;
                }
                case PulseSlugBase::ipSeqRelative : {
                    initBC.tzPressure = lastSeqEndBC.tzPressure + initialPressure;
                    break;
                }
            }

            if (initBC.tzPressure < 0.0)
                throw SimError("initial well pressure/head < zero", SimError::seSemiFatal);

            break;
        }
    }

    if (wellboreStorage == FlowHistBase::wsOpen)
        initBC.tsPressure = initBC.tzPressure;
    lastP = initBC.tzPressure;

    // get remainder
    initBC.tzTemp = tzTempBC.GetCurveY(initTime);
    initBC.tzVol = tzVolBC.GetCurveY(initTime) + volOffset;
    if (tzCompFP->IsFP())
        initBC.tzComp = tzCompFP->GetData(initBC.tzPressure);
    else
        initBC.tzComp = tzCompFTBC.GetCurveY(initTime);

    if (!control.IsGas())
        initBC.tzDens = tzDensFP->GetData(initBC.tzPressure);
}