/*
* JaamSim Discrete Event Simulation
* Copyright (C) 2013 Ausenco Engineering Canada Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.jaamsim.FluidObjects;
import com.jaamsim.CalculationObjects.CalculationEntity;
import com.jaamsim.input.EntityInput;
import com.jaamsim.input.Keyword;
import com.jaamsim.input.Output;
import com.jaamsim.units.VolumeFlowUnit;
/**
* FluidFlowCalculation is the super-class for all flows between source and destination tanks.
* @author Harry King
*
*/
public abstract class FluidFlowCalculation extends CalculationEntity {
@Keyword(description = "The Fluid being moved by the flow.",
example = "FluidFlow1 Fluid { Fluid1 }")
private final EntityInput<Fluid> fluidInput;
@Keyword(description = "The source object for the flow.",
example = "FluidFlow1 Source { Tank1 }")
protected final EntityInput<FluidComponent> sourceInput;
@Keyword(description = "The destination object for the flow.",
example = "FluidFlow1 Destination { Tank1 }")
protected final EntityInput<FluidComponent> destinationInput;
private double flowRate; // The volumetric flow rate (m3/s) for the route.
private double lastUpdateTime; // The time at which the last update was performed.
{
fluidInput = new EntityInput<>( Fluid.class, "Fluid", "Key Inputs", null);
this.addInput( fluidInput);
fluidInput.setRequired(true);
sourceInput = new EntityInput<>( FluidComponent.class, "Source", "Key Inputs", null);
this.addInput( sourceInput);
destinationInput = new EntityInput<>( FluidComponent.class, "Destination", "Key Inputs", null);
this.addInput( destinationInput);
}
@Override
public void earlyInit() {
super.earlyInit();
lastUpdateTime = 0.0;
}
@Override
public void update(double simTime) {
double dt = simTime - lastUpdateTime;
lastUpdateTime = simTime;
// Update the volume stored at the source and destination
FluidComponent source = sourceInput.getValue();
FluidComponent destination = destinationInput.getValue();
double dV = flowRate * dt;
if( dV > 0.0 && source != null ) {
dV = Math.min( dV, source.getFluidVolume() );
}
else if( dV < 0.0 && destination != null ) {
dV = - Math.min( - dV, destination.getFluidVolume() );
}
if( source != null ) { source.addVolume( -dV ); }
if( destination != null ) { destination.addVolume( dV ); }
// Set the new flow rate
this.calcFlowRate( source, destination, dt);
}
protected abstract void calcFlowRate( FluidComponent source, FluidComponent destination, double dt );
protected void setFlowRate( double rate) {
flowRate = rate;
}
public double getFlowRate() {
return flowRate;
}
protected FluidComponent getSource() {
return sourceInput.getValue();
}
protected FluidComponent getDestination() {
return destinationInput.getValue();
}
public Fluid getFluid() {
return fluidInput.getValue();
}
@Output(name = "FlowRate",
description = "The volumetric flow rate for the system.",
unitType = VolumeFlowUnit.class)
public Double getFlowRate( double simTime ) {
return flowRate;
}
}