This page is likely obsolete.
A more ellegant solution is to use system signals to write a stop file for StarCCM and let it quit itself gracefully – no additional macros needed.
The latest submission script template will write a stop file before SLURM kills a job. Get it here.
This change needs to be reflecred in this page by explaining how it works.
A running simulation of a submitted job on Neumann will be killed when the job reaches its end of life. Killing a running StarCCM simulation can result in two problems.
On this page, you find a macro which is specific for Neumann to avoid the above problems. It checks the end time of the running job and stops StarCCM savely before the job is being killed. In contrast to previous versions of this code, it is capable of later changes to the job maximal time. The previous version checked the end of a job only once. The script explained here will check the left time at every new function call.
To add this feature you need to add the following components:
Not knowing how many iterations to run, a while
loop can be used to progress a simulation until a certain criterion is met.
A while
loop continuously executes something, as long as the logical operation returns true
.
In pseudo code: while(logical_operation) {execute_something;}
The command execute_something
is the part which makes StarCCM progress the simulation by a few steps.
The logical_operation
needs to be an operation or command, which is true
as long as time is left, and as long as (StarCCM-) stopping criteria are not yet met (Mind the literal logic!).
More details on the while
syntax can be found in the Java manual.
The following code shows how this is done. It needs to be placed into your main method (usually execute0()
). It encloses the step-wise Simulation Iterator within the while
-loop. In the head of this loop, the Boolean returned by timeLeft()
is checked. timeLeft
is a method which checks how much time on your job is left. It will be explained in the next section. Also, for the sake of simplicity stopping criteria are not included here, see further below for an example with stopping criteria included.
while (timeLeft()) { // Put your iterators here sim.getSimulationIterator().step(5); } // Saving the Simulation overwriting the original file sim.saveState( resolvePath( sim.getSessionPath() ) );
The private method timeLeft()
will return a boolean value.
It's purpose is to check whether computation time during a running job is left. When more time is left than a specified buffer time - to save the simulation securely - it will return true. When the remaining time is less than a specified buffer it will return false.
This check can be done by using the information of the job manager. scontrol
is the program to receive some information on jobs (other resources). Its output is filtered with grep
and cut
to get the end time when a job is getting killed.
Usually you put the following code into your StarMacro
class, similar to the execute0()
method.
The timeLeft()
snippet:
The BufferedReader
which is used to collect the output from the scontrol
command is an object which is inside the java's io
library. It is not loaded automatically. For this reason, you need to add the import command in the beginning of your script. See further below to see how: justRunLong.java.
// for Jobtime left check import java.io.*; // to read buffer
This justrun script will run a simulation as is. It checks every 5 steps whether enough time is left. These steps are either iterations for steady state and full time steps for transient simulations,respectively.
It will not check for any other stopping criteria. So.. no max step, no file stop, or any other stopping criteria.
See the next section for a script with included stopping criteria.
Windows users: please make sure to convert the script with dos2unix
on the linux machine, and read the article on Linebreaks
// STAR-CCM+ macro: justRunLong.java // Written by Sebastian Engel 11/2017 // // This script will run a simulation as is. // It checks every 5 steps whether enough time is left. // These steps are either iterations for steady state and // full time steps for transient simulations, respectively. // // However, it will NOT check for any other stopping criteria! // So.. no max step, no file stop, or any other stopping criteria! // Considering stopping criteria will require more code. See the wiki. package macro; // for Jobtime left check import java.util.concurrent.*; // to convert milliseconds to seconds import java.io.*; // to read buffer //Star import star.common.*; import star.base.neo.*; import star.vis.*; public class justRunLong extends StarMacro { public void execute() { execute0(); } private void execute0() { Simulation sim = getActiveSimulation(); // Solve while (timeLeft()) { // Put your iterators here sim.getSimulationIterator().step(5); } // Saving the Simulation overwriting the original file sim.saveState( resolvePath( sim.getSessionPath() ) ); } private boolean timeLeft() { /* ######################################### */ // buffertime in milliseconds long bufferTime = 10*60*1000; /* ######################################### */ //Initialization of variables long diffTime = 0; long finalTime = 0; // Get current time stamp long currentTime = System.currentTimeMillis(); // Get remaining time of current job String[] command = { "/bin/sh", "-c", "date '+%s' -d $(scontrol show job $SLURM_JOBID | grep EndTime | cut -d'=' -f3 | cut -d' ' -f1)" }; try { Process proc = Runtime.getRuntime().exec(command); BufferedReader reader = new BufferedReader(new InputStreamReader(proc.getInputStream())); String s; while ((s = reader.readLine()) != null) { finalTime = Long.valueOf(s).longValue() * 1000; // in milliseconds } } catch (IOException ex) { return false;} // stop if something went wrong here //calculate remaining time diffTime = finalTime - currentTime; // decide whether enough time is left if (diffTime > bufferTime) { return true; } else { Simulation sim = getActiveSimulation(); sim.println("WARNING: The job has run out of time."); return false; } } }
This script includes also additional Stopping Criteria for a steady state case.
It will run 5 steps after checking whether:
If these statements are all logically true it will run these 5 steps. Then it will check again.
TODO
Windows users: please make sure to convert the script with dos2unix
on the linux machine, and read the article on Linebreaks
// Written by Sebastian Engel 02/2017 // Includes a method to check how much time is left, and checks whether Stopping Criterion are satisfied. // for Jobtime left check import java.util.concurrent.*; // to convert milliseconds to seconds import java.io.*; // to read buffer import java.util.ArrayList; import java.util.Collection; //Star import star.common.*; import star.base.neo.*; import star.vis.*; public class runInSlurmWithAllCriterions extends StarMacro { public void execute() { Simulation sim = getActiveSimulation(); // Initialization of special Stopping Criterion SolverStoppingCriterion maxStepCriterion = sim.getSolverStoppingCriterionManager().getSolverStoppingCriterion("Maximum Steps"); SolverStoppingCriterion stopFileCriterion = sim.getSolverStoppingCriterionManager().getSolverStoppingCriterion("Stop File"); Collection<SolverStoppingCriterion> criterions = new ArrayList<>(); // Fill criterion collection while filtering out stop file and max step criterion sim.getSolverStoppingCriterionManager() .getObjects().stream() .filter(crit -> !crit.equals(maxStepCriterion)) .filter(crit -> !crit.equals(stopFileCriterion)) .forEach(crit -> criterions.add(crit)); // Solve while criterions are true. while (timeLeft() && maxStepCriterion.getIsUsed() ? !maxStepCriterion.getIsSatisfied() : true // check max steps, only if criterion is enabled, else continue && !stopFileCriterion.getIsSatisfied() // check if stop file is present && criterions.size() == 0 ? true // continue if no additional criterion defined, else check criterions : (criterions.stream() .filter(crit -> crit.getIsUsed()) // check only enabled criterions .filter(crit -> !crit.getIsSatisfied()) // count only unsatisfied criterions .count() > 0)) // when no unsatisfied criterions are left then sim has finished { // Do something here (solve) sim.getSimulationIterator().step(5); } // Saving the Simulation, overwriting the original file sim.saveState(resolvePath(sim.getSessionPath())); } private boolean timeLeft() { /* ######################################### */ // buffertime in milliseconds long bufferTime = 10 * 60 * 1000; /* ######################################### */ //Initialization of variables long diffTime = 0; long finalTime = 0; // Get current time stamp long currentTime = System.currentTimeMillis(); // Get remaining time of current job String[] command = {"/bin/sh", "-c", "date '+%s' -d $(scontrol show job $SLURM_JOBID | grep EndTime | cut -d'=' -f3 | cut -d' ' -f1)"}; try { Process proc = Runtime.getRuntime().exec(command); BufferedReader reader = new BufferedReader(new InputStreamReader(proc.getInputStream())); String s; while ((s = reader.readLine()) != null) { finalTime = Long.valueOf(s).longValue() * 1000; // in milliseconds } } catch (IOException ex) { return false; } // stop if something went wrong here //calculate remaining time diffTime = finalTime - currentTime; // decide whether enough time is left if (diffTime > bufferTime) { return true; } else { Simulation sim = getActiveSimulation(); sim.println("WARNING: The job has run out of time."); return false; } } }