27 #include <unordered_map>
28 #include <unordered_set>
34 #include <opm/parser/eclipse/EclipseState/Runspec.hpp>
35 #include <opm/parser/eclipse/EclipseState/Schedule/GasLiftOpt.hpp>
36 #include <opm/parser/eclipse/EclipseState/Schedule/Group/Group.hpp>
37 #include <opm/parser/eclipse/EclipseState/Schedule/Group/GTNode.hpp>
38 #include <opm/parser/eclipse/EclipseState/Schedule/Group/GuideRateConfig.hpp>
39 #include <opm/parser/eclipse/EclipseState/Schedule/MessageLimits.hpp>
40 #include <opm/parser/eclipse/EclipseState/Schedule/Network/ExtNetwork.hpp>
41 #include <opm/parser/eclipse/EclipseState/Schedule/RPTConfig.hpp>
42 #include <opm/parser/eclipse/EclipseState/Schedule/ScheduleDeck.hpp>
43 #include <opm/parser/eclipse/EclipseState/Schedule/ScheduleState.hpp>
44 #include <opm/parser/eclipse/EclipseState/Schedule/Well/PAvg.hpp>
45 #include <opm/parser/eclipse/EclipseState/Schedule/Well/Well.hpp>
46 #include <opm/parser/eclipse/EclipseState/Schedule/Well/WellTestConfig.hpp>
47 #include <opm/parser/eclipse/EclipseState/Schedule/Well/WellMatcher.hpp>
48 #include <opm/parser/eclipse/EclipseState/Schedule/WriteRestartFileEvents.hpp>
50 #include <opm/parser/eclipse/Python/Python.hpp>
52 #include <opm/parser/eclipse/Units/UnitSystem.hpp>
56 class ActiveGridCells;
62 class FieldPropsManager;
64 class SCHEDULESection;
69 namespace RestartIO {
struct RstState; }
73 std::shared_ptr<const Python> m_python_handle;
74 std::string m_input_path;
80 std::optional<int> output_interval;
86 explicit ScheduleStatic(std::shared_ptr<const Python> python_handle) :
87 m_python_handle(python_handle)
94 const std::optional<int>& output_interval_,
98 template<
class Serializer>
101 m_deck_message_limits.serializeOp(serializer);
102 this->rst_info.serializeOp(serializer);
103 m_runspec.serializeOp(serializer);
104 m_unit_system.serializeOp(serializer);
105 serializer(this->m_input_path);
106 rst_info.serializeOp(serializer);
107 rst_config.serializeOp(serializer);
108 serializer(this->output_interval);
113 auto python = std::make_shared<Python>(Python::Enable::OFF);
115 st.m_deck_message_limits = MessageLimits::serializeObject();
116 st.m_runspec = Runspec::serializeObject();
117 st.m_unit_system = UnitSystem::newFIELD();
118 st.m_input_path =
"Some/funny/path";
119 st.rst_config = RSTConfig::serializeObject();
120 st.rst_info = ScheduleRestartInfo::serializeObject();
125 return this->m_input_path == other.m_input_path &&
126 this->m_deck_message_limits == other.m_deck_message_limits &&
127 this->m_unit_system == other.m_unit_system &&
128 this->rst_config == other.rst_config &&
129 this->rst_info == other.rst_info &&
130 this->m_runspec == other.m_runspec;
138 explicit Schedule(std::shared_ptr<const Python> python_handle);
145 std::shared_ptr<const Python> python,
146 const std::optional<int>& output_interval = {},
156 std::shared_ptr<const Python> python,
157 const std::optional<int>& output_interval = {},
164 std::shared_ptr<const Python> python,
165 const std::optional<int>& output_interval = {},
172 std::shared_ptr<const Python> python,
173 const std::optional<int>& output_interval = {},
176 template <
typename T>
181 std::shared_ptr<const Python> python,
182 const std::optional<int>& output_interval = {},
187 std::shared_ptr<const Python> python,
188 const std::optional<int>& output_interval = {},
194 const std::optional<int>& output_interval = {},
203 time_t getStartTime()
const;
204 time_t posixStartTime()
const;
205 time_t posixEndTime()
const;
206 time_t simTime(std::size_t timeStep)
const;
207 double seconds(std::size_t timeStep)
const;
208 double stepLength(std::size_t timeStep)
const;
209 std::optional<int> exitStatus()
const;
210 const UnitSystem& getUnits()
const {
return this->m_static.m_unit_system; }
211 const Runspec& runspec()
const {
return this->m_static.m_runspec; }
213 std::size_t numWells()
const;
214 std::size_t numWells(std::size_t timestep)
const;
215 bool hasWell(
const std::string& wellName)
const;
216 bool hasWell(
const std::string& wellName, std::size_t timeStep)
const;
218 WellMatcher wellMatcher(std::size_t report_step)
const;
219 std::vector<std::string> wellNames(
const std::string& pattern, std::size_t timeStep,
const std::vector<std::string>& matching_wells = {})
const;
220 std::vector<std::string> wellNames(
const std::string& pattern)
const;
221 std::vector<std::string> wellNames(std::size_t timeStep)
const;
222 std::vector<std::string> wellNames()
const;
224 bool hasGroup(
const std::string& groupName, std::size_t timeStep)
const;
225 std::vector<std::string> groupNames(
const std::string& pattern, std::size_t timeStep)
const;
226 std::vector<std::string> groupNames(std::size_t timeStep)
const;
227 std::vector<std::string> groupNames(
const std::string& pattern)
const;
228 std::vector<std::string> groupNames()
const;
238 std::vector<const Group*> restart_groups(std::size_t timeStep)
const;
240 std::vector<std::string> changed_wells(std::size_t reportStep)
const;
241 const Well& getWell(std::size_t well_index, std::size_t timeStep)
const;
242 const Well& getWell(
const std::string& wellName, std::size_t timeStep)
const;
243 const Well& getWellatEnd(
const std::string& well_name)
const;
244 std::vector<Well> getWells(std::size_t timeStep)
const;
245 std::vector<Well> getWellsatEnd()
const;
246 void shut_well(
const std::string& well_name, std::size_t report_step);
247 void stop_well(
const std::string& well_name, std::size_t report_step);
248 void open_well(
const std::string& well_name, std::size_t report_step);
250 std::vector<const Group*> getChildGroups2(
const std::string& group_name, std::size_t timeStep)
const;
251 std::vector<Well> getChildWells2(
const std::string& group_name, std::size_t timeStep)
const;
252 Well::ProducerCMode getGlobalWhistctlMmode(std::size_t timestep)
const;
254 const UDQConfig& getUDQConfig(std::size_t timeStep)
const;
255 void evalAction(
const SummaryState& summary_state, std::size_t timeStep);
257 GTNode groupTree(std::size_t report_step)
const;
258 GTNode groupTree(
const std::string& root_node, std::size_t report_step)
const;
259 const Group& getGroup(
const std::string& groupName, std::size_t timeStep)
const;
261 void invalidNamePattern (
const std::string& namePattern, std::size_t report_step,
const ParseContext& parseContext,
ErrorGuard& errors,
const DeckKeyword& keyword)
const;
263 std::optional<std::size_t> first_RFT()
const;
269 std::size_t size()
const;
271 bool write_rst_file(std::size_t report_step)
const;
272 const std::map< std::string, int >& rst_keywords(
size_t timestep )
const;
274 std::unordered_set<std::string> applyAction(std::size_t reportStep,
const time_point& sim_time,
const Action::ActionX& action,
const Action::Result& result,
const std::unordered_map<std::string, double>& wellpi);
275 void applyWellProdIndexScaling(
const std::string& well_name,
const std::size_t reportStep,
const double scalingFactor);
278 const GasLiftOpt& glo(std::size_t report_step)
const;
280 bool operator==(
const Schedule& data)
const;
281 std::shared_ptr<const Python> python()
const;
286 std::vector<ScheduleState>::const_iterator begin()
const;
287 std::vector<ScheduleState>::const_iterator end()
const;
288 void create_next(
const time_point& start_time,
const std::optional<time_point>& end_time);
290 void create_first(
const time_point& start_time,
const std::optional<time_point>& end_time);
299 static bool cmp(
const Schedule& sched1,
const Schedule& sched2, std::size_t report_step);
301 template<
class Serializer>
304 m_sched_deck.serializeOp(serializer);
305 serializer.vector(snapshots);
306 m_static.serializeOp(serializer);
307 restart_output.serializeOp(serializer);
309 pack_unpack<PAvg, Serializer>(serializer);
310 pack_unpack<WellTestConfig, Serializer>(serializer);
311 pack_unpack<GConSale, Serializer>(serializer);
312 pack_unpack<GConSump, Serializer>(serializer);
313 pack_unpack<WListManager, Serializer>(serializer);
314 pack_unpack<Network::ExtNetwork, Serializer>(serializer);
315 pack_unpack<Network::Balance, Serializer>(serializer);
316 pack_unpack<RPTConfig, Serializer>(serializer);
317 pack_unpack<Action::Actions, Serializer>(serializer);
318 pack_unpack<UDQActive, Serializer>(serializer);
319 pack_unpack<UDQConfig, Serializer>(serializer);
320 pack_unpack<NameOrder, Serializer>(serializer);
321 pack_unpack<GroupOrder, Serializer>(serializer);
322 pack_unpack<GuideRateConfig, Serializer>(serializer);
323 pack_unpack<GasLiftOpt, Serializer>(serializer);
324 pack_unpack<RFTConfig, Serializer>(serializer);
325 pack_unpack<RSTConfig, Serializer>(serializer);
327 pack_unpack_map<int, VFPProdTable, Serializer>(serializer);
328 pack_unpack_map<int, VFPInjTable, Serializer>(serializer);
329 pack_unpack_map<std::string, Group, Serializer>(serializer);
330 pack_unpack_map<std::string, Well, Serializer>(serializer);
333 template <
typename T,
class Serializer>
335 std::vector<T> value_list;
336 std::vector<std::size_t> index_list;
338 if (serializer.isSerializing())
339 pack_state<T>(value_list, index_list);
341 serializer.vector(value_list);
342 serializer.template vector<std::size_t, false>(index_list);
344 if (!serializer.isSerializing())
345 unpack_state<T>(value_list, index_list);
348 template <
typename T>
349 std::vector<std::pair<std::size_t, T>> unique()
const {
350 std::vector<std::pair<std::size_t, T>> values;
351 for (std::size_t index = 0; index < this->snapshots.size(); index++) {
352 const auto& member = this->snapshots[index].get<T>();
353 const auto& value = member.get();
354 if (values.empty() || !(value == values.back().second))
355 values.push_back( std::make_pair(index, value));
361 template <
typename T>
362 void pack_state(std::vector<T>& value_list, std::vector<std::size_t>& index_list)
const {
363 auto unique_values = this->unique<T>();
364 for (
auto& [index, value] : unique_values) {
365 value_list.push_back( std::move(value) );
366 index_list.push_back( index );
371 template <
typename T>
372 void unpack_state(
const std::vector<T>& value_list,
const std::vector<std::size_t>& index_list) {
373 std::size_t unique_index = 0;
374 while (unique_index < value_list.size()) {
375 const auto& value = value_list[unique_index];
376 const auto& first_index = index_list[unique_index];
377 auto last_index = this->snapshots.size();
378 if (unique_index < (value_list.size() - 1))
379 last_index = index_list[unique_index + 1];
381 auto& target_state = this->snapshots[first_index];
382 target_state.get<T>().update( std::move(value) );
383 for (std::size_t index=first_index + 1; index < last_index; index++)
384 this->snapshots[index].get<T>().update( target_state.get<T>() );
391 template <
typename K,
typename T,
class Serializer>
392 void pack_unpack_map(
Serializer& serializer) {
393 std::vector<T> value_list;
394 std::vector<std::size_t> index_list;
396 if (serializer.isSerializing())
397 pack_map<K,T>(value_list, index_list);
399 serializer.vector(value_list);
400 serializer(index_list);
402 if (!serializer.isSerializing())
403 unpack_map<K,T>(value_list, index_list);
407 template <
typename K,
typename T>
408 void pack_map(std::vector<T>& value_list,
409 std::vector<std::size_t>& index_list) {
411 const auto& last_map = this->snapshots.back().get_map<K,T>();
412 std::vector<K> key_list{ last_map.keys() };
413 std::unordered_map<K,T> current_value;
415 for (std::size_t index = 0; index < this->snapshots.size(); index++) {
416 auto& state = this->snapshots[index];
417 const auto& current_map = state.template get_map<K,T>();
418 for (
const auto& key : key_list) {
419 auto& value = current_map.get_ptr(key);
421 auto it = current_value.find(key);
422 if (it == current_value.end() || !(*value == it->second)) {
423 value_list.push_back( *value );
424 index_list.push_back( index );
426 current_value[key] = *value;
434 template <
typename K,
typename T>
435 void unpack_map(
const std::vector<T>& value_list,
436 const std::vector<std::size_t>& index_list) {
438 std::unordered_map<K, std::vector<std::pair<std::size_t, T>>> storage;
439 for (std::size_t storage_index = 0; storage_index < value_list.size(); storage_index++) {
440 const auto& value = value_list[storage_index];
441 const auto& time_index = index_list[storage_index];
443 storage[ value.name() ].emplace_back( time_index, value );
446 for (
const auto& [key, values] : storage) {
447 for (std::size_t unique_index = 0; unique_index < values.size(); unique_index++) {
448 const auto& [time_index, value] = values[unique_index];
449 auto last_index = this->snapshots.size();
450 if (unique_index < (values.size() - 1))
451 last_index = values[unique_index + 1].first;
453 auto& map_value = this->snapshots[time_index].template get_map<K,T>();
454 map_value.update(std::move(value));
456 for (std::size_t index=time_index + 1; index < last_index; index++) {
457 auto& forward_map = this->snapshots[index].template get_map<K,T>();
458 forward_map.update( key, map_value );
470 std::optional<int> exit_status;
471 std::vector<ScheduleState> snapshots;
477 void addWell(
Well well);
478 void addWell(
const std::string& wellName,
479 const std::string& group,
482 Phase preferredPhase,
483 const std::optional<double>& refDepth,
484 double drainageRadius,
486 bool automaticShutIn,
488 Well::GasInflowEquation gas_inflow,
489 std::size_t timeStep,
490 Connection::Order wellConnectionOrder);
491 bool updateWPAVE(
const std::string& wname, std::size_t report_step,
const PAvg& pavg);
493 void updateGuideRateModel(
const GuideRateModel& new_model, std::size_t report_step);
494 GTNode groupTree(
const std::string& root_node, std::size_t report_step, std::size_t level,
const std::optional<std::string>& parent_name)
const;
496 bool updateWellStatus(
const std::string& well, std::size_t reportStep, Well::Status status, std::optional<KeywordLocation> = {});
497 void addWellToGroup(
const std::string& group_name,
const std::string& well_name , std::size_t timeStep);
498 void iterateScheduleSection(std::size_t load_start,
499 std::size_t load_end,
502 const std::unordered_map<std::string, double> * target_wellpi,
505 const std::string& prefix);
507 void addGroupToGroup(
const std::string& parent_group,
const std::string& child_group);
508 void addGroup(
const std::string& groupName , std::size_t timeStep);
509 void addGroup(
Group group);
511 void addWell(
const std::string& wellName,
const DeckRecord& record, std::size_t timeStep, Connection::Order connection_order);
512 void checkIfAllConnectionsIsShut(std::size_t currentStep);
513 void end_report(std::size_t report_step);
514 void handleKeyword(std::size_t currentStep,
520 const std::vector<std::string>& matching_wells,
522 std::unordered_set<std::string> * affected_wells,
523 const std::unordered_map<std::string, double> * target_wellpi);
525 static std::string formatDate(std::time_t t);
526 std::string simulationDays(std::size_t currentStep)
const;
528 bool must_write_rst_file(std::size_t report_step)
const;
530 void applyEXIT(
const DeckKeyword&, std::size_t currentStep);
531 void applyWELOPEN(
const DeckKeyword&, std::size_t currentStep,
const ParseContext&,
ErrorGuard&,
const std::vector<std::string>& matching_wells = {}, std::unordered_set<std::string> * affected_wells =
nullptr);
533 struct HandlerContext {
536 const std::size_t currentStep;
537 const std::vector<std::string>& matching_wells;
538 const bool actionx_mode;
539 std::unordered_set<std::string> * affected_wells;
540 const std::unordered_map<std::string, double> * target_wellpi;
546 const std::size_t currentStep_,
547 const std::vector<std::string>& matching_wells_,
549 std::unordered_set<std::string> * affected_wells_,
550 const std::unordered_map<std::string, double> * target_wellpi_):
553 currentStep(currentStep_),
554 matching_wells(matching_wells_),
555 actionx_mode(actionx_mode_),
556 affected_wells(affected_wells_),
557 target_wellpi(target_wellpi_),
580 bool handleNormalKeyword(
const HandlerContext& handlerContext,
const ParseContext& parseContext,
ErrorGuard& errors);
587 void handleWELPI (
const DeckKeyword& keyword, std::size_t report_step,
const ParseContext& parseContext,
ErrorGuard& errors,
const std::vector<std::string>& matching_wells = {});
588 void handleWELPIRuntime(
const HandlerContext&);
Definition: ActionX.hpp:74
Definition: ActionResult.hpp:99
Simple class capturing active cells of a grid.
Definition: ActiveGridCells.hpp:35
Definition: DeckKeyword.hpp:36
Definition: DeckRecord.hpp:32
About cell information and dimension: The actual grid information is held in a pointer to an ERT ecl_...
Definition: EclipseGrid.hpp:55
Definition: EclipseState.hpp:55
Definition: ErrorGuard.hpp:29
Definition: FieldPropsManager.hpp:37
Definition: GTNode.hpp:31
Definition: GasLiftOpt.hpp:28
Definition: GuideRateModel.hpp:29
Definition: MessageLimits.hpp:28
Definition: ParseContext.hpp:88
Definition: RSTConfig.hpp:196
Definition: Runspec.hpp:402
Definition: ScheduleDeck.hpp:54
Definition: ScheduleDeck.hpp:142
Definition: ScheduleState.hpp:81
Definition: Schedule.hpp:135
Definition: Serializer.hpp:38
Definition: SummaryState.hpp:69
Definition: UDQConfig.hpp:51
Definition: UnitSystem.hpp:34
Definition: WellMatcher.hpp:32
Definition: WriteRestartFileEvents.hpp:31
This class implements a small container which holds the transmissibility mulitpliers for all the face...
Definition: Exceptions.hpp:29
Definition: ScheduleDeck.hpp:89
Definition: Schedule.hpp:72