• CFD, Fluid Flow, FEA, Heat/Mass Transfer

Macros in Java for STAR-CCM+

Example Scripts to Automate Simulations

This page example functions and approach to automate simulation process partially or fully. It is not intended to created a push-button simulation example.


Table of Contents:

/* Store common variables for mesh generation, boundary conditions, material
properties, solver settings, post-processing and report generation in separate
file. The constants and variables are stored in file simVars.java and the main
function and methods are stored in file named solverSettingsSTAR.java. The two
files need to be compiled together: javac solverSettingsSTAR.java simVars.java
*/
Variables to be copied into public void execute(). The variables are defined to be same as in PyFLUENT example and hence they can be use by removing the qualifier 'double' and semi-colons. The values are in default units (which is SI or MKS unless user has changed to any other such as FPS system). github.com/frkasper/MacroUtils/.../UserDeclarations.java is a good example to declare variables as per project specific requirements.
  double max_cell_quality = 0.10;
  double max_allowed_skew = 75.0;
  double max_volm_change  = 0.01;
  
  // Boundary conditions
  double[] gravity = { 0.0, -9.806, 0.0 };
  double[] v_init = { 0.1, 0.0, 0.0 };
  double radEmissivity = 0.80;
  
  // Porous resistances
  double i_res           = 2500;
  double v_res           = 50;
  
  // Solver settings
  double n_iter          = 4000;
  double t_step          = 1.0e-3;
  double duration        = 10.0;
  double iter_per_step   = 20;
  double count_t_steps   = duration / t_step;

  // Reference and limiting values
  double ref_den         = 1.225;
  double Tref            = 300;
  double t_max           = 500;
  double t_min           = 273;
  double p_min           = 100;
Alternatively, a table can be defined such as one described below and a Java macro can be used to read and assign boundary conditions.
Zone_Name   Type    Material_Name  Density   Thermal_Conductivty   Cp       RPM    LC_I    LC_V
------------------------------------------------------------------------------------------------
Tubes       Fluid   Air            1.120       0.027               1005.5     0      0      0
...
Here LC_I and LC_V is applicable to porous zones. Similar table can be created for wall boundary types.
One can define ArrayList<String> bc_list = new ArrayList<String>(Arrays.list("inlet_1", "inlet_2", "wall_htc", "wall_rot", "outlet_p")); to create a list of names to be used in various functions. The list can be name of scenes, reports, plots, derived parts, planes, zone names... where each item can be access using get(i).
Methods and Classes: uncomment/comment as needed.
import java.util.*;
import star.common.*;
import star.base.neo.*;
import star.motion.*;

public class starMacroTemplate extends StarMacro {
  public void execute() {
    importCad_Mesh(Simulation simX);
    generateSrfMesh(Simulation simX);
    generateVolMesh(Simulation simX);
    defineMatProps(Simulation simX);
    defineBndConds(Boundary bndry);
    solverSettings(Simulation simX);
    defineMonitors(Simulation simX);
    defineReports(Simulation simX);
    generateReports(Simulation simX);
    defineScenes(Simulation simX);
    saveReptPlots(Simulation simX);
  }
private void importCad_Mesh() {
    ...
  }
  
  private void generateSrfMesh() {
    ...
  }
  private void generateVolMesh(simX) {
    ...
    
    //Check and print mesh quality
    MinReport min_cell_q = (MinReport) simX.getReportManager().getReport("minCellQuality");
    MaxReport max_skew = (MaxReport) simX.getReportManager().getReport("maxCellSkewness");
  }
  private double getZones(Simulation simX, String region_type) {
    double cell_count = 0;
    ElementCountReport el_count = simX.getReportManager().createReport(ElementCountReport.clss);
    Collection<Region> all_regions = simX.getRegionManager().getRegions();
    Collection<Region> fluid_regions = simX.getRegionManager().getRegions();
    Collection<Region> solid_regions = simX.getRegionManager().getRegions();
    for (Region reg : all_regions) {
      if (reg.getRegionType() instanceof FluidRegion) {
        solid_regions.remove(reg);
        if (!(reg instanceof ShellRegion) {
        solid_regions.remove(reg);
      }
    }
    if (!(reg instanceof ShellRegion) {
      fluid_regions.remove(reg);
    }
  }
    if(region_type = "fluid") {
      elem_count.getParts().setObjects("fluid_region");
      cell_count = el_count.getReportMonitorValue();
    }
    if(region_type = "solid") {
      elem_count.getParts().setObjects("solid_region");
      cell_count = el_count.getReportMonitorValue();
    }
    simX.getReportManager().remove(el_count);
    return cell_count;
  }
  
  private static List<String> getFluidZones(Simulation simX) {
    Collection<Region> all_regions = simX.getRegionManager().getRegions();
    // List to store the names of fluid regions
    List<String> fluid_regions = new ArrayList<>();
    
    for (Region reg : all_regions) {
      // if (reg.getPhysicsContinuum().getPresentationName().equals("Fluid")) {
      if (reg.getRegionType() instanceof FluidRegion) {
        fluid_regions.add(region.getPresentationName());
      }
    }
    return fluid_regions;
  }
  
  private void defineMatProps() {
    ...
  }
  
  private void defineBndConds() {
    //Create field functions
    final double m_dot = 2.50;
    UserFieldFunction UFF_mdot = (UserFieldFunction) simX.getFieldFunctionManager().
      .getFunction("m_dot");
    UFF_mdot.setDefinition(String.valueOf(m_dot)
  }
Following code was generated by AI in Copilot. This can be tweaked to convert into a function with user-inputs taken from a text file or explicitly defined in Main function.
public class SetInletBoundary {
  public static void main(String[] args) {
    Simulation sim = getActiveSimulation();
    Region region = sim.getRegionManager().getRegion("RegionName");
    Boundary inletBoundary = region.getBoundaryManager().getBoundary("InletBoundary");

    // Scanner for user input
    Scanner scanner = new Scanner(System.in);

    System.out.println("Select inlet boundary condition type:");
    System.out.println("1. Velocity Inlet");
    System.out.println("2. Pressure Inlet");
    System.out.println("3. Mass Flow Inlet");
    int choice = scanner.nextInt();

    switch (choice) {
      case 1:   // Set Velocity Inlet
        VelocityBoundary velocityBoundary = (VelocityBoundary) inletBoundary.getValues()
          .get(VelocityBoundary.class);
        System.out.println("Enter Velocity Magnitude (m/s):");
        double velocity = scanner.nextDouble();
        velocityBoundary.getVelocityMagnitude().setValue(velocity);
        break;
      case 2:   // Set Pressure Inlet
        PressureBoundary pressureBoundary = (PressureBoundary) inletBoundary.getValues()
          .get(PressureBoundary.class);
        System.out.println("Enter Gauge Pressure (Pa):");
        double pressure = scanner.nextDouble();
        pressureBoundary.getPressure().setValue(pressure);
        break;
      case 3:   // Set Mass Flow Inlet
        MassFlowBoundary massFlowBoundary = (MassFlowBoundary) inletBoundary.getValues()
          .get(MassFlowBoundary.class);
        System.out.println("Enter Mass Flow Rate (kg/s):");
        double massFlow = scanner.nextDouble();
        massFlowBoundary.getMassFlowRate().setValue(massFlow);
        break;
      default:
        System.out.println("Invalid choice!");
        break;
    }
    scanner.close();
    sim.saveState("Setup.sim");
  }
}
Define boundary conditions on walls:
public class SetWallBC{
  public static void main(String[] args) {
    Simulation sim = getActiveSimulation();
    Region region = sim.getRegionManager().getRegion("RegionName");
    Boundary wallBoundary = region.getBoundaryManager().getBoundary("WallBoundary");

    // Scanner for user input
    Scanner scanner = new Scanner(System.in);
    System.out.println("Select wall boundary condition type:");
    System.out.println("1. Fixed Temperature");
    System.out.println("2. Known Wall Flux");
    System.out.println("3. Heat Transfer Coefficient (HTC)");
    System.out.println("4. Radiation");
    int choice = scanner.nextInt();
    switch (choice) {
      case 1:   // Set Fixed Temperature
        TemperatureBoundary temperatureBoundary = (TemperatureBoundary) wallBoundary.getValues()
          .get(TemperatureBoundary.class);
        System.out.println("Enter Fixed Temperature (K):");
        double temperature = scanner.nextDouble();
        temperatureBoundary.getTemperature().setValue(temperature);
        break;
      case 2:  // Set Known Wall Flux
        HeatFluxBoundary heatFluxBoundary = (HeatFluxBoundary) wallBoundary.getValues()
          .get(HeatFluxBoundary.class);
        System.out.println("Enter Wall Flux (W/m^2):");
        double flux = scanner.nextDouble();
        heatFluxBoundary.getHeatFlux().setValue(flux);
        break;
      case 3:  // Set HTC
        ConvectiveHeatTransferCoefficientBoundary htcBoundary = (ConvectiveHeatTransferCoefficientBoundary)
          wallBoundary.getValues().get(ConvectiveHeatTransferCoefficientBoundary.class);
        System.out.println("Enter HTC (W/m^2-K):");
        double htc = scanner.nextDouble();
        htcBoundary.getConvectiveHeatTransferCoefficient().setValue(htc);
        System.out.println("Enter Free Stream Temperature (K):");
        double freeStreamTemp = scanner.nextDouble();
        htcBoundary.getFreeStreamTemperature().setValue(freeStreamTemp);
        break;
      case 4:  // Set Radiation
        RadiationBoundary radiationBoundary = (RadiationBoundary) wallBoundary.getValues()
          .get(RadiationBoundary.class);
        System.out.println("Enter Emissivity:");
        double emissivity = scanner.nextDouble();
        radiationBoundary.getEmissivity().setValue(emissivity);
        break;
      default:
        System.out.println("Invalid choice!");
        break;
    }
    // Set Surface Roughness
    SurfaceRoughnessProperty surfaceRoughness = (SurfaceRoughnessProperty) wallBoundary.getValues()
      .get(SurfaceRoughnessProperty.class);
    System.out.println("Enter Surface Roughness (m):");
    double roughness = scanner.nextDouble();
    surfaceRoughness.getRoughnessHeight().setValue(roughness);

    // Enable Shell Conduction
    ShellConductionProperty shellConduction = (ShellConductionProperty) wallBoundary.getValues()
      .get(ShellConductionProperty.class);
    shellConduction.setEnabled(true);

    scanner.close();
    sim.saveState("Setup.sim");
  }
}
private void summarizeZones(Simulation simX, Boundary bndry) {
    Collection <Region> region_list = simX.getRegionManager().getObjects();
    System.out.println("Number of regions in model = " + region_list.size());
    
    for (Region region_i : region_list) {
      Collection <Boundary> boundary_list = simX.getBoundaryManager().getObjects();
      System.out.println("Number of boundarie in " + "region_i + " is " + 
        boundary_list.size());
    }
    Collection <Interface> iface_list = simX.getInterfaceManager().getObjects();
    integer n_iface = 0;
    for (Interface iface : iface_list) {
      n_iface = n_iface + 1;
    }
    System.out.println("Number of interfaces in domain = " + n_iface);
    
    // Ref: community.sw.siemens.com/.../getting-surface-area-using-java-api
    // Create a Surface Integral Report of the unity field funcion and then
    // use following lines to get or print on those boundaries.
    SurfaceIntegralReport surf_int = (SurfaceIntegralReport) simX.getReportManager() .getReport("Area");
    double surf_area = surf_int.getValue();
    simX.println(surf_area);
    Boundary b_wall_x = reg.getBoundaryManager().getBoundary("Wall_Pipe");
    surf_int.getParts().setObjects(b_wall_x);
    simX.println("Area of boundary is "  + area);
  }
  private void solverSettings(Simulation simX) {

    Simulation sim_1 = getActiveSimulation();
    for (int i=1; i<=3; i++) {
	  sim_1.saveState("Case_" + i + ".sim");
      
      ...
      
      StepStoppingCriterion stopCrit = (StepStoppingCriterion) 
        sim_1.getSolverStoppingCriterionManager()
        .getSolverStoppingCriterion("Maximum Steps");

      //Get max stopping criteria number and add additional iteration steps
      IntegerValue iter_count = stopCrit.getMaximumNumberStepsObject();
      double j = iter_count.getQuantity().getValue();
      iter_count.getQuantity().setValue(j);

      sim_1.getSimulationIterator().run();
    }
    // Save final sim file and exit
    sim_1.saveState("Case_" + i + "_Full.sim");
  }
}
public class CreateMonitorPoints {
  Simulation sim = getActiveSimulation();
    
  // Create mass flow monitor
  MassFlowRateReport massFlowRateReport = sim.getReportManager()
    .createReport(MassFlowRateReport.class);
  massFlowRateReport.setPresentationName("Mass Flow Rate Inlet");
  massFlowRateReport.getParts().setObjects(sim.getRegionManager()
    .getRegion("RegionName").getBoundaryManager().getBoundary("Inlet_Boundary"));
    
  // Create energy balance monitor
  EnergyBalanceReport energyBalanceReport = sim.getReportManager()
    .createReport(EnergyBalanceReport.class);
  energyBalanceReport.setPresentationName("Energy Balance");
  energyBalanceReport.getParts().setObjects(sim.getRegionManager()
    .getRegion("Region_Name"));
    
  // Optional: Adding these reports to scalar and XY plots
  MonitorPlot massFlowRatePlot = sim.getPlotManager().createMonitorPlot();
  massFlowRatePlot.setPresentationName("Mass Flow Rate Plot");
  massFlowRatePlot.getMonitorManager().addObjects(massFlowRateReport);

  MonitorPlot energyBalancePlot = sim.getPlotManager().createMonitorPlot();
  energyBalancePlot.setPresentationName("Energy Balance Plot");
  energyBalancePlot.getMonitorManager().addObjects(energyBalanceReport);
}
public class CreateMassBalanceMonitor {
    Simulation sim = getActiveSimulation();
    // Obtain the region object
    Region region = sim.getRegionManager().getRegion(Region_Name);

    // Create mass flow monitors for all inlets and outlets
    MassFlowRateReport massFlowRateReportInlet = sim.getReportManager()
      .createReport(MassFlowRateReport.class);
    massFlowRateReportInlet.setPresentationName("Mass Flow Rate Inlets");

    MassFlowRateReport massFlowRateReportOutlet = sim.getReportManager()
      .createReport(MassFlowRateReport.class);
    massFlowRateReportOutlet.setPresentationName("Mass Flow Rate Outlets");

    for (Boundary boundary : region.getBoundaryManager().getBoundaries()) {
      if (boundary.getBoundaryType() instanceof InletBoundary) {
        massFlowRateReportInlet.getParts().addObjects(boundary);
      } else if (boundary.getBoundaryType() instanceof OutletBoundary) {
        massFlowRateReportOutlet.getParts().addObjects(boundary);
      }
    }
    // Calculate mass balance
    ExpressionReport massBalanceReport = sim.getReportManager()
      .createReport(ExpressionReport.class);
    massBalanceReport.setPresentationName("Mass_Balance");
    massBalanceReport.setDefinition(
      "${Mass Flow Rate Inlets.Report} - ${Mass Flow Rate Outlets.Report}"
    );
    // Optional: Adding these reports to scalar and XY plots
    MonitorPlot massFlowRatePlot = sim.getPlotManager().createMonitorPlot();
    massFlowRatePlot.setPresentationName("Mass Flow Rate Plot");
    massFlowRatePlot.getMonitorManager().addObjects(massFlowRateReportInlet, 
      massFlowRateReportOutlet);

    MonitorPlot massBalancePlot = sim.getPlotManager().createMonitorPlot();
    massBalancePlot.setPresentationName("Mass Balance Plot");
    massBalancePlot.getMonitorManager().addObjects(massBalanceReport);
  }
}
  private void defineReports() {
    ...
  }
public void addAnnotationToScene(Simulation simX, String annoText, double xLoc, double yLoc) {

  Annotation textAnnotation = new Annotation();
  textAnnotation.setText(annoText);
  textAnnotation.setPresentationName("Annotation_1");
  simX.getAnnotationManager().getAnnotations().add(textAnnotation);

  Scene scene = simX.getSceneManager().getScene("contour_v");
  scene.getAnnotations().add(textAnnotation);

  textAnnotation.setX(xLoc);
  textAnnotation.setY(yLoc;
  textAnnotation.setFontSize(12);
  textAnnotation.setColor(new Color(0, 0, 1));
}
  private void defineScenes() {
    ...
  }
  private void generateReports(Simulation simX) {
    String rept_file = "Rep_Output.txt";
    PrintWriter out_file = new PrintWriter(new FileWriter(new File(resolvePath(rept_file))));
    Collection <Report> report_list = simX.getReportManager().getObjects();
    Iterator<Integer> rep_counter = report_list.iterator();
    while (rep_counter.hasNext()) {
      String report_name  = report_list.next().getPresentationName();
      double report_value = report_list.next().getReportMonitorValue();
      String report_units = report_list.next().getUnits().GetPresentationName();
      System.out.println(report_name + " has value " + report_value + " " 
        + report_units(); 
    }
  }
  private void saveReptPlots(Simulation simX) {
    String sep = System.getProperty("file.separator");
    for (StarPlot p : simX.getPlotManager().getObjects()) {
      simX.println("Data exported for plot: " + p.getPresentationName());
      p.export(simX.getSessionDir() + sep + p.getPresentationName() + ".csv", ",");
    }
  }
From github.com/nitronayak /StarCCMAutomation /blob /main /ExportScenesAndPlots.java
import star.common.*;
import star.vis.*;
import java.io.File;
import java.util.Scanner; 

public class ExportScenesAndPlots extends StarMacro {
  public void execute() {
    Simulation sim = getActiveSimulation();
    
    //get the name of the simulation's directory
    String dir = sim.getSessionDir(); 
    //get the right separator for your operative system
    String sep = System.getProperty("file.separator");
    File resultFolder = new File(dir + "\\" + sim + "_Results");
    resultFolder.mkdir();

    File sceneFolder = new File(resultFolder + "\\Scenes");
    sceneFolder.mkdir();
    File plotFolder = new File(resultFolder + "\\Plots");
    plotFolder.mkdir();
    
    for (Scene scn: sim.getSceneManager().getScenes()) {
      sim.println("Saving Scene: " + scn.getPresentationName());
      scn.printAndWait(resolvePath(sceneFolder + sep + scn.getPresentationName() + ".jpg"), 1,800,450);	
    }
    for (StarPlot plt : sim.getPlotManager().getObjects()) {
      sim.println("Saving Plot: " + plt.getPresentationName());
      plt.encode(resolvePath(plotFolder + sep + plt.getPresentationName() + ".jpg"), "jpg", 800, 450);
    }
  }
}
Following code is generated by AI approach: creates a short summary of simulation set-up
import star.common.*;
import star.base.neo.*;

public class SimulationSummary {

  public static void main(String[] args) {
    Simulation sim = getActiveSimulation();

    // Get basic simulation details
    String simName = sim.getPresentationName();
    String physicsContinuum = sim.getPhysicsContinuumManager().getContinuumNames().toString();
    String solver = sim.getSolverManager().getSolverNames().toString();

    // Get mesh details
    MeshPipelineController meshController = sim.get(MeshPipelineController.class);
    String meshOperation = meshController.getMeshOperation().getClass().getSimpleName();

    // Get boundary conditions summary
    StringBuilder bcSummary = new StringBuilder();
    Collection<Boundary> boundaries = sim.getRegionManager().getBoundaries();
    for (Boundary boundary : boundaries) {
      bcSummary.append(boundary.getPresentationName()).append(": ");
      bcSummary.append(boundary.getBoundaryType()).append("\n");
    }
    // Create summary string
    String summary = "Simulation Name: " + simName + "\n" +
                     "Physics Continuum: " + physicsContinuum + "\n" +
                     "Solver: " + solver + "\n" +
                     "Mesh Operation: " + meshOperation + "\n" +
                     "Boundary Conditions:\n" + bcSummary.toString();
    // Print summary to the output window
    sim.println(summary);
  }
}
Print materials defined in the set-up and their thermodynamic properties
public class printMatProps extends StarMacro { 
  public void execute() {
    Simulation sim = getActiveSimulation(); 
    Collection<Material> materials = sim.get(MaterialManager.class).getObjects(); 
    for (Material mat : materials) { 
      String matName = mat.getPresentationName(); 
      System.out.println("Material: " + matName); 
      
      Collection<MaterialProperty> properties = mat.getMaterialProperties(); 
      for (MaterialProperty property : properties) { 
        String propertyName = property.getPresentationName(); 
        double propertyValue = property.getValue(); 
        System.out.println(" Property: " + propertyName + ", Value: " + propertyValue); 
      } 
    } 
  } 
}
Summarises boundary conditions:
public class PrintBoundaryCond extends StarMacro {
  public void execute() {
    Simulation sim = getActiveSimulation();
    Collection<Boundary> boundaries = sim.get(RegionManager.class).getObjectsOfType(Boundary.class);

    for (Boundary boundary : boundaries) {
      String boundaryName = boundary.getPresentationName();
      BoundaryType boundaryType = boundary.getBoundaryType();
      System.out.println("Boundary: " + boundaryName);
      System.out.println("  Type: " + boundaryType.getPresentationName());

      Collection<BoundaryCondition> conditions = boundary.getConditions();
      for (BoundaryCondition bc : conditions) {
        String conditionName = bc.getPresentationName();
        System.out.println("  Condition: " + conditionName);

        Collection<BoundaryValue> values = bc.getValues();
        for (BoundaryValue value : values) {
          String valueName = value.getPresentationName();
          double boundaryValue = value.getValue();
          System.out.println("  Value: " + valueName + ", Value: " + boundaryValue);
        }
      }
    }
  }
}
public class CreateHistograms extends StarMacro {
  public void execute() {
    createHistogramsMeshQuality("CellQuality");
    createHistogramsMeshQuality("Skewness");
  }
  private void createHistogramsMeshQuality(String quality_type) {
    Simulation sim = getActiveSimulation();
    
    RegionManager regionManager = sim.getRegionManager();
    Collection<Region> allRegions = regionManager.getRegions();
    List<Region> solidRegions = new ArrayList<>();
    List<Region> fluidRegions = new ArrayList<>();
    for (Region region : allRegions) {
      // Check if region contains solid cells
      if (region.getInterfaceBoundaryManager().getInterfaceBoundaries().size() > 0) {
        solidRegions.add(region);
      } else {
        fluidRegions.add(region);
      }
    }
    // Define the cell quality scalar field function
    PrimitiveFieldFunction cellQualityFunction = 
      (PrimitiveFieldFunction) sim.getFieldFunctionManager().getFunction(quality_type);

    // Create histograms for solid regions
    for (Region solidRegion : solidRegions) {
      createHistogram(sim, solidRegion, cellQualityFunction, 
        solidRegion.getPresentationName() + " " + quality_type + " Histogram";
    }
    // Create histograms for fluid regions
    for (Region fluidRegion : fluidRegions) {
      createHistogram(sim, fluidRegion, cellQualityFunction, 
        fluidRegion.getPresentationName() + " " + quality_type + " Histogram";
    }
  }
  private void createHistogram(Simulation sim, Region region, 
                 PrimitiveFieldFunction function, String plotName) {
    // Create histogram report
    HistogramReport histogramReport = sim.getReportManager()
      .createReport(HistogramReport.class);
    histogramReport.setFieldFunction(function);
    histogramReport.getParts().setObjects(region);
    histogramReport.setPresentationName(plotName);

    // Create and display the plot
    ReportPlot histogramPlot = sim.getPlotManager().createReportPlot(histogramReport);
    histogramPlot.open();
  }
}
STAR-CCM+ java code as functions to generate scalar scenes on planes aligned to Cartesian coordinate systems passing though specified point, align the view perpendicular to the plane and save the plot as PNG file.
  public void execute() {
    // Specify the point through which the planes pass and field function and range
    double[] point = {0.0, 0.0, 0.0}; 
    double[] v_range = {0.0, 10.0};
    double[] p_range = {1000, 1E6};
    double[] t_range = {300, 400};
    String scalarFieldFunctionName = "VelocityMagnitude"; 
    createScalarSceneOnPlane("X", point, "Pressure", p_range);
    createScalarSceneOnPlane("Y", point, "Temperature", t_range);
    createScalarSceneOnPlane("Z", point, "Velocity", v_range);
  }
  private void createScalarSceneOnPlane(String planeAxis, double[] point, 
    String scalarFF, double[] scalarRange) {
    Simulation sim = getActiveSimulation();
    
    ScalarScene scalarScene = sim.getSceneManager().createScalarScene("Scalar Scene", "Scalar Scene");
    scalarScene.initializeAndWait();
    FieldFunction scalarFieldFunction = sim.getFieldFunctionManager().getFunction(scalarFF);
    scalarScene.getDisplayerManager().getScalarDisplayers().get(0)
      .getScalarDisplayQuantity().setFieldFunction(scalarFieldFunction);

    // Set the number of color bands to 11
    scalarScene.getDisplayerManager().getScalarDisplayers().get(0)
      .getScalarDisplayQuantity().getColorMap().setNumberOfColors(11);
    scalarScene.getDisplayerManager().getScalarDisplayers().get(0)
      .getScalarDisplayQuantity().setRange(scalarRange);

    // Create and set plane section
    PlaneSection planeSection = (PlaneSection) sim.getPartManager().createImplicitPart(new 
      NeoObjectVector(new Object[] {}), new NeoObjectVector(new Object[] {}), "PlaneSection", 0, 0, 0, 0);
    planeSection.getInputParts().setObjects(sim.getRegionManager().getRegions());
    planeSection.getOriginCoordinate().setCoordinate(point[0], point[1], point[2]);

    // Set plane normal based on the specified axis
    if (planeAxis.equalsIgnoreCase("X")) {
      planeSection.getOrientationCoordinate().setCoordinate(1, 0, 0);
    } else if (planeAxis.equalsIgnoreCase("Y")) {
      planeSection.getOrientationCoordinate().setCoordinate(0, 1, 0);
    } else if (planeAxis.equalsIgnoreCase("Z")) {
      planeSection.getOrientationCoordinate().setCoordinate(0, 0, 1);
    }

    // Add plane section to scalar scene
    scalarScene.getDisplayerManager().getPartDisplayer("Scalar Scene 1")
      .getInputParts().setObjects(planeSection);

    // Align view perpendicular to the plane and zoom to fit window (reset camera)
    if (planeAxis.equalsIgnoreCase("X")) {
      scalarScene.open(true);
      scalarScene.resetCamera();
      scalarScene.getViewManager().getAxesOrientation().setCoordinateSystemView(
        scalarScene.getActiveCamera(), CoordinateSystemViewType.XY);
    } else if (planeAxis.equalsIgnoreCase("Y")) {
      scalarScene.open(true);
      scalarScene.resetCamera();
      scalarScene.getViewManager().getAxesOrientation().setCoordinateSystemView(
        scalarScene.getActiveCamera(), CoordinateSystemViewType.YZ);
    } else if (planeAxis.equalsIgnoreCase("Z")) {
      scalarScene.open(true);
      scalarScene.resetCamera();
      scalarScene.getViewManager().getAxesOrientation().setCoordinateSystemView(
        scalarScene.getActiveCamera(), CoordinateSystemViewType.ZX);
    }
    String fileName = scalarFF + "_" + planeAxis + "_"+ point[0] + "_"point[1] +
      "_" + point[2] + ".png";
    scalarScene.printAndWait(resolvePath(fileName), 1, 800, 600);
    scalarScene.close();
  }
Process all *.sim files stored in a specified folder.
public class ProcessSimFiles {

  public static void main(String[] args) {
    // Folder containing the *.sim files
    File folder = new File("E:/CFD_Projects");
    String b_inlet = "inlet;
    
    // List all .sim files in the folder
    File[] files = folder.listFiles((dir, name)->name.toLowerCase().endsWith(".sim"));
    if (files == null || files.length == 0) {
      System.out.println("No .sim files found.");
      return;
    }
    Simulation sim = StarCCM.getNewSimulation();
    for (File f : files) {
      postProcesSim(sim, f, b_inlet);
    }
  }
  private static void postProcesSim(Simulation sim, File file, String b_inlet) {
    try {
      // Clear the previous simulation data and read a new simulation
      sim.getSimulationIterator().clearSimulation();
      sim.getSimulationIterator().readSimulation(file.getAbsolutePath()); 
      
      // Create a scene (e.g. Scalar Scene)
      Scene scene = sim.getSceneManager().createScalarScene("Scalar Scene", "Outline", "Scalar");
      scene.initializeAndWait();
      
      // Generate mass flow rate at the specified boundary
      String boundaryName = b_inlet;
      Boundary boundary = sim.getRegionManager().getBoundary(boundaryName);
      MassFlowRateReport massFlowRate = sim.getReportManager().createReport(MassFlowRateReport.class);
      massFlowRate.setObjects(boundary);
      massFlowRate.printReport();
      
      // Get the maximum and minimum values of field variables
      for (FieldFunction field : sim.getFieldFunctionManager().getObjects()) {
        PrimitiveFieldFunction primitiveField = (PrimitiveFieldFunction) field;
        
        MinReport minReport = sim.getReportManager().createReport(MinReport.class);
        minReport.setFieldFunction(primitiveField);
        minReport.printReport();
        
        MaxReport maxReport = sim.getReportManager().createReport(MaxReport.class);
        maxReport.setFieldFunction(primitiveField);
        maxReport.printReport();
      }
      sim.close();
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}
Java code for STAR-CCM+ to report mesh quality summary to a text file. The text file includes tabular data of the region name, mesh quality parameter, and the worst value of that mesh quality.
import star.common.*;
import star.meshing.*;
public class MeshQualityReport {

  public static void main(String[] args) {
    // Path to the output text file
    String outputFilePath = "mesh_q_rep.txt";
    
    // Start a new session
    Simulation sim = StarCCM.getNewSimulation();
    
    try (FileWriter writer = new FileWriter(outputFilePath)) {
      // Write the header
      writer.write("Region Name\tMesh Quality Parameter\tWorst Value\n");
      
      // Iterate over all regions
      for (Region region : sim.getRegionManager().getRegions()) {
        String regionName = region.getPresentationName();
        
        // Mesh quality parameters to check
        String[] qualityParameters = {"Aspect Ratio", "Skewness", "Orthogonality"};
        
        for (String parameter : qualityParameters) {
          double worstValue = getWorstMeshQuality(region, parameter);
          writer.write(regionName + "\t" + parameter + "\t" + worstValue + "\n");
        }
      }
    } catch (IOException e) {
      e.printStackTrace();
    } finally {
      // Close the session
      sim.close();
    }
  }
  private static double getWorstMeshQuality(Region region, String parameter) {
    double worstMeshQuality = Double.NaN;
    
    // Assume we have methods to calculate mesh quality
    switch (parameter) {
      case "Aspect Ratio":
        worstMeshQuality = getWorstAspectRatio(region);
        break;
      case "Skewness":
        worstMeshQuality = getWorstSkewness(region);
        break;
      case "Orthogonality":
        worstMeshQuality = getWorstOrthogonality(region);
        break;
      default:
        break;
    }
    return worstMeshQuality;
  }
  private static double getWorstAspectRatio(Region region) {
    double highestAspectRatio = -1.0;
    // Iterate over all cells in the region
    for (Cell cell : region.getCells()) {
      double aspectRatio = cell.getAspectRatio();
      if (aspectRatio > highestAspectRatio) {
        highestAspectRatio = aspectRatio;
      }
    }
    return highestAspectRatio;
  }
  private static double getWorstSkewness(Region region) {
    double worstSkewness = -1.0;
    // Iterate over all cells in the region
    for (Cell cell : region.getCells()) {
      double cellSkew = cell.getSkewness();
      if (cellSkew > worstSkewness) {
        worstSkewness = cellSkew;
      }
    }
    return worstSkewness;
  }
  private static double getWorstOrthogonality(Region region) {
    double worstOrtho = 10.0;
    // Iterate over all cells in the region
    for (Cell cell : region.getCells()) {
      double cellOrtho = cell.getOrthogonality();
      if (cellOrtho < worstOrtho) {
        worstOrtho = cellOrtho;
      }
    }
    return worstOrtho;
  }
}
Save output from "Mesh > Diagnostics..." to a text file. A Java or Python code can be further used to summarized the information.
  public static void saveDiagnosticsToFile(Simulation simX, String file_path) {
    // Usage: saveDiagnosticsToFile(sim, "diag_summary.txt");
    DiagnosticReportManager diagReport = simX.get(DiagnosticReportManager.class);
    String diagnostics = diagReport.generateDiagnosticsReport();

    try (FileWriter writer = new FileWriter(file_path)) {
      writer.write(diagnostics);
      System.out.println("Mesh diagnostics saved to: " + file_path);
    } catch (IOException e) {
      System.err.println("Error saving mesh diagnostics: " + e.getMessage());
    }
  }
Contact us
Disclaimers and Policies

The content on CFDyna.com is being constantly refined and improvised with on-the-job experience, testing, and training. Examples might be simplified to improve insight into the physics and basic understanding. Linked pages, articles, references, and examples are constantly reviewed to reduce errors, but we cannot warrant full correctness of all content.