/*
* 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.Graphics.DisplayEntity;
import com.jaamsim.input.EntityInput;
import com.jaamsim.input.Keyword;
import com.jaamsim.input.Output;
import com.jaamsim.input.ValueInput;
import com.jaamsim.units.AreaUnit;
import com.jaamsim.units.DimensionlessUnit;
import com.jaamsim.units.DistanceUnit;
import com.jaamsim.units.PressureUnit;
import com.jaamsim.units.SpeedUnit;
/**
* FluidComponent is the super-class for tanks, pipes, pumps, etc. in a hydraulic flow.
* @author Harry King
*
*/
public class FluidComponent extends DisplayEntity {
@Keyword(description = "The upstream component that feeds this component.",
example = "Component1 Previous { Comp1 }")
private final EntityInput<FluidComponent> previousInput;
@Keyword(description = "The hydraulic diameter of the component. " +
"Equal to the inside diameter of a pipe with a circular cross-section.",
example = "Comp1 Diameter { 1.0 m }")
private final ValueInput diameterInput;
private FluidFlow fluidFlow; // The fluid flow object that controls the flow from one component to the next.
private double baseInletPressure; // The static pressure at the component's inlet, ignoring the effect of flow acceleration.
private double baseOutletPressure; // The static pressure at the component's outlet, ignoring the effect of flow acceleration.
private double inletPressure; // The static pressure at the component's inlet.
private double outletPressure; // The static pressure at the component's outlet.
private double velocity; // The fluid velocity throughout the component.
private double flowArea; // The cross-section area of the flow.
{
previousInput = new EntityInput<>( FluidComponent.class, "Previous", "Key Inputs", null);
this.addInput( previousInput);
diameterInput = new ValueInput( "Diameter", "Key Inputs", Double.POSITIVE_INFINITY);
diameterInput.setValidRange( 0.0, Double.POSITIVE_INFINITY);
diameterInput.setUnitType( DistanceUnit.class );
this.addInput( diameterInput);
}
@Override
public void earlyInit() {
super.earlyInit();
flowArea = 0.25 * Math.PI * diameterInput.getValue() * diameterInput.getValue();
}
public void updateVelocity() {
velocity = fluidFlow.getFlowRate() / flowArea;
}
public void updateBaseInletPressure() {
FluidComponent prev = previousInput.getValue();
if( prev != null ) {
baseInletPressure = prev.getBaseOutletPressure() + prev.getDynamicPressure()
- this.getDynamicPressure();
}
else {
baseInletPressure = - this.getDynamicPressure();
}
}
/*
* Calculate the inlet pressure after allowing for acceleration
*/
public void updateInletPressure() {
FluidComponent prev = previousInput.getValue();
if( prev != null ) {
inletPressure = prev.getOutletPressure() + prev.getDynamicPressure()
- this.getDynamicPressure();
}
else {
inletPressure = - this.getDynamicPressure();
}
}
public void updateBaseOutletPressure() {
baseOutletPressure = this.calcOutletPressure( baseInletPressure, 0.0 );
}
/*
* Update the outlet pressure after allowing for acceleration
*/
public void updateOutletPressure( double flowAccel ) {
outletPressure = this.calcOutletPressure( inletPressure, flowAccel );
}
/*
* Return the outlet pressure for the given inlet pressure and flow acceleration.
*/
public double calcOutletPressure( double inletPres, double flowAccel ) {
return inletPres;
}
/*
* Return the dynamic pressure for a flow.
* (Dynamic pressure is negative for negative velocities.)
*/
public double getDynamicPressure() {
if( fluidFlow == null ) return 0.0;
return 0.5 * fluidFlow.getFluid().getDensity() * velocity * Math.abs(velocity);
}
public double getReynoldsNumber() {
if( fluidFlow == null ) return 0.0;
return Math.abs(velocity) * diameterInput.getValue() / fluidFlow.getFluid().getKinematicViscosity();
}
public void setFluidFlow( FluidFlow flow ) {
fluidFlow = flow;
}
public FluidComponent getPrevious() {
return previousInput.getValue();
}
public FluidFlow getFluidFlow() {
return fluidFlow;
}
public Fluid getFluid() {
if( fluidFlow != null ) {
return fluidFlow.getFluid();
}
else {
return null; // fluidFlow is null for FluidFixedFlow
}
}
public double getLength() {
return 0.0;
}
public double getDiameter() {
return diameterInput.getValue();
}
public double getFlowArea() {
return flowArea;
}
public void addVolume( double v ) {}
public double getBaseInletPressure() {
return baseInletPressure;
}
public double getBaseOutletPressure() {
return baseOutletPressure;
}
public void setBaseOutletPressure( double x ) {
baseOutletPressure = x;
}
public double getInletPressure() {
return inletPressure;
}
public double getOutletPressure() {
return outletPressure;
}
public void setOutletPressure( double x ) {
outletPressure = x;
}
public double getVelocity() {
return velocity;
}
public double getTargetInletPressure() {
return 0.0;
}
public double getFluidVolume() {
return 0.0;
}
@Output(name = "FlowArea",
description = "The cross-sectional area of the component.",
unitType = AreaUnit.class,
sequence = 0)
public double getFlowArea(double simTime) {
return flowArea;
}
@Output(name = "Velocity",
description = "The velocity of the fluid within the component.",
unitType = SpeedUnit.class,
sequence = 1)
public double getVelocity(double simTime) {
return velocity;
}
@Output(name = "ReynoldsNumber",
description = "The Reynolds Number for the fluid within the component. Equal to (velocity)(diameter)/(kinematic viscosity).",
unitType = DimensionlessUnit.class,
sequence = 2)
public double getReynoldsNumber(double simTime) {
return this.getReynoldsNumber();
}
@Output(name = "DynamicPressure",
description = "The dynamic pressure of the fluid flow. Equal to (0.5)(density)(velocity^2).",
unitType = PressureUnit.class,
sequence = 3)
public double getDynamicPressure(double simTime) {
return this.getDynamicPressure();
}
@Output(name = "InletPressure",
description = "The static pressure at the component's inlet.",
unitType = PressureUnit.class,
sequence = 4)
public double getInletPressure(double simTime) {
return inletPressure;
}
@Output(name = "OutletPressure",
description = "The static pressure at the component's outlet.",
unitType = PressureUnit.class,
sequence = 5)
public double getOutletPressure(double simTime) {
return outletPressure;
}
}