/* */ #include #include #include #include #include #include #include #include #include namespace Opm { namespace detail { void logTimer(const AdaptiveSimulatorTimer& substepTimer) { std::ostringstream ss; boost::posix_time::time_facet* facet = new boost::posix_time::time_facet("%d-%b-%Y"); ss.imbue(std::locale(std::locale::classic(), facet)); ss <<"\nStarting time step " << substepTimer.currentStepNum() << ", stepsize " << unit::convert::to(substepTimer.currentStepLength(), unit::day) << " days," << " at day " << (double)unit::convert::to(substepTimer.simulationTimeElapsed(), unit::day) << "/" << (double)unit::convert::to(substepTimer.totalTime(), unit::day) << ", date = " << substepTimer.currentDateTime(); OpmLog::info(ss.str()); } std::set consistentlyFailingWells(const std::vector& sr) { // If there are wells that cause repeated failures, we // close them, and restart the un-chopped timestep. std::ostringstream msg; msg << " Excessive chopping detected in report step " << sr.back().report_step << ", substep " << sr.back().current_step << "\n"; std::set failing_wells; // return empty set if no report exists // well failures in assembly is not yet registred if (sr.back().report.empty()) return failing_wells; const auto& wfs = sr.back().report.back().wellFailures(); for (const auto& wf : wfs) { msg << " Well that failed: " << wf.wellName() << "\n"; } msg.flush(); OpmLog::debug(msg.str()); // Check the last few step reports. const int num_steps = 3; const int rep_step = sr.back().report_step; const int sub_step = sr.back().current_step; const int sr_size = sr.size(); if (sr_size >= num_steps) { for (const auto& wf : wfs) { failing_wells.insert(wf.wellName()); } for (int s = 1; s < num_steps; ++s) { const auto& srep = sr[sr_size - 1 - s]; // Report must be from same report step and substep, otherwise we have // not chopped/retried enough times on this step. if (srep.report_step != rep_step || srep.current_step != sub_step) { break; } // Get the failing wells for this step, that also failed all other steps. std::set failing_wells_step; for (const auto& wf : srep.report.back().wellFailures()) { if (failing_wells.count(wf.wellName()) > 0) { failing_wells_step.insert(wf.wellName()); } } failing_wells.swap(failing_wells_step); } } return failing_wells; } void registerAdaptiveParameters() { // TODO: make sure the help messages are correct (and useful) Parameters::Register ("Continue instead of stop when minimum solver time step is reached"); Parameters::Register ("The maximum number of breakdowns before a substep is given up and " "the simulator is terminated"); Parameters::Register ("Specify the \"chattiness\" of the non-linear solver itself"); Parameters::Register ("Specify the \"chattiness\" during the time integration"); Parameters::Register ("The size of the initial time step in days"); Parameters::Register ("Always attempt to finish a report step using a single substep"); Parameters::Register ("The algorithm used to determine time-step sizes. " "Valid options are: " "'pid' (default), " "'pid+iteration', " "'pid+newtoniteration', " "'iterationcount', " "'newtoniterationcount' " "and 'hardcoded'"); Parameters::Register ("The tolerance used by the time step size control algorithm"); Parameters::Register ("The number of linear iterations which the time step control scheme " "should aim for (if applicable)"); Parameters::Register ("The number of Newton iterations which the time step control scheme " "should aim for (if applicable)"); Parameters::Register ("The decay rate of the time step size of the number of " "target iterations is exceeded"); Parameters::Register ("The growth rate of the time step size of the number of " "target iterations is undercut"); Parameters::Register ("The decay rate of the time step decrease when the " "target iterations is exceeded"); Parameters::Register ("The growth rate of the time step increase when the " "target iterations is undercut"); Parameters::Register ("The name of the file which contains the hardcoded time steps sizes"); Parameters::Register ("The minimum time step size in days for which problematic wells are not shut"); Parameters::Register ("The minimum time step size (in days for field and metric unit and hours for lab unit) " "can be reduced to based on newton iteration counts"); } } // namespace detail } // namespace Opm