Exemple #1
0
  /**
   *
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   *
   * @generated NOT
   */
  @Override
  public boolean step(STEMTime time, long timeDelta, int cycle) {

    // Validate all decorators that return deltas to make sure
    // they are of deterministic nature. The Runge Kutta integratio
    // can only handle determininistic variants

    for (Decorator decorator : this.getDecorators())
      if (decorator instanceof IntegrationDecorator) {
        IntegrationDecorator idec = (IntegrationDecorator) decorator;
        if (!idec.isDeterministic()) {
          Activator.logError(
              "Error, decorator: "
                  + idec
                  + " is not deterministic. The Runge Kutta Integrator can only handle deterministic models.",
              new Exception());
          return false;
        }
      }

    Activator act = org.eclipse.stem.ui.Activator.getDefault();
    if (act != null) {
      final Preferences preferences = act.getPluginPreferences();
      num_threads =
          (short)
              preferences.getInt(
                  org.eclipse.stem.ui.preferences.PreferenceConstants.SIMULATION_THREADS);
    } else num_threads = 2; // Just so we can run inside junit test

    final int c = cycle;

    // Initialize latches
    stepSizeBarrier =
        new CyclicBarrier(
            num_threads,
            new Runnable() {
              public void run() {
                // All threads successfully advanced time by some step h.
                // Find the smallest
                smallestH = Double.MAX_VALUE;
                maximumError = -Double.MAX_VALUE;
                for (int i = 0; i < num_threads; ++i) {
                  if (jobs[i].h <= smallestH) {
                    if (maximumError < jobs[i].maxerror) maximumError = jobs[i].maxerror;
                    smallestH = jobs[i].h;
                  }
                }
              }
            });

    updateDoneBarrier = new CyclicBarrier(num_threads);

    // Find triggers and make sure they are invoked
    for (Decorator decorator : this.getDecorators()) {
      if (decorator instanceof Trigger) {
        decorator.updateLabels(time, timeDelta, cycle);
      }
    }

    // First initialize the probe and temp label values from the current
    // label values.

    for (Decorator decorator : this.getDecorators()) {
      EList<DynamicLabel> allLabels = decorator.getLabelsToUpdate();
      for (final Iterator<DynamicLabel> currentStateLabelIter = allLabels.iterator();
          currentStateLabelIter.hasNext(); ) {
        if (decorator instanceof IntegrationDecorator) {
          // It's a standard disease model with a standard disease model label
          final IntegrationLabel iLabel = (IntegrationLabel) currentStateLabelIter.next();
          ((IntegrationLabelValue) iLabel.getProbeValue())
              .set((IntegrationLabelValue) iLabel.getCurrentValue());
          ((IntegrationLabelValue) iLabel.getTempValue())
              .set((IntegrationLabelValue) iLabel.getCurrentValue());
          ((IntegrationLabelValue) iLabel.getTempValue()).prepareCycle();
          ((IntegrationLabelValue) iLabel.getProbeValue()).prepareCycle();
        } else currentStateLabelIter.next();
      }
    }

    if (jobs == null || jobs.length != num_threads) {
      // Initialize the jobs if not done yet or of the number of threads changes
      jobs = new RkJob[num_threads];

      for (short i = 0; i < num_threads; ++i) {
        final short threadnum = i;
        jobs[i] = new RkJob("Worker " + i, threadnum, this);
      } // For each job
    } // If not initialized

    // Initialize
    int thread = 0;
    for (RkJob j : jobs) {
      j.cycle = c;
      j.time = time;
      j.timeDelta = timeDelta;
    }
    // Schedule. Jobs can be rescheduled after finished
    for (RkJob j : jobs) j.schedule();

    // Wait until all jobs completed
    for (RkJob j : jobs) {
      try {
        j.join();
      } catch (InterruptedException ie) {
        Activator.logError(ie.getMessage(), ie);
      }
    }

    // Set the common time and step size here and validate everything is right
    double minStep = Double.MAX_VALUE;
    double currentT = jobs[0].t;
    for (RkJob j : jobs) {
      // The jobs have calculated new step sizes after they finished. Pick the
      // smallest one for the next cycle
      if (j.h < minStep) minStep = j.h;
      if (j.t != currentT)
        Activator.logError(
            "Error, one thread was in misstep with other threads, its time was "
                + j.t
                + " versus "
                + currentT,
            new Exception());
    }
    return true;
  }