00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef OPM_BACKUPRESTORE_HEADER_INCLUDED
00021 #define OPM_BACKUPRESTORE_HEADER_INCLUDED
00022
00023 #include <iostream>
00024 #include <opm/common/data/SimulationDataContainer.hpp>
00025
00026
00027 #include <opm/core/simulator/BlackoilState.hpp>
00028 #include <opm/autodiff/WellStateFullyImplicitBlackoil.hpp>
00029
00030 namespace Opm {
00031
00032 namespace {
00033 template <class T>
00034 void writeValue( std::ostream& stream, const T& value )
00035 {
00036 stream.write( (const char *) &value, sizeof( T ) );
00037 }
00038
00039 template <class T>
00040 void readValue( std::istream& stream, T& value )
00041 {
00042 stream.read( (char *) &value, sizeof( T ) );
00043 }
00044
00045
00046 template <class Vector>
00047 void writeContainer( std::ostream& stream, const Vector& vector)
00048 {
00049 typedef typename Vector :: value_type T;
00050 unsigned int size = vector.size() * sizeof( T );
00051 writeValue( stream, size );
00052 if( size > 0 ) {
00053 stream.write( (const char *) vector.data(), size );
00054 }
00055 }
00056
00057
00058
00059 template <class Map>
00060 void writeMap( std::ostream& stream, const Map& m)
00061 {
00062 const unsigned int mapEntries = m.size();
00063 writeValue( stream, mapEntries );
00064 if( mapEntries > 0 )
00065 {
00066 const auto& end = m.end();
00067 for(auto it = m.begin(); it != end; ++it )
00068 {
00069
00070 writeContainer( stream, (*it).first );
00071
00072 writeContainer( stream, (*it).second );
00073 }
00074 }
00075 }
00076
00077 template <class Container>
00078 void resizeContainer( Container& container, size_t size )
00079 {
00080 container.resize( size );
00081 }
00082
00083 template <class T, size_t n>
00084 void resizeContainer( std::array<T, n>& , size_t size )
00085 {
00086 static_cast<void>(size);
00087 assert( int(size) == int(n) );
00088 }
00089
00090 template <class Container>
00091 void readData(std::istream& stream, Container& container, size_t datasize)
00092 {
00093 stream.read( reinterpret_cast<char*>( container.data() ), datasize );
00094 }
00095
00096
00097
00098 template <>
00099 void readData<std::string>(std::istream& stream, std::string& string, size_t datasize)
00100 {
00101 std::vector<char> raw_data(datasize);
00102 readData(stream, raw_data, datasize);
00103 string = std::string(raw_data.data(), datasize);
00104 }
00105
00106 template <class Container>
00107 void readContainerImpl( std::istream& stream, Container& container, const bool adjustSize )
00108 {
00109 typedef typename Container :: value_type T;
00110 unsigned int dataSize = 0;
00111 readValue( stream, dataSize );
00112 if( adjustSize && dataSize > 0 ) {
00113 resizeContainer( container, dataSize/sizeof(T) );
00114 }
00115
00116 if( dataSize != container.size() * sizeof( T ) )
00117 {
00118 OPM_THROW(std::logic_error,
00119 "Size of stored data and simulation data does not match "
00120 << dataSize << " " << (container.size() * sizeof( T )) );
00121 }
00122 if( dataSize > 0 ) {
00123 readData(stream, container, dataSize);
00124 }
00125 }
00126
00127 template <class Container>
00128 void readAndResizeContainer( std::istream& stream, Container& container )
00129 {
00130 readContainerImpl( stream, container, true );
00131 }
00132
00133 template <class Container>
00134 void readContainer( std::istream& stream, Container& container )
00135 {
00136 readContainerImpl( stream, container, false );
00137 }
00138
00139 template <class Map>
00140 void readMap( std::istream& stream, Map& m)
00141 {
00142 m.clear();
00143 unsigned int mapEntries = 0;
00144 readValue( stream, mapEntries );
00145 for( unsigned int entry = 0; entry<mapEntries; ++entry )
00146 {
00147 std::pair< typename Map :: key_type, typename Map :: mapped_type > mapEntry;
00148
00149 readAndResizeContainer( stream, mapEntry.first );
00150
00151 readContainer( stream, mapEntry.second );
00152
00153
00154 m.insert( mapEntry );
00155 }
00156 }
00157
00158 enum { SimulatorStateId = 0,
00159 WellStateId = 1,
00160 WellStateFullyImplicitBackoilId = 3 };
00161
00162 inline int objectId( const SimulationDataContainer& ) {
00163 return SimulatorStateId;
00164 }
00165
00166 inline int objectId( const WellState& ) {
00167 return WellStateId;
00168 }
00169
00170 inline int objectId( const WellStateFullyImplicitBlackoil& ) {
00171 return WellStateFullyImplicitBackoilId;
00172 }
00173
00174 template <class State>
00175 void checkObjectId( std::istream& in, const State& state )
00176 {
00177
00178 int id = -1;
00179 readValue( in, id );
00180 if( id != objectId( state ) ) {
00181 OPM_THROW(std::logic_error,"backup-restore object type mismatch");
00182 }
00183 }
00184 }
00185
00186
00187 inline
00188 std::ostream& operator << (std::ostream& out, const SimulationDataContainer& state )
00189 {
00190
00191 writeValue( out, objectId( state ) );
00192
00193 const int numPhases = state.numPhases();
00194 writeValue( out, numPhases );
00195
00196
00197 writeContainer( out, state.pressure() );
00198 writeContainer( out, state.temperature() );
00199 writeContainer( out, state.facepressure() );
00200 writeContainer( out, state.faceflux() );
00201 writeContainer( out, state.saturation() );
00202
00203 return out;
00204 }
00205
00206 inline
00207 std::istream& operator >> (std::istream& in, SimulationDataContainer& state )
00208 {
00209
00210 checkObjectId( in, state );
00211
00212 int numPhases = 0;
00213 readValue( in, numPhases );
00214
00215 if( numPhases != (int) state.numPhases() )
00216 OPM_THROW(std::logic_error,"num phases wrong");
00217
00218
00219 readContainer( in, state.pressure() );
00220 readContainer( in, state.temperature() );
00221 readContainer( in, state.facepressure() );
00222 readContainer( in, state.faceflux() );
00223 readContainer( in, state.saturation() );
00224
00225 return in;
00226 }
00227
00228
00229 inline
00230 std::ostream& operator << (std::ostream& out, const WellState& state )
00231 {
00232
00233 writeValue( out, objectId( state ) );
00234
00235
00236 writeContainer( out, state.bhp() );
00237 writeContainer( out, state.temperature() );
00238 writeContainer( out, state.wellRates() );
00239 writeContainer( out, state.perfRates() );
00240 writeContainer( out, state.perfPress() );
00241
00242 return out;
00243 }
00244
00245 inline
00246 std::istream& operator >> (std::istream& in, WellState& state )
00247 {
00248
00249 checkObjectId( in, state );
00250
00251
00252 readAndResizeContainer( in, state.bhp() );
00253 readAndResizeContainer( in, state.temperature() );
00254 readAndResizeContainer( in, state.wellRates() );
00255 readAndResizeContainer( in, state.perfRates() );
00256 readAndResizeContainer( in, state.perfPress() );
00257
00258 return in;
00259 }
00260
00261
00262 inline
00263 std::ostream& operator << (std::ostream& out, const WellStateFullyImplicitBlackoil& state )
00264 {
00265
00266 writeValue( out, objectId( state ) );
00267
00268
00269 const WellState& wellState = static_cast< const WellState& > (state);
00270 out << wellState;
00271
00272 const int numWells = state.numWells();
00273 writeValue( out, numWells );
00274 if( numWells > 0 )
00275 {
00276 const int numPhases = state.numPhases();
00277 writeValue( out, numPhases );
00278
00279
00280 writeContainer( out, state.perfPhaseRates() );
00281 writeContainer( out, state.currentControls() );
00282 writeMap( out, state.wellMap() );
00283 }
00284
00285 return out;
00286 }
00287
00288 inline
00289 std::istream& operator >> (std::istream& in, WellStateFullyImplicitBlackoil& state )
00290 {
00291
00292 checkObjectId( in, state );
00293
00294
00295 WellState& wellState = static_cast< WellState& > (state);
00296 in >> wellState;
00297
00298 int numWells = 0;
00299 readValue( in, numWells );
00300 if( numWells != state.numWells() )
00301 OPM_THROW(std::logic_error,"wrong numWells");
00302
00303 if( numWells > 0 )
00304 {
00305 int numPhases = 0;
00306 readValue( in, numPhases );
00307 if( numPhases != state.numPhases() )
00308 OPM_THROW(std::logic_error,"wrong numPhases");
00309
00310
00311 readAndResizeContainer( in, state.perfPhaseRates() );
00312 readAndResizeContainer( in, state.currentControls() );
00313 readMap( in, state.wellMap() );
00314 }
00315
00316 return in;
00317 }
00318
00319 }
00320
00321 #endif // OPM_BACKUPRESTORE_HEADER_INCLUDED