returnValue Sensor::getDelayedOutputGrid( const VariablesGrid& _y, VariablesGrid& _yDelayed ) const { // determine common time grid for delayed outputs: Grid delayedOutputTimeGrid = lastSignal.getTimePoints( ); // make sure that last time instant of horizon lies within the grid if ( acadoIsEqual( lastSignal.getLastTime(),_y.getLastTime( ) ) == BT_FALSE ) delayedOutputTimeGrid.addTime( _y.getLastTime( ) ); // add grids of all delayed output components for( uint i=0; i<getNY( ); ++i ) delayedOutputTimeGrid.merge( _y.getTimePoints( ).shiftTimes( deadTimes(i) ),MM_REPLACE ); VariablesGrid tmp; // setup common variables grid for delayed inputs _yDelayed.init( ); for( uint i=0; i<getNY( ); ++i ) { tmp = lastSignal( i ); tmp.merge( _y( i ).shiftTimes( deadTimes(i) ),MM_REPLACE,BT_FALSE ); tmp.refineGrid( delayedOutputTimeGrid ); _yDelayed.appendValues( tmp ); } return SUCCESSFUL_RETURN; }
const std::array<int, 3> GridDims::getIJK(size_t globalIndex) const { std::array<int, 3> r = { { 0, 0, 0 } }; int k = globalIndex / (getNX() * getNY()); globalIndex -= k * (getNX() * getNY()); int j = globalIndex / getNX(); globalIndex -= j * getNX(); int i = globalIndex; r[0] = i; r[1] = j; r[2] = k; return r; }
returnValue Sensor::addSensorNoise( VariablesGrid& _y ) const { if ( hasNoise( ) == BT_FALSE ) return SUCCESSFUL_RETURN; // generate current noise VariablesGrid currentNoise; if ( generateNoise( _y.getFirstTime(),_y.getLastTime(),currentNoise ) != SUCCESSFUL_RETURN ) return ACADOERROR( RET_GENERATING_NOISE_FAILED ); // determine common grid Grid commonGrid, tmpGrid; _y.getGrid( commonGrid ); currentNoise.getGrid( tmpGrid ); commonGrid.merge( tmpGrid,MM_KEEP ); // adapt input grids and add noise _y.refineGrid( commonGrid ); currentNoise.refineGrid( commonGrid ); _y += currentNoise.getValuesSubGrid( 0,getNY()-1 ); return SUCCESSFUL_RETURN; }
returnValue Sensor::setOutputDeadTimes( const Vector& _deadTimes ) { if ( _deadTimes.getDim( ) != getNY( ) ) return ACADOERROR( RET_INVALID_ARGUMENTS ); if ( _deadTimes.getMin( ) < 0.0 ) return ACADOERROR( RET_INVALID_ARGUMENTS ); if ( deadTimes.getDim( ) == 0 ) return ACADOERROR( RET_MEMBER_NOT_INITIALISED ); for( uint i=0; i<getNY(); ++i ) deadTimes( i ) = _deadTimes( i ); return SUCCESSFUL_RETURN; }
returnValue Sensor::setOutputNoise( const Noise& _noise, double _noiseSamplingTime ) { if ( _noise.getDim( ) != getNY( ) ) return ACADOERROR( RET_INVALID_ARGUMENTS ); for( uint i=0; i<getNY( ); ++i ) { if ( additiveNoise[i] != 0 ) delete additiveNoise[i]; additiveNoise[i] = _noise.clone( i ); } noiseSamplingTimes.setAll( _noiseSamplingTime ); return SUCCESSFUL_RETURN; }
returnValue Sensor::setOutputDeadTimes( double _deadTime ) { if ( _deadTime < 0.0 ) return ACADOERROR( RET_INVALID_ARGUMENTS ); if ( deadTimes.getDim( ) == 0 ) return ACADOERROR( RET_MEMBER_NOT_INITIALISED ); for( uint i=0; i<getNY(); ++i ) deadTimes( i ) = _deadTime; return SUCCESSFUL_RETURN; }
void createEclipseWriter(const char *deckString) { Opm::ParseContext parseContext; Opm::ParserConstPtr parser(new Opm::Parser()); deck = parser->parseString(deckString, parseContext); Opm::parameter::ParameterGroup params; params.insertParameter("deck_filename", "foo.data"); eclipseState.reset(new Opm::EclipseState(deck , parseContext)); auto eclGrid = eclipseState->getEclipseGrid(); BOOST_CHECK(eclGrid->getNX() == 3); BOOST_CHECK(eclGrid->getNY() == 3); BOOST_CHECK(eclGrid->getNZ() == 3); BOOST_CHECK(eclGrid->getCartesianSize() == 3*3*3); simTimer.reset(new Opm::SimulatorTimer()); simTimer->init(eclipseState->getSchedule()->getTimeMap()); // also create an UnstructuredGrid (required to create a BlackoilState) Opm::EclipseGridConstPtr constEclGrid(eclGrid); ourFineGridManagerPtr.reset(new Opm::GridManager(constEclGrid)); const UnstructuredGrid &ourFinerUnstructuredGrid = *ourFineGridManagerPtr->c_grid(); BOOST_CHECK(ourFinerUnstructuredGrid.cartdims[0] == 3); BOOST_CHECK(ourFinerUnstructuredGrid.cartdims[1] == 3); BOOST_CHECK(ourFinerUnstructuredGrid.cartdims[2] == 3); BOOST_CHECK(ourFinerUnstructuredGrid.number_of_cells == 3*3*3); Opm::PhaseUsage phaseUsage = Opm::phaseUsageFromDeck(deck); eclWriter.reset(new Opm::EclipseWriter(params, eclipseState, phaseUsage, ourFinerUnstructuredGrid.number_of_cells, 0)); // this check is disabled so far, because UnstructuredGrid uses some weird definition // of the term "face". For this grid, "number_of_faces" is 108 which is // 2*6*numCells... //BOOST_CHECK(ourFinerUnstructuredGrid.number_of_faces == 4*4*4); int numCells = ourFinerUnstructuredGrid.number_of_cells; for (int cellIdx = 0; cellIdx < numCells; ++cellIdx) BOOST_CHECK(ourFinerUnstructuredGrid.global_cell[cellIdx] == cellIdx); }
returnValue Sensor::setOutputDeadTime( uint idx, double _deadTime ) { if ( idx >= getNY( ) ) return ACADOERROR( RET_INVALID_ARGUMENTS ); if ( _deadTime < 0.0 ) return ACADOERROR( RET_INVALID_ARGUMENTS ); if ( deadTimes.getDim( ) == 0 ) return ACADOERROR( RET_MEMBER_NOT_INITIALISED ); deadTimes( idx ) = _deadTime; return SUCCESSFUL_RETURN; }
returnValue Sensor::setOutputNoise( uint idx, const Noise& _noise, double _noiseSamplingTime ) { if ( ( idx >= getNY( ) ) || ( _noise.getDim( ) != 1 ) ) return ACADOERROR( RET_INVALID_ARGUMENTS ); if ( additiveNoise[idx] != 0 ) delete additiveNoise[idx]; additiveNoise[idx] = _noise.clone( ); if ( ( idx > 0 ) && ( acadoIsEqual( _noiseSamplingTime, noiseSamplingTimes(0) ) == BT_FALSE ) ) ACADOWARNING( RET_NO_DIFFERENT_NOISE_SAMPLING_FOR_DISCRETE ); noiseSamplingTimes.setAll( _noiseSamplingTime ); // should be changed later return SUCCESSFUL_RETURN; }
returnValue Sensor::step( VariablesGrid& _y ) { // consistency checks if ( getStatus( ) != BS_READY ) return ACADOERROR( RET_BLOCK_NOT_READY ); if ( ( _y.getNumPoints( ) < 2 ) || ( _y.getNumRows( ) != getNY( ) ) ) return ACADOERROR( RET_INVALID_ARGUMENTS ); if ( acadoIsEqual( _y.getFirstTime( ),lastSignal.getLastTime( ) ) == BT_FALSE ) return ACADOERROR( RET_INVALID_ARGUMENTS ); // delay inputs and store last signal if ( delaySensorOutput( _y ) != SUCCESSFUL_RETURN ) return ACADOERROR( RET_SENSOR_STEP_FAILED ); // add sensor noise if ( addSensorNoise( _y ) != SUCCESSFUL_RETURN ) return ACADOERROR( RET_SENSOR_STEP_FAILED ); return SUCCESSFUL_RETURN; }
returnValue SimulationEnvironment::step( ) { /* Consistency check. */ if ( getStatus( ) != BS_READY ) return ACADOERROR( RET_BLOCK_NOT_READY ); ++nSteps; acadoPrintf( "\n*** Simulation Loop No. %d (starting at time %.3f) ***\n",nSteps,simulationClock.getTime( ) ); /* Perform one single simulation loop */ Vector u, p; Vector uPrevious, pPrevious; if ( getNU( ) > 0 ) feedbackControl.evaluate( simulationClock.getTime( ),uPrevious ); if ( getNP( ) > 0 ) feedbackParameter.evaluate( simulationClock.getTime( ),pPrevious ); VariablesGrid y; Vector yPrevious; if ( getNY( ) > 0 ) processOutput.evaluate( simulationClock.getTime( ),yPrevious ); // step controller // yPrevious.print("controller input y"); if ( controller->step( simulationClock.getTime( ),yPrevious ) != SUCCESSFUL_RETURN ) return ACADOERROR( RET_ENVIRONMENT_STEP_FAILED ); double compDelay = determineComputationalDelay( controller->getPreviousRealRuntime( ) ); double nextSamplingInstant = controller->getNextSamplingInstant( simulationClock.getTime( ) ); nextSamplingInstant = round( nextSamplingInstant * 1.0e6 ) / 1.0e6; // obtain new controls and parameters if ( controller->getU( u ) != SUCCESSFUL_RETURN ) return ACADOERROR( RET_ENVIRONMENT_STEP_FAILED ); // u.print("controller output u"); if ( controller->getP( p ) != SUCCESSFUL_RETURN ) return ACADOERROR( RET_ENVIRONMENT_STEP_FAILED ); if ( acadoIsEqual( simulationClock.getTime( ),endTime ) == BT_TRUE ) { simulationClock.init( nextSamplingInstant ); return SUCCESSFUL_RETURN; } if ( fabs( compDelay ) < 100.0*EPS ) { // step process without computational delay if ( process->step( simulationClock.getTime( ),nextSamplingInstant,u,p ) != SUCCESSFUL_RETURN ) return ACADOERROR( RET_ENVIRONMENT_STEP_FAILED ); // Obtain current process output if ( process->getY( y ) != SUCCESSFUL_RETURN ) return ACADOERROR( RET_ENVIRONMENT_STEP_FAILED ); // y.print("process output y"); // update history if ( getNU( ) > 0 ) feedbackControl. add( simulationClock.getTime( ),nextSamplingInstant,u ); if ( getNP( ) > 0 ) feedbackParameter.add( simulationClock.getTime( ),nextSamplingInstant,p ); if ( getNY( ) > 0 ) processOutput. add( y,IM_LINEAR ); } else { // step process WITH computational delay if ( simulationClock.getTime( )+compDelay > nextSamplingInstant ) return ACADOERROR( RET_COMPUTATIONAL_DELAY_TOO_BIG ); Grid delayGrid( 3 ); delayGrid.setTime( simulationClock.getTime( ) ); delayGrid.setTime( simulationClock.getTime( )+compDelay ); delayGrid.setTime( nextSamplingInstant ); VariablesGrid uDelayed( u.getDim( ),delayGrid,VT_CONTROL ); uDelayed.setVector( 0,uPrevious ); uDelayed.setVector( 1,u ); uDelayed.setVector( 2,u ); VariablesGrid pDelayed( p.getDim( ),delayGrid,VT_PARAMETER ); pDelayed.setVector( 0,pPrevious ); pDelayed.setVector( 1,p ); pDelayed.setVector( 2,p ); if ( process->step( uDelayed,pDelayed ) != SUCCESSFUL_RETURN ) return ACADOERROR( RET_ENVIRONMENT_STEP_FAILED ); // Obtain current process output if ( process->getY( y ) != SUCCESSFUL_RETURN ) return ACADOERROR( RET_ENVIRONMENT_STEP_FAILED ); // update history if ( getNU( ) > 0 ) feedbackControl. add( uDelayed,IM_CONSTANT ); if ( getNP( ) > 0 ) feedbackParameter.add( pDelayed,IM_CONSTANT ); if ( getNY( ) > 0 ) processOutput. add( y,IM_LINEAR ); } // update simulation clock simulationClock.init( nextSamplingInstant ); return SUCCESSFUL_RETURN; }
returnValue SimulationEnvironment::init( const Vector &x0_, const Vector &p_ ) { // 1) initialise all sub-blocks and evaluate process at start time Vector uStart, pStart; VariablesGrid yStart; if ( controller != 0 ) { if ( controller->init( startTime,x0_,p_ ) != SUCCESSFUL_RETURN ) return ACADOERROR( RET_ENVIRONMENT_INIT_FAILED ); if ( controller->getU( uStart ) != SUCCESSFUL_RETURN ) return ACADOERROR( RET_ENVIRONMENT_INIT_FAILED ); if ( controller->getP( pStart ) != SUCCESSFUL_RETURN ) return ACADOERROR( RET_ENVIRONMENT_INIT_FAILED ); } else return ACADOERROR( RET_NO_CONTROLLER_SPECIFIED ); if ( process != 0 ) { if ( process->init( startTime,x0_,uStart,pStart ) != SUCCESSFUL_RETURN ) return ACADOERROR( RET_ENVIRONMENT_INIT_FAILED ); if ( process->getY( yStart ) != SUCCESSFUL_RETURN ) return ACADOERROR( RET_ENVIRONMENT_INIT_FAILED ); } else return ACADOERROR( RET_NO_PROCESS_SPECIFIED ); simulationClock.init( startTime ); // 2) consistency checks if ( ( process != 0 ) && ( controller != 0 ) ) { if ( process->getNY( ) != controller->getNY( ) ) return ACADOERROR( RET_BLOCK_DIMENSION_MISMATCH ); // printf( "%d %d\n",process->getNU( ),controller->getNU( ) ); if ( process->getNU( ) != controller->getNU( ) ) return ACADOERROR( RET_BLOCK_DIMENSION_MISMATCH ); if ( process->getNP( ) > controller->getNP( ) ) return ACADOERROR( RET_BLOCK_DIMENSION_MISMATCH ); } // initialise history... if ( getNU( ) > 0 ) feedbackControl. add( startTime-10.0*EPS,startTime,uStart ); if ( getNP( ) > 0 ) feedbackParameter.add( startTime-10.0*EPS,startTime,pStart ); if ( getNY( ) > 0 ) processOutput. add( startTime-10.0*EPS,startTime,yStart.getVector(0) ); // ... and update block status setStatus( BS_READY ); return SUCCESSFUL_RETURN; }
void GridDims::assertIJK(size_t i, size_t j, size_t k) const { if (i >= getNX() || j >= getNY() || k >= getNZ()) throw std::invalid_argument("input index above valid range"); }
size_t GridDims::getGlobalIndex(size_t i, size_t j, size_t k) const { return (i + j * getNX() + k * getNX() * getNY()); }