93 explicit Schedule(std::shared_ptr<const Python> python_handle);
114 std::shared_ptr<const Python> python,
115 const bool lowActionParsingStrictness =
false,
116 const bool keepKeywords =
true,
117 const std::optional<int>& output_interval = {},
128 std::shared_ptr<const Python> python,
129 const bool lowActionParsingStrictness =
false,
130 const bool keepKeywords =
true,
131 const std::optional<int>& output_interval = {},
139 std::shared_ptr<const Python> python,
140 const bool lowActionParsingStrictness =
false,
141 const bool keepKeywords =
true,
142 const std::optional<int>& output_interval = {},
150 std::shared_ptr<const Python> python,
151 const bool lowActionParsingStrictness =
false,
152 const bool keepKeywords =
true,
153 const std::optional<int>& output_interval = {},
156 template <
typename T>
161 std::shared_ptr<const Python> python,
162 const bool lowActionParsingStrictness =
false,
163 const bool keepKeywords =
true,
164 const std::optional<int>& output_interval = {},
169 std::shared_ptr<const Python> python,
170 const bool lowActionParsingStrictness =
false,
171 const bool keepKeywords =
true,
172 const std::optional<int>& output_interval = {},
178 const std::optional<int>& output_interval = {},
183 static Schedule serializationTestObject();
189 std::time_t getStartTime()
const;
190 std::time_t posixStartTime()
const;
191 std::time_t posixEndTime()
const;
192 std::time_t simTime(std::size_t timeStep)
const;
193 double seconds(std::size_t timeStep)
const;
194 double stepLength(std::size_t timeStep)
const;
195 std::optional<int> exitStatus()
const;
196 const UnitSystem& getUnits()
const {
return this->m_static.m_unit_system; }
197 const Runspec& runspec()
const {
return this->m_static.m_runspec; }
199 std::size_t numWells()
const;
200 std::size_t numWells(std::size_t timestep)
const;
201 bool hasWell(
const std::string& wellName)
const;
202 bool hasWell(
const std::string& wellName, std::size_t timeStep)
const;
204 WellMatcher wellMatcher(std::size_t report_step)
const;
205 std::function<std::unique_ptr<SegmentMatcher>()> segmentMatcherFactory(std::size_t report_step)
const;
206 std::vector<std::string> wellNames(
const std::string& pattern, std::size_t timeStep,
const std::vector<std::string>& matching_wells = {})
const;
207 std::vector<std::string> wellNames(
const std::string& pattern)
const;
208 std::vector<std::string> wellNames(std::size_t timeStep)
const;
209 std::vector<std::string> wellNames()
const;
211 bool hasGroup(
const std::string& groupName, std::size_t timeStep)
const;
212 std::vector<std::string> groupNames(
const std::string& pattern, std::size_t timeStep)
const;
213 std::vector<std::string> groupNames(std::size_t timeStep)
const;
214 std::vector<std::string> groupNames(
const std::string& pattern)
const;
215 std::vector<std::string> groupNames()
const;
225 std::vector<const Group*> restart_groups(std::size_t timeStep)
const;
227 std::vector<std::string> changed_wells(std::size_t reportStep)
const;
228 const Well& getWell(std::size_t well_index, std::size_t timeStep)
const;
229 const Well& getWell(
const std::string& wellName, std::size_t timeStep)
const;
230 const Well& getWellatEnd(
const std::string& well_name)
const;
232 std::unordered_set<int> getAquiferFluxSchedule()
const;
233 std::vector<Well> getWells(std::size_t timeStep)
const;
234 std::vector<Well> getWellsatEnd()
const;
236 const std::unordered_map<std::string, std::set<int>>& getPossibleFutureConnections()
const;
238 void shut_well(
const std::string& well_name, std::size_t report_step);
239 void shut_well(
const std::string& well_name);
240 void stop_well(
const std::string& well_name, std::size_t report_step);
241 void stop_well(
const std::string& well_name);
242 void open_well(
const std::string& well_name, std::size_t report_step);
243 void open_well(
const std::string& well_name);
244 void clear_event(ScheduleEvents::Events, std::size_t report_step);
245 void applyWellProdIndexScaling(
const std::string& well_name,
const std::size_t reportStep,
const double scalingFactor);
247 std::vector<const Group*> getChildGroups2(
const std::string& group_name, std::size_t timeStep)
const;
248 std::vector<Well> getChildWells2(
const std::string& group_name, std::size_t timeStep)
const;
249 WellProducerCMode getGlobalWhistctlMmode(std::size_t timestep)
const;
251 const UDQConfig& getUDQConfig(std::size_t timeStep)
const;
252 void evalAction(
const SummaryState& summary_state, std::size_t timeStep);
254 GTNode groupTree(std::size_t report_step)
const;
255 GTNode groupTree(
const std::string& root_node, std::size_t report_step)
const;
256 const Group& getGroup(
const std::string& groupName, std::size_t timeStep)
const;
258 std::optional<std::size_t> first_RFT()
const;
264 std::size_t size()
const;
266 bool write_rst_file(std::size_t report_step)
const;
267 const std::map< std::string, int >& rst_keywords(
size_t timestep )
const;
278 const std::vector<std::string>& matching_wells,
279 const std::unordered_map<std::string, double>& wellpi);
283 const std::vector<std::string>& matching_wells,
284 const std::unordered_map<std::string, float>& wellpi);
295 const GasLiftOpt& glo(std::size_t report_step)
const;
297 bool operator==(
const Schedule& data)
const;
298 std::shared_ptr<const Python> python()
const;
303 std::vector<ScheduleState>::const_iterator begin()
const;
304 std::vector<ScheduleState>::const_iterator end()
const;
305 void create_next(
const time_point& start_time,
const std::optional<time_point>& end_time);
307 void create_first(
const time_point& start_time,
const std::optional<time_point>& end_time);
309 void treat_critical_as_non_critical(
bool value) { this->m_treat_critical_as_non_critical = value; }
317 static bool cmp(
const Schedule& sched1,
const Schedule& sched2, std::size_t report_step);
318 void applyKeywords(std::vector<std::unique_ptr<DeckKeyword>>& keywords, std::size_t report_step);
319 void applyKeywords(std::vector<std::unique_ptr<DeckKeyword>>& keywords);
321 template<
class Serializer>
324 serializer(this->m_static);
325 serializer(this->m_sched_deck);
326 serializer(this->action_wgnames);
327 serializer(this->exit_status);
328 serializer(this->snapshots);
329 serializer(this->restart_output);
330 serializer(this->completed_cells);
331 serializer(this->m_treat_critical_as_non_critical);
332 serializer(this->current_report_step);
333 serializer(this->m_lowActionParsingStrictness);
334 serializer(this->simUpdateFromPython);
336 this->
template pack_unpack<PAvg>(serializer);
337 this->
template pack_unpack<WellTestConfig>(serializer);
338 this->
template pack_unpack<GConSale>(serializer);
339 this->
template pack_unpack<GConSump>(serializer);
340 this->
template pack_unpack<GroupEconProductionLimits>(serializer);
341 this->
template pack_unpack<WListManager>(serializer);
342 this->
template pack_unpack<Network::ExtNetwork>(serializer);
343 this->
template pack_unpack<Network::Balance>(serializer);
344 this->
template pack_unpack<RPTConfig>(serializer);
345 this->
template pack_unpack<Action::Actions>(serializer);
346 this->
template pack_unpack<UDQActive>(serializer);
347 this->
template pack_unpack<UDQConfig>(serializer);
348 this->
template pack_unpack<NameOrder>(serializer);
349 this->
template pack_unpack<GroupOrder>(serializer);
350 this->
template pack_unpack<GuideRateConfig>(serializer);
351 this->
template pack_unpack<GasLiftOpt>(serializer);
352 this->
template pack_unpack<RFTConfig>(serializer);
353 this->
template pack_unpack<RSTConfig>(serializer);
354 this->
template pack_unpack<ScheduleState::BHPDefaults>(serializer);
355 this->
template pack_unpack<Source>(serializer);
357 this->
template pack_unpack_map<int, VFPProdTable>(serializer);
358 this->
template pack_unpack_map<int, VFPInjTable>(serializer);
359 this->
template pack_unpack_map<std::string, Group>(serializer);
360 this->
template pack_unpack_map<std::string, Well>(serializer);
369 for (
auto& snapshot : snapshots) {
370 for (
auto& well : snapshot.wells) {
371 well.second->updateUnitSystem(&m_static.m_unit_system);
377 template <
typename T,
class Serializer>
379 std::vector<T> value_list;
380 std::vector<std::size_t> index_list;
383 this->
template pack_state<T>(value_list, index_list);
385 serializer(value_list);
386 serializer(index_list);
389 this->
template unpack_state<T>(value_list, index_list);
392 template <
typename T>
393 std::vector<std::pair<std::size_t, T>> unique()
const {
394 std::vector<std::pair<std::size_t, T>> values;
395 for (std::size_t index = 0; index < this->snapshots.size(); index++) {
396 const auto& member = this->snapshots[index].get<T>();
397 const auto& value = member.get();
398 if (values.empty() || !(value == values.back().second))
399 values.push_back( std::make_pair(index, value));
405 template <
typename T>
406 void pack_state(std::vector<T>& value_list, std::vector<std::size_t>& index_list)
const {
407 auto unique_values = this->
template unique<T>();
408 for (
auto& [index, value] : unique_values) {
409 value_list.push_back( std::move(value) );
410 index_list.push_back( index );
415 template <
typename T>
416 void unpack_state(
const std::vector<T>& value_list,
const std::vector<std::size_t>& index_list) {
417 std::size_t unique_index = 0;
418 while (unique_index < value_list.size()) {
419 const auto& value = value_list[unique_index];
420 const auto& first_index = index_list[unique_index];
421 auto last_index = this->snapshots.size();
422 if (unique_index < (value_list.size() - 1))
423 last_index = index_list[unique_index + 1];
425 auto& target_state = this->snapshots[first_index];
426 target_state.get<T>().update( std::move(value) );
427 for (std::size_t index=first_index + 1; index < last_index; index++)
428 this->snapshots[index].get<T>().update( target_state.get<T>() );
435 template <
typename K,
typename T,
class Serializer>
436 void pack_unpack_map(
Serializer& serializer) {
437 std::vector<T> value_list;
438 std::vector<std::size_t> index_list;
441 pack_map<K,T>(value_list, index_list);
443 serializer(value_list);
444 serializer(index_list);
447 unpack_map<K,T>(value_list, index_list);
451 template <
typename K,
typename T>
452 void pack_map(std::vector<T>& value_list,
453 std::vector<std::size_t>& index_list) {
455 const auto& last_map = this->snapshots.back().get_map<K,T>();
456 std::vector<K> key_list{ last_map.keys() };
457 std::unordered_map<K,T> current_value;
459 for (std::size_t index = 0; index < this->snapshots.size(); index++) {
460 auto& state = this->snapshots[index];
461 const auto& current_map = state.template get_map<K,T>();
462 for (
const auto& key : key_list) {
463 auto& value = current_map.get_ptr(key);
465 auto it = current_value.find(key);
466 if (it == current_value.end() || !(*value == it->second)) {
467 value_list.push_back( *value );
468 index_list.push_back( index );
470 current_value[key] = *value;
478 template <
typename K,
typename T>
479 void unpack_map(
const std::vector<T>& value_list,
480 const std::vector<std::size_t>& index_list) {
482 std::unordered_map<K, std::vector<std::pair<std::size_t, T>>> storage;
483 for (std::size_t storage_index = 0; storage_index < value_list.size(); storage_index++) {
484 const auto& value = value_list[storage_index];
485 const auto& time_index = index_list[storage_index];
487 storage[ value.name() ].emplace_back( time_index, value );
490 for (
const auto& [key, values] : storage) {
491 for (std::size_t unique_index = 0; unique_index < values.size(); unique_index++) {
492 const auto& [time_index, value] = values[unique_index];
493 auto last_index = this->snapshots.size();
494 if (unique_index < (values.size() - 1))
495 last_index = values[unique_index + 1].first;
497 auto& map_value = this->snapshots[time_index].template get_map<K,T>();
498 map_value.update(std::move(value));
500 for (std::size_t index=time_index + 1; index < last_index; index++) {
501 auto& forward_map = this->snapshots[index].template get_map<K,T>();
502 forward_map.update( key, map_value );
508 friend std::ostream& operator<<(std::ostream& os,
const Schedule& sched);
509 void dump_deck(std::ostream& os)
const;
519 bool m_treat_critical_as_non_critical =
false;
523 std::optional<int> exit_status{};
524 std::vector<ScheduleState> snapshots{};
532 bool m_lowActionParsingStrictness =
false;
537 std::unordered_map<std::string, std::set<int>> possibleFutureConnections;
542 std::size_t current_report_step = 0;
547 std::shared_ptr<SimulatorUpdate> simUpdateFromPython{};
553 void addWell(
Well well);
554 void addWell(
const std::string& wellName,
555 const std::string& group,
558 Phase preferredPhase,
559 const std::optional<double>& refDepth,
560 double drainageRadius,
562 bool automaticShutIn,
564 WellGasInflowEquation gas_inflow,
565 std::size_t timeStep,
566 ConnectionOrder wellConnectionOrder);
567 bool updateWPAVE(
const std::string& wname, std::size_t report_step,
const PAvg& pavg);
569 void updateGuideRateModel(
const GuideRateModel& new_model, std::size_t report_step);
570 GTNode groupTree(
const std::string& root_node, std::size_t report_step, std::size_t level,
const std::optional<std::string>& parent_name)
const;
572 bool updateWellStatus(
const std::string& well, std::size_t reportStep, WellStatus status, std::optional<KeywordLocation> = {});
573 void addWellToGroup(
const std::string& group_name,
const std::string& well_name , std::size_t timeStep);
574 void iterateScheduleSection(std::size_t load_start,
575 std::size_t load_end,
579 const std::unordered_map<std::string, double> * target_wellpi,
580 const std::string& prefix,
581 const bool keepKeywords,
582 const bool log_to_debug =
false);
584 void addGroupToGroup(
const std::string& parent_group,
const std::string& child_group);
585 void addGroup(
const std::string& groupName , std::size_t timeStep);
586 void addGroup(
Group group);
588 void addWell(
const std::string& wellName,
const DeckRecord& record,
589 std::size_t timeStep, ConnectionOrder connection_order);
590 void checkIfAllConnectionsIsShut(std::size_t currentStep);
591 void end_report(std::size_t report_step);
594 void handleKeyword(std::size_t currentStep,
600 const std::vector<std::string>& matching_wells,
603 const std::unordered_map<std::string, double>* target_wellpi,
604 std::unordered_map<std::string, double>& wpimult_global_factor,
606 std::set<std::string>* compsegs_wells =
nullptr);
608 void internalWELLSTATUSACTIONXFromPYACTION(
const std::string& well_name, std::size_t report_step,
const std::string& wellStatus);
611 std::vector<std::string> wellNames(
const std::string& pattern,
613 bool allowEmpty =
false);
614 std::vector<std::string> wellNames(
const std::string& pattern, std::size_t timeStep,
const std::vector<std::string>& matching_wells, InputErrorAction error_action,
ErrorGuard& errors,
const KeywordLocation& location)
const;
615 static std::string formatDate(std::time_t t);
616 std::string simulationDays(std::size_t currentStep)
const;
617 void applyGlobalWPIMULT(
const std::unordered_map<std::string, double>& wpimult_global_factor);
619 bool must_write_rst_file(std::size_t report_step)
const;
621 bool isWList(std::size_t report_step,
const std::string& pattern)
const;
623 SimulatorUpdate applyAction(std::size_t reportStep,
const std::string& action_name,
const std::vector<std::string>& matching_wells);