2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2010-2010 - DIGITEO - Clement DAVID <clement.david@scilab.org>
4 * Copyright (C) 2011-2014 - Scilab Enterprises - Clement DAVID
6 * Copyright (C) 2012 - 2016 - Scilab Enterprises
8 * This file is hereby licensed under the terms of the GNU GPL v2.0,
9 * pursuant to article 5.3.4 of the CeCILL v.2.1.
10 * This file was originally licensed under the terms of the CeCILL v2.1,
11 * and continues to be available under such terms.
12 * For more information, see the COPYING file which you should have received
13 * along with this program.
17 package org.scilab.modules.xcos.modelica.listener;
19 import java.awt.event.ActionEvent;
21 import java.util.List;
22 import java.util.logging.Logger;
24 import javax.swing.AbstractAction;
25 import javax.swing.JProgressBar;
26 import javax.swing.SwingWorker;
28 import org.scilab.modules.action_binding.highlevel.ScilabInterpreterManagement;
29 import org.scilab.modules.commons.ScilabConstants;
30 import org.scilab.modules.xcos.modelica.ModelStatistics;
31 import org.scilab.modules.xcos.modelica.Modelica;
32 import org.scilab.modules.xcos.modelica.ModelicaController;
33 import org.scilab.modules.xcos.modelica.ModelicaMessages;
34 import org.scilab.modules.xcos.modelica.model.Model;
39 @SuppressWarnings(value = { "serial" })
40 public final class SolveAction extends AbstractAction {
41 private static final String COMPILE_STRING = "fw='%s'; paremb='%s'; jaco='%s'; " + "if(compile_init_modelica(fw, paremb, jaco)) then "
42 + "mopen('%s', 'w'); end ";
43 private static final String COMPUTE_STRING = "method='%s'; Nunknowns='%s'; " + "if(Compute_cic(method,Nunknowns)) then " + "mopen('%s', 'w'); " + "end ";
45 private static final String IMF_INIT = "_init";
46 private static final String EXTENSION = ".xml";
47 private static final String INCIDENCE = "i_incidence_matrix";
49 private enum ActionToPerform {EXPORT, COMPILE, COMPUTE, FINISH};
50 private static class Worker extends SwingWorker<Void, ActionToPerform> {
52 private final ModelicaController controller;
53 private final JProgressBar progress;
55 public Worker(ModelicaController controller, JProgressBar progress) {
56 this.controller = controller;
57 this.progress = progress;
61 protected Void doInBackground() throws Exception {
64 final String modelName = controller.getRoot().getName();
65 // creating a temporary status file
66 final File statusFile = File.createTempFile(modelName, null);
68 // defensive programming
69 if (!controller.isSquare()) {
70 Logger.getLogger(SolveAction.class.getName()).severe(ModelicaMessages.MODEL_INVALID);
74 * Export the compilation data to xml
76 publish(ActionToPerform.EXPORT);
78 // store the updated values
79 final File updatedInitFile = new File(ScilabConstants.TMPDIR, modelName + IMF_INIT + EXTENSION);
80 Modelica.getInstance().save(controller.getRoot(), updatedInitFile);
83 * Compile the data from xml to a modelica file
85 publish(ActionToPerform.COMPILE);
87 if (controller.isParameterEmbedded()) {
94 if (controller.isJacobianEnable()) {
100 if(!statusFile.delete())
102 System.err.println("Cannot delete '" + statusFile + "'");
104 cmd = String.format(COMPILE_STRING, modelName, paremb, jaco, statusFile.getAbsolutePath());
106 Logger.getLogger(SolveAction.class.getName()).finest("Compiling");
107 ScilabInterpreterManagement.synchronousScilabExec(cmd);
109 if (!statusFile.exists()) {
110 publish(ActionToPerform.FINISH);
113 if(!statusFile.delete())
115 System.err.println("Cannot delete '" + statusFile + "'");
120 * Launch a modelica initialization with the generated file
122 publish(ActionToPerform.COMPUTE);
124 // update the model with the computed identifiers
125 final File incidence = new File(ScilabConstants.TMPDIR, modelName + INCIDENCE + EXTENSION);
126 final Model incidenceModel = Modelica.getInstance().load(incidence);
127 controller.getRoot().setIdentifiers(incidenceModel.getIdentifiers());
128 controller.getRoot().setOutputs(incidenceModel.getOutputs());
130 // update the statistics
131 controller.getStatistics().fireChange();
134 controller.setCompileNeeded(false);
136 if(!statusFile.delete())
138 System.err.println("Cannot delete '" + statusFile + "'");
140 final ModelStatistics stats = controller.getStatistics();
141 long nUnknowns = stats.getUnknowns() - stats.getEquations();
142 cmd = String.format(COMPUTE_STRING, controller.getComputeMethod(), nUnknowns, statusFile.getAbsolutePath());
145 Logger.getLogger(SolveAction.class.getName()).finest("Computing");
146 ScilabInterpreterManagement.synchronousScilabExec(cmd);
148 if (!statusFile.exists()) {
149 publish(ActionToPerform.FINISH);
152 if(!statusFile.delete())
154 System.err.println("Cannot delete '" + statusFile + "'");
159 * Finish the action using a state instead of the done() method
161 publish(ActionToPerform.FINISH);
167 protected void process(List<ActionToPerform> chunks) {
168 // only visual notify accordingly to the last performed action
169 final ActionToPerform action = chunks.get(chunks.size() - 1);
175 if (!progress.isIndeterminate()) {
176 progress.setIndeterminate(true);
182 progress.setIndeterminate(false);
188 private final ModelicaController controller;
189 private final JProgressBar progress;
192 * Default constructor
195 * the associated controller
197 public SolveAction(final ModelicaController controller, final JProgressBar progress) {
200 putValue(NAME, ModelicaMessages.SOLVE);
201 this.controller = controller;
202 this.progress = progress;
211 * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
214 public void actionPerformed(ActionEvent e) {
215 new Worker(controller, progress).execute();