How to make StarCCM stop itself before a Neumann job ends

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.

  • All process since the last save will be lost
  • Risk of creating StarCCM ghosts (Further Information)

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:

  • a loop which will progress your simulation as long as time is left
  • a method checking how much time is left
  • additional libraries for the above components

A loop which progresses the simulation

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() ) );

Method check if enough time is left

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:

Click to display ⇲

Click to hide ⇱

	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 (in seconds)
		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;
		}
	}

Additional libraries necessary

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

Just run

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

justRunLong.java
// 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;
		}
	}
}

The full script with Stopping Criteria Check

This script includes also additional Stopping Criteria for a steady state case.
It will run 5 steps after checking whether:

  1. Enough time is left
  2. Max Steps is not yet reached
  3. All other Stopping Criteria are not yet satisfied

If these statements are all logically true it will run these 5 steps. Then it will check again.

TODO

  • might not consider inner steps iteration criterion or minimum steps criterion correctly

Windows users: please make sure to convert the script with dos2unix on the linux machine, and read the article on Linebreaks

runInSlurmWithAllCriterions.java
// 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;
        }
    }
}
guide/starccm/how_to_stop_it_before_a_neumann_job_ends.txt · Last modified: 2020/01/10 17:02 by seengel
Back to top
CC Attribution-Share Alike 3.0 Unported
chimeric.de = chi`s home Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0