diff --git a/README.MD b/README.MD
index 09dc42d..0e5ff42 100644
--- a/README.MD
+++ b/README.MD
@@ -1,6 +1,6 @@
## HVAC-LIB - Psychrometrics Analysis Library
Thermodynamics of humid air for MEP/HVAC engineers
-> VERSION: 1.0 - SNAPSHOT
+> VERSION: 1.1 - SNAPSHOT
> AUTHOR: Piotr Jażdżyk
> LINKEDIN: https://www.linkedin.com/in/pjazdzyk
@@ -12,11 +12,31 @@
HVAC-LIB is a set of libraries for moist air properties calculations including typical air thermodynamic processes in HVAC industry. The aim of this project is to create easy to use psychrometrics library, to be further
used as an engine for any type of HVAC software development.
+All output values are return as in basic SI units, with small exception to specific heat (kJ/kgK) instead of (J/kgK) and specific enthalpy is in (kJ/kg) instead of (J/kg).
-At the present state of development following modules are finalized ready for use:
-1. Moist Air thermophysical properties (MoistAir) including simplified liquid water properties for condensate handling (LiquidWater)
-2. Flow of moist air and liquid water (FlowOfMoistAir, FlowOfFluid)
-3. Heating and cooling of moist air, including real cooling coil and its condensate discharge (ProcAirHeatCool)
+LAST CHANGES (2022.11.16):
+* all fluids, flows and processes classes are immutable for now on,
+* all modules were heavily reworked and refactored implementing clean code rules where I managed to do it,
+* Builder Pattern implemented in all key classes,
+* changed packaging style to group all classes by domain, not by type,
+* decoupled many dependencies by use of interfaces,
+* split large classes into smaller pieces, to enforce SRP where possible,
+* replaced many short physical property abbreviations with full names, for ie: "density" instead of "rho", with exception to Physics classes.
+* added diagrams for better understanding all dependencies and key components
+
+The library is organized into following modules:
+* _fluids module_ - includes classes dedicated to fluid property representation and calculation
+* _flows module_ - includes classes representing fluid or humid gas flow handling
+
+The diagram below presents Fluid and Flow modules structure:
+
+
+* _process module_ - includes classes representing each thermodynamic process implemented so far in the library
+
+The diagram below presents Fluid and Flow modules structure:
+
+
+* _tests_ - includes all tests representing how to properly use each of library components
## TECH
![image](https://img.shields.io/badge/16-Java-orange?style=for-the-badge)
@@ -28,7 +48,7 @@ At the present state of development following modules are finalized ready for us
#### Moist air thermophysical properties:
* atmospheric pressure based on height above sea level,
* temperature change based on height above sea level,
-* saturation vapor pressure,
+* water vapour saturation pressure,
* dew point temperature and wet bulb temperature,
* air relative humidity,
* humidity ratio and maximum humidity ratio,
@@ -51,18 +71,23 @@ At the present state of development following modules are finalized ready for us
* option to lock one selected flow type
* setting value one type of flow will automatically recalculate others, based on provided input value and current properties of the moist air
-#### Heating and cooling with condensate discharge:
-* moist air heating or dry cooling,
-* moist air cooling based on real cooling coil average wall temperature,
-* condensate discharge is calculated for the cooling process,
-* different methods for most typical cases: determining resulting air state based on expected outlet temperature, outlet RH or available heat of the process.
+#### Air heating and cooling with condensate discharge:
+* heating & cooling process driven by heat input / output,
+* heating & cooling process driven by target outlet temperature,
+* heating & cooling process driven by target relative humidity,
+
+#### Air stream mixing:
+* simple mixing of two flows with humidity content,
+* mixing of multiple flows with humidity content,
+* mixing algorithm which will try to adjust inlet and recirculation flow accordingly, to meet target output dry air mass flow and target outlet temperature.
## LEGAL DISCLAIMER
This code is my intellectual property. Please have respect for this. You can use it freely in any academic or non-commercial use if you
properly include the source and author in your references or documentation. For commercial use, please contact me first to discuss the license fee.
-## NAMING CONVENTION
-Physics method names meets following convention:
+## PHYSICS NAMING CONVENTION
+Naming style in Physics classes is shortened. Typical property abbreviations are used, matching this popular occurrence in technical scripts or literature.
+Please find the example below:
```
calcMaTaTdpRH(){}
```
@@ -75,9 +100,15 @@ The approach presented above, which probably may cause a serious headache to any
structure, where corresponding methods are sorting themselves while writing a code using this library.
## UPCOMING FUNCTIONALITY
-1. Module for water spray air humidification
-2. Module for superheated steam air humidification
-3. Module for simplified heat and humid recovery exchanger
+1. Service layer for easier objects creation and for increased module encapsulation,
+2. REST API for humid air properties,
+3. CSV Table generators for creating user-custom tables with requested properties value range
+4. Module for water spray air humidification
+5. Module for superheated steam air humidification
+6. Module for simplified heat and humid recovery exchanger
+7. Unit conversion system
+
+Do you have a special request what this library should do to help you in your calculations? Just let me know!
## REFERENCE SOURCES
diff --git a/README_GUIDE.MD b/README_GUIDE.MD
index 706d239..974ab96 100644
--- a/README_GUIDE.MD
+++ b/README_GUIDE.MD
@@ -6,332 +6,348 @@
---
-Please find below simple user guide for most relevant current functionalities. Please consider following naming convention:
+Please find below simple user guide for most relevant current functionalities. Please consider following naming
+convention:
+
* "Ma" - moist air
* "Da" - dry air
* "Wv" - water vapour
## MOIST AIR THERMOPHYSICAL PROPERTIES
-MoistAir is a class representing a set of thermophysical properties ot air and water vapor mixture within typical pressures in the HVAC industry.
-Variables could be divided into core parameters which are: pressure, temperature, relative humidity or humidity ratio, and dependent parameters,
-which are already listed in the readme file or JavaDoc. All properties' calculation equations are gathered in separate classes with "Lib" prefix.
-This allows for quick value obtaining in any intermediate calculations without computational expensive creation of MoistAir instance.
-For some values where a direct calculation is not possible, the [Modified Brent Solver](https://github.com/pjazdzyk/Brent-Decker-Solver) is
-used for quick and efficient iterative calculations. Use an example of moist air property library is shown below:
-```
-//Saturation pressure calculation for a ta=20oC
-var saturationPressure = LibPhysicsOfAir.calc_Ma_Ps(20);
-System.out.println(saturationPressure); //Outputs 2338.80 Pa
+
+MoistAir is a class representing a set of thermophysical properties ot air and water vapor mixture within typical
+pressures in the HVAC industry.
+Variables could be divided into core parameters which are: pressure, temperature, relative humidity or humidity ratio,
+and dependent parameters,
+which are already listed in the readme file or JavaDoc. Properties calculation equations are grouped in separate
+classes with "Physics" prefix. These classes are meant to be used similarly as Java.util Math class, but for physics of
+fluids. This allows for quick value calculation in any intermediate calculations without computational expensive creation of
+instances.
+For some values where a direct calculation is not possible,
+the [Modified Brent Solver](https://github.com/pjazdzyk/brent-dekker-solver) is
+used for quick and efficient iterative calculations, what allows to solve complex and nested property equations.
+
+Naming convention in Physics classes is reduced and simplified to maintain name similarity to actual variable symbols in
+literature or scientific papers.
+
+Below is an example, which presents how to directly use calculation methods from Physics classes:
+
+```java
+// Saturation pressure calculation for air temperature of 20 oC:
+double saturationPressure = LibPhysicsOfAir.calcMaPs(20);
+System.out.println(saturationPressure); // Outputs 2338.80 Pa
```
+
For flow calculation or heating/cooling process analysis, an instance of MoistAir is required.
-Let's create an object that represents thermophysical properties of air for typical summer design values: ta=30oC, RH=45%.
-```
-var summerAir = new MoistAir("summer", 30, 45);
-```
-By default, all pressure-dependent variables are calculated for atmospheric pressure pat=101325 Pa. It is possible to use an overloaded constructor which allows for providing user-defined atmospheric pressure and humidity type.
-```
-var summerAir2 = new MoistAir("summer2", 30, 45, 90000, MoistAir.HumidityType.REL_HUMID);
-```
-It is also possible to set a specific altitude above sea level, and application will correct pressure value accordingly:
-```
-summerAir2.setElevationASL(2000);
-System.out.println(summerAir2.getPat()); //Outputs: 79495.12 Pa
-```
-For increased readability and ease of use the Builder Pattern implementation has been provided. Additionally, a set of overloaded static "of" methods are provided for user convenience. You can configure as many parameters as you want.
-If a given parameter is not provided - default values listed in LibDefaults will be used automatically, hence you can simply invoke only build() and use setters to specify values later.
-```
-//Constructed from Builder pattern
-var summerAir3 = new MoistAir.Builder()
- .withName("Summer3")
- .withTa(30).withRH(45)
- .withZElev(2000)
- .build();
-
-//Constructed from static ofAir() method.
-var summerAir4 = MoistAir.ofAir(30,45);
+Let's create an object that represents thermophysical properties of air for typical summer design values: ta=30oC,
+RH=45%.
+
+```java
+HumidGas summerAir = new MoistAir(30, 45, 90000, MoistAir.HumidityInputType.REL_HUMID);
```
-For a quick review of all thermophysical parameters just invoke toString(). Each property is also available by provided get() methods.
+
+For increased readability and ease of use the Builder Pattern implementation has been provided. Additionally, a set of
+overloaded static "of" methods are provided for user convenience. You can configure as many parameters as you want.
+If a given parameter is not provided - default values listed in LibDefaults will be used automatically, hence you can
+simply invoke only build() and use setters to specify values later.
+
+```java
+// Using Builder Pattern
+HumidGas summerAir = new MoistAir.Builder()
+ .withAirTemperature(30)
+ .withRelativeHumidity(45)
+ .build();
+
+// Static factory methods
+HumidGas exampleAir1 = MoistAir.ofAir(30, 45);
+HumidGas exampleAir2 = MoistAir.ofAir(30, 45, 90000);
```
-System.out.println(summerAir3.toString());
+
+For a quick review of all thermophysical parameters just invoke toString(). Each property is also available by provided
+get() methods.
+
+```java
+System.out.println(summerAir);
```
+
This will output:
+
```
-Instance name : Summer3
-Core parameters : Pat=79495 Pa | ta=30.000 degC | RH_Ma= 45.000 % | Wbt_Ma=20.416 degC | Tdp_Ma=16.776 degC | Ps= 4246.03 Pa | x_Ma= 0.011954 kg/kg | xMax= 0.035095 kg/kg
-Dry air : rho_Da= 0.914 kg/m3 | cp_Da= 1.0052 kJ/kgK | k_Da= 0.0267 W/(m*K) | thDiff_Da= 0.00002908 m2/s | dynVis_Da = 0.00001854 kg/(m*s) | kinVis_Da=0.0000203 m2/s | Pr_Da=0.70 | i_Da= 30.16 kJ/kg.da
-Water vapour : rho_Wv= 0.629 kg/m3 | cp_Wv= 1.8568 kJ/kgK | k_Wv= 0.0196 W/(m*K) | thDiff_Wv= 0.00001675 m2/s | dynVis_Wv = 0.00001002 kg/(m*s) | kinVis_Mv=0.0000159 m2/s | Pr_Wv=0.95 | i_Wv= 2556.60 kJ/kg.da | i_Wt= 125.70 kJ/kg.da | i_Ice= 0.00 kJ/kg.da
-Moist air : rho_Ma= 0.896 kg/m3 | cp_Ma= 1.0274 kJ/kgK | k_Ma= 0.0271 W/(m*K) | thDiff_Ma= 0.00002941 m2/s | dynVis_Ma = 0.00001837 kg/(m*s) | kinVis_Ma=0.0000205 m2/s | Pr_Ma=0.70 | i_Ma= 60.72 kJ/kg.d
+Core parameters : Pat=101325 Pa | ta=30.000 degC | RH_Ma= 45.000 % | Wbt_Ma=21.053 degC | Tdp_Ma=16.776 degC | Ps= 4246.03 Pa | x_Ma= 0.011954 kg/kg | xMax= 0.027203 kg/kg
+Dry air : rho_Da= 1.164 kg/m3 | cp_Da= 1.0052 kJ/kgK | i_Da= 30.16 kJ/kg.da
+Water vapour : rho_Wv= 0.711 kg/m3 | cp_Wv= 1.8655 kJ/kgK | i_Wv= 2556.86 kJ/kg.da | i_Wt= 125.40 kJ/kg.da | i_Ice= 0.00 kJ/kg.da
+Moist air : rho_Ma= 1.142 kg/m3 | cp_Ma= 1.0275 kJ/kgK | k_Ma= 0.0271 W/(m*K) | thDiff_Ma= 0.00002308 m2/s | dynVis_Ma = 0.00001837 kg/(m*s) | kinVis_Ma=0.0000161 m2/s | Pr_Ma=0.70 | i_Ma= 60.72 kJ/kg.da
```
## LIQUID WATER THERMOPHYSICAL PROPERTIES
-LiquidWater class is far simpler, and it requires only the temperature to initialize properties. This class was created for modeling condensate purposes and will be further extended.
-To create a liquid water instance, just use any of the constructor or builder pattern:
-```
-var water1 = new LiquidWater("water", 10);
-var water2 = new LiquidWater.Builder().withName("water").withTa(10).build();
-var water3 = LiquidWater.ofWater("water",10);
-```
-You can get water properties by appropriate get() methods. To check all parameters, just invoke toString():
+LiquidWater class is simpler, and it requires only the temperature and pressure to initialize properties. This class was created
+mainly for modeling condensate purposes. Despite the required pressure input - at present development stage, water properties are not calculated as
+pressure dependent, this might come as a feature in later development.
+To create a liquid water instance, just use a constructor or the builder pattern:
+
+```java
+// Creating Liquid water instance
+Fluid waterCondensateExample1 = new LiquidWater(90000, 10);
+Fluid waterCondensateExample2 = new LiquidWater.Builder()
+ .withTemperature(10)
+ .withPressure(90000)
+ .build();
```
-var waterSpecEnthalpy = water1.getIx();
-System.out.println(waterSpecEnthalpy); //Outputs: 41.95 kJ/kgK
-System.out.println(water1);
+To get fluid resulting properties just use getters, or print everything via toString();
-Outputs:
-Fluid name: water
+```
+// Outputs
Core parameters : ta=10.000 oC | cp=4.196 kJ/kgK | rho= 999.546 kg/m3 | ix=41.955 kJ/kg
```
+
## FLOW OF MOIST AIR
-FlowOfMoistAir instance calculates and stores mass flow and volumetric flow for moist air and its dry air component. All of these flows depend on each other. Setting one type of the flow will automatically
-calculate and set all others. Flow depends on moist air instance. It is important to emphasize that flows will not update automatically if a change emerges inside MoistAir aggregated instance caused by an external
-action (ie: in case MoistAir reference is shared across other classes). For such an event, updateFlows() method is provided. Let's try to create some flows and see how it works. Creating a flow of moist air
-with volumetric flow 5000m3/h of temperature ta=20oC and relative humidity RH=50%.
-```
-var tx= 20; //OC
-var RH = 50; //%
-var volFlowMa = 5000.0/3600.0; //m3/s
-var air1 = new MoistAir("NewAir", tx, RH);
-var flow1 = new FlowOfMoistAir("Test flow", volFlowMa, TypeOfAirFlow.MA_VOL_FLOW,air1);
-```
-Please note that if you are using constructors for flow creation, you have to specify which flow type are you providing by use of Enum AirFlowType as shown above. For simplicity and ease of use
-you can always use the Builder pattern:
-```
-var flow = new FlowOfMoistAir.Builder()
- .withTx(20).withRH(50)
- .withVolFlowMa(5000.0/3600.0)
- .withFlowName("Test flow");
- .build();
+FlowOfMoistAir instance calculates and stores mass flow and volumetric flow for moist air and its dry air component. All
+of these flows depend on each other. They are calculated only once accordingly based on provided flow rate and type of flow upon
+instance creation. Flow instance requires specific fluid which must be provided as an argument in constructor.
+
+Creating a flow of moist air
+with volumetric flow 5000m3/h of temperature ta=20oC and relative humidity RH=50%. For simplicity and ease of use
+the best way is to use the Builder pattern:
+
+```java
+// Creating flow of moist air instance
+double airTemp = 20; // oC
+double airRH = 50; // %
+double moistAirVolFLow = 5000d / 3600d; // m3/s
+HumidGas airExample = new MoistAir.Builder()
+ .withAirTemperature(airTemp)
+ .withRelativeHumidity(airRH)
+ .build();
+FlowOfHumidGas flowOfAir = new FlowOfMoistAir.Builder(airExample)
+ .withVolFlowMa(moistAirVolFLow)
+ .build();
```
-Or simpler, for a typical HVAC case, allowing for volumetric flow to be provided in m3/h:
-```
-var flow = FlowOfMoistAir.ofM3hVolFlow(5000,20,50);
+Or even simpler, by means of static factory method which takes volumetric flow in m3/h (most popular hvac unit) as an argument
+and MoistAir instance:
+
+```java
+FlowOfHumidGas flowOfAirExample = FlowOfMoistAir.ofM3hVolFlow(airExample, 5000);
```
-Results of the calculations are stored in class property fields. You can easily peek the results:
+To check all flows or parameters getters can be user, or we can print all via toString():
```
-System.out.println(flow);
-
//Outputs:
-
-Flow name: Test flow
-Locked flow: MA_VOL_FLOW
-Air properties: ta = 20.00 oC RH = 50.00 % x = 0.00726 kg.wv/kg.da status = UNSATURATED
-m_Ma = 1.653 kg/s moist air mass flow | v_Ma = 1.389 m3/s moist air vol flow | v_Ma = 5000.0 m3/h moist air vol flow
-m_Da = 1.641 kg/s dry air mass flow | v_Da = 1.363 m3/s dry air vol flow | v_Da = 4905.9 m3/h dry air vol flow
+Air properties: ta = 20.00 oC | RH = 50.00 % | x = 0.00726 kg.wv/kg.da | status = UNSATURATED
+m_Ma = 1.653 kg/s moist air mass | flowv_Ma = 1.389 m3/s moist air vol flow | v_Ma = 5000.0 m3/s moist air vol flow
+m_Da = 1.641 kg/s dry air mass flow | v_Da 1.363 m3/s dry air vol flow | v_Da = v_Da 4905.9 m3/s dry air vol flow
```
+
As you can observe, we have specified volumetric flow, and all other flows were automatically calculated.
-In HVAC dry air mass flow is required for psychrometrics calculation, volumetric moist airflow is needed for equipment capacity sizing or for final room ACH calculation.
+In HVAC discipline, dry air mass flow is required for psychrometrics calculation, volumetric moist airflow is needed for equipment
+capacity sizing or for final room ACH calculation.
Each application may need a different flow type, this is why this class combines all of them.
-"LOCKED FLOW" EXPLANATION:
-Locked flow defines which flow will have a "locked value" in case air property changes. This allows adjusting flow instance behavior depending on the application. When simulating an AHU inlet
-fan, which control system attempts to keep constant moist air volumetric flow, we want to have the same volumetric flow kept no matter how air properties will change.
-On the other hand, if we consider heating/cooling coil, we want to keep dry air mass flow locked for psychrometrics calculations and allow other flows to change accordingly to the moist air state.
-This should be carefully considered in every case. By default, using a setter of any given type of flow automatically sets this flow type as locked.
-
## FLOW OF FLUID
-FlowOfFluid is more simple compared to the above. It is designed to model a single-phase flow of any fluid class implementing the Fluid interface. At the moment LiquidWater is provided to implement condensate discharge. Examples how
-FlowOfFluid can be initiated as shown below:
+FlowOfFluid simpler compared to the above. It is designed to model a single-phase flow of any fluid class
+implementing the Fluid interface. At the moment LiquidWater is provided to implement condensate discharge. Examples how
+FlowOfFluid can be created as shown below. Similarly, as in case of flow of humid air, FlowOfFluid requires
+a Fluid instance to be created prior to instantiating the flow:
+
+```java
+// Creating flow of fluid instance
+double temp = 10.0; // oC
+double volFlow = 1.2; // m3/s
+LiquidWater waterExample = new LiquidWater.Builder()
+ .withTemperature(10)
+ .build();
+// We did not specify pressure, so the builder will assume default value.
+FlowOfFluid condensateFlow = new FlowOfSinglePhase.Builder<>(waterExample)
+ .withVolFlow(volFlow)
+ .build();
```
-//Using Constructor
-var volFlow = 1.2; // m3/s
-var temp = 10.0; //oC
-var condensate = new LiquidWater("condensate",temp);
-var condensateFlow1 = new FlowOfFluid("CondensateFlow", volFlow, TypeOfFluidFlow.VOL_FLOW, condensate);
-
-//Using Builder pattern
-var condensateFlow2 = new FlowOfFluid.Builder(LiquidWater::new).withFlowName("CondensateFlow")
- .withVolFlow(volFlow)
- .withFluidInstance(condensate)
- .build();
-//Using of() methods for water in m3/h:
-var volFlow1 = volFlow * 3600; //m3/h
-var condensateFlow3 = FlowOfFluid.ofM3hWaterVolFlow(volFlow1, temp);
-```
-Please note that Builder class in FlowOfFluid is generic, therefore an extractor must be provided as the argument (a reference to the constructor of the specific Fluid class).
## HEATING AND COOLING WITH CONDENSATE DISCHARGE
-The heating and cooling of the moist air is represented by the ProcessOfHeatingCooling class. Physical part is based on LibPhysicsOfProcess class. This class allows determining the outlet moist air properties including the condensate flow and its properties for typical HVAC cooling or heating applications. The following functionality has been
-developed so far:
-* air heating or cooling if input heating power is known,
-* air heating or cooling result if expected output temperature is known,
-* air heating or cooling result if the expected relative humidity is known.
-
-The psychrometric process of heating or cooling is based on the flow of most air. This process requires two flows: input flow and output flow. Output flow is the result of an applied process.
-Additionally, for the cooling process, there is a third part: the flow of liquid water representing the condensate discharge.
-To create the heating and cooling process class just use the constructor and pass FlowOfMoistAir instances as an input and output flow. You can specify only the input flow, in this case,
-output flow will be created automatically as an independent object cloned from the input flow. Here is some example: let's try to heat 5000m3/h of winter air of -20oC/RH=95% to the +18oC:
-```
-var inputFlow = FlowOfMoistAir.ofM3hVolFlow(5000,-20,95);
-var heater = new ProcessOfHeatingCooling(inputFlow);
-var expectedOutTemperature = 18.0; //oC
-heater.applyHeatingInQFromOutTx(expectedOutTemperature);
+
+The psychrometric process of heating or cooling is based on the flow of most air. This process requires an input
+flow. Output flow is the result of an applied process and will be created as the result of invoking runProcess() method.
+Additionally, for the cooling process, there is a third part: the flow of liquid water representing the condensate
+discharge, which also will be created during process execution.
+To create the heating and cooling process class just use the constructor and pass FlowOfMoistAir instances as an input
+and output flow. You can specify only the input flow, in this case,
+output flow will be created automatically as an independent object cloned from the input flow. Here is some example:
+let's try to heat 5000 m3/h of winter air of -20 oC / RH = 95% to the target temperature of +18oC:
+
+```java
+// Heating process example
+double targetTemp = 18.0; // oC
+// Step 1: Creating moist air instance
+HumidGas winterAmbientAir = MoistAir.ofAir(-20, 99, 101_325);
+// Step 3: creating humid air flow
+FlowOfHumidGas inletAir = FlowOfMoistAir.ofM3hVolFlow(winterAmbientAir, 5000);
+// Step 4: creating heating process
+ProcessHeatDriven heating = new HeatingForTargetTemp(inletAir, targetTemp);
+heating.runProcess();
````
-Process summary can be easily shown by invoking toString(). Output air instance can be also accessed by provided getters. Here is a process result summary:
-```
-System.out.println(heater);
-//Outputs:
--------------------------------------HEATING/COOLING PROCESS-------------------------------------
->>INLET FLOW:
-Flow name: New Flow
-Locked flow: MA_VOL_FLOW
-Air properties: ta = -20.00 oC RH = 95.00 % x = 0.00060 kg.wv/kg.da status = UNSATURATED
-m_Ma = 1.934 kg/s moist air mass flow | v_Ma = 1.389 m3/s moist air vol flow | v_Ma = 5000.0 m3/h moist air vol flow
-m_Da = 1.933 kg/s dry air mass flow | v_Da = 1.386 m3/s dry air vol flow | v_Da = 4991.4 m3/h dry air vol flow
-tx_In = -20.00 oC inlet air temperature
-RH_In = 95.00 % inlet air relative humidity
-x_In = 0.00060 kgWv/kgDa inlet air humidity ratio
-
->>OUTLET FLOW:
-Flow name: New Flow
-Locked flow: DA_MASS_FLOW
-Air properties: ta = 18.00 oC RH = 4.75 % x = 0.00060 kg.wv/kg.da status = UNSATURATED
-m_Ma = 1.934 kg/s moist air mass flow | v_Ma = 1.597 m3/s moist air vol flow | v_Ma = 5750.5 m3/h moist air vol flow
-m_Da = 1.933 kg/s dry air mass flow | v_Da = 1.595 m3/s dry air vol flow | v_Da = 5740.6 m3/h dry air vol flow
-tx_Out = 18.00 oC inlet air temperature
-RH_Out = 4.75 % inlet air relative humidity
-x_Out = 0.00060 kgWv/kgDa inlet air humidity ratio
-
->>CONDENSATE FLOW:
-Flow name: FlowOfFluid
-Locked flow: MASS_FLOW
-m_Con = 0.000 kg/s condensate mass flow | v_Con = 0.000000 m3/s condensate vol flow | v_Con = 0.000 m3/h condensate vol flow
-tx_Con = 18.00 oC condensate temperature
-
->>HEAT OF PROCESS:
-Q = 73821.55 W heating / cooling power
-
->>COIL PROPERTIES:
-ts_hydr = 6.00 oC coolant supply temperature
-tr_hydr = 12.00 oC coolant return temperature
-tm_wall = 9.00 oC average linear wall temperature
-BF = 0.000 - coil bypass factor
------------------------------------------END OF RESULTS-----------------------------------------
-```
-From the summary above we can see that the required heating power is around 73,8kW and output air property changes from -20oC/95% to 18.0oC/4.8%.
-Please note that for the heating process the condensate flow and coil properties are not relevant and could be ignored.
-The cooling process is more sophisticated. To properly calculate resulting cooling power or outlet air properties, we must include the fact that some fraction of air
-in direct contact of cooling coil wall will be cooled to approximately the average wall temperature and the water condensate will be discharged consuming a significant
-amount of cooling power. Next, this air will be mixed with part of the air which is not in direct contact. This means that the result is strongly dependent on coolant supply and
-return temperature, and resulting average wall temperature. This value must be properly provided to get a good quality result. By default, these temps are set as 6/12oC. Let's
-try to simulate cooling for a typical air conditioning scenario: ambient air 32oC/50%, expected supply temperature +24oC, volumetric flow = 5000m3/h. Coolant parameters: 8/14oC.
-```
-var inputSummerFlow = FlowOfMoistAir.ofM3hVolFlow(5000,32,50);
-var coolingCoil = new ProcessOfHeatingCooling(inputSummerFlow);
-var expectedOutSupplyTemp = 24.0; //oC
-var coolantSupTemp = 8.0;
-var coolantRetTemp = 14.0;
-coolingCoil.setTsHydr(coolantSupTemp);
-coolingCoil.setTrHydr(coolantRetTemp);
-coolingCoil.applyCoolingInQFromOutTx(expectedOutSupplyTemp);
+
+Process summary can be easily shown by invoking toString(). Output air instance can be also accessed by provided
+getters. Here is a process result summary:
+
+```
+// Outputs:
+-------------- PROCESS TYPE: HeatingForTargetTemp --------------
+INLET FLOW DATA:
+Air properties:
+ta = -20.00 oC | RH = 99.00 % | x = 0.00063 kg.wv/kg.da | status = UNSATURATED |
+Flow properties:
+m_Ma = 1.934 kg/s (moist air mass flow) | v_Ma = 1.389 m3/s (moist air vol flow) |v_Ma = 5000.0 m3/s (moist air vol flow)
+m_Da = 1.933 kg/s (dry air mass flow) | v_Da 1.386 m3/s (dry air vol flow) | v_Da = v_Da 4991.0 m3/s (dry air vol flow)
+
+OUTLET FLOW DATA:
+Air properties:
+ta = 18.00 oC | RH = 4.95 % | x = 0.00063 kg.wv/kg.da | status = UNSATURATED |
+Flow properties:
+m_Ma = 1.934 kg/s (moist air mass flow) | v_Ma = 1.597 m3/s (moist air vol flow) |v_Ma = 5750.5 m3/s (moist air vol flow)
+m_Da = 1.933 kg/s (dry air mass flow) | v_Da 1.595 m3/s (dry air vol flow) | v_Da = v_Da 5740.2 m3/s (dry air vol flow)
+
+PROCESS SPECIFIC DATA:
+Q = 73820.392 W (heat of process)
+Q = 73.82 kW (heat of process)
+```
+
+From the summary above we can see that the required heating power is around 73,8kW and output air property changes from
+-20oC/95% to 18.0 oC/4.8% what is exactly what we would expect.
+
+The cooling process is more sophisticated. To properly calculate resulting cooling power or an outlet air properties, we
+must include the fact that some fraction of air in direct contact of cooling coil wall will be cooled down to approximately
+the average wall temperature and the water condensate will be discharged consuming a significant amount of cooling power for
+its phase change. As the result - this air will be mixed with part of the air which is not in direct coil wall contact. This means
+that the result is strongly dependent on coolant supply and return temperature, and resulting average wall temperature.
+The value of average cooling coil wall temp must be provided for calculation, and for a typical case it is acceptable to
+provide arithmetic average between coolant supply and return temperatures.
+Let's try to simulate the cooling process for a typical air conditioning scenario: ambient air 32oC/50%, expected outlet air
+temperature as +24oC, volumetric flow = 5000m3/h. Coolant parameters: 8/14oC.
+
+```java
+double targetCoolingTemp = 24.0; // OC
+double averageCoilWallTemp = MathUtils.calcArithmeticAverage(8, 14); // oC
+// Step 1: Creating moist air instance
+HumidGas summerAmbientAir = MoistAir.ofAir(32 50, 90000);
+// Step 3: creating humid air flow
+FlowOfHumidGas summerAirFlow = FlowOfMoistAir.ofM3hVolFlow(summerAmbientAir, 5000);
+// Step 4: creating heating process
+ProcessHeatDriven cooling = new CoolingForTargetTemp(summerAirFlow, averageCoilWallTemp, targetCoolingTemp);
+cooling.runProcess();
```
+
Let's see the results:
+
```
--------------------------------------HEATING/COOLING PROCESS-------------------------------------
->>INLET FLOW:
-Flow name: New Flow
-Locked flow: MA_VOL_FLOW
-Air properties: ta = 32.00 oC RH = 45.00 % x = 0.01343 kg.wv/kg.da status = UNSATURATED
-m_Ma = 1.572 kg/s moist air mass flow | v_Ma = 1.389 m3/s moist air vol flow | v_Ma = 5000.0 m3/h moist air vol flow
-m_Da = 1.552 kg/s dry air mass flow | v_Da = 1.341 m3/s dry air vol flow | v_Da = 4828.7 m3/h dry air vol flow
-tx_In = 32.00 oC inlet air temperature
-RH_In = 45.00 % inlet air relative humidity
-x_In = 0.01343 kgWv/kgDa inlet air humidity ratio
-
->>OUTLET FLOW:
-Flow name: New Flow
-Locked flow: DA_MASS_FLOW
-Air properties: ta = 24.00 oC RH = 61.21 % x = 0.01142 kg.wv/kg.da status = UNSATURATED
-m_Ma = 1.569 kg/s moist air mass flow | v_Ma = 1.346 m3/s moist air vol flow | v_Ma = 4843.9 m3/h moist air vol flow
-m_Da = 1.552 kg/s dry air mass flow | v_Da = 1.306 m3/s dry air vol flow | v_Da = 4702.1 m3/h dry air vol flow
-tx_Out = 24.00 oC inlet air temperature
-RH_Out = 61.21 % inlet air relative humidity
-x_Out = 0.01142 kgWv/kgDa inlet air humidity ratio
-
->>CONDENSATE FLOW:
-Flow name: FlowOfFluid
-Locked flow: MASS_FLOW
-m_Con = 0.003 kg/s condensate mass flow | v_Con = 0.000003 m3/s condensate vol flow | v_Con = 0.011 m3/h condensate vol flow
-tx_Con = 11.00 oC condensate temperature
-
->>HEAT OF PROCESS:
-Q = -20496.41 W heating / cooling power
-
->>COIL PROPERTIES:
-ts_hydr = 8.00 oC coolant supply temperature
-tr_hydr = 14.00 oC coolant return temperature
-tm_wall = 11.00 oC average linear wall temperature
-BF = 0.619 - coil bypass factor
------------------------------------------END OF RESULTS-----------------------------------------
+-------------- PROCESS TYPE: CoolingForTargetTemp --------------
+INLET FLOW DATA:
+Air properties:
+ta = 32.00 oC | RH = 50.00 % | x = 0.01689 kg.wv/kg.da | status = UNSATURATED |
+Flow properties:
+m_Ma = 1.389 kg/s (moist air mass flow) | v_Ma = 1.389 m3/s (moist air vol flow) |v_Ma = 5000.0 m3/s (moist air vol flow)
+m_Da = 1.366 kg/s (dry air mass flow) | v_Da 1.330 m3/s (dry air vol flow) | v_Da = v_Da 4786.2 m3/s (dry air vol flow)
+
+OUTLET FLOW DATA:
+Air properties:
+ta = 24.00 oC | RH = 66.20 % | x = 0.01396 kg.wv/kg.da | status = UNSATURATED |
+Flow properties:
+m_Ma = 1.385 kg/s (moist air mass flow) | v_Ma = 1.342 m3/s (moist air vol flow) |v_Ma = 4832.7 m3/s (moist air vol flow)
+m_Da = 1.366 kg/s (dry air mass flow) | v_Da 1.295 m3/s (dry air vol flow) | v_Da = v_Da 4660.7 m3/s (dry air vol flow)
+
+CONDENSATE FLOW DATA:
+Fluid properties:
+ta = 11.00 oC | rho = 999.44 kg/m3 | fluid class = LiquidWater
+Flow properties:
+m = 0.00400 kg/s (fluid mass flow) | v = 0.00000400 m3/s (fluid vol flow) | v = 0.014 m3/h (fluid vol flow)
+
+PROCESS SPECIFIC DATA:
+Q = -21232.738 W (heat of process)
+Q = -21.23 KW (heat of process)
+BF = 0.619 [-] (coil by-pass factor)
+tm = 11.000 oC (average cooling coil wall temperature)
```
-Based on the results above: the required cooling power for the process is 20,5kW. Airflow properties have changed from 32oC/50% to 24oC/66.8%. Average wall temperature (tm_wall)
-and bypass factors were calculated based on the provided input data.
+
+Based on the results above: the required cooling power for the process is 21,2kW. Airflow properties have changed from
+32oC/50% to 24oC/66.2%. Average wall temperature (tm_wall) and bypass factors were calculated based on the provided input data.
+If for any reason you would like to use dry cooling process without specifying coil details, you can find methods for this type of process
+inside the PhysicsOfCooling class.
LIMITATIONS:
-A typical HVAC temperature range should be used. Achieving negative temperatures for cooling is not possible at the moment, ice buildup is not included in the process.
+A typical HVAC temperature range should be used. Achieving negative temperatures for cooling is not possible at the
+moment, ice buildup is not included in the process.
At this stage of development, this functionality is dedicated to air conditioning, not industrial deep cooling/freezing.
## MIXING OF TWO MOIST AIR FLOWS
-The process of mixing is represented by the ProcessOfMixing class. The physical part is based on LibPhysicsOfProcess class. The mixing process is designed to allow the mixing of two separate air flows
-and calculate output flow rate and outlet air properties as the result. Typical usage is to model the AHU recirculation section, where ambient intake is mixed with recirculated air from the room
+
+The mixing process is designed to allow the mixing of two or more moist air flows. All parameters are recalculated
+accordingly to determine the resulting output airflow. Number of streams to be mixed is practically unlimited.
+Typical usage is to model the AHU recirculation section, where ambient intake is mixed with recirculated air from the room
to reduce the heat output of the heating coil if the amount of fresh air could be reduced.
-Let's try following example: intake air of 5000m3/h (-20oC/100%) mixed with 5000 m3/h of recirculated air (15oC/30%):
-```
-var intakeFlow = FlowOfMoistAir.ofM3hVolFlow(5000,-20.0,100);
-var recircFlow = FlowOfMoistAir.ofM3hVolFlow(5000,15.0,30);
-var mixingSection = new ProcessOfMixing();
-mixingSection.setInletFlow(intakeFlow);
-mixingSection.setRecirculationFlow(recircFlow);
-mixingSection.applyMixing();
-```
-Alternatively use builder pattern for simplicity:
-```
-var mixingPlenuum = new ProcessOfMixing.Builder().withInletFlow(intakeFlow)
- .withRecirculationFlow(recircFlow)
- .build();
-mixingPlenuum.applyMixing();
-```
-Both methods will output the same result as shown below:
-```
------------------------------------------MIXING PROCESS-----------------------------------------
->>INLET FLOW:
-Flow name: New Flow
-Locked flow: DA_MASS_FLOW
-Air properties: ta = -20.00 oC RH = 100.00 % x = 0.00063 kg.wv/kg.da status = SATURATED
-m_Ma = 1.934 kg/s moist air mass flow | v_Ma = 1.389 m3/s moist air vol flow | v_Ma = 5000.0 m3/h moist air vol flow
-m_Da = 1.933 kg/s dry air mass flow | v_Da = 1.386 m3/s dry air vol flow | v_Da = 4991.0 m3/h dry air vol flow
-min_m_Da = 0.000 kg/s fixed minimum dry air mass flow
-tx_In = -20.00 oC inlet air temperature
-RH_In = 100.00 % inlet air relative humidity
-x_In = 0.00063 kgWv/kgDa inlet air humidity ratio
-
->>RECIRCULATION FLOW:
-Flow name: New Flow
-Locked flow: DA_MASS_FLOW
-Air properties: ta = 15.00 oC RH = 30.00 % x = 0.00316 kg.wv/kg.da status = UNSATURATED
-m_Ma = 1.693 kg/s moist air mass flow | v_Ma = 1.389 m3/s moist air vol flow | v_Ma = 5000.0 m3/h moist air vol flow
-m_Da = 1.687 kg/s dry air mass flow | v_Da = 1.377 m3/s dry air vol flow | v_Da = 4958.3 m3/h dry air vol flow
-min_m_Da = 0.000 kg/s fixed minimum dry air mass flow
-tx_Out = 15.00 oC recirculation air temperature
-RH_Out = 30.00 % recirculation air relative humidity
-x_Out = 0.00316 kgWv/kgDa recirculation air humidity ratio
-
->>OUTLET FLOW:
-Flow name: New Flow
-Locked flow: DA_MASS_FLOW
-Air properties: ta = -3.64 oC RH = 65.16 % x = 0.00181 kg.wv/kg.da status = UNSATURATED
-m_Ma = 3.627 kg/s moist air mass flow | v_Ma = 2.778 m3/s moist air vol flow | v_Ma = 9999.8 m3/h moist air vol flow
-m_Da = 3.620 kg/s dry air mass flow | v_Da = 2.764 m3/s dry air vol flow | v_Da = 9951.2 m3/h dry air vol flow
-min_m_Da = 0.000 kg/s fixed minimum dry air mass flow
-tx_Out = -3.64 oC outlet air temperature
-RH_Out = 65.16 % outlet air relative humidity
-x_Out = 0.00181 kgWv/kgDa outlet air humidity ratio
------------------------------------------END OF RESULTS-----------------------------------------
-```
-This process does not assume any humidity discharge. If x > xMax, water fog or ice fog is assumed to be traveling with air outside mixing plenum.
\ No newline at end of file
+For the purpose of this presentation, lets try to mix four different air flows together:
+
+```java
+// Mixing process example
+// Step 1: Creating inlet flow
+HumidGas coldAmbientAir = MoistAir.ofAir(-20, 99, 101_325);
+FlowOfHumidGas inletAirFlow = FlowOfMoistAir.ofM3hVolFlow(coldAmbientAir, 5000);
+// Step 2: Creating a couple of recirculation flows
+HumidGas returnAir1 = MoistAir.ofAir(20, 30, 101_325);
+FlowOfHumidGas returnFlow1 = FlowOfMoistAir.ofM3hVolFlow(returnAir1, 5000);
+HumidGas returnAir2 = MoistAir.ofAir(15, 45, 101_325);
+FlowOfHumidGas returnFlow2 = FlowOfMoistAir.ofM3hVolFlow(returnAir2, 2000);
+HumidGas returnAir3 = MoistAir.ofAir(18, 30, 101_325);
+FlowOfHumidGas returnFlow3 = FlowOfMoistAir.ofM3hVolFlow(returnAir3, 1000);
+// Step 3: Creating air mixing process
+ProcessWithMixing mixing = new MixingOfMoistAir(inletAirFlow, returnFlow1, returnFlow2, returnFlow3);
+mixing.runProcess();
+```
+
+Mixing process output will be as shown below:
+
+```
+-------------- PROCESS TYPE: MixingOfMoistAir --------------
+INLET FLOW DATA:
+Air properties:
+ta = -20.00 oC | RH = 99.00 % | x = 0.00063 kg.wv/kg.da | status = UNSATURATED |
+Flow properties:
+m_Ma = 1.934 kg/s (moist air mass flow) | v_Ma = 1.389 m3/s (moist air vol flow) |v_Ma = 5000.0 m3/s (moist air vol flow)
+m_Da = 1.933 kg/s (dry air mass flow) | v_Da 1.386 m3/s (dry air vol flow) | v_Da = v_Da 4991.0 m3/s (dry air vol flow)
+
+RECIRCULATION FLOW DATA:
+Air properties:
+ta = 20.00 oC | RH = 30.00 % | x = 0.00434 kg.wv/kg.da | status = UNSATURATED |
+Flow properties:
+m_Ma = 1.661 kg/s (moist air mass flow) | v_Ma = 1.389 m3/s (moist air vol flow) |v_Ma = 5000.0 m3/s (moist air vol flow)
+m_Da = 1.653 kg/s (dry air mass flow) | v_Da 1.373 m3/s (dry air vol flow) | v_Da = v_Da 4943.2 m3/s (dry air vol flow)
+
+Air properties:
+ta = 15.00 oC | RH = 45.00 % | x = 0.00475 kg.wv/kg.da | status = UNSATURATED |
+Flow properties:
+m_Ma = 0.675 kg/s (moist air mass flow) | v_Ma = 0.556 m3/s (moist air vol flow) |v_Ma = 2000.0 m3/s (moist air vol flow)
+m_Da = 0.672 kg/s (dry air mass flow) | v_Da 0.549 m3/s (dry air vol flow) | v_Da = v_Da 1975.2 m3/s (dry air vol flow)
+
+Air properties:
+ta = 18.00 oC | RH = 30.00 % | x = 0.00382 kg.wv/kg.da | status = UNSATURATED |
+Flow properties:
+m_Ma = 0.335 kg/s (moist air mass flow) | v_Ma = 0.278 m3/s (moist air vol flow) |v_Ma = 1000.0 m3/s (moist air vol flow)
+m_Da = 0.333 kg/s (dry air mass flow) | v_Da 0.275 m3/s (dry air vol flow) | v_Da = v_Da 989.9 m3/s (dry air vol flow)
+
+OUTLET FLOW DATA:
+Air properties:
+ta = 2.36 oC | RH = 62.64 % | x = 0.00280 kg.wv/kg.da | status = UNSATURATED |
+Flow properties:
+m_Ma = 4.605 kg/s (moist air mass flow) | v_Ma = 3.611 m3/s (moist air vol flow) |v_Ma = 12999.4 m3/s (moist air vol flow)
+m_Da = 4.592 kg/s (dry air mass flow) | v_Da 3.584 m3/s (dry air vol flow) | v_Da = v_Da 12903.1 m3/s (dry air vol flow)
+```
+
+This process does not assume any humidity discharge. If x > xMax, water fog or ice fog is assumed to be traveling with
+air outside process boundary.
+
+In the PhysicsOfMixing class you can find more advanced mixing algorithm, which allows fot define target output dry air mass flow,
+and output temperature. Algorithm will not only calculate the resulting flow, but will attempt to adjust an inlet flow,
+with respect of defined minimal flow limits. This might be helpful for analyzing of air heater with mixing plenum, to determine
+appropriate recirculation ratio to achieve target supply parameters.