Skip to content

Simulation Flow ​

main() is in src/ADSIDAC/ADSIDAC.cpp. It handles --help, --version, --info and --merge-only first. Then, if the process runs under MPI (OMPI_COMM_WORLD_SIZE or PMI_SIZE is set), it hands control to parallelexec (src/ADSIDAC/ParallelExec/); otherwise it runs the serial loop described here. The MPI workers run the same per-sequence logic through the same callbacks; what differs is who chooses the next branch and where the restart data comes from.

Simulation objects ​

All simulation state lives in one SimulationContext instance, g_sim (src/ADSIDAC/Global/SimulationContext.h). Its main members:

MemberClassRole
PlantSystemModuleThe plant parameters exchanged with the thermal-hydraulic solver. The channels are listed in Input/System/RELAP5_channels.txt. See System Module
SSchedulerSchedulerOptions, input and output directories, sequence termination criteria. See Scheduler
IndicatorControlPanelThe control room panel: parameter displays and trends, component state displays, alarms, and controls. Defined in Input/Indicators/ControlPanel.txt. See Control Panel Module
IEInitiatingEventControllerThe initiating events and the times at which they are activated. An event with a negative time is never activated
Communication_placeCommunicationPlaceA bulletin board for the information exchanged in one evaluation step. It is cleared at the end of every step. See Communication Place
Branch_centerBranchRecordThe branch points and branches of the tree. It collects the branch information from the crew and the reliability modules and determines the number, types and probabilities of the branches. See Branch Generation
Decision_Maker, Action_TakerOperatorDM, OperatorATThe two crew members. See Crew Module
Command_handlerCommandControlCenterHolds every activity (pivotal event) generated by the crew or the reliability modules and controls when it takes effect, which models the delay between a decision and its execution. See Command Control Center
Aux_infoAnalysisInfoContainerThe record of activities of the current sequence, written to the analysis logs when the sequence ends. See Output Data Handling
All_procedureProceduresThe operating procedures. See Procedures
All_polynomialCalculationAidPolynomial calculation aids
TranslatorConvertToStringConverts the integer constants of SimConstants.h to strings for output
System_reliabilityHWReliabilityModuleDetects component demands and generates success and failure branches. See Hardware Reliability Module
Support_system_reliabilitySupportSystemReliabilityModuleSupport-system states and their display on the panel
KPSKeyParameterHistoryThe time history of the panel values and of the operators' diagnosis confidences, written per sequence
restart_infodeque of shared_ptr<RestartNodeInfo>The snapshots of the C++ state taken at branch points that still have unexplored branches
restart_buffersmap from sequence id to byte bufferThe solver restart images of the serial run
configSimConfigThe command-line settings

Error messages from all modules are appended to err messages.txt in the working directory of the process (outputErrMessageToFile() and direct writes). The scheduler removes the file at the start of a run.

Initialization ​

The serial main() calls, in this order: SScheduler.parseOptions(), SScheduler.initiationForSimulation(), Plant.initiationForSimulation() (reads the channel list and writes the card numbers into r5pars_), Translator.initiationForSimulation(), Branch_center.initiationForSimulation(), Indicator.readInfoFromFile(), the initiationForSimulation() of both operators and of All_procedure. It then creates the solver: RelapSolver, or RestApiSolver when --solver=mock is given. With --resume it loads the checkpoint at this point.

Running a sequence ​

The serial loop calls solver.runSequence(engine_callback) once per sequence until solver.isTerminateAll() is true. For RELAP5, runSequence() calls the Fortran entry point relap5_(), which reads the input deck (first sequence) or indeck.i with a restart record number (all later sequences) and runs its time-step loop. The solver calls back into AdsidacCallback (src/ADSIDAC/Solver/AdsidacCallback.cpp):

CallbackWhenWhat it does
onFirstInit()once, in the first sequenceReads the remaining input files (panel, procedures, calculation aids, crew, reliability, initiating events), checks that every panel item is in both system decompositions, and performs the first panel scan
onScenarioStart()at the start of every sequenceUpdates the plant values and initializes the panel
onEvaluationPoint()about every 0.5 s of simulated time (dtstep.f calls Interfc when timehy - timesno >= 0.5)One evaluation step, below
onBranchingPoint()after a step that generated more than one branchIn an MPI worker: captures the restart image and hands the branches to the server and to peers. Does nothing in a serial run

One evaluation step (onEvaluationPoint()):

  1. If the solver reports a failure (csnostop), create a THFail end state and return.
  2. If this is the first step of a restarted sequence, restore the C++ state (initiationForRestart(), below).
  3. Release due commands to the communication place, let both operators scan the panel, execute due initiating events, update the plant values and the panel, update support-system states, check for component and support-system failures, and send the pending control actions to the solver.
  4. Run the information block and then the decision block of the Decision Maker and of the Action Taker.
  5. Add a data set to KPS.
  6. Scheduler::checkForTerminatingCurrentSequence(). If the sequence goes on, BranchRecord::checkAndAddBranchCluster() returns the number of branches generated in this step (cnbranch). When it is greater than 0, the commands of the current branch are sent to the command center and cgennode is set. When it is greater than 1, a RestartNodeInfo snapshot of all modules is also pushed to restart_info, and RELAP5 writes a restart record.
  7. Clear the communication place.

When the sequence has ended, the serial loop captures the solver's restart image if the sequence generated branches (kept in memory, or written to restart_seq_<n>.r in file mode), writes the key parameter histories and the analysis logs, and writes a DET checkpoint if one is due.

Choosing the next sequence ​

AdsidacCallback::restartForNewSequence() scans Branch_center.branch_cluster from the oldest branch point and takes the first one that still has an unexplored branch. It restores the restart image of the sequence that created that branch point into the solver and writes indeck.i, whose card 103 carries the restart record number stored in the cluster (BranchCluster::getNCountForRestartRELAP5()).

When no branch point has an unexplored branch, it sets terminateall, saves all pivotal-event nodes and clears the clusters, which ends the loop.

Restoring the state for the next sequence ​

At the first evaluation point of a restarted sequence, AdsidacCallback::initiationForRestart():

  1. selects the next branch of the chosen cluster, assigns it a new branch id and registers it as a child of its mother branch;
  2. finds the RestartNodeInfo snapshot of that cluster (the snapshot is dropped from restart_info when this is the cluster's last branch);
  3. clears every module and copies the snapshot back: control panel, procedures, analysis records, key parameter history, command center, both operators, initiating events, hardware reliability, calculation aids;
  4. sends the content of the selected branch alternative to the command center (BranchProbability::sendBranchInfoToCommandCenter()), so the child sequence executes its own alternative: the control value, the action time, the component failure or the procedure step. The environment variable ADS_RESTART_INJECT=0 turns this step off.

End of the simulation ​

After the loop, BranchRecord::endSimulation() writes ES_summary.txt. A resumed run then renumbers its pivotal-event files (adsidac::pe::finalize_sequential()). Finally the run statistics are recorded and the completion notification, if configured, is sent.

ADS-IDAC Engine Documentation