Beispiel #1
0
        public override SettingResponseData setSourceValues(FlowCalculationData baseData, FlowComponent caller, double flowVolume, bool lastTime)
        {
            SettingResponseData ret = new SettingResponseData();
            finalFlow -= flowVolume;
            if(lastTime)
            {
                currentVolume -= flowVolume * PhysTools.timeStep;
            }

            ret.flowVolume = flowVolume;
            ret.fluidTypeMap = currentFluidTypeMap;
            ret.temperature = currentTemperature;

            inletTemperature = currentTemperature;
            outletTemperature = currentTemperature;

            return ret;
        }
Beispiel #2
0
        public override void setDeliveryValues(FlowCalculationData baseData, FlowComponent caller, double flowVolume, bool lastTime)
        {
            finalFlow += flowVolume;
            if(lastTime)
            {
                double volumeToAdd = flowVolume * PhysTools.timeStep;
                SettingResponseData tankCurrentFluids = new SettingResponseData(currentTemperature, this.currentFluidTypeMap);
                SettingResponseData incomingFluids = new SettingResponseData(baseData.temperature, baseData.fluidTypeMap);
                SettingResponseData mixture = PhysTools.mixFluidPercentsAndTemperatures(new SettingResponseData[] { tankCurrentFluids, incomingFluids }, new double[] { currentVolume, volumeToAdd });

                this.currentTemperature = mixture.temperature;
                this.currentFluidTypeMap = mixture.fluidTypeMap;

                if(isSealed)
                {
                    currentVolume += volumeToAdd;
                    //Now, we need to calculate the pressure.
                    double gasVolume = 0.0;
                    double liquidVolume = 0.0;
                    PhysTools.normalizeFluidMixture(ref currentFluidTypeMap);               //Make sure that the percentages are normalized, otherwise very bad things would happen
                    foreach (KeyValuePair<FluidType, double> kvp in currentFluidTypeMap)
                    {
                        //NOTE: If we have multiple gasses that need to compress differently (I don't think that is possible, even with AIR and STEAM), then we need to re-think this algorithm from the ground up.
                        if (kvp.Key.isGas)
                            gasVolume += kvp.Value * currentVolume;
                        else
                            liquidVolume += kvp.Value * currentVolume;
                    }

                    percentFilled = liquidVolume / capacity;
                    double volumeForGas = capacity - liquidVolume;
                    tankPressure = (gasVolume / volumeForGas) - 1.0;                //Subtract 1.0 to convert from bara to barg.
                }
                else
                {
                    double adjustmentToMake = 0.0;
                    //Vent any gasses out the top.
                    foreach(FluidType key in currentFluidTypeMap.Keys.ToList<FluidType>())
                    {
                        if(key.isGas)
                        {
                            adjustmentToMake += currentFluidTypeMap[key];
                            currentFluidTypeMap.Remove(key);
                        }
                    }
                    if (adjustmentToMake > 0.0)
                    {
                        //We ended up removing some gas, so we need to re-normalize, and adjust the values
                        PhysTools.normalizeFluidMixture(ref currentFluidTypeMap);
                        volumeToAdd *= (1.0 - adjustmentToMake);                    //Remove the volume of gas that is escaping
                    }
                    tankPressure = 0.4;                 //TODO: Adjust non-sealed tank outlet pressures based on size/shape, etc.

                    currentVolume += volumeToAdd;

                    percentFilled = currentVolume / capacity;
                }
            }

            inletTemperature = currentTemperature;
            outletTemperature = currentTemperature;
        }
 public void applySourceResponse(SettingResponseData sourceResponse)
 {
     this.fluidTypeMap = sourceResponse.fluidTypeMap;
     this.temperature = sourceResponse.temperature;
 }
Beispiel #4
0
        private SettingResponseData setFlowValues(FlowCalculationData baseData, FlowComponent caller, double flowVolume, FlowComponent[] nodes, bool isDeliverySide, bool lastTime)
        {
            if(isDeliverySide)
            {
                for (int i = 0; i < nodes.Length; i++)
                {
                    nodes[i].setDeliveryValues(baseData, this, flowPercentageSolutions[baseData.flowDriver.name][i] * flowVolume, lastTime);
                }
                finalFlow = flowVolume;

                currentFluidTypeMap = baseData.fluidTypeMap;               //On the delivery side, the mixture comes from passed in arguments
                inletTemperature = baseData.temperature;
                outletTemperature = baseData.temperature;

                return null;
            }
            else
            {
                SettingResponseData[] responses = new SettingResponseData[nodes.Length];
                double[] volumes = new double[nodes.Length];
                bool hasNull = false;
                for (int attempt = 0; attempt < 2; attempt++)
                {
                    hasNull = false;
                    for (int i = 0; i < nodes.Length; i++)
                    {
                        volumes[i] = flowPercentageSolutions[baseData.flowDriver.name][i] * flowVolume;
                        if(responses[i] == null)
                            responses[i] = nodes[i].setSourceValues(baseData, this, volumes[i], lastTime);
                        if (responses[i] == null)
                            hasNull = true;
                    }
                    if (!hasNull)
                        break;
                }
                if (hasNull)
                    return null;

                finalFlow = flowVolume;
                SettingResponseData ret = PhysTools.mixFluidPercentsAndTemperatures(responses, volumes);
                ret.flowVolume = flowVolume;
                //ret.fluidTypeMap = PhysTools.mixFluids(responses, volumes);

                currentFluidTypeMap = ret.fluidTypeMap;                    //On source side, the mixture comes from the return values
                inletTemperature = ret.temperature;
                outletTemperature = ret.temperature;

                return ret;
            }
        }
Beispiel #5
0
        private SettingResponseData setCombiningFlowValues(FlowCalculationData baseData, FlowComponent caller, double flowVolume, FlowComponent[] nodes, bool isDeliverySide, bool lastTime)
        {
            int index = indexByName[caller.name];
            setCombiningVolumeMap[index] = flowVolume;

            double volumeSum = 0.0;
            for (int i = 0; i < setCombiningVolumeMap.Length; i++)
            {
                if (setCombiningVolumeMap[i] < 0.0)
                    return null;                //We haven't seen all of the inputs to combine them...
                else
                    volumeSum += setCombiningVolumeMap[i];
            }

            finalFlow = volumeSum;

            if (isDeliverySide)
            {
                for (int i = 0; i < nodes.Length; i++)
                {
                    nodes[i].setDeliveryValues(baseData, this, volumeSum, lastTime);
                }

                currentFluidTypeMap = baseData.fluidTypeMap;               //On the delivery side, the mixture comes from passed in arguments
                inletTemperature = baseData.temperature;
                outletTemperature = baseData.temperature;

                return null;
            }
            else
            {
                if (nodes.Length != 1)
                    throw new Exception("Source combiners can only have 1 node");
                if (setterDownstreamValue == null)
                    setterDownstreamValue = nodes[0].setSourceValues(baseData, this, volumeSum, lastTime);

                SettingResponseData ret = new SettingResponseData();
                ret.flowVolume = volumeSum;
                ret.fluidTypeMap = setterDownstreamValue.fluidTypeMap;
                ret.temperature = setterDownstreamValue.temperature;

                currentFluidTypeMap = ret.fluidTypeMap;                    //On source side, the mixture comes from the return values
                inletTemperature = ret.temperature;
                outletTemperature = ret.temperature;

                return ret;
            }
        }
Beispiel #6
0
 public override void resetState()
 {
     base.resetState();
     for (int i = 0; i < setCombiningVolumeMap.Length; i++)
     {
         setCombiningVolumeMap[i] = -1.0;
     }
     combinerDownstreamValues.Clear();
     foreach (KeyValuePair<String, double[]> iter in combinerMap)
     {
         for (int i = 0; i < iter.Value.Length; i++)
         {
             if (!indexesUsedByPump.ContainsKey(iter.Key) || indexesUsedByPump[iter.Key][i])
                 iter.Value[i] = -1.0;                            //Initialize with all negative numbers, and wait until they are not negative to know when we are done.
             else
                 iter.Value[i] = 0.0;                             //Initialize to 0 if this pump will never get this number
         }
     }
     setterDownstreamValue = null;
 }