92 explicit Schedule(std::shared_ptr<const Python> python_handle);
99 std::shared_ptr<const Python> python,
100 const std::optional<int>& output_interval = {},
111 std::shared_ptr<const Python> python,
112 const std::optional<int>& output_interval = {},
120 std::shared_ptr<const Python> python,
121 const std::optional<int>& output_interval = {},
129 std::shared_ptr<const Python> python,
130 const std::optional<int>& output_interval = {},
133 template <
typename T>
138 std::shared_ptr<const Python> python,
139 const std::optional<int>& output_interval = {},
144 std::shared_ptr<const Python> python,
145 const std::optional<int>& output_interval = {},
151 const std::optional<int>& output_interval = {},
154 static Schedule serializationTestObject();
160 std::time_t getStartTime()
const;
161 std::time_t posixStartTime()
const;
162 std::time_t posixEndTime()
const;
163 std::time_t simTime(std::size_t timeStep)
const;
164 double seconds(std::size_t timeStep)
const;
165 double stepLength(std::size_t timeStep)
const;
166 std::optional<int> exitStatus()
const;
167 const UnitSystem& getUnits()
const {
return this->m_static.m_unit_system; }
168 const Runspec& runspec()
const {
return this->m_static.m_runspec; }
170 std::size_t numWells()
const;
171 std::size_t numWells(std::size_t timestep)
const;
172 bool hasWell(
const std::string& wellName)
const;
173 bool hasWell(
const std::string& wellName, std::size_t timeStep)
const;
175 WellMatcher wellMatcher(std::size_t report_step)
const;
176 std::function<std::unique_ptr<SegmentMatcher>()> segmentMatcherFactory(std::size_t report_step)
const;
177 std::vector<std::string> wellNames(
const std::string& pattern, std::size_t timeStep,
const std::vector<std::string>& matching_wells = {})
const;
178 std::vector<std::string> wellNames(
const std::string& pattern)
const;
179 std::vector<std::string> wellNames(std::size_t timeStep)
const;
180 std::vector<std::string> wellNames()
const;
182 bool hasGroup(
const std::string& groupName, std::size_t timeStep)
const;
183 std::vector<std::string> groupNames(
const std::string& pattern, std::size_t timeStep)
const;
184 std::vector<std::string> groupNames(std::size_t timeStep)
const;
185 std::vector<std::string> groupNames(
const std::string& pattern)
const;
186 std::vector<std::string> groupNames()
const;
196 std::vector<const Group*> restart_groups(std::size_t timeStep)
const;
198 std::vector<std::string> changed_wells(std::size_t reportStep)
const;
199 const Well& getWell(std::size_t well_index, std::size_t timeStep)
const;
200 const Well& getWell(
const std::string& wellName, std::size_t timeStep)
const;
201 const Well& getWellatEnd(
const std::string& well_name)
const;
203 std::unordered_set<int> getAquiferFluxSchedule()
const;
204 std::vector<Well> getWells(std::size_t timeStep)
const;
205 std::vector<Well> getWellsatEnd()
const;
206 void shut_well(
const std::string& well_name, std::size_t report_step);
207 void shut_well(
const std::string& well_name);
208 void stop_well(
const std::string& well_name, std::size_t report_step);
209 void stop_well(
const std::string& well_name);
210 void open_well(
const std::string& well_name, std::size_t report_step);
211 void open_well(
const std::string& well_name);
212 void clear_event(ScheduleEvents::Events, std::size_t report_step);
213 void applyWellProdIndexScaling(
const std::string& well_name,
const std::size_t reportStep,
const double scalingFactor);
215 std::vector<const Group*> getChildGroups2(
const std::string& group_name, std::size_t timeStep)
const;
216 std::vector<Well> getChildWells2(
const std::string& group_name, std::size_t timeStep)
const;
217 WellProducerCMode getGlobalWhistctlMmode(std::size_t timestep)
const;
219 const UDQConfig& getUDQConfig(std::size_t timeStep)
const;
220 void evalAction(
const SummaryState& summary_state, std::size_t timeStep);
222 GTNode groupTree(std::size_t report_step)
const;
223 GTNode groupTree(
const std::string& root_node, std::size_t report_step)
const;
224 const Group& getGroup(
const std::string& groupName, std::size_t timeStep)
const;
226 std::optional<std::size_t> first_RFT()
const;
232 std::size_t size()
const;
234 bool write_rst_file(std::size_t report_step)
const;
235 const std::map< std::string, int >& rst_keywords(
size_t timestep )
const;
244 SimulatorUpdate applyAction(std::size_t reportStep,
const Action::ActionX& action,
const std::vector<std::string>& matching_wells,
const std::unordered_map<std::string, double>& wellpi);
255 const GasLiftOpt& glo(std::size_t report_step)
const;
257 bool operator==(
const Schedule& data)
const;
258 std::shared_ptr<const Python> python()
const;
263 std::vector<ScheduleState>::const_iterator begin()
const;
264 std::vector<ScheduleState>::const_iterator end()
const;
265 void create_next(
const time_point& start_time,
const std::optional<time_point>& end_time);
267 void create_first(
const time_point& start_time,
const std::optional<time_point>& end_time);
269 void treat_critical_as_non_critical(
bool value) { this->m_treat_critical_as_non_critical = value; }
277 static bool cmp(
const Schedule& sched1,
const Schedule& sched2, std::size_t report_step);
278 void applyKeywords(std::vector<std::unique_ptr<DeckKeyword>>& keywords, std::size_t report_step);
279 void applyKeywords(std::vector<std::unique_ptr<DeckKeyword>>& keywords);
281 template<
class Serializer>
284 serializer(this->m_static);
285 serializer(this->m_sched_deck);
286 serializer(this->action_wgnames);
287 serializer(this->exit_status);
288 serializer(this->snapshots);
289 serializer(this->restart_output);
290 serializer(this->completed_cells);
291 serializer(this->m_treat_critical_as_non_critical);
292 serializer(this->current_report_step);
293 serializer(this->simUpdateFromPython);
295 this->
template pack_unpack<PAvg>(serializer);
296 this->
template pack_unpack<WellTestConfig>(serializer);
297 this->
template pack_unpack<GConSale>(serializer);
298 this->
template pack_unpack<GConSump>(serializer);
299 this->
template pack_unpack<GroupEconProductionLimits>(serializer);
300 this->
template pack_unpack<WListManager>(serializer);
301 this->
template pack_unpack<Network::ExtNetwork>(serializer);
302 this->
template pack_unpack<Network::Balance>(serializer);
303 this->
template pack_unpack<RPTConfig>(serializer);
304 this->
template pack_unpack<Action::Actions>(serializer);
305 this->
template pack_unpack<UDQActive>(serializer);
306 this->
template pack_unpack<UDQConfig>(serializer);
307 this->
template pack_unpack<NameOrder>(serializer);
308 this->
template pack_unpack<GroupOrder>(serializer);
309 this->
template pack_unpack<GuideRateConfig>(serializer);
310 this->
template pack_unpack<GasLiftOpt>(serializer);
311 this->
template pack_unpack<RFTConfig>(serializer);
312 this->
template pack_unpack<RSTConfig>(serializer);
313 this->
template pack_unpack<ScheduleState::BHPDefaults>(serializer);
314 this->
template pack_unpack<Source>(serializer);
316 this->
template pack_unpack_map<int, VFPProdTable>(serializer);
317 this->
template pack_unpack_map<int, VFPInjTable>(serializer);
318 this->
template pack_unpack_map<std::string, Group>(serializer);
319 this->
template pack_unpack_map<std::string, Well>(serializer);
322 template <
typename T,
class Serializer>
324 std::vector<T> value_list;
325 std::vector<std::size_t> index_list;
328 this->
template pack_state<T>(value_list, index_list);
330 serializer(value_list);
331 serializer(index_list);
334 this->
template unpack_state<T>(value_list, index_list);
337 template <
typename T>
338 std::vector<std::pair<std::size_t, T>> unique()
const {
339 std::vector<std::pair<std::size_t, T>> values;
340 for (std::size_t index = 0; index < this->snapshots.size(); index++) {
341 const auto& member = this->snapshots[index].get<T>();
342 const auto& value = member.get();
343 if (values.empty() || !(value == values.back().second))
344 values.push_back( std::make_pair(index, value));
350 template <
typename T>
351 void pack_state(std::vector<T>& value_list, std::vector<std::size_t>& index_list)
const {
352 auto unique_values = this->
template unique<T>();
353 for (
auto& [index, value] : unique_values) {
354 value_list.push_back( std::move(value) );
355 index_list.push_back( index );
360 template <
typename T>
361 void unpack_state(
const std::vector<T>& value_list,
const std::vector<std::size_t>& index_list) {
362 std::size_t unique_index = 0;
363 while (unique_index < value_list.size()) {
364 const auto& value = value_list[unique_index];
365 const auto& first_index = index_list[unique_index];
366 auto last_index = this->snapshots.size();
367 if (unique_index < (value_list.size() - 1))
368 last_index = index_list[unique_index + 1];
370 auto& target_state = this->snapshots[first_index];
371 target_state.get<T>().update( std::move(value) );
372 for (std::size_t index=first_index + 1; index < last_index; index++)
373 this->snapshots[index].get<T>().update( target_state.get<T>() );
380 template <
typename K,
typename T,
class Serializer>
381 void pack_unpack_map(
Serializer& serializer) {
382 std::vector<T> value_list;
383 std::vector<std::size_t> index_list;
386 pack_map<K,T>(value_list, index_list);
388 serializer(value_list);
389 serializer(index_list);
392 unpack_map<K,T>(value_list, index_list);
396 template <
typename K,
typename T>
397 void pack_map(std::vector<T>& value_list,
398 std::vector<std::size_t>& index_list) {
400 const auto& last_map = this->snapshots.back().get_map<K,T>();
401 std::vector<K> key_list{ last_map.keys() };
402 std::unordered_map<K,T> current_value;
404 for (std::size_t index = 0; index < this->snapshots.size(); index++) {
405 auto& state = this->snapshots[index];
406 const auto& current_map = state.template get_map<K,T>();
407 for (
const auto& key : key_list) {
408 auto& value = current_map.get_ptr(key);
410 auto it = current_value.find(key);
411 if (it == current_value.end() || !(*value == it->second)) {
412 value_list.push_back( *value );
413 index_list.push_back( index );
415 current_value[key] = *value;
423 template <
typename K,
typename T>
424 void unpack_map(
const std::vector<T>& value_list,
425 const std::vector<std::size_t>& index_list) {
427 std::unordered_map<K, std::vector<std::pair<std::size_t, T>>> storage;
428 for (std::size_t storage_index = 0; storage_index < value_list.size(); storage_index++) {
429 const auto& value = value_list[storage_index];
430 const auto& time_index = index_list[storage_index];
432 storage[ value.name() ].emplace_back( time_index, value );
435 for (
const auto& [key, values] : storage) {
436 for (std::size_t unique_index = 0; unique_index < values.size(); unique_index++) {
437 const auto& [time_index, value] = values[unique_index];
438 auto last_index = this->snapshots.size();
439 if (unique_index < (values.size() - 1))
440 last_index = values[unique_index + 1].first;
442 auto& map_value = this->snapshots[time_index].template get_map<K,T>();
443 map_value.update(std::move(value));
445 for (std::size_t index=time_index + 1; index < last_index; index++) {
446 auto& forward_map = this->snapshots[index].template get_map<K,T>();
447 forward_map.update( key, map_value );
453 friend std::ostream& operator<<(std::ostream& os,
const Schedule& sched);
454 void dump_deck(std::ostream& os)
const;
464 bool m_treat_critical_as_non_critical =
false;
468 std::optional<int> exit_status{};
469 std::vector<ScheduleState> snapshots{};
476 std::size_t current_report_step = 0;
481 std::shared_ptr<SimulatorUpdate> simUpdateFromPython{};
487 void addWell(
Well well);
488 void addWell(
const std::string& wellName,
489 const std::string& group,
492 Phase preferredPhase,
493 const std::optional<double>& refDepth,
494 double drainageRadius,
496 bool automaticShutIn,
498 WellGasInflowEquation gas_inflow,
499 std::size_t timeStep,
500 ConnectionOrder wellConnectionOrder);
501 bool updateWPAVE(
const std::string& wname, std::size_t report_step,
const PAvg& pavg);
503 void updateGuideRateModel(
const GuideRateModel& new_model, std::size_t report_step);
504 GTNode groupTree(
const std::string& root_node, std::size_t report_step, std::size_t level,
const std::optional<std::string>& parent_name)
const;
506 bool updateWellStatus(
const std::string& well, std::size_t reportStep, WellStatus status, std::optional<KeywordLocation> = {});
507 void addWellToGroup(
const std::string& group_name,
const std::string& well_name , std::size_t timeStep);
508 void iterateScheduleSection(std::size_t load_start,
509 std::size_t load_end,
513 const std::unordered_map<std::string, double> * target_wellpi,
514 const std::string& prefix,
515 const bool log_to_debug =
false);
517 void addGroupToGroup(
const std::string& parent_group,
const std::string& child_group);
518 void addGroup(
const std::string& groupName , std::size_t timeStep);
519 void addGroup(
Group group);
521 void addWell(
const std::string& wellName,
const DeckRecord& record,
522 std::size_t timeStep, ConnectionOrder connection_order);
523 void checkIfAllConnectionsIsShut(std::size_t currentStep);
524 void end_report(std::size_t report_step);
527 void handleKeyword(std::size_t currentStep,
533 const std::vector<std::string>& matching_wells,
536 const std::unordered_map<std::string, double>* target_wellpi,
537 std::unordered_map<std::string, double>& wpimult_global_factor,
539 std::set<std::string>* compsegs_wells =
nullptr);
541 void internalWELLSTATUSACTIONXFromPYACTION(
const std::string& well_name, std::size_t report_step,
const std::string& wellStatus);
544 std::vector<std::string> wellNames(
const std::string& pattern,
546 bool allowEmpty =
false);
547 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;
548 static std::string formatDate(std::time_t t);
549 std::string simulationDays(std::size_t currentStep)
const;
550 void applyGlobalWPIMULT(
const std::unordered_map<std::string, double>& wpimult_global_factor);
552 bool must_write_rst_file(std::size_t report_step)
const;
554 bool isWList(std::size_t report_step,
const std::string& pattern)
const;
556 SimulatorUpdate applyAction(std::size_t reportStep,
const std::string& action_name,
const std::vector<std::string>& matching_wells);