/*
 * JaamSim Discrete Event Simulation
 * Copyright (C) 2013 Ausenco Engineering Canada Inc.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */
package com.jaamsim.FluidObjects;

import com.sandwell.JavaSimulation.DoubleInput;
import com.sandwell.JavaSimulation.Keyword;

/**
 * FluidCentrifugalPump models the performance of a centrifugal pump.
 * @author Harry King
 *
 */
public class FluidCentrifugalPump extends FluidComponent {

	@Keyword(desc = "Maximum volumetric flow rate that the pump can generate.",
	         example = "Pump1 MaxFlowRate { 1.0 m3/s }")
	private final DoubleInput maxFlowRateInput;

	@Keyword(desc = "Maximum static pressure that the pump can generate (at zero flow rate).",
	         example = "Pump1 MaxPressure { 1.0 Pa }")
	private final DoubleInput maxPressureInput;

	@Keyword(desc = "Maximum static pressure loss speed for the pump (at maximum flow rate).",
	         example = "Pump1 MaxPressureLoss { 1.0 Pa }")
	private final DoubleInput maxPressureLossInput;

	@Keyword(desc = "Maximum rotation speed for the pump.",
	         example = "Pump1 MaxRotationSpeed { 1.0 rpm }")
	private final DoubleInput maxRotationSpeedInput;

	@Keyword(desc = "Present rotation speed for the pump.",
	         example = "Pump1 PresentRotationSpeed { 1.0 rpm }")
	private final DoubleInput presentRotationSpeedInput;

	{
		maxFlowRateInput = new DoubleInput( "MaxFlowRate", "Key Inputs", 1.0d);
		maxFlowRateInput.setValidRange( 0.0, Double.POSITIVE_INFINITY);
		maxFlowRateInput.setUnits( "m3/s");
		this.addInput( maxFlowRateInput, true);

		maxPressureInput = new DoubleInput( "MaxPressure", "Key Inputs", 1.0d);
		maxPressureInput.setValidRange( 0.0, Double.POSITIVE_INFINITY);
		maxPressureInput.setUnits( "Pa");
		this.addInput( maxPressureInput, true);

		maxPressureLossInput = new DoubleInput( "MaxPressureLoss", "Key Inputs", 1.0d);
		maxPressureLossInput.setValidRange( 0.0, Double.POSITIVE_INFINITY);
		maxPressureLossInput.setUnits( "Pa");
		this.addInput( maxPressureLossInput, true);

		maxRotationSpeedInput = new DoubleInput( "MaxRotationSpeed", "Key Inputs", 1.0d);
		maxRotationSpeedInput.setValidRange( 0.0, Double.POSITIVE_INFINITY);
		maxRotationSpeedInput.setUnits( "rad/s");
		this.addInput( maxRotationSpeedInput, true);

		presentRotationSpeedInput = new DoubleInput( "PresentRotationSpeed", "Key Inputs", 1.0d);
		presentRotationSpeedInput.setValidRange( 0.0, Double.POSITIVE_INFINITY);
		presentRotationSpeedInput.setUnits( "rad/s");
		this.addInput( presentRotationSpeedInput, true);
	}

	/*
	 * Return the outlet pressure for the given inlet pressure and flow acceleration.
	 */
	@Override
	public double calcOutletPressure( double inletPres, double flowAccel ) {
		double speedFactor = presentRotationSpeedInput.getValue() / maxRotationSpeedInput.getValue();
		double flowFactor = this.getFluidFlow().getFlowRate() / maxFlowRateInput.getValue();
		double pres = inletPres;
		pres += maxPressureInput.getValue() * speedFactor * speedFactor;
		pres -= maxPressureLossInput.getValue() * flowFactor * flowFactor;
		return pres;
	}
}

@@ -645,43 +645,204 @@
 com.
-sandwell.JavaSimulation.DoubleInput
+jaamsim.CalculationObjects.DoubleCalculation;%0Aimport com.sandwell.JavaSimulation.DoubleInput;%0Aimport com.sandwell.JavaSimulation.EntityInput;%0Aimport com.sandwell.JavaSimulation.InputErrorException
 ;%0Aim
@@ -1634,322 +1634,282 @@
  = %22
-Maximum rotation speed for the pump.%22,%0A%09         example = %22Pump1 MaxR
+The CalculationEntity whose output sets the r
 otation
-S
+al s
 peed 
-%7B 1.0 rpm %7D%22)%0A%09private final DoubleInput maxRotationSpeedInput;%0A%0A%09@Keyword(desc = %22Present rotation speed for the pump.%22,%0A%09         example = %22Pump1 PresentRotationSpeed %7B 1.0 rpm %7D%22)%0A%09private final DoubleInput presentRot
+of the pump.  %22 +%0A%09%09%09%22The output value is ratio of present speed to maximum speed (0.0 - 1.0).%22,%0A%09         example = %22Pump1 SpeedController %7B Calc1 %7D%22)%0A%09private final EntityInput%3CDoubleCalcul
 ation
-S
+%3E s
 peed
+Controller
 Inpu
@@ -2600,66 +2600,108 @@
 %0A%0A%09%09
-maxRotationSpeedInput = new DoubleInput( %22MaxRotationSpeed
+speedControllerInput = new EntityInput%3CDoubleCalculation%3E( DoubleCalculation.class, %22SpeedController
 %22, %22
@@ -2717,443 +2717,315 @@
 s%22, 
-1.0d
+null
 );%0A%09%09
-maxRotationSpeedInput.setValidRange( 0.0, Double.POSITIVE_INFINITY);%0A%09%09maxRotationSpeedInput.setUnits( %22rad/s%22);%0A%09%09this.addInput( maxRotationSpeedInput, true);%0A%0A%09%09presentRotationSpeedInput = new DoubleInput( %22PresentRotationSpeed%22, %22Key Inputs%22, 1.0d);%0A%09%09presentRotationSpeed
+this.addInput( speedControllerInput, true);%0A%09%7D%0A%0A%09@Override%0A%09public void validate() %7B%0A%09%09super.validate();%0A%0A%09%09// Confirm that the SpeedController keyword has been set%0A%09%09if( speedController
 Input.
-s
+g
 etVal
-idRange( 0.0, Double.POSITIVE_INFINITY);%0A%09%09presentRotationSpeedInput.setUnits( %22rad/s%22);%0A%09%09this.addInput( presentRotationSpeedInput, true);
+ue() == null ) %7B%0A%09%09%09throw new InputErrorException( %22The SpeedController keyword must be set.%22 );%0A%09%09%7D
 %0A%09%7D%0A
@@ -3229,68 +3229,39 @@
 r = 
-presentRotationSpeedInput.getValue() / maxRotationSpeedInput
+speedControllerInput.getValue()
 .get

Modify FluidCentrifugalPump to accept a speed controller input