def recycling_calculation(alpha: float, gas_consumption: float, air_consumption: float, recycling: float) -> dict:
    recycling_percent = recycling / 100

    init_concentrations = {'CO2': 1.03, 'N2': 7.67, 'H2O': 2.17, 'O2': 9.69 * (alpha - 1)}
    # init_concentrations_N = 73.5
    init_concentrations_O2 = 23.15

    amount_flue_gases = 0
    for v in init_concentrations.values():
        amount_flue_gases = amount_flue_gases + v
    amount_flue_gases = amount_flue_gases * gas_consumption

    return_recirculation = amount_flue_gases * recycling_percent

    init_data_of_gases = dict()
    for k, v in init_concentrations.items():
        init_data_of_gases[k] = v * gas_consumption

    gas_volume = dict()
    for k, v in init_data_of_gases.items():
        gas_volume[k] = v * recycling_percent

    recycling_composition = {'CO2': gas_volume['CO2'] / air_consumption, 'H2O': gas_volume['H2O'] / air_consumption}
    recycling_composition['O2'] = ((air_consumption - return_recirculation) * init_concentrations_O2 / 100 + gas_volume[
        'O2']) / air_consumption
    amount_percent_gases = 1
    for v in recycling_composition.values():
        amount_percent_gases = amount_percent_gases - v
    recycling_composition['N2'] = amount_percent_gases

    return recycling_composition


def load_calculation(steam_consumption: float, diameters: dict, alpha=None) -> dict:
    # перевод из миллиметров в метры
    for key, value in diameters.items():
        diameters[key] = value / 1000

    gas_density = 0.670723907
    if alpha is None:
        alpha = (-0.0000000496 * steam_consumption ** 3 + 0.0000597347 * steam_consumption ** 2 - 0.0237830036 *
                 steam_consumption + 4.1600366991)
    total_gas_consumption = (-0.0004574291 * steam_consumption ** 3 + 0.4767036785 * steam_consumption ** 2 -
                             77.847437247 * steam_consumption + 15542.3008630679)
    gas_consumption = total_gas_consumption / 8
    air_consumption = 9.69 * alpha * gas_consumption

    hydraulic_diameter_pa = diameters['d3'] - diameters['d4']
    hydraulic_diameter_sa = diameters['d1'] - diameters['d2']
    # hydraulic_diameter_g = diametrs['d5'] - diametrs['d6']

    air_inlet_ratio_pa = hydraulic_diameter_pa / (hydraulic_diameter_pa + hydraulic_diameter_sa)
    air_inlet_ratio_sa = 1 - air_inlet_ratio_pa
    # print(air_inlet_ratio_pa, air_inlet_ratio_sa)
    primary_air_consumption = 4 * (air_consumption / 3600 * air_inlet_ratio_sa) / (
            3.14 * (diameters['d1'] / 2) ** 2 - 3.14 * (diameters['d2'] / 2) ** 2)
    secondary_air_consumption = 4 * (air_consumption / 3600 * air_inlet_ratio_pa) / (
            3.14 * (diameters['d3'] / 2) ** 2 - 3.14 * (diameters['d4'] / 2) ** 2)
    gas_inlet_rate = gas_consumption / 3600 / (3.14 * (diameters['d5'] / 2) ** 2 - 3.14 * (diameters['d6'] / 2) ** 2)
    gas_inlet_consumption = gas_consumption * gas_density / 3600
    # print(alpha, total_gas_consumption, gas_consumption, air_consumption, primary_air_consumption, secondary_air_consumption, gas_inlet_rate, gas_inlet_consumption)
    outlet_data = {'alpha': alpha, 'gas_consumption': gas_consumption, 'air_consumption': air_consumption,
                   'primary_air_consumption': primary_air_consumption,
                   'secondary_air_consumption': secondary_air_consumption, 'gas_inlet_rate': gas_inlet_rate,
                   'gas_inlet_consumption': gas_inlet_consumption}

    return outlet_data


def preprocessor_settings(path, model_parameters, model_path):
    macros_file = open(path, 'w')
    macros_file.write("""
import java.util.*;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;

import star.combustion.*;
import star.combustion.fgm.*;
import star.combustion.tablegenerators.*;
import star.common.*;
import star.mapping.*;
import star.base.neo.*;
import star.cadmodeler.*;
import star.dualmesher.VolumeControlDualMesherSizeOption;
import star.emissions.NoxModel;
import star.emissions.NoxSolver;
import star.emissions.NoxThreeEquationZeldovichModel;
import star.energy.StaticTemperatureProfile;
import star.flow.MassFlowRateProfile;
import star.flow.VelocityMagnitudeProfile;
import star.keturb.KEpsilonTurbulence;
import star.keturb.KeTwoLayerAllYplusWallTreatment;
import star.keturb.RkeTwoLayerTurbModel;
import star.material.MaterialDataBaseManager;
import star.material.MultiComponentGasModel;
import star.meshing.*;
import star.reactions.ReactingModel;
import star.resurfacer.VolumeControlResurfacerSizeOption;
import star.segregatedenergy.SegregatedFluidEnthalpyModel;
import star.segregatedflow.SegregatedFlowModel;
import star.turbulence.RansTurbulenceModel;
import star.turbulence.TurbulentModel;
import star.vis.*;

public class preprocess_macro extends StarMacro {

    String geometry_path = resolvePath("%s");
    String chemkin_path = resolvePath("%s");
    String grimech30_path = chemkin_path + "/grimech30.dat";
    String thermo30_path = chemkin_path + "/thermo30.dat";
    String transport_path = chemkin_path + "/transport.dat";
    String init_model_folder = resolvePath("%s");

    public void execute() {

        /*Simulation sim =
                getActiveSimulation();*/

        long startTime = System.currentTimeMillis();

        importGeometry();
        createCylinderParts();
        createVolumeMeshControl();
        createBoundaries();
        generateVolumeMesh();
        settingPhysicsContinuum();
        createFgmTable();
        setInitialConditions();
        createLineSection();
        createPlaneSection();
        createScene();
        createPlot();
        createXYZTable();
        //initializeSolution();
        saveState();

        long endTime = System.currentTimeMillis();

        long durationInMilliseconds = endTime - startTime;
        double durationInSeconds = durationInMilliseconds / 1000.0;

        String filename = init_model_folder + "/exec_time.txt";

        try (BufferedWriter writer = new BufferedWriter(new FileWriter(filename))) {
            writer.write("Время создания модели: " + durationInSeconds + "\\n");
        } catch (IOException e) {
            //sim.println("Ошибка при записи в файл: " + e.getMessage());
        }

    }

    private void importGeometry() {

        Simulation simulation =
                getActiveSimulation();

        CadModel cadModel =
                simulation.get(SolidModelManager.class).createSolidModel();

        cadModel.resetSystemOptions();

        ImportCadFileFeature importCadFileFeature =
                cadModel.importCadFile(resolvePath(geometry_path), true, false, false, false, false, false, false, true, false, true, NeoProperty.fromString("{\'NX\': 1, \'STEP\': 1, \'SE\': 1, \'CGR\': 1, \'SW\': 1, \'IFC\': 1, \'ACIS\': 1, \'JT\': 1, \'IGES\': 1, \'CATIAV5\': 1, \'CATIAV4\': 1, \'3DXML\': 1, \'CREO\': 1, \'INV\': 1}"), false, true);

        star.cadmodeler.Body cadmodelerBody =
                ((star.cadmodeler.Body) importCadFileFeature.getBodyByIndex(1));

        Face face_0 =
                ((Face) importCadFileFeature.getFaceByLocation(cadmodelerBody,new DoubleVector(new double[] {0.01, 0.72, 0})));

        cadModel.setFaceNameAttributes(new NeoObjectVector(new Object[] {face_0}), "Air inlet", false);

        ArrayList<double[]> coordinates = calculateCoordinatesClockwise(0.314, (int) %s);

    	ArrayList<Face> faces  = new ArrayList<>();

    	for (double[] coordinate : coordinates) {
        	faces.add((Face) importCadFileFeature.getFaceByLocation(cadmodelerBody,new DoubleVector(coordinate)));
    	}

        cadModel.setFaceNameAttributes(faces, "Air blades", false);

        Face face_2 =
                ((Face) importCadFileFeature.getFaceByLocation(cadmodelerBody,new DoubleVector(new double[] {0.01, 0.153, 0})));

        cadModel.setFaceNameAttributes(new NeoObjectVector(new Object[] {face_2}), "CH4", false);

        Face face_3 =
                ((Face) importCadFileFeature.getFaceByLocation(cadmodelerBody,new DoubleVector(new double[] {0.01, 0.114, 0})));

        cadModel.setFaceNameAttributes(new NeoObjectVector(new Object[] {face_3}), "No Gas 1", false);

        Face face_4 =
                ((Face) importCadFileFeature.getFaceByLocation(cadmodelerBody,new DoubleVector(new double[] {0.01, 0.07, 0})));

        cadModel.setFaceNameAttributes(new NeoObjectVector(new Object[] {face_4}), "No Gas 2", false);

        Face face_5 =
                ((Face) importCadFileFeature.getFaceByLocation(cadmodelerBody,new DoubleVector(new double[] {-10.667, 0.6180132, -0.6180132})));

        cadModel.setFaceNameAttributes(new NeoObjectVector(new Object[] {face_5}), "Outlet", false);

        cadModel.update();

        simulation.get(SolidModelManager.class).endEditCadModel(cadModel);

        cadModel.createParts(new NeoObjectVector(new Object[] {cadmodelerBody}), new NeoObjectVector(new Object[] {}), true, false, 1, false, false, 3, "SharpEdges", 30.0, 2, true, 1.0E-5, false);

    }

    private void createCylinderParts() {

        Simulation simulation =
                getActiveSimulation();

        Units units_0 =
                simulation.getUnitsManager().getPreferredUnits(Dimensions.Builder().length(1).build());

        MeshPartFactory meshPartFactory =
                simulation.get(MeshPartFactory.class);

        SimpleCylinderPart simpleCylinderPart_0 =
                meshPartFactory.createNewCylinderPart(simulation.get(SimulationPartManager.class));

        simpleCylinderPart_0.setDoNotRetessellate(true);

        LabCoordinateSystem labCoordinateSystem_0 =
                simulation.getCoordinateSystemManager().getLabCoordinateSystem();

        simpleCylinderPart_0.setCoordinateSystem(labCoordinateSystem_0);

        simpleCylinderPart_0.getStartCoordinate().setCoordinateSystem(labCoordinateSystem_0);

        simpleCylinderPart_0.getStartCoordinate().setCoordinate(units_0, units_0, units_0, new DoubleVector(new double[] {0.01, 0.0, 0.0}));

        simpleCylinderPart_0.getEndCoordinate().setCoordinateSystem(labCoordinateSystem_0);

        simpleCylinderPart_0.getEndCoordinate().setCoordinate(units_0, units_0, units_0, new DoubleVector(new double[] {-0.667, 0.0, 0.0}));

        simpleCylinderPart_0.getRadius().setUnits(units_0);

        simpleCylinderPart_0.getRadius().setValue(0.721);

        simpleCylinderPart_0.getTessellationDensityOption().setSelected(TessellationDensityOption.Type.MEDIUM);

        simpleCylinderPart_0.rebuildSimpleShapePart();

        simpleCylinderPart_0.setDoNotRetessellate(false);

        SimpleCylinderPart simpleCylinderPart_1 =
                meshPartFactory.createNewCylinderPart(simulation.get(SimulationPartManager.class));

        simpleCylinderPart_1.setDoNotRetessellate(true);

        simpleCylinderPart_1.setCoordinateSystem(labCoordinateSystem_0);

        simpleCylinderPart_1.getStartCoordinate().setCoordinateSystem(labCoordinateSystem_0);

        simpleCylinderPart_1.getStartCoordinate().setCoordinate(units_0, units_0, units_0, new DoubleVector(new double[] {-0.667, 0.0, 0.0}));

        simpleCylinderPart_1.getEndCoordinate().setCoordinateSystem(labCoordinateSystem_0);

        simpleCylinderPart_1.getEndCoordinate().setCoordinate(units_0, units_0, units_0, new DoubleVector(new double[] {-1.111, 0.0, 0.0}));

        simpleCylinderPart_1.getRadius().setUnits(units_0);

        simpleCylinderPart_1.getRadius().setValue(0.535);

        simpleCylinderPart_1.getTessellationDensityOption().setSelected(TessellationDensityOption.Type.MEDIUM);

        simpleCylinderPart_1.rebuildSimpleShapePart();

        simpleCylinderPart_1.setDoNotRetessellate(false);

        SimpleCylinderPart simpleCylinderPart_2 =
                meshPartFactory.createNewCylinderPart(simulation.get(SimulationPartManager.class));

        simpleCylinderPart_2.setDoNotRetessellate(true);

        simpleCylinderPart_2.setCoordinateSystem(labCoordinateSystem_0);

        simpleCylinderPart_2.getStartCoordinate().setCoordinateSystem(labCoordinateSystem_0);

        simpleCylinderPart_2.getStartCoordinate().setCoordinate(units_0, units_0, units_0, new DoubleVector(new double[] {-1.111, 0.0, 0.0}));

        simpleCylinderPart_2.getEndCoordinate().setCoordinateSystem(labCoordinateSystem_0);

        simpleCylinderPart_2.getEndCoordinate().setCoordinate(units_0, units_0, units_0, new DoubleVector(new double[] {-10.667, 0.0, 0.0}));

        simpleCylinderPart_2.getRadius().setUnits(units_0);

        simpleCylinderPart_2.getRadius().setValue(1.5);

        simpleCylinderPart_2.getTessellationDensityOption().setSelected(TessellationDensityOption.Type.MEDIUM);

        simpleCylinderPart_2.rebuildSimpleShapePart();

        simpleCylinderPart_2.setDoNotRetessellate(false);

    }

    private void createVolumeMeshControl(){

        Simulation simulation =
                getActiveSimulation();

        Units units_0 =
                ((Units) simulation.getUnitsManager().getObject("m"));

        SimpleCylinderPart simpleCylinderPart_0 =
                ((SimpleCylinderPart) simulation.get(SimulationPartManager.class).getPart("Cylinder"));

        SimpleCylinderPart simpleCylinderPart_1 =
                ((SimpleCylinderPart) simulation.get(SimulationPartManager.class).getPart("Cylinder 2"));

        SimpleCylinderPart simpleCylinderPart_2 =
                ((SimpleCylinderPart) simulation.get(SimulationPartManager.class).getPart("Cylinder 3"));

        SolidModelPart solidModelPart_0 =
                ((SolidModelPart) simulation.get(SimulationPartManager.class).getPart("Body 1"));

        AutoMeshOperation autoMeshOperation =
                simulation.get(MeshOperationManager.class).createAutoMeshOperation(new StringVector(new String[] {}), new NeoObjectVector(new Object[] {solidModelPart_0}));

        autoMeshOperation.getMeshers().setMeshersByNames(new StringVector(new String[] {"star.resurfacer.ResurfacerAutoMesher", "star.dualmesher.DualAutoMesher"}));

        VolumeCustomMeshControl volumeCustomMeshControl_0 =
                autoMeshOperation.getCustomMeshControls().createVolumeControl();

        VolumeCustomMeshControl volumeCustomMeshControl_1 =
                autoMeshOperation.getCustomMeshControls().createVolumeControl();

        VolumeCustomMeshControl volumeCustomMeshControl_2 =
                autoMeshOperation.getCustomMeshControls().createVolumeControl();

        SurfaceCustomMeshControl surfaceCustomMeshControl_0 =
                autoMeshOperation.getCustomMeshControls().createSurfaceControl();

        volumeCustomMeshControl_0.getGeometryObjects().setQuery(null);

        volumeCustomMeshControl_0.getGeometryObjects().setObjects(simpleCylinderPart_0);

        volumeCustomMeshControl_1.getGeometryObjects().setQuery(null);

        volumeCustomMeshControl_1.getGeometryObjects().setObjects(simpleCylinderPart_1);

        volumeCustomMeshControl_2.getGeometryObjects().setQuery(null);

        volumeCustomMeshControl_2.getGeometryObjects().setObjects(simpleCylinderPart_2);

        surfaceCustomMeshControl_0.getGeometryObjects().setQuery(null);

        PartSurface partSurface_0 =
                ((PartSurface) solidModelPart_0.getPartSurfaceManager().getPartSurface("Default"));

        PartSurface partSurface_1 =
                ((PartSurface) solidModelPart_0.getPartSurfaceManager().getPartSurface("Outlet"));

        surfaceCustomMeshControl_0.getGeometryObjects().setObjects(partSurface_0, partSurface_1);

        surfaceCustomMeshControl_0.getCustomConditions().get(PartsTargetSurfaceSizeOption.class).setSelected(PartsTargetSurfaceSizeOption.Type.CUSTOM);

        PartsTargetSurfaceSize partsTargetSurfaceSize_0 =
                surfaceCustomMeshControl_0.getCustomValues().get(PartsTargetSurfaceSize.class);

        Units units_1 =
                ((Units) simulation.getUnitsManager().getObject(""));

        partsTargetSurfaceSize_0.getRelativeSizeScalar().setValueAndUnits(20.0, units_1);

        VolumeControlResurfacerSizeOption volumeControlResurfacerSizeOption_0 =
                volumeCustomMeshControl_0.getCustomConditions().get(VolumeControlResurfacerSizeOption.class);

        volumeControlResurfacerSizeOption_0.setVolumeControlBaseSizeOption(true);

        VolumeControlDualMesherSizeOption volumeControlDualMesherSizeOption_0 =
                volumeCustomMeshControl_0.getCustomConditions().get(VolumeControlDualMesherSizeOption.class);

        volumeControlDualMesherSizeOption_0.setVolumeControlBaseSizeOption(true);

        VolumeControlSize volumeControlSize_0 =
                volumeCustomMeshControl_0.getCustomValues().get(VolumeControlSize.class);

        volumeControlSize_0.getRelativeSizeScalar().setValueAndUnits(2.0, units_1);

        VolumeControlResurfacerSizeOption volumeControlResurfacerSizeOption_1 =
                volumeCustomMeshControl_1.getCustomConditions().get(VolumeControlResurfacerSizeOption.class);

        volumeControlResurfacerSizeOption_1.setVolumeControlBaseSizeOption(true);

        VolumeControlDualMesherSizeOption volumeControlDualMesherSizeOption_1 =
                volumeCustomMeshControl_1.getCustomConditions().get(VolumeControlDualMesherSizeOption.class);

        volumeControlDualMesherSizeOption_1.setVolumeControlBaseSizeOption(true);

        VolumeControlSize volumeControlSize_1 =
                volumeCustomMeshControl_1.getCustomValues().get(VolumeControlSize.class);

        volumeControlSize_1.getRelativeSizeScalar().setValueAndUnits(2.0, units_1);

        VolumeControlResurfacerSizeOption volumeControlResurfacerSizeOption_2 =
                volumeCustomMeshControl_2.getCustomConditions().get(VolumeControlResurfacerSizeOption.class);

        volumeControlResurfacerSizeOption_2.setVolumeControlBaseSizeOption(true);

        VolumeControlDualMesherSizeOption volumeControlDualMesherSizeOption_2 =
                volumeCustomMeshControl_2.getCustomConditions().get(VolumeControlDualMesherSizeOption.class);

        volumeControlDualMesherSizeOption_2.setVolumeControlBaseSizeOption(true);

        VolumeControlSize volumeControlSize_2 =
                volumeCustomMeshControl_2.getCustomValues().get(VolumeControlSize.class);

        volumeControlSize_2.getRelativeSizeScalar().setValueAndUnits(5.0, units_1);

        autoMeshOperation.getDefaultValues().get(BaseSize.class).setValueAndUnits(%s, units_0);

        autoMeshOperation.getMesherParallelModeOption().setSelected(MesherParallelModeOption.Type.PARALLEL);

    }

    private void createBoundaries() {

        Simulation simulation =
                getActiveSimulation();

        Region region =
                simulation.getRegionManager().createEmptyRegion(null);

        region.setPresentationName("Body 1");

        SolidModelPart solidModelPart_0 =
                ((SolidModelPart) simulation.get(SimulationPartManager.class).getPart("Body 1"));

        region.getPartGroup().addObjects(solidModelPart_0);

        Boundary boundary_0 =
                region.getBoundaryManager().createEmptyBoundary("", null);

        boundary_0.setPresentationName("Air blades");

        InletBoundary inletBoundary =
                ((InletBoundary) simulation.get(ConditionTypeManager.class).get(InletBoundary.class));

        boundary_0.setBoundaryType(inletBoundary);

        boundary_0.getGeometryPartEntityGroup().setQuery(null);

        PartSurface partSurface_2 =
                ((PartSurface) solidModelPart_0.getPartSurfaceManager().getPartSurface("Air blades"));

        boundary_0.getGeometryPartEntityGroup().setObjects(partSurface_2);

        Boundary boundary_1 =
                region.getBoundaryManager().createEmptyBoundary("", null);

        boundary_1.setPresentationName("Air inlet");

        boundary_1.getGeometryPartEntityGroup().setQuery(null);

        PartSurface partSurface_3 =
                ((PartSurface) solidModelPart_0.getPartSurfaceManager().getPartSurface("Air inlet"));

        boundary_1.getGeometryPartEntityGroup().setObjects(partSurface_3);

        boundary_1.setBoundaryType(inletBoundary);

        Boundary boundary_2 =
                region.getBoundaryManager().createEmptyBoundary("", null);

        boundary_2.setPresentationName("CH4");

        boundary_2.getGeometryPartEntityGroup().setQuery(null);

        PartSurface partSurface_4 =
                ((PartSurface) solidModelPart_0.getPartSurfaceManager().getPartSurface("CH4"));

        boundary_2.getGeometryPartEntityGroup().setObjects(partSurface_4);

        MassFlowBoundary massFlowBoundary =
                ((MassFlowBoundary) simulation.get(ConditionTypeManager.class).get(MassFlowBoundary.class));

        boundary_2.setBoundaryType(massFlowBoundary);

        Boundary boundary_3 =
                region.getBoundaryManager().createEmptyBoundary("", null);

        boundary_3.setPresentationName("No Gas 1");

        boundary_3.getGeometryPartEntityGroup().setQuery(null);

        PartSurface partSurface_5 =
                ((PartSurface) solidModelPart_0.getPartSurfaceManager().getPartSurface("No Gas 1"));

        boundary_3.getGeometryPartEntityGroup().setObjects(partSurface_5);

        Boundary boundary_4 =
                region.getBoundaryManager().createEmptyBoundary("", null);

        boundary_4.setPresentationName("No Gas 2");

        boundary_4.getGeometryPartEntityGroup().setQuery(null);

        PartSurface partSurface_6 =
                ((PartSurface) solidModelPart_0.getPartSurfaceManager().getPartSurface("No Gas 2"));

        boundary_4.getGeometryPartEntityGroup().setObjects(partSurface_6);

        Boundary boundary_5 =
                region.getBoundaryManager().createEmptyBoundary("", null);

        boundary_5.setPresentationName("Outlet");

        boundary_5.getGeometryPartEntityGroup().setQuery(null);

        PartSurface partSurface_1 =
                ((PartSurface) solidModelPart_0.getPartSurfaceManager().getPartSurface("Outlet"));

        boundary_5.getGeometryPartEntityGroup().setObjects(partSurface_1);

        PressureBoundary pressureBoundary =
                ((PressureBoundary) simulation.get(ConditionTypeManager.class).get(PressureBoundary.class));

        boundary_5.setBoundaryType(pressureBoundary);

    }

    private void generateVolumeMesh() {

        Simulation simulation =
                getActiveSimulation();

        MeshPipelineController meshPipelineController =
                simulation.get(MeshPipelineController.class);

        meshPipelineController.generateVolumeMesh();

    }

    private void settingPhysicsContinuum() {

        Simulation simulation =
                getActiveSimulation();

        PhysicsContinuum physicsContinuum =
                ((PhysicsContinuum) simulation.getContinuumManager().getContinuum("Physics 1"));

        physicsContinuum.enable(SteadyModel.class);

        physicsContinuum.enable(MultiComponentGasModel.class);

        physicsContinuum.enable(ReactingModel.class);

        physicsContinuum.enable(FlameletBasedModel.class);

        physicsContinuum.enable(FgmCombustionModel.class);

        physicsContinuum.enable(FgmReactionModel.class);

        physicsContinuum.enable(SegregatedFluidEnthalpyModel.class);

        physicsContinuum.enable(FgmIdealGasModel.class);

        physicsContinuum.enable(TurbulentModel.class);

        physicsContinuum.enable(RansTurbulenceModel.class);

        physicsContinuum.enable(SegregatedFlowModel.class);

        physicsContinuum.enable(KEpsilonTurbulence.class);

        physicsContinuum.enable(RkeTwoLayerTurbModel.class);

        physicsContinuum.enable(KeTwoLayerAllYplusWallTreatment.class);

        physicsContinuum.enable(TfcCombustionPartiallyPremixedModel.class);

        physicsContinuum.enable(SolutionInterpolationModel.class);

        physicsContinuum.enable(NoxModel.class);

        physicsContinuum.enable(NoxThreeEquationZeldovichModel.class);

        ProgressVariableIgnitor progressVariableIgnitor =
                physicsContinuum.get(IgnitorManager.class).createIgnitor(ProgressVariableIgnitor.class);

        progressVariableIgnitor.getGeometryPartGroup().setQuery(null);

        SimpleCylinderPart simpleCylinderPart_0 =
                ((SimpleCylinderPart) simulation.get(SimulationPartManager.class).getPart("Cylinder 3"));

        progressVariableIgnitor.getGeometryPartGroup().setObjects(simpleCylinderPart_0);

        PulseActivator pulseActivator =
                ((PulseActivator) progressVariableIgnitor.getActivator());

        Units units_0 =
                ((Units) simulation.getUnitsManager().getObject(""));

        pulseActivator.getBegin().setValueAndUnits(200.0, units_0);

        pulseActivator.getEnd().setValueAndUnits(250.0, units_0);

        TfcCombustionPartiallyPremixedModel tfcCombustionPartiallyPremixedModel_0 =
                physicsContinuum.getModelManager().getModel(TfcCombustionPartiallyPremixedModel.class);

        tfcCombustionPartiallyPremixedModel_0.getLaminarFlameSpeedOptions().setMethod(LaminarFlameSpeedGulderOption.class);

    }

    private void createFgmTable() {

        Simulation simulation =
                getActiveSimulation();

        PhysicsContinuum physicsContinuum =
                ((PhysicsContinuum) simulation.getContinuumManager().getContinuum("Physics 1"));

        FgmTableGenerator fgmTableGenerator =
                physicsContinuum.get(FgmTableGenerator.class);

        FgmTableParameters fgmTableParameters =
                ((FgmTableParameters) fgmTableGenerator.getTableParameters());

        fgmTableParameters.getTableProgressVariableDefinition().setSelected(TableProgressVariableDefinitionOption.Type.CHEMENTHALPY);

        Fgm0dIgnitionNumericalSettings fgm0dIgnitionNumericalSettings =
                ((Fgm0dIgnitionNumericalSettings) fgmTableParameters.getFgm0dIgnitionNumericalSettings());

        TableAxisParameters tableAxisParameters =
                ((TableAxisParameters) fgm0dIgnitionNumericalSettings.getTableAxisParametersManager().getComponent("Heat Loss Ratio"));

        tableAxisParameters.setAdapt(true);

        FixedGridParameters fixedGridParameters =
                tableAxisParameters.getFixedGridParameters();

        IntegerValue integerValue_0 =
                fixedGridParameters.getDimensionSizeValue();

        integerValue_0.getQuantity().setValue(1.0);

        TableChemistryDefinition tableChemistryDefinition =
                ((TableChemistryDefinition) fgmTableGenerator.getTableChemistryDefinition());

        tableChemistryDefinition.importCaseFromChemkin(resolvePath(grimech30_path), resolvePath(thermo30_path), resolvePath(transport_path), "", "");

        TableFluidStreamCollection tableFluidStreamCollection =
                ((TableFluidStreamCollection) fgmTableGenerator.getTableFluidStreamCollection());

        TableFluidStream tableFluidStream_0 =
                ((TableFluidStream) tableFluidStreamCollection.getOxidizerStream());

        Units units_1 =
                ((Units) simulation.getUnitsManager().getObject("K"));

        tableFluidStream_0.getTemperature().setValueAndUnits(483.0, units_1);

        tableFluidStream_0.getFluidStreamComposition().setArray(new DoubleVector(new double[] {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.767, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.233, 0.0}));

        TableFluidStream tableFluidStream_1 =
                ((TableFluidStream) tableFluidStreamCollection.getFuelStream());

        tableFluidStream_1.getFluidStreamComposition().setArray(new DoubleVector(new double[] {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}));

        TableSpeciesForPostProcessing tableSpeciesForPostProcessing_0 =
                ((TableSpeciesForPostProcessing) fgmTableParameters.getTableSpeciesForPostProcessing());

        ((TableSpeciesGroup) tableSpeciesForPostProcessing_0.getTableSpeciesGroup()).setQuery(null);

        star.material.MaterialDataBase materialMaterialDataBase =
                simulation.get(MaterialDataBaseManager.class).getMatlDataBase("Table Generator");

        star.material.DataBaseMaterialManager materialDataBaseMaterialManager =
                materialMaterialDataBase.getFolder("Physics 1-Fgm");

        star.material.DataBaseGas materialDataBaseGas_0 =
                ((star.material.DataBaseGas) materialDataBaseMaterialManager.getMaterial("CH4_Gas"));

        star.material.DataBaseGas materialDataBaseGas_1 =
                ((star.material.DataBaseGas) materialDataBaseMaterialManager.getMaterial("CO_Gas"));

        star.material.DataBaseGas materialDataBaseGas_2 =
                ((star.material.DataBaseGas) materialDataBaseMaterialManager.getMaterial("CO2_Gas"));

        star.material.DataBaseGas materialDataBaseGas_3 =
                ((star.material.DataBaseGas) materialDataBaseMaterialManager.getMaterial("H2O_Gas"));

        star.material.DataBaseGas materialDataBaseGas_4 =
                ((star.material.DataBaseGas) materialDataBaseMaterialManager.getMaterial("N2_Gas"));

        star.material.DataBaseGas materialDataBaseGas_5 =
                ((star.material.DataBaseGas) materialDataBaseMaterialManager.getMaterial("NO_Gas"));

        star.material.DataBaseGas materialDataBaseGas_6 =
                ((star.material.DataBaseGas) materialDataBaseMaterialManager.getMaterial("NO2_Gas"));

        star.material.DataBaseGas materialDataBaseGas_7 =
                ((star.material.DataBaseGas) materialDataBaseMaterialManager.getMaterial("O2_Gas"));

        star.material.DataBaseGas materialDataBaseGas_8 =
                ((star.material.DataBaseGas) materialDataBaseMaterialManager.getMaterial("OH_Gas"));

        ((TableSpeciesGroup) tableSpeciesForPostProcessing_0.getTableSpeciesGroup()).setObjects(materialDataBaseGas_0, materialDataBaseGas_1, materialDataBaseGas_2, materialDataBaseGas_3, materialDataBaseGas_4, materialDataBaseGas_5, materialDataBaseGas_6, materialDataBaseGas_7, materialDataBaseGas_8);

        FgmCombustionSolver fgmCombustionSolver =
                ((FgmCombustionSolver) simulation.getSolverManager().getSolver(FgmCombustionSolver.class));

        fgmCombustionSolver.setDifferentURFNumber(true);

        Units units_2 =
                ((Units) simulation.getUnitsManager().getObject(""));

        fgmCombustionSolver.getUrfProgressVariableQuantity().setValueAndUnits(0.8, units_2);

        NoxSolver noxSolver =
                ((NoxSolver) simulation.getSolverManager().getSolver(NoxSolver.class));

        noxSolver.getUrfQuantity().setValueAndUnits(0.8, units_2);

        FgmTable fgmTable =
                ((FgmTable) fgmTableGenerator.getFgmTable());

        fgmTable.constructTable();

    }

    private void setInitialConditions() {

        Simulation simulation =
                getActiveSimulation();

        Region region =
                simulation.getRegionManager().getRegion("Body 1");

        Boundary boundary =
                region.getBoundaryManager().getBoundary("CH4");

        MixtureFractionArrayProfile mixtureFractionArrayProfile =
                boundary.getValues().get(MixtureFractionArrayProfile.class);

        mixtureFractionArrayProfile.getMethod(ConstantArrayProfileMethod.class).getQuantity().setArray(new DoubleVector(new double[] {1.0}));

    }

    private void createPlaneSection() {

        Simulation simulation =
                getActiveSimulation();

        PlaneSection planeSection =
                (PlaneSection) simulation.getPartManager().createImplicitPart(new NeoObjectVector(new Object[] {}), new DoubleVector(new double[] {0.0, 0.0, 1.0}), new DoubleVector(new double[] {0.0, 0.0, 0.0}), 0, 1, new DoubleVector(new double[] {0.0}), null);

        planeSection.getInputParts().setQuery(null);

        Region region =
                simulation.getRegionManager().getRegion("Body 1");

        planeSection.getInputParts().setObjects(region);

    }

    private void createScene() {

        Simulation simulation =
                getActiveSimulation();

        simulation.getSceneManager().createScalarScene("Scalar Scene", "Outline", "Scalar", null);

        Scene scene =
                simulation.getSceneManager().getScene("Scalar Scene 1");

        scene.initializeAndWait();

        ScalarDisplayer scalarDisplayer =
                ((ScalarDisplayer) scene.getDisplayerManager().getObject("Scalar 1"));

        Legend legend =
                scalarDisplayer.getLegend();

        PredefinedLookupTable predefinedLookupTable =
                ((PredefinedLookupTable) simulation.get(LookupTableManager.class).getObject("blue-yellow-red"));

        legend.setLookupTable(predefinedLookupTable);

        SceneUpdate sceneUpdate =
                scene.getSceneUpdate();

        HardcopyProperties hardcopyProperties =
                sceneUpdate.getHardcopyProperties();

        hardcopyProperties.setCurrentResolutionWidth(1440);

        hardcopyProperties.setCurrentResolutionHeight(720);

        scene.resetCamera();

        scene.closeInteractive();

        PartDisplayer partDisplayer =
                ((PartDisplayer) scene.getDisplayerManager().getObject("Outline 1"));

        partDisplayer.setOutline(false);

        scalarDisplayer.getInputParts().setQuery(null);

        PlaneSection planeSection =
                ((PlaneSection) simulation.getPartManager().getObject("Plane Section"));

        scalarDisplayer.getInputParts().setObjects(planeSection);

        scalarDisplayer.setFillMode(ScalarFillMode.NODE_SMOOTH);

    }

    private void createLineSection() {

        Simulation simulation =
                getActiveSimulation();

        LineSection lineSection =
                simulation.getPartManager().createLineSection(new NeoObjectVector(new Object[] {}), new DoubleVector(new double[] {0.0, 0.0, 0.0}), new DoubleVector(new double[] {0.0, 0.0, 1.0}), 0, true, null);

        lineSection.getInputParts().setQuery(null);

        Region region =
                simulation.getRegionManager().getRegion("Body 1");

        lineSection.getInputParts().setObjects(region);

        LineSectionPointPoint lineSectionPointPoint =
                lineSection.getPointPoint();

        Units units_1 =
                ((Units) simulation.getUnitsManager().getObject("m"));

        lineSectionPointPoint.getStartPointCoordinate().setCoordinate(units_1, units_1, units_1, new DoubleVector(new double[] {-10.666999816894531, 0.0, 0.0}));

        lineSectionPointPoint.getEndPointCoordinate().setCoordinate(units_1, units_1, units_1, new DoubleVector(new double[] {0.009999999776482582, 0.0, 0.0}));

    }

    private void createPlot() {

        Simulation simulation =
                getActiveSimulation();

        XYPlot xYPlot =
                simulation.getPlotManager().create("star.common.XYPlot");

        PlotUpdate plotUpdate =
                xYPlot.getPlotUpdate();

        HardcopyProperties hardcopyProperties =
                plotUpdate.getHardcopyProperties();

        hardcopyProperties.setCurrentResolutionWidth(1440);

        hardcopyProperties.setCurrentResolutionHeight(720);

        xYPlot.getParts().setQuery(null);

        LineSection lineSection_1 =
                ((LineSection) simulation.getPartManager().getObject("Line Section"));

        xYPlot.getParts().setObjects(lineSection_1);

        YAxisType yAxisType_0 =
                ((YAxisType) xYPlot.getYAxes().getAxisType("Y Type 1"));

        FieldFunctionUnits fieldFunctionUnits_0 =
                yAxisType_0.getScalarFunction();

        PrimitiveFieldFunction primitiveFieldFunction_0 =
                ((PrimitiveFieldFunction) simulation.getFieldFunctionManager().getFunction("Temperature"));

        fieldFunctionUnits_0.setFieldFunction(primitiveFieldFunction_0);

        YAxisType yAxisType_1 =
                xYPlot.getYAxes().createAxisType();

        FieldFunctionUnits fieldFunctionUnits_1 =
                yAxisType_1.getScalarFunction();

        PrimitiveFieldFunction primitiveFieldFunction_1 =
                ((PrimitiveFieldFunction) simulation.getFieldFunctionManager().getFunction("NitrogenOxide"));

        fieldFunctionUnits_1.setFieldFunction(primitiveFieldFunction_1);

        YAxisType yAxisType_2 =
                xYPlot.getYAxes().createAxisType();

        FieldFunctionUnits fieldFunctionUnits_2 =
                yAxisType_2.getScalarFunction();

        PrimitiveFieldFunction primitiveFieldFunction_2 =
                ((PrimitiveFieldFunction) simulation.getFieldFunctionManager().getFunction("MassFractionCO2"));

        fieldFunctionUnits_2.setFieldFunction(primitiveFieldFunction_2);

        YAxisType yAxisType_3 =
                xYPlot.getYAxes().createAxisType();

        FieldFunctionUnits fieldFunctionUnits_3 =
                yAxisType_3.getScalarFunction();

        PrimitiveFieldFunction primitiveFieldFunction_3 =
                ((PrimitiveFieldFunction) simulation.getFieldFunctionManager().getFunction("MassFractionCO"));

        fieldFunctionUnits_3.setFieldFunction(primitiveFieldFunction_3);

        AxisType axisType_0 =
                xYPlot.getXAxisType();

        Units units_1 =
                ((Units) simulation.getUnitsManager().getObject("m"));

        axisType_0.getDirectionVector().setComponentsAndUnits(-1.0, 0.0, 0.0, units_1);

    }

    private void createXYZTable() {

        Simulation simulation =
                getActiveSimulation();

        XyzInternalTable xyzInternalTable =
                simulation.getTableManager().create("star.common.XyzInternalTable");

        PrimitiveFieldFunction primitiveFieldFunction_0 =
                ((PrimitiveFieldFunction) simulation.getFieldFunctionManager().getFunction("NitrogenOxide"));

        PrimitiveFieldFunction primitiveFieldFunction_1 =
                ((PrimitiveFieldFunction) simulation.getFieldFunctionManager().getFunction("Temperature"));

        PrimitiveFieldFunction primitiveFieldFunction_2 =
                ((PrimitiveFieldFunction) simulation.getFieldFunctionManager().getFunction("MassFractionCO"));

        PrimitiveFieldFunction primitiveFieldFunction_3 =
                ((PrimitiveFieldFunction) simulation.getFieldFunctionManager().getFunction("MassFractionCO2"));

        PrimitiveFieldFunction primitiveFieldFunction_4 =
                ((PrimitiveFieldFunction) simulation.getFieldFunctionManager().getFunction("Volume"));

        xyzInternalTable.setFieldFunctions(new NeoObjectVector(new Object[] {primitiveFieldFunction_4, primitiveFieldFunction_0, primitiveFieldFunction_1, primitiveFieldFunction_2, primitiveFieldFunction_3}));

        xyzInternalTable.getParts().setQuery(null);

        Region region =
                simulation.getRegionManager().getRegion("Body 1");

        xyzInternalTable.getParts().setObjects(region);

    }

    private void initializeSolution() {
    
        Simulation simulation =
                    getActiveSimulation();

    	Solution solution = 
      		simulation.getSolution();

    	solution.initializeSolution();

    }

    private void saveState() {
    
        Simulation simulation =
                    getActiveSimulation();

        simulation.saveState(resolvePath("%s"));

    }

    public static ArrayList<double[]> calculateCoordinatesClockwise(double R, int bladeCount) {

        double stepDegrees = 360.0/bladeCount;
    
        ArrayList<double[]> coordinates = new ArrayList<>();
    
        for (double theta = 360.0; theta > 0; theta -= stepDegrees) {
            double radianTheta = Math.toRadians(theta);
            double x = (double) (R * Math.cos(radianTheta));
            double y = (double) (R * Math.sin(radianTheta));
            double z = 0.01;
            coordinates.add(new double[] {z, x, y});
        }
        return coordinates;
    }

}
    """ % (model_parameters['geometry_path'],
           model_parameters['chemkin_path'],
           model_parameters['init_model_folder'],
           str(model_parameters['bladeCount']),
           str(model_parameters['mesh_base_size']),
           model_path))
    macros_file.close()


def fuel_settings(path, fuel_parameters, model_path):
    macros_file = open(path, 'w')
    macros_file.write("""
import java.util.*;

import star.common.*;
import star.base.neo.*;
import star.flow.*;

public class fuel_macro extends StarMacro {

    public void execute() {

        setInitialConditions();

    }

    private void setInitialConditions() {

        Simulation simulation = getActiveSimulation();

        Solution solution =
                simulation.getSolution();

        simulation.clearSolution();

        Region region =
                simulation.getRegionManager().getRegion("Body 1");

        Boundary boundary_0 = 
          region.getBoundaryManager().getBoundary("Air blades");

        VelocityMagnitudeProfile velocityMagnitudeProfile_0 = 
          boundary_0.getValues().get(VelocityMagnitudeProfile.class);

        Units units_0 = 
          ((Units) simulation.getUnitsManager().getObject("m/s"));

        velocityMagnitudeProfile_0.getMethod(ConstantScalarProfileMethod.class).getQuantity().setValueAndUnits(%s, units_0);

        Boundary boundary_1 = 
          region.getBoundaryManager().getBoundary("Air inlet");

        VelocityMagnitudeProfile velocityMagnitudeProfile_1 = 
          boundary_1.getValues().get(VelocityMagnitudeProfile.class);

        velocityMagnitudeProfile_1.getMethod(ConstantScalarProfileMethod.class).getQuantity().setValueAndUnits(%s, units_0);

        Boundary boundary_2 = 
          region.getBoundaryManager().getBoundary("CH4");

        MassFlowRateProfile massFlowRateProfile_0 = 
          boundary_2.getValues().get(MassFlowRateProfile.class);

        Units units_1 = 
          ((Units) simulation.getUnitsManager().getObject("kg/s"));

        massFlowRateProfile_0.getMethod(ConstantScalarProfileMethod.class).getQuantity().setValueAndUnits(%s, units_1);

        simulation.saveState(resolvePath("%s"));
    }
}
    """ % (str(fuel_parameters['secondary_air_consumption']),
           str(fuel_parameters['primary_air_consumption']),
           str(fuel_parameters['gas_inlet_consumption']),
           model_path))
    macros_file.close()


def fgm_table_settings(path, recycling_parameters, model_path):
    macros_file = open(path, 'w')
    macros_file.write("""
package macro;

import java.util.*;

import star.common.*;
import star.base.neo.*;
import star.combustion.fgm.*;
import star.combustion.tablegenerators.*;

public class recycle_macro extends StarMacro {

    public void execute() {
        execute0();
    }

    private void execute0() {

        Simulation simulation_0 = 
          getActiveSimulation();

        PhysicsContinuum physicsContinuum_0 = 
          ((PhysicsContinuum) simulation_0.getContinuumManager().getContinuum("Physics 1"));

        FgmTableGenerator fgmTableGenerator_0 = 
          physicsContinuum_0.get(FgmTableGenerator.class);

        FgmTable fgmTable_0 = 
          ((FgmTable) fgmTableGenerator_0.getFgmTable());

        fgmTable_0.deleteTable();

        TableFluidStreamCollection tableFluidStreamCollection_0 = 
          ((TableFluidStreamCollection) fgmTableGenerator_0.getTableFluidStreamCollection());

        TableFluidStream tableFluidStream_0 = 
          ((TableFluidStream) tableFluidStreamCollection_0.getOxidizerStream());

        tableFluidStream_0.getFluidStreamComposition().setArray(new DoubleVector(new double[] {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, %s, 0.0, 0.0, 0.0, %s, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, %s, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, %s, 0.0}));

        fgmTable_0.constructTable();

        Solution solution_0 = 
          simulation_0.getSolution();

        solution_0.initializeSolution();

        simulation_0.saveState(resolvePath("%s"));
    }
}
    """ % (str(recycling_parameters['CO2']),
           str(recycling_parameters['H2O']),
           str(recycling_parameters['N2']),
           str(recycling_parameters['O2']),
           model_path))
    macros_file.close()


def setting_and_running_solver(path, solver_parameters, model_path):
    macros_file = open(path, 'w')
    macros_file.write("""
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.*;

import star.combustion.*;
import star.combustion.fgm.*;
import star.combustion.tablegenerators.*;
import star.common.*;
import star.mapping.*;
import star.base.neo.*;
import star.cadmodeler.*;
import star.dualmesher.VolumeControlDualMesherSizeOption;
import star.emissions.NoxModel;
import star.emissions.NoxSolver;
import star.emissions.NoxThreeEquationZeldovichModel;
import star.energy.StaticTemperatureProfile;
import star.flow.MassFlowRateProfile;
import star.flow.VelocityMagnitudeProfile;
import star.keturb.KEpsilonTurbulence;
import star.keturb.KeTwoLayerAllYplusWallTreatment;
import star.keturb.RkeTwoLayerTurbModel;
import star.material.MaterialDataBaseManager;
import star.material.MultiComponentGasModel;
import star.meshing.*;
import star.reactions.ReactingModel;
import star.resurfacer.VolumeControlResurfacerSizeOption;
import star.segregatedenergy.SegregatedFluidEnthalpyModel;
import star.segregatedflow.SegregatedFlowModel;
import star.turbulence.RansTurbulenceModel;
import star.turbulence.TurbulentModel;
import star.vis.*;

public class run_macros extends StarMacro {

    List<String> sceneParameters = Arrays.asList("Temperature", "NitrogenOxide", "MassFractionCO", "MassFractionCO2");
    String experiment_path = "%s";

    public void execute() {

        Simulation sim =
                getActiveSimulation();

        long startTime = System.currentTimeMillis();
        
        setStoppingCriterion();
        runSimulation();
        for (String param : sceneParameters) {
            changeSceneFieldFunction(param);
            String scene_path = experiment_path + System.getProperty("file.separator") + "scenes" + System.getProperty("file.separator") + param + ".png";
            saveScene(scene_path);
        }

        String path_plot = experiment_path + System.getProperty("file.separator") + "plot.csv";
        savePlotData(path_plot);

        String data_table_path = experiment_path + System.getProperty("file.separator") + "data_table.csv";
        saveXYZTable(data_table_path);

        saveState();
        
        long endTime = System.currentTimeMillis();
        
        long durationInMilliseconds = endTime - startTime;
        double durationInSeconds = durationInMilliseconds / 1000.0;

        String filename = experiment_path + "/exec_time.txt";

        try (BufferedWriter writer = new BufferedWriter(new FileWriter(filename, true))) {
            writer.write("Время расчета модели: " + durationInSeconds + "\\n");
        } catch (IOException e) {
            //sim.println("Ошибка при добавлении строки в файл: " + e.getMessage());
        }

    }

    private void setStoppingCriterion() {

        Simulation simulation =
                getActiveSimulation();

        StepStoppingCriterion stepStoppingCriterion =
                ((StepStoppingCriterion) simulation.getSolverStoppingCriterionManager().getSolverStoppingCriterion("Maximum Steps"));

        IntegerValue integerValue =
                stepStoppingCriterion.getMaximumNumberStepsObject();

        integerValue.getQuantity().setValue(%s);

    }

    private void runSimulation() {

        Simulation simulation =
                getActiveSimulation();

        Solution solution =
                simulation.getSolution();

        solution.initializeSolution();

        ResidualPlot residualPlot =
                ((ResidualPlot) simulation.getPlotManager().getPlot("Residuals"));

        residualPlot.openInteractive();

        simulation.getSimulationIterator().run();

    }

    private void changeSceneFieldFunction(String FieldFunction) {

        Simulation simulation =
                getActiveSimulation();

        Scene scene =
                simulation.getSceneManager().getScene("Scalar Scene 1");

        ScalarDisplayer scalarDisplayer =
                ((ScalarDisplayer) scene.getDisplayerManager().getObject("Scalar 1"));

        PrimitiveFieldFunction primitiveFieldFunction =
                ((PrimitiveFieldFunction) simulation.getFieldFunctionManager().getFunction(FieldFunction));

        scalarDisplayer.getScalarDisplayQuantity().setFieldFunction(primitiveFieldFunction);

    }

    private void changePlotFieldFunction(String fieldFunction) {
    
        Simulation simulation =
                getActiveSimulation();

        XYPlot xYPlot =
                ((XYPlot) simulation.getPlotManager().getPlot("XY Plot 1"));

        YAxisType yAxisType =
                ((YAxisType) xYPlot.getYAxes().getAxisType("Y Type 1"));

        FieldFunctionUnits fieldFunctionUnits =
                yAxisType.getScalarFunction();

        PrimitiveFieldFunction primitiveFieldFunction =
                ((PrimitiveFieldFunction) simulation.getFieldFunctionManager().getFunction(fieldFunction));

        fieldFunctionUnits.setFieldFunction(primitiveFieldFunction);

    }

    private void saveScene(String pathName) {

        Simulation simulation =
                getActiveSimulation();

        Scene scene =
                simulation.getSceneManager().getScene("Scalar Scene 1");

        scene.resetCamera();

        scene.printAndWait(resolvePath(pathName), 1, 1920, 1080, true, false);

    }

    private void saveXYZTable(String pathName) {

        Simulation simulation =
                getActiveSimulation();

        XyzInternalTable xyzInternalTable =
                ((XyzInternalTable) simulation.getTableManager().getTable("XYZ Internal Table"));

        xyzInternalTable.extract();

        xyzInternalTable.export(resolvePath(pathName), ";");

    }

    private void savePlotData(String save_path) {
    
        Simulation simulation =
                getActiveSimulation();

        XYPlot xYPlot =
                ((XYPlot) simulation.getPlotManager().getPlot("XY Plot 1"));

        xYPlot.export(resolvePath(save_path), ",");

    }

    private void saveState() {
    
        Simulation simulation =
                getActiveSimulation();

        simulation.saveState(resolvePath("%s"));

    }

}
    """ % (solver_parameters['experiment_path'],
           str(solver_parameters['stopping_criterion']),
           model_path))
    macros_file.close()